#ifndef __SIDEIGC_H_
#define __SIDEIGC_H_
class CsideIGC : public IsideIGC
{
public:
CsideIGC(void)
:
m_activeF(false), m_dwPrivate(NULL)
{
}
~CsideIGC(void)
{
}
public:
virtual HRESULT Initialize(ImissionIGC* pMission, Time now, const void* data, int dataSize);
virtual void Terminate(void);
virtual void Update(Time now)
{
for (BucketLinkIGC* l = m_buckets.first();
(l != NULL);
l = l->next())
{
l->data()->Update(now);
}
m_lastUpdate = now;
}
virtual int Export(void* data) const;
virtual ObjectType GetObjectType(void) const
{
return OT_side;
}
virtual ObjectID GetObjectID(void) const
{
return m_data.sideID;
}
virtual ImissionIGC* GetMission(void) const
{
return m_pMission;
}
virtual IcivilizationIGC* GetCivilization(void) const
{
return m_pCivilization;
}
virtual void SetCivilization(IcivilizationIGC* pciv)
{
assert (pciv);
assert (m_pCivilization);
if (m_pCivilization != pciv)
{
m_pCivilization->Release();
m_pCivilization = pciv;
pciv->AddRef();
m_data.ttbmDevelopmentTechs = GetCivilization()->GetBaseTechs();
m_ttbmBuildingTechs.ClearAll();
m_data.civilizationID = GetCivilization()->GetObjectID();
{
for (StationLinkIGC* psl = m_stations.first(); (psl != NULL); psl = psl->next())
{
IstationIGC* pstation = psl->data();
pstation->SetBaseStationType(pciv->GetInitialStationType());
}
}
}
}
virtual void DestroyBuckets(void);
virtual void CreateBuckets(void);
void SetName(const char* newVal)
{
UTL::putName(m_data.name, newVal);
}
virtual const char* GetName(void) const
{
return m_data.name;
}
virtual SquadID GetSquadID() const
{
return m_data.squadID;
}
virtual void SetSquadID(SquadID squadID)
{
m_data.squadID = squadID;
}
virtual const TechTreeBitMask GetTechs(void) const
{
return m_ttbmBuildingTechs | m_data.ttbmDevelopmentTechs;
}
virtual const TechTreeBitMask& GetBuildingTechs(void) const
{
return m_ttbmBuildingTechs;
}
virtual void ResetBuildingTechs(void)
{
TechTreeBitMask ttbm;
ttbm.ClearAll();
{
for (StationLinkIGC* l = m_stations.first();
(l != NULL);
l = l->next())
{
ttbm |= l->data()->GetStationType()->GetEffectTechs();
}
}
SetBuildingTechs(ttbm);
}
virtual void SetBuildingTechs(const TechTreeBitMask& ttbm)
{
if (ttbm != m_ttbmBuildingTechs)
{
m_ttbmBuildingTechs = ttbm;
m_pMission->GetIgcSite()->SideBuildingTechChange(this);
AdjustBuckets();
}
}
virtual const TechTreeBitMask& GetDevelopmentTechs(void) const
{
return m_data.ttbmDevelopmentTechs;
}
virtual void SetDevelopmentTechs(const TechTreeBitMask& ttbm)
{
if (ttbm != m_data.ttbmDevelopmentTechs)
{
m_data.ttbmDevelopmentTechs = ttbm;
m_pMission->GetIgcSite()->SideDevelopmentTechChange(this);
AdjustBuckets();
}
}
virtual bool IsNewDevelopmentTechs(const TechTreeBitMask& ttbm)
{
if (!(ttbm <= m_data.ttbmDevelopmentTechs))
return true;
else
return false;
}
virtual bool ApplyDevelopmentTechs(const TechTreeBitMask& ttbm)
{
bool rc;
if (!(ttbm <= m_data.ttbmDevelopmentTechs))
{
rc = true;
m_data.ttbmDevelopmentTechs |= ttbm;
m_pMission->GetIgcSite()->SideDevelopmentTechChange(this);
AdjustBuckets();
}
else
rc = false;
return rc;
}
virtual const TechTreeBitMask& GetInitialTechs(void) const
{
return m_data.ttbmInitialTechs;
}
virtual void SetInitialTechs(const TechTreeBitMask& ttbm)
{
m_data.ttbmInitialTechs = ttbm;
}
virtual void UpdateInitialTechs(void)
{
m_data.ttbmInitialTechs = m_data.ttbmDevelopmentTechs;
}
virtual bool CanBuy(const IbuyableIGC* b) const
{
ObjectType type = b->GetObjectType();
if (type == OT_bucket)
{
b = ((IbucketIGC*)b)->GetBuyable();
type = b->GetObjectType();
}
TechTreeBitMask ttbmSide = (m_ttbmBuildingTechs | m_data.ttbmDevelopmentTechs);
const TechTreeBitMask& ttbmRequired = b->GetRequiredTechs();
bool bAvailable;
if (type == OT_development)
{
bAvailable = (ttbmRequired <= ttbmSide) ||
(b->GetObjectID() == c_didTeamMoney); }
else
{
if (type == OT_stationType)
{
const IstationTypeIGC* pstSuccessor = ((IstationTypeIGC*)b)->GetSuccessorStationType(this);
if (pstSuccessor != b)
return false;
}
bAvailable = false;
for (StationLinkIGC* psl = m_stations.first(); (psl != NULL); psl = psl->next())
{
TechTreeBitMask ttbmStation = psl->data()->GetStationType()->GetLocalTechs() |
ttbmSide;
if (ttbmRequired <= ttbmStation)
{
bAvailable = true;
break;
}
}
}
return bAvailable;
}
virtual void AddStation(IstationIGC* s)
{
AddIbaseIGC((BaseListIGC*)&m_stations, s);
SetBuildingTechs(m_ttbmBuildingTechs |
s->GetStationType()->GetEffectTechs());
}
virtual void DeleteStation(IstationIGC* s)
{
DeleteIbaseIGC((BaseListIGC*)&m_stations, s);
ResetBuildingTechs();
}
virtual IstationIGC* GetStation(StationID id) const
{
return (IstationIGC*)GetIbaseIGC((BaseListIGC*)&m_stations, id);
}
virtual const StationListIGC* GetStations(void) const
{
return &m_stations;
}
virtual void AddShip(IshipIGC* s)
{
AddIbaseIGC((BaseListIGC*)&m_ships, s);
}
virtual void DeleteShip(IshipIGC* s)
{
DeleteIbaseIGC((BaseListIGC*)&m_ships, s);
}
virtual IshipIGC* GetShip(ShipID id) const
{
return (IshipIGC*)GetIbaseIGC((BaseListIGC*)&m_ships, id);
}
virtual const ShipListIGC* GetShips(void) const
{
return &m_ships;
}
virtual void AddBucket(IbucketIGC* b)
{
AddIbaseIGC((BaseListIGC*)&m_buckets, b);
}
virtual void DeleteBucket(IbucketIGC* b)
{
DeleteIbaseIGC((BaseListIGC*)&m_buckets, b);
}
virtual IbucketIGC* GetBucket(BucketID bucketID) const
{
return (IbucketIGC*)GetIbaseIGC((BaseListIGC*)&m_buckets, bucketID);
}
virtual const BucketListIGC* GetBuckets(void) const
{
return &m_buckets;
}
virtual const GlobalAttributeSet& GetGlobalAttributeSet(void) const
{
return m_data.gasAttributes;
}
virtual void SetGlobalAttributeSet(const GlobalAttributeSet& gas)
{
m_data.gasAttributes = gas;
m_pMission->GetIgcSite()->SideGlobalAttributeChange(this);
}
virtual void ApplyGlobalAttributeSet(const GlobalAttributeSet& gas)
{
m_data.gasAttributes.Apply(gas);
m_pMission->GetIgcSite()->SideGlobalAttributeChange(this);
}
virtual void ResetGlobalAttributeSet(void)
{
m_data.gasAttributes.Initialize();
m_pMission->GetIgcSite()->SideGlobalAttributeChange(this);
}
virtual const TechTreeBitMask& GetUltimateTechs(void) const
{
return m_ttbmUltimateTechs;
}
virtual bool GetActiveF(void) const
{
return m_activeF;
}
virtual void SetActiveF(bool activeF)
{
m_activeF = activeF;
}
virtual const Color& GetColor(void) const
{
return m_data.color;
}
virtual void SetPrivateData(DWORD dwPrivate)
{
m_dwPrivate = dwPrivate;
}
virtual DWORD GetPrivateData(void) const
{
return m_dwPrivate;
}
virtual void AddToStockpile(IbuyableIGC* b, short count)
{
assert (count > 0);
StockpileLink* plink = m_stockpile.first();
{
while (plink)
{
if (plink->data().buyable == b)
break;
plink = plink->next();
}
}
if (!plink)
{
plink = new StockpileLink;
plink->data().buyable = b;
plink->data().count = 0;
m_stockpile.first(plink);
}
assert (plink);
plink->data().count += count;
}
virtual short RemoveFromStockpile(IbuyableIGC* b, short count)
{
assert (count > 0);
StockpileLink* plink = m_stockpile.first();
while (plink)
{
assert (plink->data().count > 0);
if (plink->data().buyable == b)
{
if (count >= plink->data().count)
{
count = plink->data().count;
delete plink;
}
else
plink->data().count -= count;
return count;
}
plink = plink->next();
}
return 0;
}
virtual short GetStockpile(IbuyableIGC* b) const
{
StockpileLink* plink = m_stockpile.first();
while (plink)
{
if (plink->data().buyable == b)
return plink->data().count;
plink = plink->next();
}
return 0;
}
virtual const StockpileList* GetStockpile(void) const
{
return &m_stockpile;
}
virtual short GetKills(void) const
{
return m_data.nKills;
}
virtual void AddKill(void)
{
m_data.nKills++;
}
virtual short GetDeaths(void) const
{
return m_data.nDeaths;
}
virtual void AddDeath(void)
{
m_data.nDeaths++;
}
virtual short GetEjections(void) const
{
return m_data.nEjections;
}
virtual void AddEjection(void)
{
m_data.nEjections++;
}
virtual short GetBaseKills(void) const
{
return m_data.nBaseKills;
}
virtual void AddBaseKill(void)
{
m_data.nBaseKills++;
}
virtual short GetBaseCaptures(void) const
{
return m_data.nBaseCaptures;
}
virtual void AddBaseCapture(void)
{
m_data.nBaseCaptures++;
}
unsigned char GetConquestPercent(void) const
{
return m_data.conquest;
}
void SetConquestPercent(unsigned char newVal)
{
m_data.conquest = newVal;
}
unsigned char GetTerritoryCount(void) const
{
return m_data.territory;
}
void SetTerritoryCount(unsigned char newVal)
{
m_data.territory = newVal;
}
short GetFlags(void) const
{
return m_data.nFlags;
}
void SetFlags(short newVal)
{
m_data.nFlags = newVal;
}
short GetArtifacts(void) const
{
return m_data.nArtifacts;
}
void SetArtifacts(short newVal)
{
m_data.nArtifacts = newVal;
}
float GetTimeEndured() const
{
return m_data.fTimeEndured;
}
void SetTimeEndured(float fSeconds)
{
m_data.fTimeEndured = fSeconds;
}
virtual long GetProsperityPercentBought(void) const;
virtual long GetProsperityPercentComplete(void) const;
void Reset(void)
{
m_data.nFlags = 0;
m_data.nArtifacts = 0;
m_data.nDeaths = 0;
m_data.nEjections = 0;
m_data.nKills = 0;
m_data.nBaseKills = 0;
m_data.nBaseCaptures = 0;
m_data.conquest = 0;
}
private:
void AdjustBuckets(void)
{
for (BucketLinkIGC* l = m_buckets.first();
(l != NULL);
l = l->next())
{
IbucketIGC* b = l->data();
if (!b->GetCompleteF())
{
IbuyableIGC* pbuy = b->GetBuyable();
switch (pbuy->GetObjectType())
{
case OT_development:
{
IdevelopmentIGC* d = (IdevelopmentIGC*)pbuy;
assert (d->GetObjectType() == OT_development);
if (d->IsObsolete(m_data.ttbmDevelopmentTechs))
{
b->SetTimeAndMoney(1000 * b->GetTimeToBuild(),
b->GetPrice());
}
else if ((b->GetMoney() != 0) && !CanBuy(pbuy))
b->SetEmpty();
}
break;
case OT_stationType:
{
Money money = b->GetMoney();
if ((money != 0) && !CanBuy(pbuy))
{
IstationTypeIGC* pstSuccessor = ((IstationTypeIGC*)pbuy)->GetSuccessorStationType(this);
if (pstSuccessor != pbuy)
{
for (BucketLinkIGC* l2 = m_buckets.first();
(l2 != NULL);
l2 = l2->next())
{
IbucketIGC* b2 = l2->data();
if (b2->GetBuyable() == pstSuccessor)
{
b2->SetTimeAndMoney(b->GetTime(), money);
break;
}
}
}
b->SetEmpty();
}
}
break;
default:
{
if ((b->GetMoney() != 0) && !CanBuy(pbuy))
b->SetEmpty();
}
}
}
}
}
ImissionIGC* m_pMission;
DWORD m_dwPrivate; DataSideIGC m_data;
IcivilizationIGC* m_pCivilization;
TechTreeBitMask m_ttbmBuildingTechs;
TechTreeBitMask m_ttbmUltimateTechs;
StationListIGC m_stations;
BucketListIGC m_buckets;
ShipListIGC m_ships;
StockpileList m_stockpile;
Time m_lastUpdate;
bool m_activeF;
};
#endif