The Great Disinheritance: make FixedGuns a component

master
Peter 2017-05-08 19:20:10 +02:00
parent 3a0ab63d5f
commit 93104a3984
8 changed files with 76 additions and 41 deletions

View File

@ -10,6 +10,7 @@
#include "Pi.h"
#include "json/JsonUtils.h"
#include "Propulsion.h"
#include "FixedGuns.h"
static const float KINETIC_ENERGY_MULT = 0.00001f;
const double DynamicBody::DEFAULT_DRAG_COEFF = 0.1; // 'smooth sphere'
@ -17,6 +18,7 @@ const double DynamicBody::DEFAULT_DRAG_COEFF = 0.1; // 'smooth sphere'
DynamicBody::DynamicBody()
: ModelBody()
, m_propulsion(nullptr)
, m_fixedGuns(nullptr)
{
m_dragCoeff = DEFAULT_DRAG_COEFF;
m_flags = Body::FLAG_CAN_MOVE_FRAME;
@ -44,6 +46,8 @@ void DynamicBody::AddFeature( Feature f ) {
m_features[f] = true;
if(f == Feature::PROPULSION && m_propulsion == nullptr) {
m_propulsion = new Propulsion();
} else if(f == Feature::FIXED_GUNS && m_fixedGuns == nullptr) {
m_fixedGuns = new FixedGuns();
}
}
@ -137,6 +141,16 @@ Propulsion *DynamicBody::GetPropulsion() {
return m_propulsion;
}
const FixedGuns *DynamicBody::GetFixedGuns() const {
assert(m_fixedGuns != nullptr);
return m_fixedGuns;
}
FixedGuns *DynamicBody::GetFixedGuns() {
assert(m_fixedGuns != nullptr);
return m_fixedGuns;
}
void DynamicBody::SetTorque(const vector3d &t)
{
m_torque = t;
@ -278,6 +292,8 @@ DynamicBody::~DynamicBody()
{
if(m_propulsion != nullptr)
delete m_propulsion;
if(m_fixedGuns != nullptr)
delete m_fixedGuns;
}
vector3d DynamicBody::GetVelocity() const

View File

@ -11,6 +11,7 @@
#include "Orbit.h"
class Propulsion;
class FixedGuns;
class DynamicBody: public ModelBody {
private:
@ -78,6 +79,8 @@ public:
void SetDecelerating(bool decel) { m_decelerating = decel; }
const Propulsion *GetPropulsion() const;
Propulsion *GetPropulsion();
const FixedGuns *GetFixedGuns() const;
FixedGuns *GetFixedGuns();
void AddFeature( Feature f );
protected:
virtual void SaveToJson(Json::Value &jsonObj, Space *space) override;
@ -111,6 +114,7 @@ private:
bool m_features[MAX_FEATURE];
Propulsion *m_propulsion;
FixedGuns *m_fixedGuns;
};
#endif /* _DYNAMICBODY_H */

View File

@ -15,7 +15,7 @@ bool FixedGuns::IsFiring()
{
bool gunstate = false;
for (int j = 0; j < Guns::GUNMOUNT_MAX; j++)
gunstate |= m_state[j];
gunstate |= m_is_firing[j];
return gunstate;
}
@ -23,7 +23,7 @@ void FixedGuns::Init(DynamicBody *b)
{
for (int i=0; i<Guns::GUNMOUNT_MAX; i++) {
// Initialize structs
m_state[i] = 0;
m_is_firing[i] = false;
m_gun[i].recharge = 0;
m_gun[i].temp_slope = 0;
m_gun[i].projData.lifespan = 0;
@ -49,7 +49,7 @@ void FixedGuns::SaveToJson( Json::Value &jsonObj, Space *space )
for (int i = 0; i<Guns::GUNMOUNT_MAX; i++)
{
Json::Value gunArrayEl(Json::objectValue); // Create JSON object to contain gun.
gunArrayEl["state"] = m_state[i];
gunArrayEl["state"] = m_is_firing[i];
gunArrayEl["recharge"] = FloatToStr(m_recharge_stat[i]);
gunArrayEl["temperature"] = FloatToStr(m_temperature_stat[i]);
gunArray.append(gunArrayEl); // Append gun object to array.
@ -71,7 +71,7 @@ void FixedGuns::LoadFromJson( const Json::Value &jsonObj, Space *space )
if (!gunArrayEl.isMember("recharge")) throw SavedGameCorruptException();
if (!gunArrayEl.isMember("temperature")) throw SavedGameCorruptException();
m_state[i] = gunArrayEl["state"].asBool();
m_is_firing[i] = gunArrayEl["state"].asBool();
m_recharge_stat[i] = StrToFloat(gunArrayEl["recharge"].asString());
m_temperature_stat[i] = StrToFloat(gunArrayEl["temperature"].asString());
}
@ -85,6 +85,7 @@ void FixedGuns::InitGun( SceneGraph::Model *m, const char *tag, int num)
m_gun[num].pos = trans.GetTranslate();
m_gun[num].dir = trans.GetOrient().VectorZ();
} else {
Output("WARNING: tag %s not found for gun %i\n", tag, num);
// XXX deprecated
m_gun[num].pos = (num==Guns::GUN_FRONT) ? vector3f(0,0,0) : vector3f(0,0,0);
m_gun[num].dir = (num==Guns::GUN_REAR) ? vector3f(0,0,-1) : vector3f(0,0,1);
@ -93,9 +94,10 @@ void FixedGuns::InitGun( SceneGraph::Model *m, const char *tag, int num)
void FixedGuns::MountGun(int num, float recharge, float lifespan, float damage, float length, float width, bool mining, const Color& color, float speed )
{
if ( num >= Guns::GUNMOUNT_MAX ) return;
if(num >= Guns::GUNMOUNT_MAX)
return;
// Here we have projectile data MORE recharge time
m_state[num] = 0;
m_is_firing[num] = false;
m_gun[num].recharge = recharge;
m_gun[num].temp_slope = 0.01; // TODO: More fun if you have a variable "speed" for temperature
m_gun[num].projData.lifespan = lifespan;
@ -110,25 +112,34 @@ void FixedGuns::MountGun(int num, float recharge, float lifespan, float damage,
void FixedGuns::UnMountGun( int num )
{
m_state[num] = 0;
m_gun[num].recharge = 0;
m_gun[num].temp_slope = 0;
m_gun[num].projData.lifespan = 0;
m_gun[num].projData.damage = 0;
m_gun[num].projData.length = 0;
m_gun[num].projData.width = 0;
m_gun[num].projData.mining = false;
m_gun[num].projData.speed = 0;
m_gun[num].projData.color = Color::BLACK;
m_gun_present[num] = false;
if(num >= Guns::GUNMOUNT_MAX)
return;
if(!m_gun_present[num])
return;
m_is_firing[num] = false;
m_gun[num].recharge = 0;
m_gun[num].temp_slope = 0;
m_gun[num].projData.lifespan = 0;
m_gun[num].projData.damage = 0;
m_gun[num].projData.length = 0;
m_gun[num].projData.width = 0;
m_gun[num].projData.mining = false;
m_gun[num].projData.speed = 0;
m_gun[num].projData.color = Color::BLACK;
m_gun_present[num] = false;
}
bool FixedGuns::Fire( int num, Body* b )
{
if (!m_gun_present[num]) return false;
if (!m_state[num]) return false;
if (!m_is_firing[num]) return false;
Output("Firing gun %i, present\n", num);
Output(" is firing\n");
if (m_recharge_stat[num]>0) return false;
Output(" recharge stat <= 0\n");
if (m_temperature_stat[num] > 1.0) return false;
Output(" temperature stat <= 1.0\n");
const vector3d dir = b->GetOrient() * vector3d(m_gun[num].dir);
const vector3d pos = b->GetOrient() * vector3d(m_gun[num].pos) + b->GetPosition();
const vector3d dirVel = m_gun[num].projData.speed * dir.Normalized();

View File

@ -23,7 +23,7 @@ class FixedGuns
{
public:
FixedGuns();
~FixedGuns();
virtual ~FixedGuns();
void Init(DynamicBody *b);
void InitGun( SceneGraph::Model *m, const char *tag, int num);
void UpdateGuns( float timeStep );
@ -37,8 +37,10 @@ class FixedGuns
inline float GetGunRange( int idx ) { return m_gun[idx].projData.speed*m_gun[idx].projData.lifespan; };
inline float GetProjSpeed(int idx ) { return m_gun[idx].projData.speed; };
inline void SetCoolingBoost( float cooler ) { m_cooler_boost = cooler; };
inline void SetGunFiringState( int idx, int s ) { if (m_gun_present[idx]) m_state[idx] = s; };
protected:
inline void SetGunFiringState( int idx, int s ) {
if(m_gun_present[idx])
m_is_firing[idx] = s;
};
virtual void SaveToJson( Json::Value &jsonObj, Space *space);
virtual void LoadFromJson( const Json::Value &jsonObj, Space *space);
private:
@ -52,7 +54,7 @@ class FixedGuns
ProjectileData projData;
};
bool m_state[Guns::GUNMOUNT_MAX];
bool m_is_firing[Guns::GUNMOUNT_MAX];
float m_recharge_stat[Guns::GUNMOUNT_MAX];
float m_temperature_stat[Guns::GUNMOUNT_MAX];
//TODO: Make it a vector and rework struct Gun to have bool dir={Forward,Backward}

View File

@ -57,7 +57,7 @@ void Ship::SaveToJson(Json::Value &jsonObj, Space *space)
shipObj["hyperspace_destination"] = hyperspaceDestObj; // Add hyperspace destination object to ship object.
shipObj["hyperspace_countdown"] = FloatToStr(m_hyperspace.countdown);
FixedGuns::SaveToJson( shipObj, space );
GetFixedGuns()->SaveToJson( shipObj, space );
shipObj["ecm_recharge"] = FloatToStr(m_ecmRecharge);
shipObj["ship_type_id"] = m_type->id;
@ -84,7 +84,8 @@ void Ship::LoadFromJson(const Json::Value &jsonObj, Space *space)
AddFeature( Feature::PROPULSION ); // add component propulsion
DynamicBody::LoadFromJson(jsonObj, space);
AddFeature( Feature::PROPULSION ); // add component propulsion
AddFeature( Feature::FIXED_GUNS ); // add component fixed guns
if (!jsonObj.isMember("ship")) throw SavedGameCorruptException();
Json::Value shipObj = jsonObj["ship"];
@ -133,7 +134,7 @@ void Ship::LoadFromJson(const Json::Value &jsonObj, Space *space)
m_hyperspace.countdown = StrToFloat(shipObj["hyperspace_countdown"].asString());
m_hyperspace.duration = 0;
FixedGuns::LoadFromJson( shipObj, space );
GetFixedGuns()->LoadFromJson( shipObj, space );
m_ecmRecharge = StrToFloat(shipObj["ecm_recharge"].asString());
SetShipId(shipObj["ship_type_id"].asString()); // XXX handle missing thirdparty ship
@ -240,8 +241,8 @@ void Ship::Init()
m_landingGearAnimation = GetModel()->FindAnimation("gear_down");
InitGun( GetModel(), "tag_gunmount_0", 0);
InitGun( GetModel(), "tag_gunmount_1", 1);
GetFixedGuns()->InitGun( GetModel(), "tag_gunmount_0", 0);
GetFixedGuns()->InitGun( GetModel(), "tag_gunmount_1", 1);
// If we've got the tag_landing set then use it for an offset
// otherwise use zero so that it will dock but look clearly incorrect
@ -270,6 +271,7 @@ Ship::Ship(const ShipType::Id &shipId): DynamicBody(),
m_landingGearAnimation(nullptr)
{
AddFeature( Feature::PROPULSION ); // add component propulsion
AddFeature( Feature::FIXED_GUNS ); // add component fixed guns
Properties().Set("flightState", EnumStrings::GetString("ShipFlightState", m_flightState));
Properties().Set("alertStatus", EnumStrings::GetString("ShipAlertStatus", m_alertState));
@ -294,7 +296,7 @@ Ship::Ship(const ShipType::Id &shipId): DynamicBody(),
m_hyperspace.countdown = 0;
m_hyperspace.now = false;
FixedGuns::Init(this);
GetFixedGuns()->Init(this);
m_ecmRecharge = 0;
m_shieldCooldown = 0.0f;
m_curAICmd = 0;
@ -542,14 +544,14 @@ void Ship::UpdateGunsStats() {
float cooler = 1.0f;
Properties().Get("laser_cooler_cap", cooler);
FixedGuns::SetCoolingBoost( cooler );
GetFixedGuns()->SetCoolingBoost( cooler );
for (int num=0; num < 2; num++) {
std::string prefix(num?"laser_rear_":"laser_front_");
int damage = 0;
Properties().Get(prefix+"damage", damage);
if (!damage) {
FixedGuns::UnMountGun(num);
GetFixedGuns()->UnMountGun(num);
return;
} else {
Properties().PushLuaTable();
@ -564,10 +566,10 @@ void Ship::UpdateGunsStats() {
const float speed = prop.Get<float>(prefix+"speed");
const float recharge = prop.Get<float>(prefix+"rechargeTime");
FixedGuns::MountGun( num, recharge, lifespan, damage, length, width, mining, c, speed );
GetFixedGuns()->MountGun( num, recharge, lifespan, damage, length, width, mining, c, speed );
if (prop.Get<int>(prefix+"dual")) FixedGuns::IsDual( num, true );
else FixedGuns::IsDual( num, false );
if (prop.Get<int>(prefix+"dual")) GetFixedGuns()->IsDual( num, true );
else GetFixedGuns()->IsDual( num, false );
lua_pop(prop.GetLua(), 1);
}
}
@ -923,7 +925,7 @@ void Ship::UpdateAlertState()
if (GetPositionRelTo(ship).LengthSqr() < ALERT_DISTANCE*ALERT_DISTANCE) {
ship_is_near = true;
Uint32 gunstate = ship->IsFiring();
Uint32 gunstate = GetFixedGuns()->IsFiring();
if (gunstate) {
ship_is_firing = true;
break;
@ -1078,9 +1080,9 @@ void Ship::StaticUpdate(const float timeStep)
m_launchLockTimeout = 0;
// lasers
FixedGuns::UpdateGuns( timeStep );
GetFixedGuns()->UpdateGuns( timeStep );
for (int i=0; i<2; i++)
if (FixedGuns::Fire(i, this)) {
if (GetFixedGuns()->Fire(i, this)) {
Sound::BodyMakeNoise(this, "Pulse_Laser", 1.0f);
LuaEvent::Queue("onShipFiring", this);
};
@ -1190,7 +1192,7 @@ void Ship::SetGunState(int idx, int state)
if (m_flightState != FLYING)
return;
FixedGuns::SetGunFiringState( idx, state );
GetFixedGuns()->SetGunFiringState( idx, state );
}
bool Ship::SetWheelState(bool down)

View File

@ -50,7 +50,7 @@ struct shipstats_t {
float fuel_tank_mass_left;
};
class Ship: public DynamicBody, public FixedGuns {
class Ship: public DynamicBody {
friend class ShipController; //only controllers need access to AITimeStep
friend class PlayerShipController;
public:

View File

@ -269,7 +269,7 @@ public:
m_leadTime = m_evadeTime = m_closeTime = 0.0;
m_lastVel = m_target->GetVelocity();
m_prop = m_dBody->GetPropulsion();
m_fguns = dynamic_cast<FixedGuns*>(m_dBody);
m_fguns = m_dBody->GetFixedGuns();
assert(m_prop!=nullptr);
assert(m_fguns!=nullptr);
}
@ -298,7 +298,7 @@ public:
m_lastVel = m_target->GetVelocity();
// Ensure needed sub-system:
m_prop = m_dBody->GetPropulsion();
m_fguns = dynamic_cast<FixedGuns*>(m_dBody);
m_fguns = m_dBody->GetFixedGuns();
assert(m_prop!=nullptr);
assert(m_fguns!=nullptr);
}

View File

@ -582,7 +582,7 @@ void WorldView::RefreshButtonStateAndVisibility()
}
}
const float activeWeaponTemp = Pi::player->GetGunTemperature(GetActiveWeapon());
const float activeWeaponTemp = Pi::player->GetFixedGuns()->GetGunTemperature(GetActiveWeapon());
if (activeWeaponTemp > 0.0f) {
m_hudWeaponTemp->SetValue(activeWeaponTemp);
m_hudWeaponTemp->Show();