#ifndef __STATIONIGC_H_
#define __STATIONIGC_H_
#include "modelIGC.h"
class CstationIGC;
class MyStationType : public IstationTypeIGC
{
public:
MyStationType(CstationIGC* pstation)
:
m_pstation(pstation),
m_pStationType(NULL)
{
}
~MyStationType(void)
{
if (m_pStationType)
m_pStationType->Release();
}
virtual HRESULT Initialize(ImissionIGC* pMission, Time now, const void* data, int length);
virtual void Terminate(void);
virtual void Update(Time now);
virtual ObjectType GetObjectType(void) const;
virtual ObjectID GetObjectID(void) const;
virtual const void* GetData(void) const;
virtual const char* GetName(void) const;
virtual const char* GetDescription(void) const;
virtual const char* GetModelName(void) const;
virtual const TechTreeBitMask& GetRequiredTechs(void) const;
virtual const TechTreeBitMask& GetEffectTechs(void) const;
virtual Money GetPrice(void) const;
virtual DWORD GetTimeToBuild(void) const;
virtual BuyableGroupID GetGroupID(void) const;
virtual HitPoints GetMaxArmorHitPoints(void) const;
virtual DefenseTypeID GetArmorDefenseType(void) const;
virtual HitPoints GetMaxShieldHitPoints(void) const;
virtual DefenseTypeID GetShieldDefenseType(void) const;
virtual float GetArmorRegeneration(void) const;
virtual float GetShieldRegeneration(void) const;
virtual float GetSignature(void) const;
virtual float GetRadius(void) const;
virtual float GetScannerRange(void) const;
virtual Money GetIncome(void) const;
virtual const TechTreeBitMask& GetLocalTechs(void) const;
virtual StationAbilityBitMask GetCapabilities(void) const;
virtual bool HasCapability(StationAbilityBitMask sabm) const;
virtual const char* GetTextureName(void) const;
virtual const char* GetBuilderName(void) const;
virtual const char* GetIconName(void) const;
virtual IstationTypeIGC* GetSuccessorStationType(const IsideIGC* pside);
virtual AsteroidAbilityBitMask GetBuildAABM(void) const;
virtual int GetLaunchSlots(void) const;
virtual const Vector& GetLaunchPosition(int slotID) const;
virtual const Vector& GetLaunchDirection(int slotID) const;
virtual int GetLandSlots(void) const;
virtual int GetCapLandSlots(void) const;
virtual int GetLandPlanes(int slotID) const;
virtual const Vector& GetLandPosition(int slotID, int planeID) const;
virtual const Vector& GetLandDirection(int slotID, int planeID) const;
virtual SoundID GetInteriorSound() const;
virtual SoundID GetInteriorAlertSound() const;
virtual SoundID GetExteriorSound() const;
virtual SoundID GetConstructorNeedRockSound() const;
virtual SoundID GetConstructorUnderAttackSound() const;
virtual SoundID GetConstructorDestroyedSound() const;
virtual SoundID GetCompletionSound() const;
virtual SoundID GetUnderAttackSound() const;
virtual SoundID GetCriticalSound() const;
virtual SoundID GetDestroyedSound() const;
virtual SoundID GetCapturedSound() const;
virtual SoundID GetEnemyCapturedSound() const;
virtual SoundID GetEnemyDestroyedSound() const;
virtual StationClassID GetClassID() const;
virtual IdroneTypeIGC* GetConstructionDroneType(void) const;
private:
IstationTypeIGC* GetStationType(void) const
{
return m_pStationType;
}
void SetStationType(IstationTypeIGC* pst)
{
if (m_pStationType)
m_pStationType->Release();
m_pStationType = pst;
if (pst)
{
pst->AddRef();
m_pStationData = (const DataStationTypeIGC*)(m_pStationType->GetData());
}
else
m_pStationData = NULL;
}
CstationIGC* m_pstation;
IstationTypeIGC* m_pStationType;
const DataStationTypeIGC* m_pStationData;
friend class CstationIGC;
};
class CstationIGC : public TmodelIGC<IstationIGC>
{
public:
CstationIGC(void)
:
m_myStationType(this),
m_hullFraction(1.0f),
m_shieldFraction(0.0f)
{
}
virtual HRESULT Initialize(ImissionIGC* pMission, Time now, const void* data, int length);
virtual void Terminate(void)
{
AddRef();
{
ShipLinkIGC* l;
while (l = m_shipsDocked.first()) l->data()->SetStation(NULL);
}
GetMyMission()->DeleteStation(this);
TmodelIGC<IstationIGC>::Terminate();
m_myStationType.SetStationType(NULL);
Release();
}
virtual void Update(Time now)
{
float dt = now - GetMyLastUpdate();
if (dt > 0.0f)
{
if (m_hullFraction != 1.0f)
{
m_hullFraction += dt * m_myStationType.GetArmorRegeneration() / m_myStationType.GetMaxArmorHitPoints();
if (m_hullFraction > 1.0f)
m_hullFraction = 1.0f;
}
else
{
float m = m_myStationType.GetMaxShieldHitPoints();
if ((m_shieldFraction != 1.0f) && (m != 0.0f))
{
SetShieldFraction(m_shieldFraction + dt * m_myStationType.GetShieldRegeneration() / m);
}
}
TmodelIGC<IstationIGC>::Update(now);
}
}
virtual int Export(void* data) const;
virtual ObjectType GetObjectType(void) const
{
return OT_station;
}
virtual ObjectID GetObjectID(void) const
{
return m_stationID;
}
virtual void SetCluster(IclusterIGC* cluster)
{
AddRef();
{
IclusterIGC* c = GetCluster();
if (c)
{
assert (cluster == NULL);
c->DeleteStation(this);
c->GetClusterSite()->MoveStation();
}
}
TmodelIGC<IstationIGC>::SetCluster(cluster);
if (cluster)
{
cluster->AddStation(this);
cluster->GetClusterSite()->MoveStation();
}
Release();
}
virtual void SetSide(IsideIGC* psideNew)
{
IsideIGC* psideOld = GetSide();
if (psideOld != psideNew)
{
IclusterIGC* pcluster = GetCluster();
if (psideOld != NULL)
{
if (pcluster)
pcluster->GetClusterSite()->DeleteScanner(psideOld->GetObjectID(), this);
psideOld->DeleteStation(this);
}
TmodelIGC<IstationIGC>::SetSide(psideNew);
if (psideNew != NULL)
{
psideNew->AddStation(this);
if (pcluster)
pcluster->GetClusterSite()->AddScanner(psideNew->GetObjectID(), this);
GetHitTest()->SetUseTrueShapeSelf(psideNew);
}
if (pcluster != NULL)
pcluster->GetClusterSite()->MoveStation();
}
}
virtual DamageResult ReceiveDamage(DamageTypeID type,
float amount,
Time timeCollision,
const Vector& position1,
const Vector& position2,
ImodelIGC* launcher);
virtual float GetFraction(void) const
{
return m_hullFraction;
}
virtual void SetFraction(float newVal)
{
m_hullFraction = newVal;
}
virtual float GetHitPoints(void) const
{
return m_hullFraction * (float)m_myStationType.GetMaxArmorHitPoints();
}
bool InScannerRange(ImodelIGC* pModel) const
{
assert (pModel);
bool rc;
IclusterIGC* pcluster = GetCluster();
if (pModel->GetCluster() == pcluster)
{
if (pModel->GetFlag() == NA)
{
float m = m_myStationType.GetScannerRange() * pModel->GetSignature();
{
IsideIGC* pside = pModel->GetSide();
if (pside)
m /= pside->GetGlobalAttributeSet().GetAttribute(c_gaSignature);
}
float r = GetRadius() + pModel->GetRadius() + m;
rc = ((GetPosition() - pModel->GetPosition()).LengthSquared() <= r * r) &&
LineOfSightExist(pcluster, this, pModel);
}
else
rc = true;
}
else
rc = false;
return rc;
}
bool CanSee(ImodelIGC* pModel) const
{
assert (pModel);
IsideIGC* side = GetSide();
return (pModel->GetSide() == side) || pModel->SeenBySide(side) ||
InScannerRange(pModel); }
virtual const IstationTypeIGC* GetStationType(void) const
{
return &m_myStationType;
}
virtual IstationTypeIGC* GetBaseStationType(void) const
{
return m_myStationType.GetStationType();
}
virtual void SetBaseStationType(IstationTypeIGC* pst);
virtual float GetShieldFraction(void) const
{
return m_shieldFraction;
}
virtual void SetShieldFraction(float newVal)
{
if (newVal < 0.0f)
newVal = 0.0f;
else if (newVal > 1.0f)
newVal = 1.0f;
m_shieldFraction = newVal;
}
virtual bool CanBuy(const IbuyableIGC* b) const
{
IsideIGC* s = GetSide();
assert (s);
assert (b->GetObjectType() != OT_bucket);
return b->GetRequiredTechs() <= (m_myStationType.GetLocalTechs() | s->GetTechs());
}
virtual bool IsObsolete(IbuyableIGC* b) const
{
IbuyableIGC* pSuccessor = GetSuccessor(b);
return (pSuccessor != b);
}
virtual IbuyableIGC* GetSuccessor(IbuyableIGC* b) const
{
assert (b);
IbuyableIGC* pSuccessor = b;
if (CanBuy(b))
{
IbuyableIGC* pNext = pSuccessor;
ObjectType type = b->GetObjectType();
while (true)
{
switch (type)
{
case OT_partType:
{
pNext = ((IpartTypeIGC*)pNext)->GetSuccessorPartType();
}
break;
case OT_hullType:
{
pNext = ((IhullTypeIGC*)pNext)->GetSuccessorHullType();
}
break;
default:
{
pNext = NULL;
}
}
if (pNext == NULL)
break;
if (CanBuy(pNext))
pSuccessor = pNext;
}
assert (pSuccessor);
}
return pSuccessor;
}
virtual IpartTypeIGC* GetSimilarPart(IpartTypeIGC* ppt) const
{
for (PartTypeLinkIGC* pptl = GetMission()->GetPartTypes()->first(); (pptl != NULL); pptl = pptl->next())
{
IpartTypeIGC* pptTry = pptl->data();
if (pptTry->GetSuccessorPartType() == ppt)
{
if (CanBuy(pptTry))
return pptTry;
else
ppt = pptTry;
}
}
return NULL;
}
virtual void AddShip(IshipIGC* s);
virtual void DeleteShip(IshipIGC* s);
virtual IshipIGC* GetShip(ShipID shipID) const;
virtual const ShipListIGC* GetShips(void) const;
virtual void Launch(IshipIGC* pship);
virtual void RepairAndRefuel(IshipIGC* pship) const;
virtual bool InGarage(IshipIGC* pship, const Vector& position);
virtual void SetLastDamageReport(Time timeLastDamage)
{
m_timeLastDamageReport = timeLastDamage;
}
virtual Time GetLastDamageReport(void) const
{
return m_timeLastDamageReport;
}
virtual SoundID GetInteriorSound() const
{
return (GetFraction() > 0.8) ? m_myStationType.GetInteriorSound()
: m_myStationType.GetInteriorAlertSound();
}
virtual SoundID GetExteriorSound() const
{
return m_myStationType.GetExteriorSound();
}
private:
MyStationType m_myStationType;
float m_hullFraction;
float m_shieldFraction;
Time m_timeLastDamageReport;
ShipListIGC m_shipsDocked;
StationID m_stationID;
unsigned char m_undockPosition;
};
#endif