123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
- /*
- ** Copyright (C) 1996, 1997 Microsoft Corporation. All Rights Reserved.
- **
- ** File: buildingEffectIGC.cpp
- **
- ** Author:
- **
- ** Description:
- ** Implementation of the CclusterIGC class. This file was initially created by
- ** the ATL wizard for the core object.
- **
- ** History:
- */
- // buildingEffectIGC.cpp : Implementation of buildingEffectIGC
- #ifndef __BUILDINGEFFECTIGC_H_
- #define __BUILDINGEFFECTIGC_H_
- const float c_dtShrink = 10.0f;
- const float c_dtOpaque = 10.0f;
- const float c_dtGrow = 10.0f;
- const float c_dtEnvelope = 10.0f;
- class CbuildingEffectIGC : public TmodelIGC<IbuildingEffectIGC>
- {
- public:
- CbuildingEffectIGC(void)
- {
- }
- ~CbuildingEffectIGC(void)
- {
- }
- public:
- // IbaseIGC
- virtual HRESULT Initialize(ImissionIGC* pMission, Time now, const void* data, int dataSize)
- {
- TmodelIGC<IbuildingEffectIGC>::Initialize(pMission, now, data, dataSize);
- {
- ZRetailAssert (data && (dataSize > sizeof(DataBuildingEffectBase)));
- DataBuildingEffectBase* dataBuilding = (DataBuildingEffectBase*)data;
- m_positionStart = dataBuilding->positionStart;
- m_positionStop = dataBuilding->positionStop;
- m_radiusAsteroid = dataBuilding->radiusAsteroid;
- m_radiusStation = dataBuilding->radiusStation;
- m_timeEnvelope = pMission->GetIgcSite()->ClientTimeFromServerTime(dataBuilding->timeStart);
- m_timeGrow = m_timeEnvelope + c_dtEnvelope;
- m_timeOpaque = m_timeGrow + c_dtGrow;
- m_timeShrink = m_timeOpaque + c_dtOpaque;
- m_timeComplete = m_timeShrink + c_dtShrink;
- }
- assert (sizeof(DataBuildingEffectIGC) != sizeof(DataBuildingEffectExport));
- IclusterIGC* pcluster;
- const Color* pcolor;
- if (dataSize == sizeof(DataBuildingEffectIGC))
- {
- DataBuildingEffectIGC* dataBuilding = (DataBuildingEffectIGC*)data;
- m_pshipBuilder = dataBuilding->pshipBuilder;
- assert (m_pshipBuilder);
- m_pshipBuilder->SetStateM(drillingMaskIGC | buildingMaskIGC);
- m_pside = m_pshipBuilder->GetSide();
- m_pstationType = (IstationTypeIGC*)(m_pshipBuilder->GetBaseData());
- m_pasteroid = dataBuilding->pasteroid;
- assert (m_pasteroid);
- m_pasteroid->SetBuildingEffect(this);
- pcluster = dataBuilding->pcluster;
- pcolor = &(m_pshipBuilder->GetSide()->GetColor());
- }
- else
- {
- ZRetailAssert (dataSize == sizeof(DataBuildingEffectExport));
- DataBuildingEffectExport* dataBuilding = (DataBuildingEffectExport*)data;
- pcluster = pMission->GetCluster(dataBuilding->clusterID);
- m_pasteroid = pcluster->GetAsteroid(dataBuilding->asteroidID);
- assert (m_pasteroid);
- m_pasteroid->SetBuildingEffect(this);
- pcolor = &(dataBuilding->color);
- }
- LoadEffect(Color(50.0f/255.0f, 28.0f/255.0f, 146.0f/255.0f), //*pcolor,
- (c_mtNotPickable | c_mtCastRay | c_mtHitable | c_mtDamagable | c_mtPredictable));
- m_radiusMax = 1.1f * (m_radiusAsteroid > m_radiusStation ? m_radiusAsteroid : m_radiusStation);
- SetRadius(1.0f);
- SetPosition(m_positionStart);
- GetHitTest()->SetNoHit(m_pasteroid->GetHitTest());
- assert (GetVelocity().LengthSquared() == 0.0f);
- assert (pcluster);
- SetCluster(pcluster);
- //Set the BB's effect, since it was probably created as a result of a collision.
- SetBB(now, now, 0.0f);
- return S_OK;
- }
- virtual void Terminate(void)
- {
- AddRef();
- if (m_pasteroid)
- {
- m_pasteroid->SetBuildingEffect(NULL);
- m_pasteroid = NULL;
- }
- if (m_pshipBuilder)
- {
- GetMyMission()->GetIgcSite()->KillShipEvent(GetMyLastUpdate(), m_pshipBuilder, NULL,
- 0.0f, m_pshipBuilder->GetPosition(), Vector::GetZero());
- m_pshipBuilder = NULL;
- }
- m_pside = NULL;
- m_pstationType = NULL;
- TmodelIGC<IbuildingEffectIGC>::Terminate();
- Release();
- }
- int Export(void* data) const
- {
- if (data)
- {
- DataBuildingEffectExport* pdbe = (DataBuildingEffectExport*)data;
- pdbe->timeStart = GetMyMission()->GetIgcSite()->ServerTimeFromClientTime(m_timeEnvelope);
- pdbe->asteroidID = m_pasteroid ? m_pasteroid->GetObjectID() : NA;
- pdbe->clusterID = GetCluster()->GetObjectID();
- pdbe->radiusAsteroid = m_radiusAsteroid;
- pdbe->radiusStation = m_radiusStation;
- pdbe->positionStart = m_positionStart;
- pdbe->positionStop = m_positionStop;
- assert (m_pshipBuilder);
- pdbe->color = m_pshipBuilder->GetSide()->GetColor();
- }
- return sizeof(DataBuildingEffectExport);
- }
- virtual void Update(Time now)
- {
- if (now >= m_timeComplete)
- {
- Terminate();
- }
- else
- {
- Vector position;
- float radius;
- float aInner;
- float fInner;
- float fOuter;
- if (now >= m_timeShrink)
- {
- float f = (now - m_timeShrink) / c_dtShrink;
- position = m_positionStop;
- radius = m_radiusStation * f + m_radiusMax * (1.0f - f);
- aInner = 1.0f - f;
- fInner = 1.0f - f;
- fOuter = 1.0f - f;
- }
- else if (now >= m_timeOpaque)
- {
- float f = (now - m_timeOpaque) / c_dtOpaque;
- position = m_positionStop;
- radius = m_radiusMax;
- aInner = 0.5f + 0.5f * f;
- fInner = 1.0f;
- fOuter = 1.0f;
- }
- else if (now >= m_timeGrow)
- {
- float f = (now - m_timeGrow) / c_dtGrow;
- position = m_positionStop;
- radius = m_radiusMax * f + m_radiusAsteroid * (1.0f - f);
- aInner = 0.5f;
- fInner = 1.0f;
- fOuter = 1.0f;
- }
- else
- {
- float dt = (now - m_timeEnvelope);
- float f = (dt > 0.0f) ? (dt / c_dtEnvelope) : 0.0f;
- position = m_positionStop * f + m_positionStart * (1.0f - f);
- radius = f * m_radiusAsteroid + 1.0f - f;
- aInner = 0.5f;
- fInner = 1.0f;
- fOuter = 1.0f;
- }
- SetPosition(position);
- SetRadius(radius);
- assert (GetThingSite());
- GetThingSite()->SetColors(aInner, fInner, fOuter);
- }
- }
- virtual ObjectType GetObjectType(void) const
- {
- return OT_buildingEffect;
- }
- // ImodelIGC
- virtual void SetCluster(IclusterIGC* cluster)
- {
- AddRef();
- {
- IclusterIGC* c = GetCluster();
- if (c)
- c->DeleteModel(this);
- }
- TmodelIGC<IbuildingEffectIGC>::SetCluster(cluster);
- if (cluster)
- cluster->AddModel(this);
- Release();
- }
- virtual void HandleCollision(Time timeCollision,
- float tCollision,
- const CollisionEntry& entry,
- ImodelIGC* pModel)
- {
- ObjectType type = pModel->GetObjectType();
- if ((type != OT_buildingEffect) &&
- (type != OT_asteroid) &&
- (type != OT_station) &&
- (type != OT_probe))
- {
- pModel->HandleCollision(timeCollision, tCollision, entry, this);
- }
- }
- // IdamageIGC
- virtual DamageResult ReceiveDamage(DamageTypeID type,
- float amount,
- Time timeCollision,
- const Vector& position1,
- const Vector& position2,
- ImodelIGC* launcher)
- {
- if (m_pasteroid)
- {
- m_pasteroid->ReceiveDamage(type, amount, timeCollision, m_pasteroid->GetPosition(), position2, launcher);
- }
- return c_drNoDamage;
- }
- virtual float GetFraction(void) const
- {
- return 1.0f;
- }
- virtual void SetFraction(float newVal)
- {
- }
- virtual float GetHitPoints(void) const
- {
- return m_pasteroid ? m_pasteroid->GetHitPoints() : 1.0f;
- }
- // IbuildingEffectIGC
- virtual void BuilderTerminated(void)
- {
- m_pshipBuilder = NULL;
- }
- virtual IasteroidIGC* GetAsteroid(void) const
- {
- return m_pasteroid;
- }
- virtual void MakeUnhitable(void)
- {
- assert (m_pasteroid);
- m_pasteroid = NULL;
- TmodelIGC<IbuildingEffectIGC>::MakeUnhitable(); //Virtual wrapper for a non-virtual function
- }
- virtual void AsteroidUpdate(Time now)
- {
- if ((now >= m_timeShrink) && m_pshipBuilder)
- {
- //transform the asteroid into the station
- assert (m_pstationType);
- assert (m_pside);
- GetMyMission()->GetIgcSite()->SendChatf(m_pshipBuilder, CHAT_TEAM, m_pside->GetObjectID(),
- m_pstationType->GetCompletionSound(),
- "Finished building %s", m_pstationType->GetName());
- //Quietly kill the ship (after nuking its parts to prevent treasure from being created)
- {
- const PartListIGC* parts = m_pshipBuilder->GetParts();
- PartLinkIGC* plink;
- while (plink = parts->first()) //Not ==
- plink->data()->Terminate();
- }
- m_pshipBuilder->SetAmmo(0);
- m_pshipBuilder->SetFuel(0.0f);
- m_pshipBuilder->SetStateM(0);
- GetMyMission()->GetIgcSite()->KillShipEvent(now, m_pshipBuilder, NULL, 0.0f, m_pshipBuilder->GetPosition(), Vector::GetZero());
- m_pshipBuilder = NULL;
- IasteroidIGC* pasteroid = m_pasteroid;
- m_pasteroid->SetBuildingEffect(NULL); //Clear the building effect so it isn't nuked along with the asteroid
- assert (m_pasteroid == NULL);
- GetMyMission()->GetIgcSite()->BuildStation(pasteroid,
- m_pside,
- m_pstationType,
- now);
- }
- }
- private:
- TRef<IshipIGC> m_pshipBuilder;
- TRef<IasteroidIGC> m_pasteroid;
- TRef<IstationTypeIGC> m_pstationType;
- TRef<IsideIGC> m_pside;
- Time m_timeComplete;
- Time m_timeShrink;
- Time m_timeOpaque;
- Time m_timeGrow;
- Time m_timeEnvelope;
- Vector m_positionStart;
- Vector m_positionStop;
- float m_radiusAsteroid;
- float m_radiusStation;
- float m_radiusMax;
- };
- #endif
|