123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- /*
- ** Copyright (C) 1996, 1997 Microsoft Corporation. All Rights Reserved.
- **
- ** File: mineIGC.h
- **
- ** Author:
- **
- ** Description:
- ** Header for the CmineIGC class. This file was initially created by
- ** the ATL wizard.
- **
- ** History:
- */
- // mineIGC.h : Declaration of the CmineIGC
- #ifndef __MINEIGC_H_
- #define __MINEIGC_H_
- #include "modelIGC.h"
- const char c_msStart = 0;
- const char c_msExploded = 1;
- const char c_msScattered = 2;
- class CmineIGC : public TmodelIGC<ImineIGC>
- {
- public:
- CmineIGC(void);
- ~CmineIGC(void);
- public:
- // IbaseIGC
- virtual HRESULT Initialize(ImissionIGC* pMission, Time now, const void* data, int dataSize);
- virtual void Terminate(void);
- virtual void Update(Time now);
- virtual int Export(void* data) const;
- virtual ObjectType GetObjectType(void) const
- {
- return OT_mine;
- }
- virtual ObjectID GetObjectID(void) const
- {
- return m_mineID;
- }
- // ImodelIGC
- virtual void SetCluster(IclusterIGC* cluster)
- {
- AddRef();
- {
- IclusterIGC* c = GetCluster();
- if (c)
- c->DeleteMine(this);
- }
- TmodelIGC<ImineIGC>::SetCluster(cluster);
- if (cluster)
- cluster->AddMine(this);
- Release();
- }
- virtual void HandleCollision(Time timeCollision,
- float tCollision,
- const CollisionEntry& entry,
- ImodelIGC* pmodel)
- {
- if (pmodel->GetObjectType() == OT_ship)
- {
- const float c_dtArmTime = 1.0f;
- if ((pmodel->GetSide() != GetSide()) && (timeCollision >= m_time0 + c_dtArmTime))
- {
- //Find the length of the ship's path within the minefield
- const Vector& dV = pmodel->GetVelocity();
- double a = dV * dV;
- if (a > 1.0) //ya got to be moving at least a little to get nailed
- {
- const Vector& pMe = GetPosition();
- const Vector& pHim = pmodel->GetPosition();
- Vector pEnter = pHim + tCollision * dV;
- //What time do we leave the minefield?
- //R^2(t) = |pHim + t * vHim - pMe|^2 = (myRadius + hisRadius)^2
- Vector dP = pMe - pHim; //Note: sense is reversed wrt dV to eliminate a - sign below
- float rMe = GetRadius();
- float rHim = pmodel->GetRadius();
- double r = rMe + rHim;
- double halfB = dP * dV;
- double c = dP * dP - r * r;
- double b2ac = halfB * halfB - a * c;
- if (b2ac >= 0.0f)
- {
- double s = sqrt(b2ac);
- float tExit = (float)((halfB + s) / a);
- float tStop = GetHitTest()->GetTstop();
- if (tExit > tStop)
- tExit = tStop;
- float dt = tExit - tCollision;
- if (dt > 0.0f)
- {
- const float c_damageMultiplier = 1.0f / (5.0f * 5.0f * 100.0f);
- float speed2 = float(a);
- float amount = dt * speed2 * m_mineType->GetPower() * rHim * rHim * c_damageMultiplier / (2.0f * rMe);
- float endurance = m_mineType->GetEndurance();
- float oldEndurance = endurance * m_fraction;
- float newEndurance = oldEndurance * float(exp(-amount / endurance));
- float damage = oldEndurance - newEndurance;
- m_fraction = newEndurance / endurance;
- Vector position1 = pHim + dV * tCollision;
- const float c_radiusPlacement = 10.0f;
- Vector position2 = position1 + dV * ((c_radiusPlacement + rHim) / float(sqrt(a))) + Vector::RandomPosition(c_radiusPlacement);
- ((IshipIGC*)pmodel)->AddMineDamage(m_mineType->GetDamageType(), damage, timeCollision,
- m_launcher,
- position1,
- position2);
- if (newEndurance < 1.0f)
- GetMyMission()->GetIgcSite()->KillMineEvent(this);
- else
- GetThingSite()->SetMineStrength(m_fraction);
- }
- }
- }
- }
- }
- }
- // ImineIGC
- virtual ImineTypeIGC* GetMineType(void) const
- {
- return m_mineType;
- }
- virtual IshipIGC* GetLauncher(void) const
- {
- return m_launcher;
- }
- virtual void SetCreateNow (void)
- {
- m_bCreateNow = true;
- }
- virtual float GetStrength(void) const
- {
- return m_fraction;
- }
- virtual void ReduceStrength(float amount)
- {
- float endurance = m_mineType->GetEndurance();
- float newEndurance = endurance * m_fraction * float(exp(-amount / endurance));
- m_fraction = (newEndurance / endurance);
- if (m_fraction < 0.25f)
- GetMyMission()->GetIgcSite()->KillMineEvent(this);
- else
- GetThingSite()->SetMineStrength(m_fraction);
- }
- virtual float GetTimeFraction(void) const
- {
- Time timeNow = GetMyLastUpdate();
- float f = (m_timeExpire - timeNow) / (m_timeExpire - m_time0);
- if (f < 0.0f)
- f = 0.0f;
- else if (f > 1.0f)
- f = 1.0f;
- return f;
- }
- private:
- ImineTypeIGC* m_mineType;
- IshipIGC* m_launcher;
- Time m_time0;
- Time m_timeExpire;
- float m_fraction;
- MineID m_mineID;
- bool m_bCreateNow;
- };
- #endif //__MINEIGC_H_
|