From 4c10730f87f80e47945c4ec014c5ea4c2f9d4710 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Fri, 10 Jul 2015 22:13:39 +0200 Subject: [PATCH] CCarrierObject interface --- src/graphics/engine/camera.cpp | 16 +++++--- src/graphics/engine/pyro.cpp | 20 +++++++--- src/object/auto/autopowercaptor.cpp | 16 +++++--- src/object/auto/autopowerstation.cpp | 24 ++++++----- src/object/brain.cpp | 4 +- src/object/interface/carrier_object.h | 57 +++++++++++++++++++++++++++ src/object/motion/motionbee.cpp | 4 +- src/object/motion/motionhuman.cpp | 25 ++++++------ src/object/object_interface_type.h | 1 + src/object/old_object.cpp | 11 ++++-- src/object/old_object.h | 4 +- src/object/old_object_interface.h | 2 - src/object/robotmain.cpp | 27 +++++++------ src/object/task/taskbuild.cpp | 3 +- src/object/task/taskflag.cpp | 3 +- src/object/task/taskmanip.cpp | 54 +++++++++++++------------ src/object/task/taskmanip.h | 3 ++ src/object/task/taskreset.cpp | 19 +++++---- src/object/task/tasktake.cpp | 31 +++++++-------- src/object/task/tasktake.h | 6 +-- src/physics/physics.cpp | 17 ++++---- 21 files changed, 224 insertions(+), 123 deletions(-) create mode 100644 src/object/interface/carrier_object.h diff --git a/src/graphics/engine/camera.cpp b/src/graphics/engine/camera.cpp index ef6fb998..de49a868 100644 --- a/src/graphics/engine/camera.cpp +++ b/src/graphics/engine/camera.cpp @@ -33,6 +33,7 @@ #include "object/object.h" #include "object/object_manager.h" #include "object/robotmain.h" +#include "object/interface/carrier_object.h" #include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -47,13 +48,16 @@ void SetTransparency(CObject* obj, float value) { obj->SetTransparency(value); - CObject *cargo = obj->GetCargo(); - if (cargo != NULL) - cargo->SetTransparency(value); + if (obj->Implements(ObjectInterfaceType::Carrier)) + { + CObject* cargo = dynamic_cast(obj)->GetCargo(); + if (cargo != nullptr) + cargo->SetTransparency(value); + } - cargo = obj->GetPower(); - if (cargo != NULL) - cargo->SetTransparency(value); + CObject* power = obj->GetPower(); + if (power != nullptr) + power->SetTransparency(value); } diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index 8d37358d..f2d94081 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -1364,11 +1364,15 @@ void CPyro::DeleteObject(bool primary, bool secondary) m_object->SetPower(nullptr); } - sub = m_object->GetCargo(); - if ( sub != nullptr ) + if (m_object->Implements(ObjectInterfaceType::Carrier)) { - CObjectManager::GetInstancePointer()->DeleteObject(sub); - m_object->SetCargo(nullptr); + CCarrierObject* carrierObject = dynamic_cast(m_object); + sub = carrierObject->GetCargo(); + if (sub != nullptr) + { + CObjectManager::GetInstancePointer()->DeleteObject(sub); + carrierObject->SetCargo(nullptr); + } } } @@ -1383,8 +1387,12 @@ void CPyro::DeleteObject(bool primary, bool secondary) if (transporter->GetPower() == m_object) transporter->SetPower(nullptr); - if (transporter->GetCargo() == m_object) - transporter->SetCargo(nullptr); + if (transporter->Implements(ObjectInterfaceType::Carrier)) + { + CCarrierObject* carrier = dynamic_cast(transporter); + if (carrier->GetCargo() == m_object) + carrier->SetCargo(nullptr); + } } } diff --git a/src/object/auto/autopowercaptor.cpp b/src/object/auto/autopowercaptor.cpp index 4326d5e9..8868c76a 100644 --- a/src/object/auto/autopowercaptor.cpp +++ b/src/object/auto/autopowercaptor.cpp @@ -26,6 +26,7 @@ #include "object/object_manager.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" +#include "object/interface/carrier_object.h" #include "object/interface/transportable_object.h" #include "ui/interface.h" @@ -267,13 +268,16 @@ void CAutoPowerCaptor::ChargeObject(float rTime) power->SetEnergy(energy); } - power = obj->GetCargo(); - if ( power != nullptr && power->GetType() == OBJECT_POWER ) + if (obj->Implements(ObjectInterfaceType::Carrier)) { - float energy = power->GetEnergy(); - energy += rTime/2.0f; - if ( energy > 1.0f ) energy = 1.0f; - power->SetEnergy(energy); + power = dynamic_cast(obj)->GetCargo(); + if ( power != nullptr && power->GetType() == OBJECT_POWER ) + { + float energy = power->GetEnergy(); + energy += rTime/2.0f; + if ( energy > 1.0f ) energy = 1.0f; + power->SetEnergy(energy); + } } } } diff --git a/src/object/auto/autopowerstation.cpp b/src/object/auto/autopowerstation.cpp index 01a5a856..a3e5fe6e 100644 --- a/src/object/auto/autopowerstation.cpp +++ b/src/object/auto/autopowerstation.cpp @@ -26,6 +26,7 @@ #include "math/geometry.h" #include "object/object_manager.h" +#include "object/interface/carrier_object.h" #include "ui/interface.h" #include "ui/gauge.h" @@ -151,17 +152,20 @@ bool CAutoPowerStation::EventProcess(const Event &event) big -= add/4.0f; // discharge the large battery } - power = vehicle->GetCargo(); - if ( power != 0 && power->GetType() == OBJECT_POWER ) + if (vehicle->Implements(ObjectInterfaceType::Carrier)) { - energy = power->GetEnergy(); - add = event.rTime*0.2f; - if ( add > big*4.0f ) add = big*4.0f; - if ( add > 1.0f-energy ) add = 1.0f-energy; - energy += add; // Charging the battery - power->SetEnergy(energy); - if ( energy < freq ) freq = energy; - big -= add/4.0f; // discharge the large battery + power = dynamic_cast(vehicle)->GetCargo(); + if ( power != nullptr && power->GetType() == OBJECT_POWER ) + { + energy = power->GetEnergy(); + add = event.rTime*0.2f; + if ( add > big*4.0f ) add = big*4.0f; + if ( add > 1.0f-energy ) add = 1.0f-energy; + energy += add; // Charging the battery + power->SetEnergy(energy); + if ( energy < freq ) freq = energy; + big -= add/4.0f; // discharge the large battery + } } } } diff --git a/src/object/brain.cpp b/src/object/brain.cpp index 672607d7..9fcbed73 100644 --- a/src/object/brain.cpp +++ b/src/object/brain.cpp @@ -33,6 +33,7 @@ #include "object/task/taskmanager.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" +#include "object/interface/carrier_object.h" #include "physics/physics.h" @@ -2393,7 +2394,8 @@ void CBrain::UpdateInterface() bFly = bEnable; if ( bFly && (type == OBJECT_HUMAN || type == OBJECT_TECH) ) { - if ( m_object->GetCargo() != 0 ) bFly = false; // if holder -> not fly + if (m_object->Implements(ObjectInterfaceType::Carrier) && dynamic_cast(m_object)->IsCarryingCargo()) + bFly = false; } EnableInterface(pw, EVENT_OBJECT_GASUP, bFly && m_main->CanPlayerInteract()); EnableInterface(pw, EVENT_OBJECT_GASDOWN, bFly && m_main->CanPlayerInteract()); diff --git a/src/object/interface/carrier_object.h b/src/object/interface/carrier_object.h new file mode 100644 index 00000000..3108049e --- /dev/null +++ b/src/object/interface/carrier_object.h @@ -0,0 +1,57 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#pragma once + +#include "object/object.h" +#include "object/object_interface_type.h" + +struct Event; + +/** + * \class CCarrierObject + * \brief Interface for carrier objects + */ +class CCarrierObject +{ +public: + explicit CCarrierObject(ObjectInterfaceTypes& types) + { + types[static_cast(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(obj)->IsCarryingCargo(); +} diff --git a/src/object/motion/motionbee.cpp b/src/object/motion/motionbee.cpp index d7b3b814..9d4c5daa 100644 --- a/src/object/motion/motionbee.cpp +++ b/src/object/motion/motionbee.cpp @@ -24,6 +24,8 @@ #include "graphics/engine/oldmodelmanager.h" +#include "object/interface/carrier_object.h" + #include "physics/physics.h" @@ -436,7 +438,7 @@ bool CMotionBee::EventFrame(const Event &event) action = MB_MARCH; // flying m_actionType = -1; - if ( m_object->GetCargo() != 0 ) m_actionType = MBS_HOLD; // carries the ball + if (IsObjectCarryingCargo(m_object)) m_actionType = MBS_HOLD; // carries the ball if ( m_object->GetRuin() ) // destroyed? { diff --git a/src/object/motion/motionhuman.cpp b/src/object/motion/motionhuman.cpp index 5881c6c4..f2cc2255 100644 --- a/src/object/motion/motionhuman.cpp +++ b/src/object/motion/motionhuman.cpp @@ -29,6 +29,7 @@ #include "math/geometry.h" #include "object/robotmain.h" +#include "object/interface/carrier_object.h" #include "physics/physics.h" @@ -739,7 +740,7 @@ bool CMotionHuman::EventFrame(const Event &event) s = 0.0f; } - if ( m_object->GetCargo() != 0 ) // carries something? + if (IsObjectCarryingCargo(m_object)) // carries something? { s *= 1.3f; } @@ -771,7 +772,7 @@ bool CMotionHuman::EventFrame(const Event &event) s = 0.0f; } - if ( m_object->GetCargo() != 0 ) // carries something? + if (IsObjectCarryingCargo(m_object)) // carries something? { s *= 1.3f; } @@ -836,7 +837,7 @@ bool CMotionHuman::EventFrame(const Event &event) else { action = MH_MARCH; // walking - if ( m_object->GetCargo() != 0 ) action = MH_MARCHTAKE; // take walking + if (IsObjectCarryingCargo(m_object)) action = MH_MARCHTAKE; // take walking rTime[0] = rTime[1] = m_armMember; lTime[0] = lTime[1] = m_armMember+0.5f; } @@ -875,7 +876,7 @@ bool CMotionHuman::EventFrame(const Event &event) armAction = action; legAction = action; - if ( m_object->GetCargo() != 0 ) // carries something? + if (IsObjectCarryingCargo(m_object)) // carries something? { armAction = MH_MARCHTAKE; // take walking } @@ -989,7 +990,7 @@ bool CMotionHuman::EventFrame(const Event &event) aa = 0.5f; if ( i%2 == 0 ) // arm? { - if ( m_object->GetCargo() == 0 ) // does nothing? + if (! IsObjectCarryingCargo(m_object)) { aa = 2.0f; // moves a lot } @@ -1620,16 +1621,16 @@ bool CMotionHuman::EventFrame(const Event &event) float speedX = m_physics->GetLinMotionX(MO_REASPEED); - if ( m_object->GetCargo() == 0 ) - { - if ( speedX > 0.0f ) synchro = 0.21f; // synchro forward - else synchro = 0.29f; // synchro backward - } - else + if (IsObjectCarryingCargo(m_object)) { if ( speedX > 0.0f ) synchro = 0.15f; // synchro forward else synchro = 0.35f; // synchro backward } + else + { + if ( speedX > 0.0f ) synchro = 0.21f; // synchro forward + else synchro = 0.29f; // synchro backward + } time = rTime[1]+synchro; if ( fabs(m_lastSoundMarch-time) > 0.4f && @@ -1637,7 +1638,7 @@ bool CMotionHuman::EventFrame(const Event &event) { volume[0] = 0.5f; freq[0] = 1.0f; - if ( m_object->GetCargo() != 0 ) + if (IsObjectCarryingCargo(m_object)) { //? volume[0] *= 2.0f; freq[0] = 0.7f; diff --git a/src/object/object_interface_type.h b/src/object/object_interface_type.h index a25baa56..c98d8362 100644 --- a/src/object/object_interface_type.h +++ b/src/object/object_interface_type.h @@ -36,6 +36,7 @@ enum class ObjectInterfaceType Transportable, //!< objects that can be carried by robots or astronaut Programmable, //!< objects that can be programmed in CBOT Jostleable, //!< object that can be jostled + Carrier, //!< object that can carry other objects Max //!< maximum value (for getting number of items in enum) }; diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp index 9781f808..6d7e340b 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -82,7 +82,6 @@ void uObject(CBotVar* botThis, void* user) { CObject* object = static_cast(user); CObject* power; - CObject* cargo; CPhysics* physics; CBotVar *pVar, *pSub; ObjectType type; @@ -167,9 +166,12 @@ void uObject(CBotVar* botThis, void* user) // Updates the transported object's type. pVar = pVar->GetNext(); // "load" - cargo = object->GetCargo(); - if ( cargo == 0 ) pVar->SetPointer(0); - else pVar->SetPointer(cargo->GetBotVar()); + if (object->Implements(ObjectInterfaceType::Carrier)) + { + CObject* cargo = dynamic_cast(object)->GetCargo(); + if (cargo == nullptr) pVar->SetPointer(0); + else pVar->SetPointer(cargo->GetBotVar()); + } pVar = pVar->GetNext(); // "id" value = object->GetID(); @@ -191,6 +193,7 @@ COldObject::COldObject(int id) , CTransportableObject(m_implementedInterfaces) , CProgrammableObject(m_implementedInterfaces) , CJostleableObject(m_implementedInterfaces) + , CCarrierObject(m_implementedInterfaces) { // A bit of a hack since CBrain is set externally in SetBrain() m_implementedInterfaces[static_cast(ObjectInterfaceType::Programmable)] = false; diff --git a/src/object/old_object.h b/src/object/old_object.h index 2fe48f18..640c2769 100644 --- a/src/object/old_object.h +++ b/src/object/old_object.h @@ -26,6 +26,7 @@ #include "object/object.h" +#include "object/interface/carrier_object.h" #include "object/interface/interactive_object.h" #include "object/interface/jostleable_object.h" #include "object/interface/programmable_object.h" @@ -58,7 +59,8 @@ class COldObject : public CObject, public CInteractiveObject, public CTransportableObject, public CProgrammableObject, - public CJostleableObject + public CJostleableObject, + public CCarrierObject { friend class CObjectFactory; friend class CObjectManager; diff --git a/src/object/old_object_interface.h b/src/object/old_object_interface.h index 754156c9..1b268661 100644 --- a/src/object/old_object_interface.h +++ b/src/object/old_object_interface.h @@ -158,8 +158,6 @@ public: virtual void SetPower(CObject* power) = 0; virtual CObject* GetPower() = 0; - virtual void SetCargo(CObject* cargo) = 0; - virtual CObject* GetCargo() = 0; virtual void SetCmdLine(unsigned int rank, float value) = 0; virtual float GetCmdLine(unsigned int rank) = 0; diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index 09cfec35..db9f73ff 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -4941,16 +4941,18 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char * if (obj->GetDead()) continue; if (obj->IsExploding()) continue; - CObject* power = obj->GetPower(); - CObject* cargo = obj->GetCargo(); - - if (cargo != nullptr) // object transported? + if (obj->Implements(ObjectInterfaceType::Carrier)) { - line.reset(new CLevelParserLine("CreateFret")); - IOWriteObject(line.get(), cargo); - levelParser.AddLine(std::move(line)); + CObject* cargo = dynamic_cast(obj)->GetCargo(); + if (cargo != nullptr) // object transported? + { + line.reset(new CLevelParserLine("CreateFret")); + IOWriteObject(line.get(), cargo); + levelParser.AddLine(std::move(line)); + } } + CObject* power = obj->GetPower(); if (power != nullptr) // battery transported? { line.reset(new CLevelParserLine("CreatePower")); @@ -5091,8 +5093,7 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot) levelParser.Load(); m_base = nullptr; - CObject* cargo = nullptr; - CObject* power = nullptr; + CObject* sel = nullptr; int objRank = 0; for (auto& line : levelParser.GetLines()) @@ -5112,9 +5113,11 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot) m_lightning->SetStatus(sleep, delay, magnetic, progress); } + CObject* cargo = nullptr; if (line->GetCommand() == "CreateFret") cargo = IOReadObject(line.get(), filename, -1); + CObject* power = nullptr; if (line->GetCommand() == "CreatePower") power = IOReadObject(line.get(), filename, -1); @@ -5127,7 +5130,8 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot) if (cargo != nullptr) { - obj->SetCargo(cargo); + assert(obj->Implements(ObjectInterfaceType::Carrier)); // TODO: exception? + dynamic_cast(obj)->SetCargo(cargo); CTaskManip* task = new CTaskManip(obj); task->Start(TMO_AUTO, TMA_GRAB); // holds the object! delete task; @@ -5138,9 +5142,6 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot) obj->SetPower(power); dynamic_cast(power)->SetTransporter(obj); } - - cargo = nullptr; - power = nullptr; } } diff --git a/src/object/task/taskbuild.cpp b/src/object/task/taskbuild.cpp index 99e93a10..f106885f 100644 --- a/src/object/task/taskbuild.cpp +++ b/src/object/task/taskbuild.cpp @@ -32,6 +32,7 @@ #include "object/motion/motionhuman.h" #include "object/object_manager.h" #include "object/robotmain.h" +#include "object/interface/carrier_object.h" #include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -366,7 +367,7 @@ Error CTaskBuild::Start(ObjectType type) if ( speed.x != 0.0f || speed.z != 0.0f ) return ERR_BUILD_MOTOR; - if ( m_object->GetCargo() != 0 ) return ERR_MANIP_BUSY; + if (IsObjectCarryingCargo(m_object)) return ERR_MANIP_BUSY; m_metal = SearchMetalObject(oAngle, 2.0f, 100.0f, Math::PI*0.25f, err); if ( err == ERR_BUILD_METALNEAR && m_metal != 0 ) diff --git a/src/object/task/taskflag.cpp b/src/object/task/taskflag.cpp index 19bf8ea5..6c950b06 100644 --- a/src/object/task/taskflag.cpp +++ b/src/object/task/taskflag.cpp @@ -28,6 +28,7 @@ #include "object/object_manager.h" #include "object/motion/motionhuman.h" +#include "object/interface/carrier_object.h" #include "physics/physics.h" @@ -85,7 +86,7 @@ Error CTaskFlag::Start(TaskFlagOrder order, int rank) if ( speed.x != 0.0f || speed.z != 0.0f ) return ERR_FLAG_MOTOR; - if ( m_object->GetCargo() != 0 ) return ERR_FLAG_BUSY; + if (IsObjectCarryingCargo(m_object)) return ERR_FLAG_BUSY; if ( order == TFL_CREATE ) { diff --git a/src/object/task/taskmanip.cpp b/src/object/task/taskmanip.cpp index aa9eb200..c2aec87e 100644 --- a/src/object/task/taskmanip.cpp +++ b/src/object/task/taskmanip.cpp @@ -27,6 +27,7 @@ #include "object/object_manager.h" #include "object/robotmain.h" +#include "object/interface/carrier_object.h" #include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -50,6 +51,9 @@ CTaskManip::CTaskManip(CObject* object) : CTask(object) { m_arm = TMA_NEUTRAL; m_hand = TMH_OPEN; + + assert(m_object->Implements(ObjectInterfaceType::Carrier)); + m_carrier = dynamic_cast(m_object); } // Object's destructor. @@ -318,22 +322,22 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) type = m_object->GetType(); if ( type == OBJECT_BEE ) // bee? { - if ( m_object->GetCargo() == 0 ) + if ( m_carrier->GetCargo() == 0 ) { if ( !m_physics->GetLand() ) return ERR_MANIP_FLY; other = SearchTakeUnderObject(m_targetPos, MARGIN_BEE); if ( other == 0 ) return ERR_MANIP_NIL; - m_object->SetCargo(other); // takes the ball + m_carrier->SetCargo(other); // takes the ball dynamic_cast(other)->SetTransporter(m_object); dynamic_cast(other)->SetTransporterPart(0); // taken with the base other->SetPosition(0, Math::Vector(0.0f, -3.0f, 0.0f)); } else { - other = m_object->GetCargo(); // other = ball - m_object->SetCargo(0); // lick the ball + other = m_carrier->GetCargo(); // other = ball + m_carrier->SetCargo(0); // lick the ball dynamic_cast(other)->SetTransporter(0); pos = m_object->GetPosition(0); pos.y -= 3.0f; @@ -386,7 +390,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) if ( order == TMO_AUTO ) { - if ( m_object->GetCargo() == 0 ) + if ( m_carrier->GetCargo() == 0 ) { m_order = TMO_GRAB; } @@ -400,11 +404,11 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) m_order = order; } - if ( m_order == TMO_GRAB && m_object->GetCargo() != 0 ) + if ( m_order == TMO_GRAB && m_carrier->GetCargo() != 0 ) { return ERR_MANIP_BUSY; } - if ( m_order == TMO_DROP && m_object->GetCargo() == 0 ) + if ( m_order == TMO_DROP && m_carrier->GetCargo() == 0 ) { return ERR_MANIP_EMPTY; } @@ -500,7 +504,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm) if ( m_timeLimit < 0.5f ) m_timeLimit = 0.5f; } - if ( m_object->GetCargo() == 0 ) // not carrying anything? + if ( m_carrier->GetCargo() == 0 ) // not carrying anything? { m_hand = TMH_OPEN; // open clamp } @@ -625,7 +629,7 @@ Error CTaskManip::IsEnded() { if ( m_bSubm ) m_speed = 1.0f/1.5f; if ( !TransporterTakeObject() && - m_object->GetCargo() == 0 ) + m_carrier->GetCargo() == 0 ) { m_hand = TMH_OPEN; // reopens the clamp m_arm = TMA_NEUTRAL; @@ -654,7 +658,7 @@ Error CTaskManip::IsEnded() if ( m_step == 1 ) { if ( m_bSubm ) m_speed = 1.0f/0.7f; - cargo = m_object->GetCargo(); + cargo = m_carrier->GetCargo(); if ( TransporterDeposeObject() ) { if ( (m_arm == TMA_OTHER || @@ -694,7 +698,7 @@ bool CTaskManip::Abort() { int i; - if ( m_object->GetCargo() == 0 ) // not carrying anything? + if ( m_carrier->GetCargo() == 0 ) // not carrying anything? { m_hand = TMH_OPEN; // open clamp m_arm = TMA_NEUTRAL; @@ -1091,7 +1095,7 @@ bool CTaskManip::TransporterTakeObject() if ( m_arm == TMA_GRAB ) // takes immediately? { - cargo = m_object->GetCargo(); + cargo = m_carrier->GetCargo(); if ( cargo == 0 ) return false; // nothing to take? m_cargoType = cargo->GetType(); @@ -1129,7 +1133,7 @@ bool CTaskManip::TransporterTakeObject() cargo->SetAngleY(0, 0.0f); } - m_object->SetCargo(cargo); // takes + m_carrier->SetCargo(cargo); // takes } if ( m_arm == TMA_FFRONT ) // takes on the ground in front? @@ -1161,7 +1165,7 @@ bool CTaskManip::TransporterTakeObject() cargo->SetAngleY(0, 0.0f); } - m_object->SetCargo(cargo); // takes + m_carrier->SetCargo(cargo); // takes } if ( m_arm == TMA_FBACK ) // takes on the ground behind? @@ -1179,7 +1183,7 @@ bool CTaskManip::TransporterTakeObject() cargo->SetAngleZ(0, Math::PI/2.0f); cargo->SetAngleY(0, 0.0f); - m_object->SetCargo(cargo); // takes + m_carrier->SetCargo(cargo); // takes } if ( m_arm == TMA_POWER ) // takes battery in the back? @@ -1196,7 +1200,7 @@ bool CTaskManip::TransporterTakeObject() dynamic_cast(cargo)->SetTransporterPart(3); // takes with the hand m_object->SetPower(0); - m_object->SetCargo(cargo); // takes + m_carrier->SetCargo(cargo); // takes } if ( m_arm == TMA_OTHER ) // battery takes from friend? @@ -1218,7 +1222,7 @@ bool CTaskManip::TransporterTakeObject() cargo->SetAngleZ(0, Math::PI/2.0f); cargo->SetAngleY(0, 0.0f); - m_object->SetCargo(cargo); // takes + m_carrier->SetCargo(cargo); // takes } return true; @@ -1237,7 +1241,7 @@ bool CTaskManip::TransporterDeposeObject() if ( m_arm == TMA_FFRONT ) // deposits on the ground in front? { - cargo = m_object->GetCargo(); + cargo = m_carrier->GetCargo(); if ( cargo == 0 ) return false; // nothing transported? m_cargoType = cargo->GetType(); @@ -1251,12 +1255,12 @@ bool CTaskManip::TransporterDeposeObject() cargo->FloorAdjust(); // plate well on the ground dynamic_cast(cargo)->SetTransporter(0); - m_object->SetCargo(0); // deposit + m_carrier->SetCargo(0); // deposit } if ( m_arm == TMA_FBACK ) // deposited on the ground behind? { - cargo = m_object->GetCargo(); + cargo = m_carrier->GetCargo(); if ( cargo == 0 ) return false; // nothing transported? m_cargoType = cargo->GetType(); @@ -1269,12 +1273,12 @@ bool CTaskManip::TransporterDeposeObject() cargo->SetAngleZ(0, 0.0f); dynamic_cast(cargo)->SetTransporter(0); - m_object->SetCargo(0); // deposit + m_carrier->SetCargo(0); // deposit } if ( m_arm == TMA_POWER ) // deposits battery in the back? { - cargo = m_object->GetCargo(); + cargo = m_carrier->GetCargo(); if ( cargo == 0 ) return false; // nothing transported? m_cargoType = cargo->GetType(); @@ -1290,7 +1294,7 @@ bool CTaskManip::TransporterDeposeObject() cargo->SetAngleZ(0, 0.0f); m_object->SetPower(cargo); // uses - m_object->SetCargo(0); + m_carrier->SetCargo(0); } if ( m_arm == TMA_OTHER ) // deposits battery on friend? @@ -1301,7 +1305,7 @@ bool CTaskManip::TransporterDeposeObject() cargo = other->GetPower(); if ( cargo != 0 ) return false; // the other already has a battery? - cargo = m_object->GetCargo(); + cargo = m_carrier->GetCargo(); if ( cargo == 0 ) return false; m_cargoType = cargo->GetType(); @@ -1315,7 +1319,7 @@ bool CTaskManip::TransporterDeposeObject() cargo->SetAngleZ(0, 0.0f); dynamic_cast(cargo)->SetTransporterPart(0); // carried by the base - m_object->SetCargo(0); // deposit + m_carrier->SetCargo(0); // deposit } return true; diff --git a/src/object/task/taskmanip.h b/src/object/task/taskmanip.h index e1e665e2..1ec7a762 100644 --- a/src/object/task/taskmanip.h +++ b/src/object/task/taskmanip.h @@ -28,6 +28,8 @@ +class CCarrierObject; + enum TaskManipOrder { TMO_AUTO = 0, // deposits or takes automatically @@ -78,6 +80,7 @@ protected: void SoundManip(float time, float amplitude=1.0f, float frequency=1.0f); protected: + CCarrierObject* m_carrier; TaskManipOrder m_order; TaskManipArm m_arm; TaskManipHand m_hand; diff --git a/src/object/task/taskreset.cpp b/src/object/task/taskreset.cpp index 546b75d7..64d5bd6b 100644 --- a/src/object/task/taskreset.cpp +++ b/src/object/task/taskreset.cpp @@ -23,6 +23,7 @@ #include "object/brain.h" #include "object/object_manager.h" #include "object/robotmain.h" +#include "object/interface/carrier_object.h" #include "object/interface/transportable_object.h" @@ -164,14 +165,16 @@ bool CTaskReset::EventProcess(const Event &event) Error CTaskReset::Start(Math::Vector goal, Math::Vector angle) { - CObject* cargo; - int i; - - cargo = m_object->GetCargo(); - if ( cargo != nullptr && cargo->GetResetCap() == RESET_MOVE ) + if (m_object->Implements(ObjectInterfaceType::Carrier)) { - dynamic_cast(cargo)->SetTransporter(0); - m_object->SetCargo(0); // does nothing + CCarrierObject* carrier = dynamic_cast(m_object); + CObject* cargo = carrier->GetCargo(); + if ( cargo != nullptr && cargo->GetResetCap() == RESET_MOVE ) + { + assert(cargo->Implements(ObjectInterfaceType::Transportable)); + dynamic_cast(cargo)->SetTransporter(nullptr); + carrier->SetCargo(nullptr); // does nothing + } } if ( !m_main->GetNiceReset() ) // quick return? @@ -208,7 +211,7 @@ Error CTaskReset::Start(Math::Vector goal, Math::Vector angle) m_object->SetResetBusy(true); - i = m_sound->Play(SOUND_GGG, m_begin, 1.0f, 2.0f, true); + int i = m_sound->Play(SOUND_GGG, m_begin, 1.0f, 2.0f, true); m_sound->AddEnvelope(i, 0.0f, 0.5f, RESET_DELAY_ZOOM, SOPER_STOP); m_bError = false; diff --git a/src/object/task/tasktake.cpp b/src/object/task/tasktake.cpp index 0acfaa06..aeca7739 100644 --- a/src/object/task/tasktake.cpp +++ b/src/object/task/tasktake.cpp @@ -28,6 +28,7 @@ #include "object/motion/motionhuman.h" #include "object/object_manager.h" #include "object/robotmain.h" +#include "object/interface/carrier_object.h" #include "object/interface/transportable_object.h" #include "physics/physics.h" @@ -39,9 +40,10 @@ CTaskTake::CTaskTake(CObject* object) : CTask(object) { - m_terrain = CRobotMain::GetInstancePointer()->GetTerrain(); - m_arm = TTA_NEUTRAL; + + assert(m_object->Implements(ObjectInterfaceType::Carrier)); + m_carrier = dynamic_cast(m_object); } // Object's destructor. @@ -113,14 +115,11 @@ Error CTaskTake::Start() m_physics->SetMotorSpeed(Math::Vector(0.0f, 0.0f, 0.0f)); - if ( m_object->GetCargo() == 0 ) - { - m_order = TTO_TAKE; - } - else - { + if (m_carrier->IsCarryingCargo()) m_order = TTO_DEPOSE; - } + else + m_order = TTO_TAKE; + if ( m_order == TTO_TAKE ) { @@ -260,7 +259,7 @@ Error CTaskTake::IsEnded() { if ( m_step == 1 ) { - cargo = m_object->GetCargo(); + cargo = m_carrier->GetCargo(); TransporterDeposeObject(); if ( m_arm == TTA_FRIEND && (m_cargoType == OBJECT_POWER || @@ -470,7 +469,7 @@ bool CTaskTake::TransporterTakeObject() cargo->SetAngleX(0, 0.0f); cargo->SetAngleZ(0, 0.8f); - m_object->SetCargo(cargo); // takes + m_carrier->SetCargo(cargo); // takes } if ( m_arm == TTA_FRIEND ) // takes friend's battery? @@ -492,7 +491,7 @@ bool CTaskTake::TransporterTakeObject() cargo->SetAngleX(0, 0.0f); cargo->SetAngleZ(0, 0.8f); - m_object->SetCargo(cargo); // takes + m_carrier->SetCargo(cargo); // takes } return true; @@ -511,7 +510,7 @@ bool CTaskTake::TransporterDeposeObject() if ( m_arm == TTA_FFRONT ) // deposes on the ground in front? { - cargo = m_object->GetCargo(); + cargo = m_carrier->GetCargo(); if ( cargo == 0 ) return false; // does nothing? m_cargoType = cargo->GetType(); @@ -525,7 +524,7 @@ bool CTaskTake::TransporterDeposeObject() cargo->FloorAdjust(); // plate well on the ground dynamic_cast(cargo)->SetTransporter(0); - m_object->SetCargo(0); // deposit + m_carrier->SetCargo(0); // deposit } if ( m_arm == TTA_FRIEND ) // deposes battery on friends? @@ -536,7 +535,7 @@ bool CTaskTake::TransporterDeposeObject() cargo = other->GetPower(); if ( cargo != 0 ) return false; // the other already has a battery? - cargo = m_object->GetCargo(); + cargo = m_carrier->GetCargo(); if ( cargo == 0 ) return false; m_cargoType = cargo->GetType(); @@ -550,7 +549,7 @@ bool CTaskTake::TransporterDeposeObject() cargo->SetAngleZ(0, 0.0f); dynamic_cast(cargo)->SetTransporterPart(0); // carried by the base - m_object->SetCargo(0); // deposit + m_carrier->SetCargo(0); // deposit } return true; diff --git a/src/object/task/tasktake.h b/src/object/task/tasktake.h index c4f5ed7c..b95f4598 100644 --- a/src/object/task/tasktake.h +++ b/src/object/task/tasktake.h @@ -26,6 +26,8 @@ #include "object/object.h" +class CCarrierObject; + enum TaskTakeOrder { @@ -62,9 +64,7 @@ protected: bool IsFreeDeposeObject(Math::Vector pos); protected: - //TODO this is same member as in base class, probable should be deleted - Gfx::CTerrain* m_terrain; - + CCarrierObject* m_carrier; TaskTakeOrder m_order; TaskTakeArm m_arm; int m_step; diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 5315798c..9261df6b 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -43,6 +43,7 @@ #include "object/task/task.h" #include "object/level/parserline.h" #include "object/level/parserparam.h" +#include "object/interface/carrier_object.h" #include "object/interface/jostleable_object.h" #include "object/interface/transportable_object.h" @@ -811,7 +812,7 @@ void CPhysics::MotorUpdate(float aTime, float rTime) type == OBJECT_TECH ) { power = 0; - if ( m_object->GetCargo() != 0 && // carries something? + if (IsObjectCarryingCargo(m_object)&& // carries something? !m_object->IsSpaceshipCargo() ) { motorSpeed.x *= 0.7f; // forward more slowly @@ -826,7 +827,7 @@ void CPhysics::MotorUpdate(float aTime, float rTime) motorSpeed.z *= 0.5f; motorSpeed.y *= 0.5f; - if ( m_object->GetCargo() != 0 ) // carries something? + if (IsObjectCarryingCargo(m_object)) // carries something? { motorSpeed.x *= 0.2f; motorSpeed.z *= 0.9f; @@ -3039,18 +3040,20 @@ void CPhysics::FrameParticle(float aTime, float rTime) void CPhysics::PowerParticle(float factor, bool bBreak) { Character* character; - CObject* cargo; Math::Matrix* mat; Math::Vector pos, ppos, eye, speed; Math::Point dim; bool bCarryPower; bCarryPower = false; - cargo = m_object->GetCargo(); - if ( cargo != 0 && cargo->GetType() == OBJECT_POWER && - m_object->GetAngleZ(1) == ARM_STOCK_ANGLE1 ) + if (m_object->Implements(ObjectInterfaceType::Carrier)) { - bCarryPower = true; // carries a battery + CObject* cargo = dynamic_cast(m_object)->GetCargo(); + if ( cargo != nullptr && cargo->GetType() == OBJECT_POWER && + m_object->GetAngleZ(1) == ARM_STOCK_ANGLE1 ) + { + bCarryPower = true; // carries a battery + } } mat = m_object->GetWorldMatrix(0);