Shielder subclass

master
krzys-h 2015-08-17 14:06:31 +02:00
parent 63bee182d2
commit 1059ae37c1
14 changed files with 225 additions and 117 deletions

View File

@ -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

View File

@ -40,6 +40,8 @@
#include "object/interface/damageable_object.h"
#include "object/subclass/shielder.h"
#include <cstring>
@ -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<CShielder*>(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<CShielder*>(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<CShielder*>(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;
}
}
}
}

View File

@ -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<CShielder*>(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<CShielder*>(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);

View File

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

View File

@ -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<CLevelParserParam>(GetActiveVirus()));
}
if ( Implements(ObjectInterfaceType::TaskExecutor) )
{
if ( m_type == OBJECT_MOBILErs )
{
line->AddParam("bShieldActive", MakeUnique<CLevelParserParam>(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;

View File

@ -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;

View File

@ -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!");

View File

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

View File

@ -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> CShielder::Create(
const ObjectCreateParams& params,
Gfx::COldModelManager* modelManager,
Gfx::CEngine* engine)
{
assert(params.type == OBJECT_MOBILErs);
auto obj = MakeUnique<CShielder>(params.id);
obj->SetTeam(params.team);
obj->SetTrainer(params.trainer);
obj->SetToy(params.toy);
auto physics = MakeUnique<CPhysics>(obj.get());
auto motion = MakeUnique<CMotionVehicle>(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<CTaskShield*>(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<CLevelParserParam>(IsBackgroundTask()));
}

View File

@ -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<CShielder> 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;
};

View File

@ -34,6 +34,8 @@
#include "object/interface/powered_object.h"
#include "object/subclass/shielder.h"
#include "physics/physics.h"
#include <string.h>
@ -51,6 +53,7 @@ CTaskShield::CTaskShield(COldObject* object) : CBackgroundTask(object)
m_effectLight = -1;
assert(m_object->Implements(ObjectInterfaceType::Powered));
m_shielder = dynamic_cast<CShielder*>(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;
}

View File

@ -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;

View File

@ -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<CShielder*>(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<CShielder*>(pThis)->SetShieldRadius(radius);
script->m_taskExecutor->StartTaskShield(TSM_UPDATE, 0.0f);
}
}

View File

@ -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<CShielder*>(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<CShielder*>(m_object)->GetShieldRadius()*((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit));
}
}