123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- /*
- ** Copyright (C) 1996, 1997 Microsoft Corporation. All Rights Reserved.
- **
- ** File: treasureIGC.cpp
- **
- ** Author:
- **
- ** Description:
- ** Implementation of the CtreasureIGC class. This file was initially created by
- ** the ATL wizard.
- **
- ** History:
- */
- // treasureIGC.cpp : Implementation of CtreasureIGC
- #include "pch.h"
- #include "treasureIGC.h"
- #include <stdio.h>
- const float c_deceleration = 10.0f;
- /////////////////////////////////////////////////////////////////////////////
- // CtreasureIGC
- HRESULT CtreasureIGC::Initialize(ImissionIGC* pMission, Time now, const void* data, int dataSize)
- {
- //Does this treasure already exist? If so, abort which will prevent it from being terminated
- if (pMission->GetTreasure(((DataTreasureIGC*)data)->objectID))
- return E_ABORT;
- ZRetailAssert (data && (dataSize == sizeof(DataTreasureIGC)));
- {
- DataTreasureIGC* dataTreasure = (DataTreasureIGC*)data;
- m_data = *dataTreasure;
- m_data.createNow = false;
- if (dataTreasure->createNow)
- {
- m_data.time0 = now;
- }
- else
- {
- m_data.time0 = pMission->GetIgcSite()->ClientTimeFromServerTime(m_data.time0);
- }
- TmodelIGC<ItreasureIGC>::Initialize(pMission, now, &m_data, sizeof(m_data));
- if (m_data.treasureCode == c_tcPart)
- {
- IpartTypeIGC* pt = pMission->GetPartType(m_data.treasureID);
- assert (pt);
- m_buyable = (IbuyableIGC*)(pt);
- if (m_data.amount == NA)
- {
- switch (pt->GetEquipmentType())
- {
- case ET_Dispenser:
- case ET_ChaffLauncher:
- case ET_Magazine:
- {
- m_data.amount = randomInt(1, pt->GetAmount(NULL));
- }
- break;
- case ET_Pack:
- {
- short a = ((DataPackTypeIGC*)(pt->GetData()))->amount;
- assert (a > 2);
- m_data.amount = randomInt(a/2, a);
- }
- break;
- default:
- m_data.amount = 0;
- }
- }
- assert (m_buyable);
- m_buyable->AddRef();
- }
- else if (m_data.treasureCode == c_tcDevelopment)
- {
- m_buyable = (IbuyableIGC*)(pMission->GetDevelopment(m_data.treasureID));
- assert (m_buyable);
- m_buyable->AddRef();
- }
- else
- {
- m_buyable = NULL;
- if (m_data.treasureCode == c_tcCash)
- m_data.amount = m_data.treasureID;
- }
- Vector p0;
- const Vector* pposition;
- const Vector* pvelocity;
- m_speed0 = m_data.v0.Length();
- m_stationaryF = (m_speed0 == 0.0f);
- {
- float dt = now - m_data.time0;
- if (m_speed0 <= c_deceleration * dt)
- {
- //drifted to a stop
- m_stationaryF = true;
- p0 = m_data.p0 + m_data.v0 * (0.5f * m_speed0 / c_deceleration);
- pposition = &p0;
- pvelocity = &(Vector::GetZero());
- }
- else
- {
- pposition = &(m_data.p0);
- pvelocity = &(m_data.v0);
- }
- }
- static const char* cName = "acs14";
- const char* name;
- const char* texture = NULL;
- const char* icon;
- if (m_buyable)
- {
- name = m_buyable->GetModelName();
- icon = m_buyable->GetIconName();
- }
- else if (m_data.treasureCode == c_tcFlag)
- {
- if (m_data.treasureID != SIDE_TEAMLOBBY)
- {
- name = NULL;
- texture = "biosflag";
- icon = "flag";
- SetName("Flag");
- IsideIGC* pside = pMission->GetSide(m_data.treasureID);
- assert (pside);
- SetSide(pside);
- }
- else
- {
- name = "artifact";
- icon = "articon";
- SetName("Artifact");
- }
- SetSignature(1.5f);
- }
- else
- {
- assert ((m_data.treasureCode == c_tcCash) || (m_data.treasureCode == c_tcPowerup));
- name = cName;
- icon = (m_data.treasureCode == c_tcCash) ? "cashicon" : "iconpu";
- }
- if (texture)
- {
- HRESULT rc = LoadDecal(texture, icon,
- Color(1.0f,
- 1.0f,
- 1.0f,
- 1.0f),
- false,
- 1.0f,
- m_stationaryF
- ? (c_mtStatic | c_mtHitable | c_mtSeenBySide | c_mtPredictable)
- : (c_mtCastRay | c_mtSeenBySide | c_mtPredictable));
- assert (SUCCEEDED(rc));
- }
- else
- {
- HRESULT rc = Load(0, name, texture, icon,
- m_stationaryF
- ? (c_mtStatic | c_mtHitable | c_mtSeenBySide | c_mtPredictable)
- : (c_mtCastRay | c_mtSeenBySide | c_mtPredictable));
- assert (SUCCEEDED(rc));
- Orientation o;
- Rotation r;
- //Parts get a random orientation
- o.Set(Vector::RandomDirection());
- //and a random rotation
- r.axis(Vector::RandomDirection());
- r.angle(random(-6, 6));
- SetOrientation(o);
- SetRotation(r);
- }
- SetRadius(5.0f); //NYI -- needs to be gotten from the DB
- SetMass(0.0f);
- m_expire = m_data.time0 + m_data.lifespan;
- SetPosition(*pposition);
- SetVelocity(*pvelocity);
- SetCluster(pMission->GetCluster(m_data.clusterID));
- pMission->AddTreasure(this);
- //Fun and games time ... treasures can be created in the cluster update
- //so initialize everything as if we were in the resolve collisions part
- //of the cluster update before adding the object to the cluster.
- //Fortunately, the KD tree is no longer used in the update by this point
- //and all we need to do is set the bounding box
- SetBB(now, now, 0.0f);
- }
- return S_OK;
- }
- void CtreasureIGC::Update(Time now)
- {
- if (now >= m_expire)
- GetMyMission()->GetIgcSite()->KillTreasureEvent(this);
- else
- {
- if ((!m_stationaryF) && (now > m_data.time0))
- {
- float dt1 = GetMyLastUpdate() - m_data.time0;
- float v1 = m_speed0 - c_deceleration * dt1;
- if (v1 <= 0.0f)
- {
- //The object came, previously, to a complete stop
- m_stationaryF = true;
- SetPosition(m_data.p0 + m_data.v0 * (0.5f * m_speed0 / c_deceleration));
- SetVelocity(Vector::GetZero());
- MakeStatic();
- }
- else
- {
- //Still moving ... calculate the object's position at the start and stop
- assert (m_speed0 != 0.0f);
- Vector p1 = m_data.p0 +
- m_data.v0 *
- (dt1 - 0.5f * dt1 * dt1 * c_deceleration / m_speed0);
- SetPosition(p1);
- if (now == GetMyLastUpdate())
- {
- SetVelocity(m_data.v0 * (v1 / m_speed0));
- }
- else
- {
- float dt2 = now - m_data.time0;
- float v2 = m_speed0 - c_deceleration * dt2;
- Vector p2 = (v2 > 0.0f)
- ? (m_data.p0 +
- m_data.v0 *
- (dt2 - 0.5f * dt2 * dt2 * c_deceleration / m_speed0))
- : (m_data.p0 + m_data.v0 * (0.5f * m_speed0 / c_deceleration));
- SetVelocity((p2 - p1) / (now - GetMyLastUpdate()));
- }
- }
- }
- TmodelIGC<ItreasureIGC>::Update(now);
- }
- }
- int CtreasureIGC::Export(void* data) const
- {
- if (data)
- {
- DataTreasureIGC* dataTreasure = (DataTreasureIGC*)data;
- *dataTreasure = m_data;
- dataTreasure->time0 = GetMyMission()->GetIgcSite()->ServerTimeFromClientTime(m_data.time0);
- }
- return sizeof(DataTreasureIGC);
- }
|