/* ** Copyright (C) 1996, 1997 Microsoft Corporation. All Rights Reserved. ** ** File: sideIGC.h ** ** Author: ** ** Description: ** Header for the CsideIGC class. This file was initially created by ** the ATL wizard. ** ** History: */ // sideIGC.h : Declaration of the CsideIGC #ifndef __SIDEIGC_H_ #define __SIDEIGC_H_ ///////////////////////////////////////////////////////////////////////////// // CsideIGC class CsideIGC : public IsideIGC { public: CsideIGC(void) : m_activeF(false), // sides are inactive until mission creation is over m_dwPrivate(NULL) { } ~CsideIGC(void) { } public: // IbaseIGC virtual HRESULT Initialize(ImissionIGC* pMission, Time now, const void* data, int dataSize); virtual void Terminate(void); virtual void Update(Time now) { //Update the buckets attached to the station. 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; } // IsideIGC 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(); // set the tech bits for the new civ m_data.ttbmDevelopmentTechs = GetCivilization()->GetBaseTechs(); m_ttbmBuildingTechs.ClearAll(); m_data.civilizationID = GetCivilization()->GetObjectID(); //Turn all space stations into the base space station for the new civ { 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) { //See what the new set of building techs is, from scratch 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 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) { //A non-localized item ... buyable based only on global tech bits bAvailable = (ttbmRequired <= ttbmSide) || (b->GetObjectID() == c_didTeamMoney); //If you have the team money dev ... you can buy it } else { //Station types can not be bought if they are obsolete if (type == OT_stationType) { //Station types can not be bought if their successor is available const IstationTypeIGC* pstSuccessor = ((IstationTypeIGC*)b)->GetSuccessorStationType(this); if (pstSuccessor != b) return false; } //Station type or drone type: these are built at stations so see if any station //can build them. 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); //See what the new set of building techs is, from scratch 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); //See if there are already entries in the stockpile 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) { //Empty the side buckets we can no longer build 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)) { //This will not give us anything ... so mark it as complete 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) { //Find the bucket that corresponds to the successor station 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; // private data for consumer 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 //__SIDEIGC_H_