CDestroyableObject, CFragileObject, CShieldedObject and CShieldedAutoRegenObject

master
krzys-h 2015-08-13 13:41:25 +02:00
parent 8a0a7b45ea
commit e5e1d4973f
26 changed files with 380 additions and 356 deletions

View File

@ -215,7 +215,6 @@ void InitializeEventTypeTexts()
EVENT_TYPE_TEXT[EVENT_INTERFACE_GROUND] = "EVENT_INTERFACE_GROUND";
EVENT_TYPE_TEXT[EVENT_INTERFACE_GADGET] = "EVENT_INTERFACE_GADGET";
EVENT_TYPE_TEXT[EVENT_INTERFACE_FOG] = "EVENT_INTERFACE_FOG";
EVENT_TYPE_TEXT[EVENT_INTERFACE_HIMSELF] = "EVENT_INTERFACE_HIMSELF";
EVENT_TYPE_TEXT[EVENT_INTERFACE_EDITMODE]= "EVENT_INTERFACE_EDITMODE";
EVENT_TYPE_TEXT[EVENT_INTERFACE_EDITVALUE]= "EVENT_INTERFACE_EDITVALUE";
EVENT_TYPE_TEXT[EVENT_INTERFACE_SOLUCE4] = "EVENT_INTERFACE_SOLUCE4";

View File

@ -239,7 +239,6 @@ enum EventType
EVENT_INTERFACE_GROUND = 472,
EVENT_INTERFACE_GADGET = 473,
EVENT_INTERFACE_FOG = 474,
EVENT_INTERFACE_HIMSELF = 475,
EVENT_INTERFACE_EDITMODE= 476,
EVENT_INTERFACE_EDITVALUE= 477,
EVENT_INTERFACE_SOLUCE4 = 478,

View File

@ -210,7 +210,6 @@ void InitializeRestext()
stringsEvent[EVENT_INTERFACE_TOOLTIP] = TR("Help balloons\\Explain the function of the buttons");
stringsEvent[EVENT_INTERFACE_MOVIES] = TR("Film sequences\\Films before and after the missions");
stringsEvent[EVENT_INTERFACE_NICERST] = TR("Exit film\\Film at the exit of exercises");
stringsEvent[EVENT_INTERFACE_HIMSELF] = TR("Friendly fire\\Your shooting can damage your own objects ");
stringsEvent[EVENT_INTERFACE_SCROLL] = TR("Scrolling\\Scrolling when the mouse touches right or left border");
stringsEvent[EVENT_INTERFACE_INVERTX] = TR("Mouse inversion X\\Inversion of the scrolling direction on the X axis");
stringsEvent[EVENT_INTERFACE_INVERTY] = TR("Mouse inversion Y\\Inversion of the scrolling direction on the Y axis");

View File

