From 1059ae37c174286f79bdc013f8235054473532f8 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Mon, 17 Aug 2015 14:06:31 +0200 Subject: [PATCH] Shielder subclass --- src/CMakeLists.txt | 1 + src/graphics/engine/particle.cpp | 28 ++++--- src/graphics/engine/pyro.cpp | 17 +++-- src/object/object_factory.cpp | 5 +- src/object/old_object.cpp | 53 ------------- src/object/old_object.h | 6 -- src/object/old_object_interface.cpp | 16 ---- src/object/old_object_interface.h | 9 --- src/object/subclass/shielder.cpp | 113 ++++++++++++++++++++++++++++ src/object/subclass/shielder.h | 58 ++++++++++++++ src/object/task/taskshield.cpp | 20 +++-- src/object/task/taskshield.h | 5 ++ src/script/scriptfunc.cpp | 5 +- src/ui/object_interface.cpp | 6 +- 14 files changed, 225 insertions(+), 117 deletions(-) create mode 100644 src/object/subclass/shielder.cpp create mode 100644 src/object/subclass/shielder.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 23e07165..8ddb35a9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -206,6 +206,7 @@ set(BASE_SOURCES object/subclass/base_robot.cpp object/subclass/base_vehicle.cpp object/subclass/exchange_post.cpp + object/subclass/shielder.cpp object/subclass/static_object.cpp physics/physics.cpp script/cbottoken.cpp diff --git a/src/graphics/engine/particle.cpp b/src/graphics/engine/particle.cpp index ce872b48..02a6d259 100644 --- a/src/graphics/engine/particle.cpp +++ b/src/graphics/engine/particle.cpp @@ -40,6 +40,8 @@ #include "object/interface/damageable_object.h" +#include "object/subclass/shielder.h" + #include @@ -1217,7 +1219,7 @@ void CParticle::FrameParticle(float rTime) m_particle[i].goal = m_particle[i].pos; if (object != nullptr) { - if (object->GetShieldRadius() > 0.0f) // protected by shield? + if (object->GetType() == OBJECT_MOBILErs && dynamic_cast(object)->GetActiveShieldRadius() > 0.0f) // protected by shield? { CreateParticle(m_particle[i].pos, Math::Vector(0.0f, 0.0f, 0.0f), Math::Point(6.0f, 6.0f), PARTIGUNDEL, 2.0f); if (m_lastTimeGunDel > 0.2f) @@ -1263,7 +1265,7 @@ void CParticle::FrameParticle(float rTime) m_particle[i].goal = m_particle[i].pos; if (object != nullptr) { - if (object->GetShieldRadius() > 0.0f) + if (object->GetType() == OBJECT_MOBILErs && dynamic_cast(object)->GetActiveShieldRadius() > 0.0f) { CreateParticle(m_particle[i].pos, Math::Vector(0.0f, 0.0f, 0.0f), Math::Point(6.0f, 6.0f), PARTIGUNDEL, 2.0f); if (m_lastTimeGunDel > 0.2f) @@ -3614,18 +3616,22 @@ CObject* CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos, Math::Vector oPos = obj->GetPosition(); - if ( type == PARTIGUN2 || // shooting insect? - type == PARTIGUN3 ) // suiciding spider? + if (obj->GetType() == OBJECT_MOBILErs) { - // Test if the ball is entered into the sphere of a shield. - float shieldRadius = obj->GetShieldRadius(); - if (shieldRadius > 0.0f) + CShielder* shielder = dynamic_cast(obj); + if ( type == PARTIGUN2 || // shooting insect? + type == PARTIGUN3 ) // suiciding spider? { - float dist = Math::Distance(oPos, pos); - if (dist <= shieldRadius) + // Test if the ball is entered into the sphere of a shield. + float shieldRadius = shielder->GetActiveShieldRadius(); + if (shieldRadius > 0.0f) { - best = obj; - shield = true; + float dist = Math::Distance(oPos, pos); + if (dist <= shieldRadius) + { + best = obj; + shield = true; + } } } } diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index 3d451456..872134f1 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -37,6 +37,8 @@ #include "object/motion/motionhuman.h" +#include "object/subclass/shielder.h" + // Graphics module namespace namespace Gfx @@ -2202,12 +2204,15 @@ CObject* CPyro::FallSearchBeeExplo() Math::Vector oPos = obj->GetPosition(); - float shieldRadius = obj->GetShieldRadius(); - if ( shieldRadius > 0.0f ) + if (obj->GetType() == OBJECT_MOBILErs) { - float distance = Math::Distance(oPos, bulletCrashSphere.sphere.pos); - if (distance <= shieldRadius) - return obj; + float shieldRadius = dynamic_cast(obj)->GetActiveShieldRadius(); + if ( shieldRadius > 0.0f ) + { + float distance = Math::Distance(oPos, bulletCrashSphere.sphere.pos); + if (distance <= shieldRadius) + return obj; + } } if ( obj->GetType() == OBJECT_BASE ) @@ -2273,7 +2278,7 @@ void CPyro::FallProgress(float rTime) } else { - if (obj->GetShieldRadius() > 0.0f) // protected by shield? + if (obj->GetType() == OBJECT_MOBILErs && dynamic_cast(obj)->GetShieldRadius() > 0.0f) // protected by shield? { m_particle->CreateParticle(pos, Math::Vector(0.0f, 0.0f, 0.0f), Math::Point(6.0f, 6.0f), PARTIGUNDEL, 2.0f, 0.0f, 0.0f); diff --git a/src/object/object_factory.cpp b/src/object/object_factory.cpp index d1e1ed16..9a4ad582 100644 --- a/src/object/object_factory.cpp +++ b/src/object/object_factory.cpp @@ -45,6 +45,7 @@ #include "object/subclass/base_building.h" #include "object/subclass/base_robot.h" #include "object/subclass/exchange_post.h" +#include "object/subclass/shielder.h" #include "object/subclass/static_object.h" #include "physics/physics.h" @@ -248,7 +249,6 @@ CObjectUPtr CObjectFactory::CreateObject(const ObjectCreateParams& params) case OBJECT_MOBILErt: case OBJECT_MOBILErc: case OBJECT_MOBILErr: - case OBJECT_MOBILErs: case OBJECT_MOBILEsa: case OBJECT_MOBILEtg: case OBJECT_MOBILEft: @@ -259,6 +259,9 @@ CObjectUPtr CObjectFactory::CreateObject(const ObjectCreateParams& params) case OBJECT_APOLLO2: return CBaseRobot::Create(params, m_oldModelManager, m_engine); + case OBJECT_MOBILErs: + return CShielder::Create(params, m_oldModelManager, m_engine); + default: break; } diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp index 6081c329..6e7abc95 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -147,7 +147,6 @@ COldObject::COldObject(int id) m_gunGoalH = 0.0f; m_shieldRadius = 0.0f; m_magnifyDamage = 1.0f; - m_param = 0.0f; m_character = Character(); m_character.wheelFront = 1.0f; @@ -659,11 +658,6 @@ void COldObject::SetType(ObjectType type) m_type = type; m_name = GetObjectName(m_type); - if ( m_type == OBJECT_MOBILErs ) - { - m_param = 1.0f; // shield up to default - } - // TODO: Temporary hack if ( m_type == OBJECT_MOBILEfa || // WingedGrabber m_type == OBJECT_MOBILEfs || // WingedSniffer @@ -1015,14 +1009,6 @@ void COldObject::Write(CLevelParserLine* line) line->AddParam("bVirusActive", MakeUnique(GetActiveVirus())); } - if ( Implements(ObjectInterfaceType::TaskExecutor) ) - { - if ( m_type == OBJECT_MOBILErs ) - { - line->AddParam("bShieldActive", MakeUnique(IsBackgroundTask())); - } - } - if ( m_physics != nullptr ) { m_physics->Write(line); @@ -1153,17 +1139,6 @@ void COldObject::Read(CLevelParserLine* line) SetActiveVirus(line->GetParam("bVirusActive")->AsBool(false)); } - if (Implements(ObjectInterfaceType::TaskExecutor)) - { - if ( m_type == OBJECT_MOBILErs ) - { - if( line->GetParam("bShieldActive")->AsBool(false) ) - { - StartTaskShield(TSM_START); - } - } - } - if ( m_physics != nullptr ) { m_physics->Read(line); @@ -1246,21 +1221,6 @@ Math::Sphere COldObject::GetJostlingSphere() const } -// Specifies the radius of the shield. - -void COldObject::SetShieldRadius(float radius) -{ - m_shieldRadius = radius; -} - -// Returns the radius of the shield. - -float COldObject::GetShieldRadius() -{ - return m_shieldRadius; -} - - // Positioning an object on a certain height, above the ground. void COldObject::SetFloorHeight(float height) @@ -2745,19 +2705,6 @@ float COldObject::GetMagnifyDamage() } -// Management of free parameter. - -void COldObject::SetParam(float value) -{ - m_param = value; -} - -float COldObject::GetParam() -{ - return m_param; -} - - void COldObject::SetDying(DeathType deathType) { m_dying = deathType; diff --git a/src/object/old_object.h b/src/object/old_object.h index 0706fe92..8cc048a5 100644 --- a/src/object/old_object.h +++ b/src/object/old_object.h @@ -130,9 +130,6 @@ public: int GetShadowLight(); int GetEffectLight(); - void SetShieldRadius(float radius); - float GetShieldRadius() override; - void SetFloorHeight(float height); void FloorAdjust() override; @@ -239,9 +236,6 @@ public: void SetMagnifyDamage(float factor) override; float GetMagnifyDamage() override; - void SetParam(float value) override; - float GetParam() override; - void SetDying(DeathType deathType) override; DeathType GetDying() override; bool IsDying() override; diff --git a/src/object/old_object_interface.cpp b/src/object/old_object_interface.cpp index 4d5bb13d..16b63d4b 100644 --- a/src/object/old_object_interface.cpp +++ b/src/object/old_object_interface.cpp @@ -52,11 +52,6 @@ void COldObjectInterface::SetDrawFront(bool bDraw) throw std::logic_error("SetDrawFront: not implemented!"); } -float COldObjectInterface::GetShieldRadius() -{ - throw std::logic_error("GetShieldRadius: not implemented!"); -} - void COldObjectInterface::FloorAdjust() { @@ -106,17 +101,6 @@ bool COldObjectInterface::GetVirusMode() } -void COldObjectInterface::SetParam(float value) -{ - throw std::logic_error("SetParam: not implemented!"); -} - -float COldObjectInterface::GetParam() -{ - throw std::logic_error("GetParam: not implemented!"); -} - - CAuto* COldObjectInterface::GetAuto() { throw std::logic_error("GetAuto: not implemented!"); diff --git a/src/object/old_object_interface.h b/src/object/old_object_interface.h index 5a3e72ca..20d7c629 100644 --- a/src/object/old_object_interface.h +++ b/src/object/old_object_interface.h @@ -85,15 +85,6 @@ public: virtual void SetVirusMode(bool bEnable); virtual bool GetVirusMode(); - // These go to Shielder subclass - //! Shielder radius (only while active) [0 or RADIUS_SHIELD_MIN..RADIUS_SHIELD_MAX] - virtual float GetShieldRadius(); - //! Shielder radius [0..1] - //@{ - virtual void SetParam(float value); - virtual float GetParam(); - //@} - // This will be eventually removed after refactoring to subclasses virtual CAuto* GetAuto(); }; diff --git a/src/object/subclass/shielder.cpp b/src/object/subclass/shielder.cpp new file mode 100644 index 00000000..91f0e3af --- /dev/null +++ b/src/object/subclass/shielder.cpp @@ -0,0 +1,113 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#include "object/subclass/shielder.h" + +#include "common/make_unique.h" + +#include "graphics/engine/oldmodelmanager.h" + +#include "level/parser/parserline.h" +#include "level/parser/parserparam.h" + +#include "object/object_create_params.h" + +#include "object/motion/motionvehicle.h" + +#include "object/task/taskshield.h" + +#include "physics/physics.h" + + +CShielder::CShielder(int id) + : CBaseRobot(id, OBJECT_MOBILErs), + m_shieldRadius(1.0f) +{} + +CShielder::~CShielder() +{} + +std::unique_ptr CShielder::Create( + const ObjectCreateParams& params, + Gfx::COldModelManager* modelManager, + Gfx::CEngine* engine) +{ + assert(params.type == OBJECT_MOBILErs); + auto obj = MakeUnique(params.id); + + obj->SetTeam(params.team); + obj->SetTrainer(params.trainer); + obj->SetToy(params.toy); + + auto physics = MakeUnique(obj.get()); + auto motion = MakeUnique(obj.get()); + + motion->SetPhysics(physics.get()); + physics->SetMotion(motion.get()); + + motion->Create(params.pos, params.angle, params.type, params.power, modelManager); + + obj->SetProgrammable(); + obj->SetMovable(std::move(motion), std::move(physics)); + + return std::move(obj); +} + +void CShielder::SetShieldRadius(float shieldRadius) +{ + m_shieldRadius = shieldRadius; +} + +float CShielder::GetShieldRadius() +{ + return m_shieldRadius; +} + +float CShielder::GetActiveShieldRadius() +{ + if (IsBackgroundTask()) + { + CTaskShield* taskShield = dynamic_cast(GetBackgroundTask()); + if (taskShield != nullptr) + { + return taskShield->GetActiveRadius(); + } + } + return 0.0f; +} + + +// TODO: Is shield radius saved somewhere? I can't find it + +void CShielder::Read(CLevelParserLine* line) +{ + COldObject::Read(line); + + if( line->GetParam("bShieldActive")->AsBool(false) ) + { + StartTaskShield(TSM_START); + } +} + +void CShielder::Write(CLevelParserLine* line) +{ + COldObject::Write(line); + + line->AddParam("bShieldActive", MakeUnique(IsBackgroundTask())); +} diff --git a/src/object/subclass/shielder.h b/src/object/subclass/shielder.h new file mode 100644 index 00000000..51c837f3 --- /dev/null +++ b/src/object/subclass/shielder.h @@ -0,0 +1,58 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#pragma once + +#include "object/subclass/base_robot.h" + +struct ObjectCreateParams; + +namespace Gfx +{ +class COldModelManager; +class CEngine; +} + +class CShielder : public CBaseRobot +{ +public: + CShielder(int id); + virtual ~CShielder(); + +public: + static std::unique_ptr Create( + const ObjectCreateParams& params, + Gfx::COldModelManager* modelManager, + Gfx::CEngine* engine); + +public: + //! Shielder radius (only while active) [0 or RADIUS_SHIELD_MIN..RADIUS_SHIELD_MAX] + float GetActiveShieldRadius(); + //! Shielder radius [0..1] + //@{ + void SetShieldRadius(float shieldRadius); + float GetShieldRadius(); + //@} + + void Write(CLevelParserLine* line) override; + void Read(CLevelParserLine* line) override; + +protected: + float m_shieldRadius; +}; diff --git a/src/object/task/taskshield.cpp b/src/object/task/taskshield.cpp index b60e7eea..61091941 100644 --- a/src/object/task/taskshield.cpp +++ b/src/object/task/taskshield.cpp @@ -34,6 +34,8 @@ #include "object/interface/powered_object.h" +#include "object/subclass/shielder.h" + #include "physics/physics.h" #include @@ -51,6 +53,7 @@ CTaskShield::CTaskShield(COldObject* object) : CBackgroundTask(object) m_effectLight = -1; assert(m_object->Implements(ObjectInterfaceType::Powered)); + m_shielder = dynamic_cast(object); } // Object's destructor. @@ -255,8 +258,6 @@ Error CTaskShield::Start(TaskShieldMode mode, float delay) { Math::Point dim; - m_object->SetShieldRadius(GetRadius()); - Math::Matrix* mat = m_object->GetWorldMatrix(0); Math::Vector pos = Math::Vector(7.0f, 15.0f, 0.0f); pos = Transform(*mat, pos); // sphere position @@ -333,8 +334,6 @@ Error CTaskShield::Stop() if ( m_phase == TS_SHIELD ) { - m_object->SetShieldRadius(0.0f); - if ( m_rankSphere != -1 ) { m_particle->SetPhase(m_rankSphere, Gfx::PARPHEND, 3.0f); @@ -379,8 +378,6 @@ Error CTaskShield::IsEnded() if ( m_phase == TS_SHIELD ) { - m_object->SetShieldRadius(GetRadius()); - energy = GetObjectEnergy(m_object); if ( energy == 0.0f || m_delay <= 0.0f ) @@ -414,8 +411,6 @@ Error CTaskShield::IsEnded() pos.z = 0.0f; m_object->SetPartPosition(3, pos); - m_object->SetShieldRadius(GetRadius()); - pos = m_shieldPos; speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = GetRadius(); @@ -472,8 +467,6 @@ bool CTaskShield::Abort() { Math::Vector pos; - m_object->SetShieldRadius(0.0f); - pos.x = 7.0f; pos.y = 4.5f; pos.z = 0.0f; @@ -561,5 +554,10 @@ void CTaskShield::IncreaseShield() float CTaskShield::GetRadius() { - return RADIUS_SHIELD_MIN + (RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)*m_object->GetParam(); + return RADIUS_SHIELD_MIN + (RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)*m_shielder->GetShieldRadius(); +} + +float CTaskShield::GetActiveRadius() +{ + return m_phase == TS_SHIELD ? GetRadius() : 0.0f; } diff --git a/src/object/task/taskshield.h b/src/object/task/taskshield.h index e62a3194..fd133a94 100644 --- a/src/object/task/taskshield.h +++ b/src/object/task/taskshield.h @@ -47,6 +47,8 @@ enum TaskShieldMode TSM_START = 4, // start with shield up }; +class CShielder; + class CTaskShield : public CBackgroundTask @@ -62,6 +64,8 @@ public: bool IsBusy(); bool Abort(); + float GetActiveRadius(); + protected: Error Stop(); bool CreateLight(Math::Vector pos); @@ -69,6 +73,7 @@ protected: float GetRadius(); protected: + CShielder* m_shielder; TaskShieldPhase m_phase = TS_UP1; float m_progress = 0.0f; float m_speed = 0.0f; diff --git a/src/script/scriptfunc.cpp b/src/script/scriptfunc.cpp index e04c63ba..3a16cc05 100644 --- a/src/script/scriptfunc.cpp +++ b/src/script/scriptfunc.cpp @@ -52,6 +52,7 @@ #include "object/subclass/base_alien.h" #include "object/subclass/exchange_post.h" +#include "object/subclass/shielder.h" #include "object/task/taskinfo.h" @@ -2508,7 +2509,7 @@ bool CScriptFunctions::rShield(CBotVar* var, CBotVar* result, int& exception, vo } else // up ? { - pThis->SetParam(radius); + dynamic_cast(pThis)->SetShieldRadius(radius); err = script->m_taskExecutor->StartTaskShield(TSM_UP, 1000.0f); if ( err != ERR_OK ) { @@ -2526,7 +2527,7 @@ bool CScriptFunctions::rShield(CBotVar* var, CBotVar* result, int& exception, vo else // up? { //? result->SetValInt(1); // shows the error - pThis->SetParam(radius); + dynamic_cast(pThis)->SetShieldRadius(radius); script->m_taskExecutor->StartTaskShield(TSM_UPDATE, 0.0f); } } diff --git a/src/ui/object_interface.cpp b/src/ui/object_interface.cpp index 83b814f9..a29ddc0b 100644 --- a/src/ui/object_interface.cpp +++ b/src/ui/object_interface.cpp @@ -42,6 +42,8 @@ #include "object/motion/motion.h" #include "object/motion/motionvehicle.h" +#include "object/subclass/shielder.h" + #include "physics/physics.h" #include "script/script.h" @@ -584,7 +586,7 @@ bool CObjectInterface::EventProcess(const Event &event) ps = static_cast< CSlider* >(pw->SearchControl(EVENT_OBJECT_DIMSHIELD)); if ( ps != 0 ) { - m_object->SetParam((ps->GetVisibleValue()-(RADIUS_SHIELD_MIN/g_unit))/((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit)); + dynamic_cast(m_object)->SetShieldRadius((ps->GetVisibleValue()-(RADIUS_SHIELD_MIN/g_unit))/((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit)); } } } @@ -1708,7 +1710,7 @@ void CObjectInterface::UpdateInterface() ps = static_cast< CSlider* >(pw->SearchControl(EVENT_OBJECT_DIMSHIELD)); if ( ps != 0 ) { - ps->SetVisibleValue((RADIUS_SHIELD_MIN/g_unit)+m_object->GetParam()*((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit)); + ps->SetVisibleValue((RADIUS_SHIELD_MIN/g_unit)+dynamic_cast(m_object)->GetShieldRadius()*((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit)); } }