@ -38,7 +38,6 @@ CSettings::CSettings()
m_soluce4 = true;
m_movies = true;
m_niceReset = true;
m_himselfDamage = true;
m_systemMouse = false;
m_fontSize = 19.0f;
@ -78,7 +77,6 @@ void CSettings::SaveSettings()
GetConfigFile().SetIntProperty("Setup", "Soluce4", m_soluce4);
GetConfigFile().SetIntProperty("Setup", "Movies", m_movies);
GetConfigFile().SetIntProperty("Setup", "NiceReset", m_niceReset);
GetConfigFile().SetIntProperty("Setup", "HimselfDamage", m_himselfDamage);
GetConfigFile().SetIntProperty("Setup", "CameraScroll", camera->GetCameraScroll());
GetConfigFile().SetIntProperty("Setup", "CameraInvertX", camera->GetCameraInvertX());
GetConfigFile().SetIntProperty("Setup", "CameraInvertY", camera->GetCameraInvertY());
@ -168,9 +166,6 @@ void CSettings::LoadSettings()
if (GetConfigFile().GetIntProperty("Setup", "NiceReset", iValue))
m_niceReset = iValue;
if (GetConfigFile().GetIntProperty("Setup", "HimselfDamage", iValue))
m_himselfDamage = iValue;
if (GetConfigFile().GetIntProperty("Setup", "CameraScroll", iValue))
camera->SetCameraScroll(iValue);
@ -378,15 +373,6 @@ bool CSettings::GetNiceReset()
return m_niceReset;
}
void CSettings::SetHimselfDamage(bool himselfDamage)
{
m_himselfDamage = himselfDamage;
}
bool CSettings::GetHimselfDamage()
{
return m_himselfDamage;
}
void CSettings::SetSystemMouse(bool systemMouse)
{
m_systemMouse = systemMouse;

View File

@ -54,9 +54,6 @@ public:
void SetNiceReset(bool niceReset);
bool GetNiceReset();
void SetHimselfDamage(bool himselfDamage);
bool GetHimselfDamage();
void SetSystemMouse(bool systemMouse);
bool GetSystemMouse();
@ -95,7 +92,6 @@ protected:
bool m_soluce4;
bool m_movies;
bool m_niceReset;
bool m_himselfDamage;
bool m_systemMouse;
float m_fontSize;

View File

@ -50,55 +50,6 @@ const float FOG_HSUP = 10.0f;
const float FOG_HINF = 100.0f;
//! Check if an object can be destroyed, but is not an enemy
bool IsSoft(ObjectType type)
{
return ( type == OBJECT_HUMAN ||
type == OBJECT_MOBILEfa ||
type == OBJECT_MOBILEta ||
type == OBJECT_MOBILEwa ||
type == OBJECT_MOBILEia ||
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_MOBILEft ||
type == OBJECT_MOBILEtt ||
type == OBJECT_MOBILEwt ||
type == OBJECT_MOBILEit ||
type == OBJECT_MOBILEdr || // robot?
type == OBJECT_METAL ||
type == OBJECT_POWER ||
type == OBJECT_ATOMIC || // cargo?
type == OBJECT_DERRICK ||
type == OBJECT_STATION ||
type == OBJECT_FACTORY ||
type == OBJECT_REPAIR ||
type == OBJECT_DESTROYER||
type == OBJECT_CONVERT ||
type == OBJECT_TOWER ||
type == OBJECT_RESEARCH ||
type == OBJECT_RADAR ||
type == OBJECT_INFO ||
type == OBJECT_ENERGY ||
type == OBJECT_LABO ||
type == OBJECT_NUCLEAR ||
type == OBJECT_PARA ); // building?
}
//! Check if an object is a destroyable enemy
bool IsAlien(ObjectType type)
{
@ -113,11 +64,10 @@ bool IsAlien(ObjectType type)
type == OBJECT_MOBILEtg );
}
//! Returns the damping factor for friendly fire
float GetDecay(ObjectType type)
//! Check if an object can be destroyed, but is not an enemy
bool IsSoft(CObject* object)
{
if (IsSoft(type)) return 0.004f;
return 1.0f;
return object->Implements(ObjectInterfaceType::Destroyable) && !IsAlien(object->GetType());
}
CParticle::CParticle(CEngine* engine)
@ -1006,7 +956,7 @@ void CParticle::FrameParticle(float rTime)
if (object->GetType() == OBJECT_MOTHER)
object->ExplodeObject(ExplosionType::Bang, 0.1f);
else
object->ExplodeObject(ExplosionType::Bang, 0.0f, GetDecay(object->GetType()));
object->ExplodeObject(ExplosionType::Bang, 0.0f);
}
m_particle[i].zoom = 1.0f-(m_particle[i].time-m_particle[i].duration);
@ -1207,7 +1157,7 @@ void CParticle::FrameParticle(float rTime)
m_particle[i].goal = m_particle[i].pos;
if (object != nullptr)
{
object->ExplodeObject(ExplosionType::Burn, 0.0f, GetDecay(object->GetType()));
object->ExplodeObject(ExplosionType::Burn, 0.0f);
m_exploGunCounter++;
@ -1386,7 +1336,7 @@ void CParticle::FrameParticle(float rTime)
m_particle[i].goal = m_particle[i].pos;
if (object != nullptr)
{
object->ExplodeObject(ExplosionType::Bang, 0.0f, GetDecay(object->GetType()));
object->ExplodeObject(ExplosionType::Bang, 0.0f);
m_exploGunCounter ++;
@ -3609,8 +3559,6 @@ CObject* CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos,
{
if (m_main->GetMovieLock()) return nullptr; // current movie?
bool himself = m_main->GetHimselfDamage();
float min = 5.0f;
if (type == PARTIGUN2) min = 2.0f; // shooting insect?
if (type == PARTIGUN3) min = 3.0f; // suiciding spider?
@ -3641,48 +3589,24 @@ CObject* CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos,
if (type == PARTIGUN1) // fireball shooting?
{
if (oType == OBJECT_MOTHER) continue;
if (himself) // damage is oneself?
{
if ( !IsAlien(oType) &&
!IsSoft(oType) ) continue;
}
else // damage only to enemies?
{
if (!IsAlien(oType)) continue;
}
if (!obj->Implements(ObjectInterfaceType::Destroyable)) continue;
}
else if (type == PARTIGUN2) // shooting insect?
{
if (!IsSoft(oType)) continue;
if (!IsSoft(obj)) continue;
}
else if (type == PARTIGUN3) // suiciding spider?
{
if (!IsSoft(oType)) continue;
if (!IsSoft(obj)) continue;
}
else if (type == PARTIGUN4) // orgaball shooting?
{
if (oType == OBJECT_MOTHER) continue;
if (himself) // damage is oneself?
{
if ( !IsAlien(oType) &&
!IsSoft(oType) ) continue;
}
else // damage only to enemies?
{
if (!IsAlien(oType)) continue;
}
if (!obj->Implements(ObjectInterfaceType::Destroyable)) continue;
}
else if (type == PARTITRACK11) // phazer shooting?
{
if (himself) // damage is oneself?
{
if ( !IsAlien(oType) &&
!IsSoft(oType) ) continue;
}
else // damage only to enemies?
{
if (!IsAlien(oType)) continue;
}
if (!obj->Implements(ObjectInterfaceType::Destroyable)) continue;
}
else
{

View File

@ -270,11 +270,8 @@ bool CPyro::Create(PyroType type, CObject* obj, float force)
{
m_object->SetDead(true);
if ( obj->Implements(ObjectInterfaceType::Movable) )
{
CMotion* motion = dynamic_cast<CMovableObject*>(obj)->GetMotion();
motion->SetAction(MHS_DEADg, 1.0f);
}
assert(obj->Implements(ObjectInterfaceType::Movable));
dynamic_cast<CMovableObject*>(obj)->GetMotion()->SetAction(MHS_DEADg, 1.0f);
m_camera->StartCentering(m_object, Math::PI*0.5f, 99.9f, 0.0f, 1.5f);
m_camera->StartOver(CAM_OVER_EFFECT_FADEOUT_WHITE, m_pos, 1.0f);
@ -285,11 +282,9 @@ bool CPyro::Create(PyroType type, CObject* obj, float force)
{
m_object->SetDead(true);
if ( obj->Implements(ObjectInterfaceType::Movable) )
{
CMotion* motion = dynamic_cast<CMovableObject*>(obj)->GetMotion();
motion->SetAction(MHS_DEADw, 4.0f);
}
assert(obj->Implements(ObjectInterfaceType::Movable));
dynamic_cast<CMovableObject*>(obj)->GetMotion()->SetAction(MHS_DEADw, 1.0f);
m_camera->StartCentering(m_object, Math::PI*0.5f, 99.9f, 0.0f, 3.0f);
m_camera->StartOver(CAM_OVER_EFFECT_FADEOUT_BLACK, m_pos, 1.0f);
m_speed = 1.0f/10.0f;

View File

@ -1201,8 +1201,8 @@ void CRobotMain::ExecuteCmd(char *cmd)
if (strcmp(cmd, "addhusky") == 0)
{
CObject* object = GetSelect();
if (object != nullptr)
object->SetMagnifyDamage(object->GetMagnifyDamage()*0.1f);
if (object != nullptr && object->Implements(ObjectInterfaceType::Shielded))
dynamic_cast<CShieldedObject*>(object)->SetMagnifyDamage(dynamic_cast<CShieldedObject*>(object)->GetMagnifyDamage()*0.1f);
return;
}
@ -1240,7 +1240,8 @@ void CRobotMain::ExecuteCmd(char *cmd)
dynamic_cast<CPowerContainerObject*>(power)->SetEnergyLevel(1.0f);
}
object->SetShield(1.0f);
if (object->Implements(ObjectInterfaceType::Shielded))
dynamic_cast<CShieldedObject*>(object)->SetShield(1.0f);
if (object->Implements(ObjectInterfaceType::JetFlying))
dynamic_cast<CJetFlyingObject*>(object)->SetReactorRange(1.0f);
@ -1267,8 +1268,8 @@ void CRobotMain::ExecuteCmd(char *cmd)
if (strcmp(cmd, "fullshield") == 0)
{
CObject* object = GetSelect();
if (object != nullptr)
object->SetShield(1.0f);
if (object != nullptr && object->Implements(ObjectInterfaceType::Shielded))
dynamic_cast<CShieldedObject*>(object)->SetShield(1.0f);
return;
}
@ -3487,7 +3488,6 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
if (line->GetCommand() == "LevelController" && m_sceneReadPath.empty())
{
m_controller = m_objMan->CreateObject(Math::Vector(0.0f, 0.0f, 0.0f), 0.0f, OBJECT_CONTROLLER, 100.0f);
m_controller->SetMagnifyDamage(100.0f);
if (m_controller->Implements(ObjectInterfaceType::Programmable))
{
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(m_controller);
@ -5817,11 +5817,6 @@ bool CRobotMain::GetNiceReset()
return m_settings->GetNiceReset();
}
bool CRobotMain::GetHimselfDamage()
{
return m_settings->GetHimselfDamage();
}
bool CRobotMain::GetShowSoluce()
{
return m_showSoluce;

View File

@ -235,7 +235,6 @@ public:
bool GetSoluce4();
bool GetMovies();
bool GetNiceReset();
bool GetHimselfDamage();
bool GetShowSoluce();
bool GetSceneSoluce();
bool GetShowAll();

View File

@ -246,11 +246,14 @@ bool CAuto::CreateInterface(bool bSelect)
pos.y = oy+sy*0;
pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT);
pos.x = ox+sx*14.9f;
pos.y = oy+sy*0;
ddim.x = 14.0f/640.0f;
ddim.y = 66.0f/480.0f;
pw->CreateGauge(pos, ddim, 3, EVENT_OBJECT_GSHIELD);
if ( m_object->Implements(ObjectInterfaceType::Shielded) )
{
pos.x = ox+sx*14.9f;
pos.y = oy+sy*0;
ddim.x = 14.0f/640.0f;
ddim.y = 66.0f/480.0f;
pw->CreateGauge(pos, ddim, 3, EVENT_OBJECT_GSHIELD);
}
UpdateInterface();
m_lastUpdateTime = 0.0f;
@ -340,7 +343,8 @@ void CAuto::UpdateInterface(float rTime)
pg = static_cast<Ui::CGauge*>(pw->SearchControl(EVENT_OBJECT_GSHIELD));
if ( pg != nullptr )
{
pg->SetLevel(m_object->GetShield());
assert(m_object->Implements(ObjectInterfaceType::Shielded));
pg->SetLevel(dynamic_cast<CShieldedObject*>(m_object)->GetShield());
}
pg = static_cast<Ui::CGauge*>(pw->SearchControl(EVENT_OBJECT_GPROGRESS));

View File

@ -83,7 +83,7 @@ bool CAutoRepair::EventProcess(const Event &event)
CObject* vehicle;
Math::Vector pos, speed;
Math::Point dim;
float angle, shield;
float angle;
CAuto::EventProcess(event);
@ -144,16 +144,16 @@ bool CAutoRepair::EventProcess(const Event &event)
if ( m_phase == ARP_REPAIR )
{
vehicle = SearchVehicle();
if (vehicle != nullptr)
assert(vehicle->Implements(ObjectInterfaceType::Shielded));
if ( m_progress < 1.0f ||
(vehicle != 0 && vehicle->GetShield() < 1.0f) )
(vehicle != nullptr && dynamic_cast<CShieldedObject*>(vehicle)->GetShield() < 1.0f) )
{
if ( vehicle != 0 )
if ( vehicle != nullptr )
{
shield = vehicle->GetShield();
shield += event.rTime*0.2f;
if ( shield > 1.0f ) shield = 1.0f;
vehicle->SetShield(shield);
CShieldedObject* shielded = dynamic_cast<CShieldedObject*>(vehicle);
shielded->SetShield(shielded->GetShield() + event.rTime*0.2f);
}
if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time )
@ -241,34 +241,8 @@ CObject* CAutoRepair::SearchVehicle()
for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
{
ObjectType type = obj->GetType();
if ( type != OBJECT_MOBILEfa &&
type != OBJECT_MOBILEta &&
type != OBJECT_MOBILEwa &&
type != OBJECT_MOBILEia &&
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_MOBILEdr ) continue;
if ( !obj->Implements(ObjectInterfaceType::Shielded) ) continue;
if ( !dynamic_cast<CShieldedObject*>(obj)->IsRepairable() ) continue;
if ( obj->Implements(ObjectInterfaceType::Movable) && !dynamic_cast<CMovableObject*>(obj)->GetPhysics()->GetLand() ) continue; // in flight?

View File

@ -0,0 +1,39 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
#pragma once
#include "object/object_interface_type.h"
/**
* \class CDestroyableObject
* \brief Interface for objects that can be destroyed
*
* NOTE: None of the objects should inherit this class directly. Instead, inherit one of the subclasses (CShieldedObject or CFragileObject)
*/
class CDestroyableObject
{
public:
explicit CDestroyableObject(ObjectInterfaceTypes& types)
{
types[static_cast<int>(ObjectInterfaceType::Destroyable)] = true;
}
virtual ~CDestroyableObject()
{}
};

View File

@ -0,0 +1,38 @@
/*
* 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/interface/destroyable_object.h"
/**
* \class CFragileObject
* \brief Interface for objects that can be destroyed immediately after hit
*/
class CFragileObject : public CDestroyableObject
{
public:
explicit CFragileObject(ObjectInterfaceTypes& types)
: CDestroyableObject(types)
{
types[static_cast<int>(ObjectInterfaceType::Fragile)] = true;
}
virtual ~CFragileObject()
{}
};

View File

@ -0,0 +1,41 @@
/*
* 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/interface/shielded_object.h"
/**
* \class CShieldedAutoRegenObject
* \brief Interface for shielded objects with auto regeneration
*/
class CShieldedAutoRegenObject : public CShieldedObject
{
public:
explicit CShieldedAutoRegenObject(ObjectInterfaceTypes& types)
: CShieldedObject(types)
{
types[static_cast<int>(ObjectInterfaceType::ShieldedAutoRegen)] = true;
}
virtual ~CShieldedAutoRegenObject()
{}
//! Return time (in seconds) required for full shield regeneration
virtual float GetShieldFullRegenTime() = 0;
};

View File

@ -0,0 +1,46 @@
/*
* 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/interface/destroyable_object.h"
/**
* \class CShieldedObject
* \brief Interface for objects that can be destroyed, but only after the shield goes down to 0
*/
class CShieldedObject : public CDestroyableObject
{
public:
explicit CShieldedObject(ObjectInterfaceTypes& types)
: CDestroyableObject(types)
{
types[static_cast<int>(ObjectInterfaceType::Shielded)] = true;
}
virtual ~CShieldedObject()
{}
virtual void SetShield(float level) = 0;
virtual float GetShield() = 0;
virtual void SetMagnifyDamage(float factor) = 0;
virtual float GetMagnifyDamage() = 0;
//! Returns true if this object can be repaired in RepairStation
virtual bool IsRepairable() = 0;
};

View File

@ -613,7 +613,7 @@ bool CMotionHuman::EventFrame(const Event &event)
float s, a, prog, rTime[2], lTime[2], time, rot, hr, hl;
float al, ar, af;
float tSt[9], tNd[9];
float aa, bb, shield, deadFactor = 0.0f, level;
float aa, bb, deadFactor = 0.0f, level;
int i, ii, st, nd, action, legAction, armAction;
bool bOnBoard, bSwim;
@ -648,11 +648,6 @@ bool CMotionHuman::EventFrame(const Event &event)
m_object->SetCirVibration(Math::Vector(0.0f, m_main->GetPersoAngle()+0.2f, 0.0f));
}
shield = m_object->GetShield();
shield += event.rTime*(1.0f/120.0f); // regeneration in 120 seconds
if ( shield > 1.0f ) shield = 1.0f;
m_object->SetShield(shield);
bSwim = m_physics->GetSwim();
rot = m_physics->GetCirMotionY(MO_MOTSPEED);

View File

@ -47,6 +47,10 @@ enum class ObjectInterfaceType
PowerContainer, //!< objects that hold power
Ranged, //!< objects that have a operation range to be displayed after pressing button in the UI
TraceDrawing, //!< objects that can draw wheel trace
Destroyable, //!< objects that can be destroyed (base for Shielded and Fragile)
Fragile, //!< objects that are destroyed immediately after hit
Shielded, //!< objects that can be destroyed after the shield goes down to 0
ShieldedAutoRegen, //!< shielded objects with auto shield regeneration
Old, //!< old objects, TODO: remove once no longer necessary
Max //!< maximum value (for getting number of items in enum)
};

View File

@ -88,6 +88,7 @@ COldObject::COldObject(int id)
, CPowerContainerObjectImpl(m_implementedInterfaces, this)
, CRangedObject(m_implementedInterfaces)
, CTraceDrawingObject(m_implementedInterfaces)
, CShieldedAutoRegenObject(m_implementedInterfaces)
{
// A bit of a hack since we don't have subclasses yet, set externally in SetProgrammable()
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false;
@ -290,7 +291,7 @@ void COldObject::DeleteObject(bool bAll)
if ( !bAll ) m_main->CreateShortcuts();
}
// Simplifies a object (he was the programmable, among others).
// Simplifies a object (destroys all logic classes, making it a static object)
void COldObject::Simplify()
{
@ -307,6 +308,12 @@ void COldObject::Simplify()
m_physics->DeleteObject();
m_physics.reset();
}
if ( m_motion != nullptr )
{
m_motion->DeleteObject();
m_motion.reset();
}
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Movable)] = false;
if ( m_objectInterface != nullptr )
{
@ -314,12 +321,6 @@ void COldObject::Simplify()
m_objectInterface.reset();
}
if ( m_motion != nullptr )
{
m_motion->DeleteObject();
m_motion.reset();
}
if ( m_auto != nullptr )
{
m_auto->DeleteObject();
@ -334,71 +335,63 @@ void COldObject::Simplify()
// If false is returned, the object is still screwed.
// If true is returned, the object is destroyed.
bool COldObject::ExplodeObject(ExplosionType type, float force, float decay)
bool COldObject::ExplodeObject(ExplosionType type, float force)
{
Gfx::PyroType pyroType;
float loss, shield;
assert(Implements(ObjectInterfaceType::Destroyable));
assert(Implements(ObjectInterfaceType::Shielded) || Implements(ObjectInterfaceType::Fragile));
if ( type == ExplosionType::Burn )
{
if ( m_type == OBJECT_MOBILEtg ||
m_type == OBJECT_METAL ||
m_type == OBJECT_POWER ||
m_type == OBJECT_ATOMIC ||
m_type == OBJECT_TNT ||
m_type == OBJECT_SCRAP1 ||
m_type == OBJECT_SCRAP2 ||
m_type == OBJECT_SCRAP3 ||
m_type == OBJECT_SCRAP4 ||
m_type == OBJECT_SCRAP5 ||
m_type == OBJECT_BULLET ||
m_type == OBJECT_EGG ) // object that isn't burning?
if ( Implements(ObjectInterfaceType::Fragile) ) // object that isn't burning?
{
type = ExplosionType::Bang;
force = 1.0f;
decay = 1.0f;
}
}
if ( type == ExplosionType::Bang )
{
// TODO: I don't understand, why does it apply damage only once every 0.5 second?
if ( m_shotTime < 0.5f ) return false;
m_shotTime = 0.0f;
}
if ( m_type == OBJECT_HUMAN && m_bDead ) return false;
// Calculate the power lost by the explosion.
if ( force == 0.0f )
{
if ( m_type == OBJECT_HUMAN )
{
loss = LOSS_SHIELD_H;
}
else if ( m_type == OBJECT_MOTHER )
{
loss = LOSS_SHIELD_M;
}
else
{
loss = LOSS_SHIELD;
}
}
else
bool deadAlready = true;
float loss = 1.0f;
if ( Implements(ObjectInterfaceType::Shielded) )
{
// Calculate the power lost by the explosion.
loss = force;
if ( loss == 0.0f )
{
if ( m_type == OBJECT_HUMAN )
{
loss = LOSS_SHIELD_H;
}
else if ( m_type == OBJECT_MOTHER )
{
loss = LOSS_SHIELD_M;
}
else
{
loss = LOSS_SHIELD;
}
}
loss *= m_magnifyDamage;
loss *= m_main->GetGlobalMagnifyDamage();
// Decreases the power of the shield.
float shield = GetShield();
shield -= loss;
SetShield(shield);
deadAlready = (shield <= 0.0f);
}
loss *= m_magnifyDamage;
loss *= m_main->GetGlobalMagnifyDamage();
loss *= decay;
// Decreases the power of the shield.
shield = GetShield();
shield -= loss;
if ( shield < 0.0f ) shield = 0.0f;
SetShield(shield);
if ( shield > 0.0f ) // not dead yet?
Gfx::PyroType pyroType = Gfx::PT_NULL;
if ( !deadAlready ) // not dead yet?
{
if ( type == ExplosionType::Water )
{
@ -463,7 +456,7 @@ bool COldObject::ExplodeObject(ExplosionType type, float force, float decay)
pyroType = Gfx::PT_FRAGW;
}
}
else // explosion?
else if ( type == ExplosionType::Bang ) // explosion?
{
if ( m_type == OBJECT_ANT ||
m_type == OBJECT_SPIDER ||
@ -513,23 +506,23 @@ bool COldObject::ExplodeObject(ExplosionType type, float force, float decay)
{
pyroType = Gfx::PT_EXPLOT;
}
}
loss = 1.0f;
loss = 1.0f;
}
}
m_engine->GetPyroManager()->Create(pyroType, this, loss);
if ( shield == 0.0f ) // dead?
if (pyroType != Gfx::PT_NULL)
{
if ( Implements(ObjectInterfaceType::Programmable) )
{
StopProgram();
}
m_main->SaveOneScript(this);
m_engine->GetPyroManager()->Create(pyroType, this, loss);
}
if ( shield > 0.0f ) return false; // not dead yet
if ( !deadAlready ) return false; // not dead yet
if ( Implements(ObjectInterfaceType::Programmable) )
{
StopProgram();
}
m_main->SaveOneScript(this);
if ( GetSelect() )
{
@ -710,6 +703,81 @@ void COldObject::SetType(ObjectType type)
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Powered)] = true;
}
// TODO: Hacking some more
if ( m_type == OBJECT_MOBILEtg ||
m_type == OBJECT_METAL ||
m_type == OBJECT_POWER ||
m_type == OBJECT_ATOMIC ||
m_type == OBJECT_TNT ||
m_type == OBJECT_SCRAP1 ||
m_type == OBJECT_SCRAP2 ||
m_type == OBJECT_SCRAP3 ||
m_type == OBJECT_SCRAP4 ||
m_type == OBJECT_SCRAP5 ||
m_type == OBJECT_BULLET ||
m_type == OBJECT_EGG )
{
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Destroyable)] = true;
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Fragile)] = true;
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Shielded)] = false;
}
else if( m_type == OBJECT_HUMAN ||
m_type == OBJECT_MOBILEfa ||
m_type == OBJECT_MOBILEta ||
m_type == OBJECT_MOBILEwa ||
m_type == OBJECT_MOBILEia ||
m_type == OBJECT_MOBILEfc ||
m_type == OBJECT_MOBILEtc ||
m_type == OBJECT_MOBILEwc ||
m_type == OBJECT_MOBILEic ||
m_type == OBJECT_MOBILEfi ||
m_type == OBJECT_MOBILEti ||
m_type == OBJECT_MOBILEwi ||
m_type == OBJECT_MOBILEii ||
m_type == OBJECT_MOBILEfs ||
m_type == OBJECT_MOBILEts ||
m_type == OBJECT_MOBILEws ||
m_type == OBJECT_MOBILEis ||
m_type == OBJECT_MOBILErt ||
m_type == OBJECT_MOBILErc ||
m_type == OBJECT_MOBILErr ||
m_type == OBJECT_MOBILErs ||
m_type == OBJECT_MOBILEsa ||
m_type == OBJECT_MOBILEtg ||
m_type == OBJECT_MOBILEft ||
m_type == OBJECT_MOBILEtt ||
m_type == OBJECT_MOBILEwt ||
m_type == OBJECT_MOBILEit ||
m_type == OBJECT_FACTORY ||
m_type == OBJECT_REPAIR ||
m_type == OBJECT_DESTROYER||
m_type == OBJECT_DERRICK ||
m_type == OBJECT_STATION ||
m_type == OBJECT_CONVERT ||
m_type == OBJECT_TOWER ||
m_type == OBJECT_RESEARCH ||
m_type == OBJECT_RADAR ||
m_type == OBJECT_INFO ||
m_type == OBJECT_ENERGY ||
m_type == OBJECT_LABO ||
m_type == OBJECT_NUCLEAR ||
m_type == OBJECT_PARA )
{
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Destroyable)] = true;
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Fragile)] = false;
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Shielded)] = true;
}
else
{
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Destroyable)] = false;
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Fragile)] = false;
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Shielded)] = false;
}
// TODO: #TooMuchHacking
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::ShieldedAutoRegen)] = (m_type == OBJECT_HUMAN);
if ( m_type == OBJECT_MOBILEwc ||
m_type == OBJECT_MOBILEtc ||
m_type == OBJECT_MOBILEfc ||
@ -1943,6 +2011,11 @@ bool COldObject::EventFrame(const Event &event)
UpdateTransformObject();
UpdateSelectParticle();
if (Implements(ObjectInterfaceType::ShieldedAutoRegen))
{
SetShield(GetShield() + event.rTime*(1.0f/GetShieldFullRegenTime()));
}
return true;
}
@ -2195,6 +2268,8 @@ bool COldObject::IsRechargeable()
void COldObject::SetShield(float level)
{
if (level > 1.0f) level = 1.0f;
if (level < 0.0f) level = 0.0f;
m_shield = level;
}
@ -3242,3 +3317,16 @@ void COldObject::SetTraceWidth(float width)
{
m_traceWidth = width;
}
bool COldObject::IsRepairable()
{
if (m_type == OBJECT_HUMAN) return false;
return true;
}
float COldObject::GetShieldFullRegenTime()
{
if (m_type == OBJECT_HUMAN) return 120.0f;
assert(false);
return 0.0f;
}

View File

@ -37,6 +37,7 @@
#include "object/interface/powered_object.h"
#include "object/interface/programmable_object.h"
#include "object/interface/ranged_object.h"
#include "object/interface/shielded_auto_regen_object.h"
#include "object/interface/task_executor_object.h"
#include "object/interface/trace_drawing_object.h"
#include "object/interface/transportable_object.h"
@ -84,7 +85,8 @@ class COldObject : public CObject,
public CControllableObject,
public CPowerContainerObjectImpl,
public CRangedObject,
public CTraceDrawingObject
public CTraceDrawingObject,
public CShieldedAutoRegenObject
{
friend class CObjectFactory;
friend class CObjectManager;
@ -103,7 +105,7 @@ public:
~COldObject();
void Simplify() override;
bool ExplodeObject(ExplosionType type, float force, float decay=1.0f) override;
bool ExplodeObject(ExplosionType type, float force = 1.0f) override;
bool EventProcess(const Event& event) override;
void UpdateMapping();
@ -316,6 +318,9 @@ public:
float GetTraceWidth() override;
void SetTraceWidth(float width) override;
bool IsRepairable() override;
float GetShieldFullRegenTime() override;
protected:
bool EventFrame(const Event &event);
void VirusFrame(float rTime);

View File

@ -25,7 +25,7 @@ void COldObjectInterface::Simplify()
throw std::logic_error("Simplify: not implemented!");
}
bool COldObjectInterface::ExplodeObject(ExplosionType type, float force, float decay)
bool COldObjectInterface::ExplodeObject(ExplosionType type, float force)
{
throw std::logic_error("ExplodeObject: not implemented!");
}
@ -104,16 +104,6 @@ Character* COldObjectInterface::GetCharacter()
throw std::logic_error("GetCharacter: not implemented!");
}
void COldObjectInterface::SetShield(float level)
{
throw std::logic_error("SetShield: not implemented!");
}
float COldObjectInterface::GetShield()
{
throw std::logic_error("GetShield: not implemented!");
}
void COldObjectInterface::SetFixed(bool bFixed)
{
@ -137,17 +127,6 @@ bool COldObjectInterface::GetVirusMode()
}
void COldObjectInterface::SetMagnifyDamage(float factor)
{
throw std::logic_error("SetMagnifyDamage: not implemented!");
}
float COldObjectInterface::GetMagnifyDamage()
{
throw std::logic_error("GetMagnifyDamage: not implemented!");
}
void COldObjectInterface::SetParam(float value)
{
throw std::logic_error("SetParam: not implemented!");

View File

@ -63,7 +63,7 @@ public:
virtual ~COldObjectInterface() {}
virtual void Simplify();
virtual bool ExplodeObject(ExplosionType type, float force, float decay=1.0f);
virtual bool ExplodeObject(ExplosionType type, float force = 1.0f);
virtual void DeletePart(int part);
virtual void SetType(ObjectType type);
@ -93,12 +93,6 @@ public:
virtual void FlatParent();
// This goes to CShieldedObject (probably will inherit from CDestroyableObject)
virtual void SetShield(float level);
virtual float GetShield();
virtual void SetMagnifyDamage(float factor);
virtual float GetMagnifyDamage();
// This goes to CBaseAlien or something like that
virtual void SetFixed(bool bFixed);
virtual bool GetFixed();

View File

@ -43,7 +43,7 @@ CExchangePost::CExchangePost(int id)
: COldObject(id)
, m_infoUpdate(false)
{
m_type = OBJECT_INFO;
SetType(OBJECT_INFO);
}
std::unique_ptr<CExchangePost> CExchangePost::Create(

View File

@ -543,21 +543,15 @@ void CTaskShield::IncreaseShield()
{
for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
{
ObjectType type = obj->GetType();
if ( type == OBJECT_MOTHER ||
type == OBJECT_ANT ||
type == OBJECT_SPIDER ||
type == OBJECT_BEE ||
type == OBJECT_WORM ) continue;
if (!obj->Implements(ObjectInterfaceType::Shielded));
CShieldedObject* shielded = dynamic_cast<CShieldedObject*>(shielded);
if (!shielded->IsRepairable()) continue; // NOTE: Looks like the original code forgot to check that
Math::Vector oPos = obj->GetPosition();
float dist = Math::Distance(oPos, m_shieldPos);
if ( dist <= GetRadius()+10.0f )
{
float shield = obj->GetShield();
shield += 0.1f;
if ( shield > 1.0f ) shield = 1.0f;
obj->SetShield(shield);
shielded->SetShield(shielded->GetShield() + 0.1f);
}
}
}

View File

@ -3877,7 +3877,8 @@ void CScriptFunctions::uObject(CBotVar* botThis, void* user)
// Updates the shield level of the object.
pVar = pVar->GetNext(); // "shieldLevel"
value = object->GetShield();
if ( !obj->Implements(ObjectInterfaceType::Shielded) ) value = 1.0f;
else value = dynamic_cast<CShieldedObject*>(object)->GetShield();
pVar->SetValFloat(value);
// Updates the temperature of the reactor.

View File

@ -1339,31 +1339,7 @@ bool CObjectInterface::CreateInterface(bool bSelect)
pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT);
}
if ( type == OBJECT_MOBILEfa ||
type == OBJECT_MOBILEta ||
type == OBJECT_MOBILEwa ||
type == OBJECT_MOBILEia ||
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_MOBILEft ||
type == OBJECT_MOBILEtt ||
type == OBJECT_MOBILEwt ||
type == OBJECT_MOBILEit ) // vehicle?
if ( m_object->Implements(ObjectInterfaceType::Powered) ) // vehicle?
{
pos.x = ox+sx*14.5f;
pos.y = oy+sy*0;
@ -1372,34 +1348,7 @@ bool CObjectInterface::CreateInterface(bool bSelect)
pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY);
}
if ( type == OBJECT_HUMAN ||
type == OBJECT_TECH ||
type == OBJECT_MOBILEfa ||
type == OBJECT_MOBILEta ||
type == OBJECT_MOBILEwa ||
type == OBJECT_MOBILEia ||
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 ) // vehicle?
if ( m_object->Implements(ObjectInterfaceType::Shielded) ) // vehicle?
{
pos.x = ox+sx*14.9f;
pos.y = oy+sy*0;
@ -1534,7 +1483,8 @@ void CObjectInterface::UpdateInterface(float rTime)
pg = static_cast< CGauge* >(pw->SearchControl(EVENT_OBJECT_GSHIELD));
if ( pg != 0 )
{
pg->SetLevel(m_object->GetShield());
assert(m_object->Implements(ObjectInterfaceType::Shielded));
pg->SetLevel(dynamic_cast<CShieldedObject*>(m_object)->GetShield());
}
pg = static_cast< CGauge* >(pw->SearchControl(EVENT_OBJECT_GRANGE));

View File

@ -112,14 +112,6 @@ void CScreenSetupGame::CreateInterface()
pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
pos.y -= ddim.y/2;
//? pos.y -= 0.048f;
//? pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_NICERST);
//? pc->SetState(STATE_SHADOW);
//? pos.y -= 0.048f;
//? pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_HIMSELF);
//? pc->SetState(STATE_SHADOW);
ddim.x = dim.x*6;
ddim.y = dim.y*0.5f;
pos.x = ox+sx*10;
@ -225,12 +217,6 @@ bool CScreenSetupGame::EventProcess(const Event &event)
UpdateSetupButtons();
break;
case EVENT_INTERFACE_HIMSELF:
m_settings->SetHimselfDamage(!m_settings->GetHimselfDamage());
ChangeSetupButtons();
UpdateSetupButtons();
break;
case EVENT_INTERFACE_SCROLL:
m_camera->SetCameraScroll(!m_camera->GetCameraScroll());
ChangeSetupButtons();
@ -354,12 +340,6 @@ void CScreenSetupGame::UpdateSetupButtons()
pc->SetState(STATE_CHECK, m_settings->GetNiceReset());
}
pc = static_cast<CCheck*>(pw->SearchControl(EVENT_INTERFACE_HIMSELF));
if ( pc != 0 )
{
pc->SetState(STATE_CHECK, m_settings->GetHimselfDamage());
}
pc = static_cast<CCheck*>(pw->SearchControl(EVENT_INTERFACE_SCROLL));
if ( pc != 0 )
{