summaryrefslogtreecommitdiffstats
path: root/src/objects
diff options
context:
space:
mode:
Diffstat (limited to 'src/objects')
-rw-r--r--src/objects/CutsceneHead.cpp231
-rw-r--r--src/objects/CutsceneHead.h28
-rw-r--r--src/objects/CutsceneObject.cpp153
-rw-r--r--src/objects/CutsceneObject.h25
-rw-r--r--src/objects/DummyObject.cpp3
-rw-r--r--src/objects/DummyObject.h2
-rw-r--r--src/objects/Object.cpp737
-rw-r--r--src/objects/Object.h46
-rw-r--r--src/objects/ObjectData.cpp73
-rw-r--r--src/objects/ParticleObject.cpp876
-rw-r--r--src/objects/ParticleObject.h22
-rw-r--r--src/objects/Projectile.cpp2
-rw-r--r--src/objects/Stinger.cpp232
-rw-r--r--src/objects/Stinger.h40
14 files changed, 1509 insertions, 961 deletions
diff --git a/src/objects/CutsceneHead.cpp b/src/objects/CutsceneHead.cpp
deleted file mode 100644
index 15611c29..00000000
--- a/src/objects/CutsceneHead.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-#include "common.h"
-#include <rpskin.h>
-
-#include "main.h"
-#include "RwHelper.h"
-#include "RpAnimBlend.h"
-#include "AnimBlendClumpData.h"
-#include "Bones.h"
-#include "Directory.h"
-#include "CutsceneMgr.h"
-#include "Streaming.h"
-#include "CutsceneHead.h"
-#include "CdStream.h"
-
-#ifdef GTA_PS2_STUFF
-// this is a total hack to switch between PC and PS2 code
-static bool lastLoadedSKA;
-#endif
-
-CCutsceneHead::CCutsceneHead(CObject *obj)
-{
- RpAtomic *atm;
-
- assert(RwObjectGetType(obj->m_rwObject) == rpCLUMP);
-#ifdef PED_SKIN
- unk1 = 0;
- bIsSkinned = false;
- m_parentObject = (CCutsceneObject*)obj;
- // Hide original head
- if(IsClumpSkinned(obj->GetClump())){
- m_parentObject->SetRenderHead(false);
- bIsSkinned = true;
- }else
-#endif
- {
- m_pHeadNode = RpAnimBlendClumpFindFrame((RpClump*)obj->m_rwObject, "Shead")->frame;
- atm = (RpAtomic*)GetFirstObject(m_pHeadNode);
- if(atm){
- assert(RwObjectGetType((RwObject*)atm) == rpATOMIC);
- RpAtomicSetFlags(atm, RpAtomicGetFlags(atm) & ~rpATOMICRENDER);
- }
- }
-}
-
-void
-CCutsceneHead::CreateRwObject(void)
-{
- RpAtomic *atm;
-
- CEntity::CreateRwObject();
- assert(RwObjectGetType(m_rwObject) == rpCLUMP);
- atm = GetFirstAtomic((RpClump*)m_rwObject);
- RpSkinAtomicSetHAnimHierarchy(atm, RpHAnimFrameGetHierarchy(GetFirstChild(RpClumpGetFrame((RpClump*)m_rwObject))));
-}
-
-void
-CCutsceneHead::DeleteRwObject(void)
-{
- CEntity::DeleteRwObject();
-}
-
-void
-CCutsceneHead::ProcessControl(void)
-{
- RpAtomic *atm;
- RpHAnimHierarchy *hier;
-
- // android/xbox calls is at the end
- CPhysical::ProcessControl();
-
-#ifdef PED_SKIN
- if(bIsSkinned){
- UpdateRpHAnim();
- UpdateRwFrame();
-
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(m_parentObject->GetClump());
- int idx = RpHAnimIDGetIndex(hier, BONE_head);
- RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
- if(RwV3dLength(&mat->pos) > 100.0f){
- m_matrix.SetRotateY(PI/2);
- m_matrix = CMatrix(mat) * m_matrix;
- }
- }else
-#endif
- {
- m_matrix.SetRotateY(PI/2);
- m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix;
- UpdateRwFrame(); // android/xbox don't call this
- }
-
- assert(RwObjectGetType(m_rwObject) == rpCLUMP);
- atm = GetFirstAtomic((RpClump*)m_rwObject);
- hier = RpSkinAtomicGetHAnimHierarchy(atm);
-#ifdef GTA_PS2_STUFF
- // PS2 only plays anims in cutscene, PC always plays anims
- if(!lastLoadedSKA || CCutsceneMgr::IsRunning())
-#endif
- RpHAnimHierarchyAddAnimTime(hier, CTimer::GetTimeStepNonClipped()/50.0f);
-}
-
-void
-CCutsceneHead::Render(void)
-{
- RpAtomic *atm;
-
-#ifdef PED_SKIN
- if(bIsSkinned){
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(m_parentObject->GetClump());
- RpHAnimHierarchyUpdateMatrices(hier);
- int idx = RpHAnimIDGetIndex(hier, BONE_head);
- RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
- if(RwV3dLength(&mat->pos) > 100.0f){
- m_matrix.SetRotateY(PI/2);
- m_matrix = CMatrix(mat) * m_matrix;
- }
- // This is head...it has no limbs
-#ifndef FIX_BUGS
- RenderLimb(BONE_Lhand);
- RenderLimb(BONE_Rhand);
-#endif
- }else
-#endif
- {
- m_matrix.SetRotateY(PI/2);
- m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix;
- }
-
- UpdateRwFrame();
-
- assert(RwObjectGetType(m_rwObject) == rpCLUMP);
- atm = GetFirstAtomic((RpClump*)m_rwObject);
- RpHAnimHierarchyUpdateMatrices(RpSkinAtomicGetHAnimHierarchy(atm));
-
- CObject::Render();
-}
-
-#ifdef PED_SKIN
-void
-CCutsceneHead::RenderLimb(int32 bone)
-{
- // It's not clear what this is...
- // modelinfo for this object is not a ped so it also doesn't have any limbs
-#ifndef FIX_BUGS
- RpAtomic *atomic;
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(m_parentObject->GetClump());
- int idx = RpHAnimIDGetIndex(hier, bone);
- RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
- CPedModelInfo *mi = (CPedModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
- assert(mi->GetModelType() == MITYPE_PED);
- switch(bone){
- case BONE_Lhand:
- atomic = mi->getLeftHand();
- break;
- case BONE_Rhand:
- atomic = mi->getRightHand();
- break;
- default:
- return;
- }
- if(atomic){
- RwFrame *frame = RpAtomicGetFrame(atomic);
- RwMatrixTransform(RwFrameGetMatrix(frame), &mats[idx], rwCOMBINEREPLACE);
- RwFrameUpdateObjects(frame);
- RpAtomicRender(atomic);
- }
-#endif
-}
-#endif
-
-void
-CCutsceneHead::PlayAnimation(const char *animName)
-{
- RpAtomic *atm;
- RpHAnimHierarchy *hier;
- RpHAnimAnimation *anim;
- uint32 offset, size;
- RwStream *stream;
-
-#ifdef GTA_PS2_STUFF
- lastLoadedSKA = false;
-#endif
-
- assert(RwObjectGetType(m_rwObject) == rpCLUMP);
- atm = GetFirstAtomic((RpClump*)m_rwObject);
- hier = RpSkinAtomicGetHAnimHierarchy(atm);
-
- sprintf(gString, "%s.anm", animName);
-
- if(CCutsceneMgr::ms_pCutsceneDir->FindItem(gString, offset, size)){
- stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, "ANIM\\CUTS.IMG");
- assert(stream);
-
- CStreaming::MakeSpaceFor(size * CDSTREAM_SECTOR_SIZE);
- CStreaming::ImGonnaUseStreamingMemory();
-
- RwStreamSkip(stream, offset*2048);
- if(RwStreamFindChunk(stream, rwID_HANIMANIMATION, nil, nil)){
- anim = RpHAnimAnimationStreamRead(stream);
- RpHAnimHierarchySetCurrentAnim(hier, anim);
- }
-
- CStreaming::IHaveUsedStreamingMemory();
-
- RwStreamClose(stream, nil);
- }
-#ifdef GTA_PS2_STUFF
-#ifdef LIBRW
- else{
- sprintf(gString, "%s.ska", animName);
-
- if(CCutsceneMgr::ms_pCutsceneDir->FindItem(gString, offset, size)){
- stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, "ANIM\\CUTS.IMG");
- assert(stream);
-
- CStreaming::MakeSpaceFor(size * CDSTREAM_SECTOR_SIZE);
- CStreaming::ImGonnaUseStreamingMemory();
-
- RwStreamSkip(stream, offset*2048);
- anim = rw::Animation::streamReadLegacy(stream);
- RpHAnimHierarchySetCurrentAnim(hier, anim);
-
- CStreaming::IHaveUsedStreamingMemory();
-
- RwStreamClose(stream, nil);
-
- lastLoadedSKA = true;
- }
- }
-#endif
-#endif
-}
diff --git a/src/objects/CutsceneHead.h b/src/objects/CutsceneHead.h
deleted file mode 100644
index c931eb01..00000000
--- a/src/objects/CutsceneHead.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#pragma once
-
-#include "CutsceneObject.h"
-
-class CCutsceneHead : public CCutsceneObject
-{
-public:
- RwFrame *m_pHeadNode;
-#ifdef PED_SKIN
- int32 unk1;
- CCutsceneObject *m_parentObject;
- int32 unk2;
- int32 bIsSkinned;
-#endif
-
- CCutsceneHead(CObject *obj);
-
- void CreateRwObject(void);
- void DeleteRwObject(void);
- void ProcessControl(void);
- void Render(void);
- void RenderLimb(int32 bone);
-
- void PlayAnimation(const char *animName);
-};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CCutsceneHead, 0x19C);
-#endif
diff --git a/src/objects/CutsceneObject.cpp b/src/objects/CutsceneObject.cpp
index 5c10d37d..8d1be357 100644
--- a/src/objects/CutsceneObject.cpp
+++ b/src/objects/CutsceneObject.cpp
@@ -11,7 +11,11 @@
#include "ModelIndices.h"
#include "Shadows.h"
#include "Timecycle.h"
+#include "CutsceneShadow.h"
#include "CutsceneObject.h"
+#include "ModelIndices.h"
+#include "RpAnimBlend.h"
+
CCutsceneObject::CCutsceneObject(void)
{
@@ -21,12 +25,19 @@ CCutsceneObject::CCutsceneObject(void)
ObjectCreatedBy = CUTSCENE_OBJECT;
m_fMass = 1.0f;
m_fTurnMass = 1.0f;
+
+ m_pAttachTo = nil;
+ m_pAttachmentObject = nil;
+ m_pShadow = nil;
+}
-#ifdef PED_SKIN
- bRenderHead = true;
- bRenderRightHand = true;
- bRenderLeftHand = true;
-#endif
+CCutsceneObject::~CCutsceneObject(void)
+{
+ if ( m_pShadow )
+ {
+ delete m_pShadow;
+ m_pShadow = nil;
+ }
}
void
@@ -40,21 +51,37 @@ CCutsceneObject::SetModelIndex(uint32 id)
}
void
+CCutsceneObject::CreateShadow(void)
+{
+ if ( IsPedModel(GetModelIndex()) )
+ {
+ m_pShadow = new CCutsceneShadow();
+ if (!m_pShadow->IsInitialized())
+ m_pShadow->Create(m_rwObject, 6, true, 4, true);
+ }
+}
+
+void
CCutsceneObject::ProcessControl(void)
{
CPhysical::ProcessControl();
- if(CTimer::GetTimeStep() < 1/100.0f)
- m_vecMoveSpeed *= 100.0f;
+ if ( m_pAttachTo )
+ {
+ if ( m_pAttachmentObject )
+ GetMatrix() = CMatrix((RwMatrix*)m_pAttachTo);
+ else
+ GetMatrix() = CMatrix(RwFrameGetLTM((RwFrame*)m_pAttachTo));
+ }
else
- m_vecMoveSpeed *= 1.0f/CTimer::GetTimeStep();
-
- ApplyMoveSpeed();
-
-#ifdef PED_SKIN
- if(IsClumpSkinned(GetClump()))
- UpdateRpHAnim();
-#endif
+ {
+ if(CTimer::GetTimeStep() < 1/100.0f)
+ m_vecMoveSpeed *= 100.0f;
+ else
+ m_vecMoveSpeed *= 1.0f/CTimer::GetTimeStep();
+
+ ApplyMoveSpeed();
+ }
}
static RpMaterial*
@@ -67,14 +94,52 @@ MaterialSetAlpha(RpMaterial *material, void *data)
void
CCutsceneObject::PreRender(void)
{
- if(IsPedModel(GetModelIndex())){
- CShadows::StoreShadowForPedObject(this,
- CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue],
- CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue],
- CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue],
- CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
- CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue],
- CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
+ if ( m_pAttachTo )
+ {
+ if ( m_pAttachmentObject )
+ {
+ m_pAttachmentObject->UpdateRpHAnim();
+ GetMatrix() = CMatrix((RwMatrix*)m_pAttachTo);
+ }
+ else
+ GetMatrix() = CMatrix(RwFrameGetLTM((RwFrame*)m_pAttachTo));
+
+ if ( RwObjectGetType(m_rwObject) == rpCLUMP && IsClumpSkinned(GetClump()) )
+ {
+ RpAtomic *atomic = GetFirstAtomic(GetClump());
+ atomic->boundingSphere.center = (*RPANIMBLENDCLUMPDATA(GetClump()))->frames[0].hanimFrame->t;
+ }
+ }
+
+ if ( RwObjectGetType(m_rwObject) == rpCLUMP )
+ UpdateRpHAnim();
+
+ if(IsPedModel(GetModelIndex()))
+ {
+ if ( m_pShadow == nil )
+ {
+ CShadows::StoreShadowForPedObject(this,
+ CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
+ }
+ else
+ {
+ if ( m_pShadow->IsInitialized() )
+ m_pShadow->UpdateForCutscene();
+
+ CShadows::StoreShadowForCutscenePedObject(this,
+ CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
+ }
+
// For some reason xbox/android limbs are transparent here...
RpGeometry *geometry = RpAtomicGetGeometry(GetFirstAtomic(GetClump()));
RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR);
@@ -85,47 +150,11 @@ CCutsceneObject::PreRender(void)
void
CCutsceneObject::Render(void)
{
-#ifdef PED_SKIN
- if(IsClumpSkinned(GetClump())){
- if(bRenderLeftHand) RenderLimb(BONE_Lhand);
- if(bRenderRightHand) RenderLimb(BONE_Rhand);
- if(bRenderHead) RenderLimb(BONE_head);
- }
-#endif
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void *)rwCULLMODECULLNONE);
CObject::Render();
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void *)rwCULLMODECULLBACK);
}
-#ifdef PED_SKIN
-void
-CCutsceneObject::RenderLimb(int32 bone)
-{
- RpAtomic *atomic;
- CPedModelInfo *mi = (CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex());
- switch(bone){
- case BONE_head:
- atomic = mi->getHead();
- break;
- case BONE_Lhand:
- atomic = mi->getLeftHand();
- break;
- case BONE_Rhand:
- atomic = mi->getRightHand();
- break;
- default:
- return;
- }
- if(atomic){
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
- int idx = RpHAnimIDGetIndex(hier, bone);
- RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
- RwFrame *frame = RpAtomicGetFrame(atomic);
- *RwFrameGetMatrix(frame) = *mat;
- RwFrameUpdateObjects(frame);
- RpAtomicRender(atomic);
- }
-}
-#endif
-
bool
CCutsceneObject::SetupLighting(void)
{
@@ -137,7 +166,7 @@ CCutsceneObject::SetupLighting(void)
}else{
CVector coors = GetPosition();
float lighting = CPointLights::GenerateLightsAffectingObject(&coors);
- if(!bHasBlip && lighting != 1.0f){
+ if(lighting != 1.0f){
SetAmbientAndDirectionalColours(lighting);
return true;
}
diff --git a/src/objects/CutsceneObject.h b/src/objects/CutsceneObject.h
index 407adcc7..af24c0a6 100644
--- a/src/objects/CutsceneObject.h
+++ b/src/objects/CutsceneObject.h
@@ -2,32 +2,23 @@
#include "Object.h"
+class CCutsceneShadow;
+
class CCutsceneObject : public CObject
{
public:
-#ifdef PED_SKIN
- bool bRenderHead;
- bool bRenderRightHand;
- bool bRenderLeftHand;
-
- bool GetRenderHead(void) { return bRenderHead; }
- bool GetRenderRightHand(void) { return bRenderRightHand; }
- bool GetRenderLeftHand(void) { return bRenderLeftHand; }
- void SetRenderHead(bool render) { bRenderHead = render; }
- void SetRenderRightHand(bool render) { bRenderRightHand = render; }
- void SetRenderLeftHand(bool render) { bRenderLeftHand = render; }
-#endif
-
+ CCutsceneShadow *m_pShadow;
+ void *m_pAttachTo;
+ CObject *m_pAttachmentObject;
+
CCutsceneObject(void);
+ ~CCutsceneObject(void);
void SetModelIndex(uint32 id);
+ void CreateShadow(void);
void ProcessControl(void);
void PreRender(void);
void Render(void);
- void RenderLimb(int32 bone);
bool SetupLighting(void);
void RemoveLighting(bool reset);
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CCutsceneObject, 0x198);
-#endif
diff --git a/src/objects/DummyObject.cpp b/src/objects/DummyObject.cpp
index d5805073..8656abbb 100644
--- a/src/objects/DummyObject.cpp
+++ b/src/objects/DummyObject.cpp
@@ -3,6 +3,8 @@
#include "DummyObject.h"
#include "Pools.h"
+// --MIAMI: file done
+
CDummyObject::CDummyObject(CObject *obj)
{
SetModelIndexNoCreate(obj->GetModelIndex());
@@ -10,4 +12,5 @@ CDummyObject::CDummyObject(CObject *obj)
AttachToRwObject(obj->m_rwObject);
obj->DetachFromRwObject();
m_level = obj->m_level;
+ m_area = obj->m_area;
}
diff --git a/src/objects/DummyObject.h b/src/objects/DummyObject.h
index d6f88335..680df685 100644
--- a/src/objects/DummyObject.h
+++ b/src/objects/DummyObject.h
@@ -10,5 +10,3 @@ public:
CDummyObject(void) {}
CDummyObject(CObject *obj);
};
-
-VALIDATE_SIZE(CDummyObject, 0x68);
diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp
index 411e245a..0605f54f 100644
--- a/src/objects/Object.cpp
+++ b/src/objects/Object.cpp
@@ -12,9 +12,18 @@
#include "World.h"
#include "Floater.h"
#include "soundlist.h"
+#include "WaterLevel.h"
+#include "Timecycle.h"
+#include "Stats.h"
+#include "SpecialFX.h"
+
+#define BEACHBALL_MAX_SCORE 250
+// the proportion of the ball speed compared to the player speed when it hits the player
+#define BEACHBALL_SPEED_PROPORTION 0.4f
int16 CObject::nNoTempObjects;
-int16 CObject::nBodyCastHealth = 1000;
+//int16 CObject::nBodyCastHealth = 1000;
+float CObject::fDistToNearestTree;
void *CObject::operator new(size_t sz) { return CPools::GetObjectPool()->New(); }
void *CObject::operator new(size_t sz, int handle) { return CPools::GetObjectPool()->New(handle);};
@@ -30,11 +39,12 @@ CObject::CObject(void)
m_bCameraToAvoidThisObject = false;
ObjectCreatedBy = UNKNOWN_OBJECT;
m_nEndOfLifeTime = 0;
-// m_nRefModelIndex = -1; // duplicate
-// bUseVehicleColours = false; // duplicate
+ // m_nRefModelIndex = -1; // duplicate
+ // bUseVehicleColours = false; // duplicate
m_colour2 = 0;
m_colour1 = m_colour2;
m_nBonusValue = 0;
+ m_nCostValue = 0;
bIsPickup = false;
bPickupObjWithMessage = false;
bOutOfStock = false;
@@ -43,8 +53,12 @@ CObject::CObject(void)
bHasBeenDamaged = false;
m_nRefModelIndex = -1;
bUseVehicleColours = false;
+ // bIsStreetLight = false; // duplicate
m_pCurSurface = nil;
m_pCollidingEntity = nil;
+ m_nBeachballBounces = 0;
+ bIsStreetLight = false;
+ m_area = AREA_EVERYWHERE;
}
CObject::CObject(int32 mi, bool createRW)
@@ -69,22 +83,23 @@ CObject::CObject(CDummyObject *dummy)
dummy->DetachFromRwObject();
Init();
m_level = dummy->m_level;
+ m_area = dummy->m_area;
}
CObject::~CObject(void)
{
CRadar::ClearBlipForEntity(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(this));
- if(m_nRefModelIndex != -1)
+ if (m_nRefModelIndex != -1)
CModelInfo::GetModelInfo(m_nRefModelIndex)->RemoveRef();
- if(ObjectCreatedBy == TEMP_OBJECT && nNoTempObjects != 0)
+ if (ObjectCreatedBy == TEMP_OBJECT && nNoTempObjects != 0)
nNoTempObjects--;
}
-void
-CObject::ProcessControl(void)
-{
+void
+CObject::ProcessControl(void)
+{
CVector point, impulse;
if (m_nCollisionDamageEffect)
ObjectDamage(m_fDamageImpulse);
@@ -98,7 +113,8 @@ CObject::ProcessControl(void)
m_vecMoveSpeed *= fTimeStep;
m_vecTurnSpeed *= fTimeStep;
}
- if ((GetModelIndex() == MI_EXPLODINGBARREL || GetModelIndex() == MI_PETROLPUMP) && bHasBeenDamaged && bIsVisible
+ int16 mi = GetModelIndex();
+ if ((mi == MI_EXPLODINGBARREL || mi == MI_PETROLPUMP || mi == MI_PETROLPUMP2) && bHasBeenDamaged && bIsVisible
&& (CGeneral::GetRandomNumber() & 0x1F) == 10) {
bExplosionProof = true;
bIsVisible = false;
@@ -106,11 +122,73 @@ CObject::ProcessControl(void)
bAffectedByGravity = false;
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
}
+ if (mi == MI_RCBOMB) {
+ float fTurnForce = -(m_fTurnMass / 20.0f);
+ CPhysical::ApplyTurnForce(m_vecMoveSpeed * fTurnForce, -GetForward());
+ float fScalar = 1.0f - m_vecMoveSpeed.MagnitudeSqr() / 5.0f;
+ float fScalarTimed = Pow(fScalar, CTimer::GetTimeStep());
+ m_vecMoveSpeed *= fScalarTimed;
+ }
+ if (mi == MI_BEACHBALL) {
+ float fTimeStep = Pow(0.95f, CTimer::GetTimeStep());
+ float fPreviousVecSpeedMag = m_vecMoveSpeed.Magnitude2D();
+ m_vecMoveSpeed.x *= fTimeStep;
+ m_vecMoveSpeed.y *= fTimeStep;
+ m_vecMoveSpeed.z += fPreviousVecSpeedMag - m_vecMoveSpeed.Magnitude2D();
+ if (!FindPlayerVehicle()) {
+ CVector distance;
+ distance.x = FindPlayerCoors().x - GetPosition().x;
+ distance.y = FindPlayerCoors().y - GetPosition().y;
+ distance.z = FindPlayerCoors().z - GetPosition().z;
+ if (distance.z > 0.0 && distance.z < 1.5f && distance.Magnitude2D() < 1.0f) {
+ CVector playerSpeed = FindPlayerSpeed();
+ if (fPreviousVecSpeedMag < 0.05f && playerSpeed.Magnitude() > 0.1f) {
+ playerSpeed.z = 0.0f;
+ playerSpeed.Normalise();
+ playerSpeed.z = 0.3f;
+ m_vecMoveSpeed = CVector(
+ playerSpeed.x * BEACHBALL_SPEED_PROPORTION,
+ playerSpeed.y * BEACHBALL_SPEED_PROPORTION,
+ 0.3f * BEACHBALL_SPEED_PROPORTION
+ );
+ PlayOneShotScriptObject(SCRIPT_SOUND_HIT_BALL, GetPosition());
+ m_vecTurnSpeed += CVector(
+ ((CGeneral::GetRandomNumber() % 16) - 7) / 10.0f,
+ ((CGeneral::GetRandomNumber() % 16) - 7) / 10.0f,
+ 0.0f);
+ if (m_nBeachballBounces > 0) {
+ m_nBeachballBounces++;
+ }
+ if (m_nBeachballBounces > 0) {
+ sprintf(gString, "%d", m_nBeachballBounces);
+ CMoneyMessages::RegisterOne(GetPosition(), gString, 255, 50, 0, 0.6f, 0.5f);
+ CStats::RegisterHighestScore(3, m_nBeachballBounces);
+ }
+ }
+ }
+ if (distance.z > -1.05 && distance.z < -0.6 && m_vecMoveSpeed.z < 0.0f && distance.Magnitude2D() < 0.9f) {
+ m_vecMoveSpeed.x += (CGeneral::GetRandomNumber() % 8 - 3) / 100.0f;
+ m_vecMoveSpeed.y += (CGeneral::GetRandomNumber() % 8 - 3) / 100.0f;
+ m_vecMoveSpeed.z = Max(m_vecMoveSpeed.z + 0.3f, 0.2f);
+ PlayOneShotScriptObject(SCRIPT_SOUND_HIT_BALL, GetPosition());
+ m_vecTurnSpeed.x += (CGeneral::GetRandomNumber() % 16 - 7) / 10.0f;
+ m_vecTurnSpeed.y += (CGeneral::GetRandomNumber() % 16 - 7) / 10.0f;
+ m_nBeachballBounces++;
+ m_nBeachballBounces = Min(m_nBeachballBounces, BEACHBALL_MAX_SCORE);
+ sprintf(gString, "%d", m_nBeachballBounces);
+ CMoneyMessages::RegisterOne(GetPosition(), gString, 255, 50, 0, 0.6f, 0.5f);
+ CStats::RegisterHighestScore(3, m_nBeachballBounces);
+ }
+ }
+ }
+ if (bIsBIGBuilding) {
+ bIsInSafePosition = true;
+ }
}
-void
+void
CObject::Teleport(CVector vecPos)
-{
+{
CWorld::Remove(this);
m_matrix.GetPosition() = vecPos;
m_matrix.UpdateRW();
@@ -121,27 +199,131 @@ CObject::Teleport(CVector vecPos)
void
CObject::Render(void)
{
- if(bDoNotRender)
+ if (bDoNotRender)
return;
- if(m_nRefModelIndex != -1 && ObjectCreatedBy == TEMP_OBJECT && bUseVehicleColours){
+ if (m_nRefModelIndex != -1 && ObjectCreatedBy == TEMP_OBJECT && bUseVehicleColours) {
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(m_nRefModelIndex);
assert(mi->GetModelType() == MITYPE_VEHICLE);
mi->SetVehicleColour(m_colour1, m_colour2);
}
+ float red = (0.8f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed_Obj()) * 165.75f;
+ float green = (0.8f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen_Obj()) * 165.75f;
+ float blue = (0.8f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue_Obj()) * 165.75f;
+
+ red = clamp(red, 0.0f, 255.0f);
+ green = clamp(green, 0.0f, 255.0f);
+ blue = clamp(blue, 0.0f, 255.0f);
+
+ int alpha = CGeneral::GetRandomNumberInRange(196, 225);
+
+ RwRGBA color = { (uint8)red, (uint8)green, (uint8)blue, (uint8)alpha };
+
+ if (this->GetModelIndex() == MI_YT_MAIN_BODY) {
+ float moveSpeedMagnitude = this->GetMoveSpeed().Magnitude();
+ if (moveSpeedMagnitude > 0.0f) {
+ float scaleMax = GetColModel()->boundingBox.max.y * 0.85f;
+
+ CVector dir = this->GetMoveSpeed() + 0.3f * this->GetRight() - 0.5f * this->GetForward();
+ dir.z += 0.05f * moveSpeedMagnitude;
+
+ CVector pos = scaleMax * this->GetForward() + 2.25f * this->GetRight() + this->GetPosition();
+
+ float fWaterLevel;
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.75f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 1.2f * moveSpeedMagnitude, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+
+ float scaleMin = GetColModel()->boundingBox.min.y;
+
+ dir = this->GetMoveSpeed() - 0.5f * this->GetForward();
+ dir.z += 0.05f * moveSpeedMagnitude;
+
+ pos = scaleMin * this->GetForward() + 4.5f * this->GetRight() + this->GetPosition();
+
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.55f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+
+ pos = scaleMin * 1.1f * this->GetForward() + 2.25f * this->GetRight() + this->GetPosition();
+
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.55f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+
+ pos = scaleMin * 1.1f * this->GetForward() - 0.05f * this->GetRight() + this->GetPosition();
+
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.55f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+ }
+ }
+
+ if (this->GetModelIndex() == MI_YT_MAIN_BODY2) {
+ float moveSpeedMagnitude = this->GetMoveSpeed().Magnitude();
+ if (moveSpeedMagnitude > 0.0f) {
+ float scaleMax = GetColModel()->boundingBox.max.y * 0.85f;
+
+ CVector dir = this->GetMoveSpeed() - 0.3f * this->GetRight() - 0.5f * this->GetForward();
+ dir.z += 0.05f * moveSpeedMagnitude;
+
+ CVector pos = scaleMax * this->GetForward() - 2.25f * this->GetRight() + this->GetPosition();
+
+ float fWaterLevel;
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.75f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 1.2f * moveSpeedMagnitude, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+
+ float scaleMin = GetColModel()->boundingBox.min.y;
+
+ dir = this->GetMoveSpeed() - 0.5f * this->GetForward();
+ dir.z += 0.05f * moveSpeedMagnitude;
+
+ pos = scaleMin * this->GetForward() - 4.5f * this->GetRight() + this->GetPosition();
+
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.55f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+
+ pos = scaleMin * 1.1f * this->GetForward() - 2.25f * this->GetRight() + this->GetPosition();
+
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.55f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+ }
+ }
+
CEntity::Render();
}
bool
CObject::SetupLighting(void)
{
- DeActivateDirectional();
- SetAmbientColours();
-
- if(bRenderScorched){
+ if (bRenderScorched) {
WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f);
return true;
+ } else if (bIsPickup) {
+ SetFullAmbient();
+ return true;
+ } else if (bIsWeapon) {
+ ActivateDirectional();
+ SetAmbientColoursForPedsCarsAndObjects();
+ return true;
}
return false;
}
@@ -149,17 +331,20 @@ CObject::SetupLighting(void)
void
CObject::RemoveLighting(bool reset)
{
- if(reset)
- WorldReplaceScorchedLightsWithNormal(Scene.world);
+ if (reset) {
+ SetAmbientColours();
+ DeActivateDirectional();
+ }
}
-void
-CObject::ObjectDamage(float amount)
+void
+CObject::ObjectDamage(float amount)
{
if (!m_nCollisionDamageEffect || !bUsesCollision)
return;
static int8 nFrameGen = 0;
bool bBodyCastDamageEffect = false;
+#if 0
if (GetModelIndex() == MI_BODYCAST) {
if (amount > 50.0f)
nBodyCastHealth = (int16)(nBodyCastHealth - 0.5f * amount);
@@ -169,133 +354,363 @@ CObject::ObjectDamage(float amount)
bBodyCastDamageEffect = true;
amount = 0.0f;
}
+#endif
if ((amount * m_fCollisionDamageMultiplier > 150.0f || bBodyCastDamageEffect) && m_nCollisionDamageEffect) {
- const CVector& vecPos = m_matrix.GetPosition();
+ const CVector &vecPos = m_matrix.GetPosition();
const float fDirectionZ = 0.0002f * amount;
- switch (m_nCollisionDamageEffect)
- {
- case DAMAGE_EFFECT_CHANGE_MODEL:
- bRenderDamaged = true;
- break;
- case DAMAGE_EFFECT_SPLIT_MODEL:
- break;
- case DAMAGE_EFFECT_SMASH_COMPLETELY:
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- break;
- case DAMAGE_EFFECT_CHANGE_THEN_SMASH:
- if (!bRenderDamaged) {
+ switch (m_nCollisionDamageEffect) {
+ case DAMAGE_EFFECT_CHANGE_MODEL:
+ bRenderDamaged = true;
+ return;
+ case DAMAGE_EFFECT_SPLIT_MODEL:
+ return;
+ case DAMAGE_EFFECT_SMASH_AND_DAMAGE_TRAFFICLIGHTS:
+ {
+ static RwRGBA debrisColor = { 0xc8,0xc8,0xc8,0xff };
+ if (bRenderDamaged) {
+ break;
+ }
bRenderDamaged = true;
+ CVector min = 0.85f * GetColModel()->boundingBox.min;
+ CVector max = 0.85f * GetColModel()->boundingBox.max;
+ min.z = max.z;
+ min = GetMatrix() * min;
+ max = GetMatrix() * max;
+ CVector temp = (max - min) * 0.02f;
+ for (int32 i = 0; i < 50; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f)
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ CVector pos = min + temp * (float)i;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ float fColorFactor = CGeneral::GetRandomNumberInRange(0.6f, 1.2f);
+ RwRGBA color = debrisColor;
+ color.red *= fColorFactor;
+ color.green *= fColorFactor;
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-0.40f, 0.40f);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, pos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, min);
+ break;
+ }
+ case DAMAGE_EFFECT_CHANGE_THEN_SMASH: {
+ if (!bRenderDamaged) {
+ bRenderDamaged = true;
+ return;
+ }
+ // fall through
+ }
+ case DAMAGE_EFFECT_SMASH_COMPLETELY: {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ break;
}
- else {
+ case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY:
+ case DAMAGE_EFFECT_SMASH_YELLOW_TARGET_COMPLETELY:
+ {
bIsVisible = false;
bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
SetIsStatic(true);
bExplosionProof = true;
SetMoveSpeed(0.0f, 0.0f, 0.0f);
SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ const RwRGBA color = { 96, 48, 0, 255 };
+ for (int32 i = 0; i < 25; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ RwRGBA randomColor = color;
+ switch (m_nCollisionDamageEffect) {
+ case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY: {
+ float fRandom = CGeneral::GetRandomNumberInRange(0.01f, 1.0f);
+ randomColor.red *= fRandom;
+ randomColor.green *= fRandom;
+ randomColor.blue *= fRandom;
+ break;
+ }
+ case DAMAGE_EFFECT_SMASH_YELLOW_TARGET_COMPLETELY: {
+ randomColor.red = 0xff;
+ randomColor.green = 0xfc;
+ break;
+ }
+ }
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos);
+ break;
}
- break;
- case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY: {
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- const RwRGBA color = { 96, 48, 0, 255 };
- for (int32 i = 0; i < 25; i++) {
- CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(0.1f, 0.25f) + fDirectionZ);
- ++nFrameGen;
- int32 currentFrame = nFrameGen & 3;
- float fRandom = CGeneral::GetRandomNumberInRange(0.01f, 1.0f);
- RwRGBA randomColor = { uint8(color.red * fRandom), uint8(color.green * fRandom) , color.blue, color.alpha };
- float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
- int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
- CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ case DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ static const RwRGBA color = { 128, 128, 128, 255 };
+ CVector position = GetPosition();
+ for (int32 i = 0; i < 45; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ float fRandom = CGeneral::GetRandomNumberInRange(0.5f, 1.0f);
+ RwRGBA randomColor = { uint8(color.red * fRandom), uint8(color.green * fRandom), uint8(color.blue * fRandom), color.alpha };
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_1, vecPos);
+ break;
}
- PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos);
- break;
- }
- case DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY: {
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- const RwRGBA color = { 128, 128, 128, 255 };
- for (int32 i = 0; i < 45; i++) {
- CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(0.1f, 0.25f) + fDirectionZ);
- ++nFrameGen;
- int32 currentFrame = nFrameGen & 3;
- float fRandom = CGeneral::GetRandomNumberInRange(0.5f, 1.0f);
- RwRGBA randomColor = { uint8(color.red * fRandom), uint8(color.green * fRandom), uint8(color.blue * fRandom), color.alpha };
- float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
- int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
- CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ case DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY:
+ case DAMAGE_EFFECT_BURST_BEACHBALL:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ const RwRGBA color1 = { 200, 0, 0, 255 };
+ const RwRGBA color2 = { 200, 200, 200, 255 };
+ for (int32 i = 0; i < 10; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ RwRGBA color = color2;
+ if (nFrameGen & 1)
+ color = color1;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ }
+ if (m_nCollisionDamageEffect == DAMAGE_EFFECT_BURST_BEACHBALL) {
+ PlayOneShotScriptObject(SCRIPT_SOUND_HIT_BALL, vecPos);
+ } else {
+ PlayOneShotScriptObject(SCRIPT_SOUND_TIRE_COLLISION, vecPos);
+ }
+ break;
}
- PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_1, vecPos);
- break;
- }
- case DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY: {
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- const RwRGBA color1 = { 200, 0, 0, 255 };
- const RwRGBA color2 = { 200, 200, 200, 255 };
- for (int32 i = 0; i < 10; i++) {
- CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(0.1f, 0.25f) + fDirectionZ);
- ++nFrameGen;
- int32 currentFrame = nFrameGen & 3;
- RwRGBA color = color2;
- if (nFrameGen & 1)
- color = color1;
- float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
- int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
- CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ case DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ const RwRGBA color1 = { 200, 0, 0, 255 };
+ const RwRGBA color2 = { 200, 200, 200, 255 };
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ for (int32 i = 0; i < 32; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ const RwRGBA &color = nFrameGen & 1 ? color1 : color2;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos);
+ break;
}
- PlayOneShotScriptObject(SCRIPT_SOUND_TIRE_COLLISION, vecPos);
- break;
- }
- case DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY: {
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- const RwRGBA color1 = { 200, 0, 0, 255 };
- const RwRGBA color2 = { 200, 200, 200, 255 };
- for (int32 i = 0; i < 32; i++) {
- CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(0.1f, 0.25f) + fDirectionZ);
- ++nFrameGen;
- int32 currentFrame = nFrameGen & 3;
- RwRGBA color = color2;
- if (nFrameGen & 1)
- color = color1;
- float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
- int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
- CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW1:
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW2:
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW3:
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW4:
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW5:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ CRGBA possibleColor1;
+ CRGBA possibleColor2;
+ switch (m_nCollisionDamageEffect) {
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW1:
+ possibleColor1 = CRGBA(0xC0, 0x3E, 0xC, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW2:
+ possibleColor1 = CRGBA(0xA3, 0x36, 0x21, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW3:
+ possibleColor1 = CRGBA(0x12, 0x31, 0x24, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW4:
+ possibleColor1 = CRGBA(0xC0, 0xC8, 0xBE, 0xFF);
+ possibleColor2 = CRGBA(0x10, 0x57, 0x85, 0xFF);
+ break;
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW5:
+ possibleColor1 = CRGBA(0xD0, 0x94, 0x1B, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ }
+ for (int32 i = 0; i < 16; i++) {
+ CVector vecDir(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.15f) + fDirectionZ
+ );
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ ++nFrameGen;
+ int32 nCurFrame = nFrameGen & 0x3;
+ CRGBA &selectedColor = nFrameGen & 0x1 ? possibleColor1 : possibleColor2;
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, selectedColor, nRotationSpeed, 0, nCurFrame, 0);
+ if (!(i % 7)) {
+ static CRGBA secondParticleColors[4] = {
+ CRGBA(0xA0, 0x60, 0x60, 0xFF),
+ CRGBA(0x60, 0xA0, 0x60, 0xFF),
+ CRGBA(0x60, 0x60, 0xA0, 0xFF),
+ CRGBA(0xA0, 0xA0, 0xA0, 0xFF)
+ };
+ vecDir *= 0.5f;
+ CRGBA &secondParticleColor = secondParticleColors[nFrameGen & 3];
+ int32 nSecondRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_DEBRIS, vecPos, vecDir, nil, 0.1f, secondParticleColor, nSecondRotationSpeed, 0, 1, 0);
+ }
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos);
+ break;
}
- PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos);
- break;
- }
+ case DAMAGE_EFFECT_SMASH_VEGPALM:
+ {
+ static RwRGBA primaryColor1 = { 0x39, 0x4D, 0x29, 0xff };
+ static RwRGBA primaryColor2 = { 0x94, 0x7D, 0x73, 0xff };
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ float fRadius = GetColModel()->boundingSphere.radius;
+ for (int32 i = 0; i < 32; i++) {
+ CVector particleDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.25f, 0.25f),
+ CGeneral::GetRandomNumberInRange(-0.25f, 0.25f),
+ CGeneral::GetRandomNumberInRange(-0.05f, 0.05f) + fDirectionZ
+ );
+ CVector particlePos = vecPos;
+ particlePos.z += CGeneral::GetRandomNumberInRange(0.0f, 1.0f) * fRadius;
+ ++nFrameGen;
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ int32 nCurFrame = nFrameGen & 0x3;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ RwRGBA& particleColor = nFrameGen & 1 ? primaryColor1 : primaryColor2;
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, particlePos, particleDir, nil, fSize, particleColor, nRotationSpeed, 0, nCurFrame, 0);
+ if ((i % 7) == 0) {
+ static RwRGBA secondaryColor = { 0x9A, 0x99, 0x99, 0x3E };
+ CParticle::AddParticle(PARTICLE_DEBRIS, particlePos, particleDir, nil, 0.3, secondaryColor, nRotationSpeed, 0, 0, 0);
+ }
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos);
+ break;
+ }
+ case DAMAGE_EFFECT_SMASH_BLACKBAG:
+ case DAMAGE_EFFECT_SMASH_BEACHLOUNGE_WOOD:
+ case DAMAGE_EFFECT_SMASH_BEACHLOUNGE_TOWEL:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ CRGBA possibleColor1;
+ CRGBA possibleColor2;
+ switch (m_nCollisionDamageEffect) {
+ case DAMAGE_EFFECT_SMASH_BLACKBAG:
+ possibleColor1 = CRGBA(0, 0, 0, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ case DAMAGE_EFFECT_SMASH_BEACHLOUNGE_WOOD:
+ possibleColor1 = CRGBA(0x8F, 0x8A, 0x8C, 0xFF);
+ possibleColor2 = CRGBA(0x73, 0x75, 0x7B, 0xFF);
+ break;
+ case DAMAGE_EFFECT_SMASH_BEACHLOUNGE_TOWEL:
+ possibleColor1 = CRGBA(0x52, 0x92, 0x4A, 0xFF);
+ possibleColor2 = CRGBA(0xCE, 0xCF, 0xCE, 0xFF);
+ break;
+ }
+ for (int32 i = 0; i < 16; i++) {
+ CVector vecDir(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 nCurFrame = nFrameGen & 0x3;
+ CRGBA &selectedColor = nFrameGen & 0x1 ? possibleColor1 : possibleColor2;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, selectedColor, nRotationSpeed, 0, nCurFrame, 0);
+ }
+ if (m_nCollisionDamageEffect == DAMAGE_EFFECT_SMASH_BLACKBAG) {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos);
+ } else if (m_nCollisionDamageEffect == DAMAGE_EFFECT_SMASH_BEACHLOUNGE_WOOD) {
+ PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos);
+ }
+ break;
+ }
+ default:
+ DEV("Unhandled collision damage effect id: %d\n", m_nCollisionDamageEffect);
+ return;
}
}
}
@@ -307,9 +722,9 @@ CObject::RefModelInfo(int32 modelId)
CModelInfo::GetModelInfo(modelId)->AddRef();
}
-void
-CObject::Init(void)
-{
+void
+CObject::Init(void)
+{
m_type = ENTITY_TYPE_OBJECT;
CObjectData::SetObjectData(GetModelIndex(), *this);
m_nEndOfLifeTime = 0;
@@ -326,18 +741,25 @@ CObject::Init(void)
m_colour1 = 0;
m_colour2 = 0;
m_nBonusValue = 0;
+ bIsWeapon = false;
+ m_nCostValue = 0;
m_pCollidingEntity = nil;
CColPoint point;
- CEntity* outEntity = nil;
- const CVector& vecPos = m_matrix.GetPosition();
+ CEntity *outEntity = nil;
+ const CVector &vecPos = m_matrix.GetPosition();
if (CWorld::ProcessVerticalLine(vecPos, vecPos.z - 10.0f, point, outEntity, true, false, false, false, false, false, nil))
m_pCurSurface = outEntity;
else
m_pCurSurface = nil;
- if (GetModelIndex() == MI_BODYCAST)
- nBodyCastHealth = 1000;
- else if (GetModelIndex() == MI_BUOY)
+
+ if (GetModelIndex() == MI_BUOY)
bTouchingWater = true;
+
+ if (CModelInfo::GetModelInfo(GetModelIndex())->GetModelType() == MITYPE_WEAPON)
+ bIsWeapon = true;
+ bIsStreetLight = IsLightObject(GetModelIndex());
+
+ m_area = AREA_EVERYWHERE;
}
bool
@@ -352,6 +774,8 @@ CObject::CanBeDeleted(void)
return true;
case CUTSCENE_OBJECT:
return false;
+ case CONTROLLED_SUB_OBJECT:
+ return false;
default:
return true;
}
@@ -360,9 +784,9 @@ CObject::CanBeDeleted(void)
void
CObject::DeleteAllMissionObjects()
{
- CObjectPool* objectPool = CPools::GetObjectPool();
+ CObjectPool *objectPool = CPools::GetObjectPool();
for (int32 i = 0; i < objectPool->GetSize(); i++) {
- CObject* pObject = objectPool->GetSlot(i);
+ CObject *pObject = objectPool->GetSlot(i);
if (pObject && pObject->ObjectCreatedBy == MISSION_OBJECT) {
CWorld::Remove(pObject);
delete pObject;
@@ -370,12 +794,12 @@ CObject::DeleteAllMissionObjects()
}
}
-void
-CObject::DeleteAllTempObjects()
+void
+CObject::DeleteAllTempObjects()
{
- CObjectPool* objectPool = CPools::GetObjectPool();
+ CObjectPool *objectPool = CPools::GetObjectPool();
for (int32 i = 0; i < objectPool->GetSize(); i++) {
- CObject* pObject = objectPool->GetSlot(i);
+ CObject *pObject = objectPool->GetSlot(i);
if (pObject && pObject->ObjectCreatedBy == TEMP_OBJECT) {
CWorld::Remove(pObject);
delete pObject;
@@ -383,8 +807,8 @@ CObject::DeleteAllTempObjects()
}
}
-void
-CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius)
+void
+CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius)
{
CObjectPool *objectPool = CPools::GetObjectPool();
for (int32 i = 0; i < objectPool->GetSize(); i++) {
@@ -395,3 +819,18 @@ CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius)
}
}
}
+
+bool
+IsObjectPointerValid(CObject *pObject)
+{
+ if (!pObject)
+ return false;
+ int index = CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pObject);
+#ifdef FIX_BUGS
+ if (index < 0 || index >= CPools::GetObjectPool()->GetSize())
+#else
+ if (index < 0 || index > CPools::GetObjectPool()->GetSize())
+#endif
+ return false;
+ return pObject->bIsBIGBuilding || pObject->m_entryInfoList.first;
+}
diff --git a/src/objects/Object.h b/src/objects/Object.h
index c9a1bba8..e34043a8 100644
--- a/src/objects/Object.h
+++ b/src/objects/Object.h
@@ -8,6 +8,7 @@ enum {
MISSION_OBJECT = 2,
TEMP_OBJECT = 3,
CUTSCENE_OBJECT = 4,
+ CONTROLLED_SUB_OBJECT = 5,
};
enum CollisionSpecialResponseCase
@@ -25,13 +26,29 @@ enum CollisionDamageEffect
DAMAGE_EFFECT_NONE,
DAMAGE_EFFECT_CHANGE_MODEL,
DAMAGE_EFFECT_SPLIT_MODEL,
- DAMAGE_EFFECT_SMASH_COMPLETELY,
+ DAMAGE_EFFECT_SMASH_AND_DAMAGE_TRAFFICLIGHTS,
+
+ DAMAGE_EFFECT_SMASH_COMPLETELY = 20,
DAMAGE_EFFECT_CHANGE_THEN_SMASH,
DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY = 50,
+ DAMAGE_EFFECT_SMASH_YELLOW_TARGET_COMPLETELY = 51,
+
DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY = 60,
DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY = 70,
- DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY = 80
+ DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY = 80,
+
+ DAMAGE_EFFECT_SMASH_NEWSTANDNEW1 = 91,
+ DAMAGE_EFFECT_SMASH_NEWSTANDNEW2 = 92,
+ DAMAGE_EFFECT_SMASH_NEWSTANDNEW3 = 93,
+ DAMAGE_EFFECT_SMASH_NEWSTANDNEW4 = 94,
+ DAMAGE_EFFECT_SMASH_NEWSTANDNEW5 = 95,
+
+ DAMAGE_EFFECT_SMASH_BLACKBAG = 100,
+ DAMAGE_EFFECT_SMASH_VEGPALM = 110,
+ DAMAGE_EFFECT_BURST_BEACHBALL = 120,
+ DAMAGE_EFFECT_SMASH_BEACHLOUNGE_WOOD = 131,
+ DAMAGE_EFFECT_SMASH_BEACHLOUNGE_TOWEL = 132,
};
class CVehicle;
@@ -43,18 +60,23 @@ public:
CMatrix m_objectMatrix;
float m_fUprootLimit;
int8 ObjectCreatedBy;
- int8 bIsPickup : 1;
- int8 bPickupObjWithMessage : 1;
- int8 bOutOfStock : 1;
- int8 bGlassCracked : 1;
- int8 bGlassBroken : 1;
- int8 bHasBeenDamaged : 1;
- int8 bUseVehicleColours : 1;
- int8 m_nBonusValue;
+ uint8 bIsPickup : 1;
+ uint8 bAmmoCollected : 1;
+ uint8 bPickupObjWithMessage : 1;
+ uint8 bOutOfStock : 1;
+ uint8 bGlassCracked : 1;
+ uint8 bGlassBroken : 1;
+ uint8 bHasBeenDamaged : 1;
+ uint8 bUseVehicleColours : 1;
+ uint8 bIsWeapon : 1;
+ uint8 bIsStreetLight : 1;
+ int8 m_nBonusValue;
+ uint16 m_nCostValue;
float m_fCollisionDamageMultiplier;
uint8 m_nCollisionDamageEffect;
uint8 m_nSpecialCollisionResponseCases;
bool m_bCameraToAvoidThisObject;
+ uint8 m_nBeachballBounces;
uint32 m_obj_unused1;
uint32 m_nEndOfLifeTime;
int16 m_nRefModelIndex;
@@ -63,7 +85,7 @@ public:
int8 m_colour1, m_colour2;
static int16 nNoTempObjects;
- static int16 nBodyCastHealth;
+ static float fDistToNearestTree;
static void *operator new(size_t);
static void *operator new(size_t, int);
@@ -91,4 +113,4 @@ public:
static void DeleteAllTempObjectsInArea(CVector point, float fRadius);
};
-VALIDATE_SIZE(CObject, 0x198);
+bool IsObjectPointerValid(CObject* pObject);
diff --git a/src/objects/ObjectData.cpp b/src/objects/ObjectData.cpp
index 589cc3f7..04ac0b9c 100644
--- a/src/objects/ObjectData.cpp
+++ b/src/objects/ObjectData.cpp
@@ -6,6 +6,8 @@
#include "FileMgr.h"
#include "ObjectData.h"
+//--MIAMI: file done
+
CObjectInfo CObjectData::ms_aObjectInfo[NUMOBJECTINFO];
// Another ugly file reader
@@ -18,11 +20,55 @@ CObjectData::Initialise(const char *filename)
float percentSubmerged;
int damageEffect, responseCase, camAvoid;
CBaseModelInfo *mi;
+
+ ms_aObjectInfo[0].m_fMass = 99999.0f;
+ ms_aObjectInfo[0].m_fTurnMass = 99999.0f;
+ ms_aObjectInfo[0].m_fAirResistance = 0.99f;
+ ms_aObjectInfo[0].m_fElasticity = 0.1f;
+ ms_aObjectInfo[0].m_fBuoyancy = GRAVITY * ms_aObjectInfo[0].m_fMass * 2.0f;
+ ms_aObjectInfo[0].m_fUprootLimit = 0.0f;
+ ms_aObjectInfo[0].m_fCollisionDamageMultiplier = 1.0f;
+ ms_aObjectInfo[0].m_nCollisionDamageEffect = 0;
+ ms_aObjectInfo[0].m_nSpecialCollisionResponseCases = 0;
+ ms_aObjectInfo[0].m_bCameraToAvoidThisObject = false;
+
+ ms_aObjectInfo[1].m_fMass = 99999.0f;
+ ms_aObjectInfo[1].m_fTurnMass = 99999.0f;
+ ms_aObjectInfo[1].m_fAirResistance = 0.99f;
+ ms_aObjectInfo[1].m_fElasticity = 0.1f;
+ ms_aObjectInfo[1].m_fBuoyancy = ms_aObjectInfo[0].m_fBuoyancy;
+ ms_aObjectInfo[1].m_fUprootLimit = 0.0f;
+ ms_aObjectInfo[1].m_fCollisionDamageMultiplier = 1.0f;
+ ms_aObjectInfo[1].m_nCollisionDamageEffect = 0;
+ ms_aObjectInfo[1].m_nSpecialCollisionResponseCases = 0;
+ ms_aObjectInfo[1].m_bCameraToAvoidThisObject = true;
+
+ ms_aObjectInfo[2].m_fMass = 99999.0f;
+ ms_aObjectInfo[2].m_fTurnMass = 99999.0f;
+ ms_aObjectInfo[2].m_fAirResistance = 0.99f;
+ ms_aObjectInfo[2].m_fElasticity = 0.1f;
+ ms_aObjectInfo[2].m_fBuoyancy = ms_aObjectInfo[0].m_fBuoyancy;
+ ms_aObjectInfo[2].m_fUprootLimit = 0.0f;
+ ms_aObjectInfo[2].m_fCollisionDamageMultiplier = 1.0f;
+ ms_aObjectInfo[2].m_nCollisionDamageEffect = 0;
+ ms_aObjectInfo[2].m_bCameraToAvoidThisObject = false;
+ ms_aObjectInfo[2].m_nSpecialCollisionResponseCases = 4;
+
+ ms_aObjectInfo[3].m_fMass = 99999.0f;
+ ms_aObjectInfo[3].m_fTurnMass = 99999.0f;
+ ms_aObjectInfo[3].m_fAirResistance = 0.99f;
+ ms_aObjectInfo[3].m_fElasticity = 0.1f;
+ ms_aObjectInfo[3].m_fBuoyancy = ms_aObjectInfo[0].m_fBuoyancy;
+ ms_aObjectInfo[3].m_fUprootLimit = 0.0f;
+ ms_aObjectInfo[3].m_fCollisionDamageMultiplier = 1.0f;
+ ms_aObjectInfo[3].m_nCollisionDamageEffect = 0;
+ ms_aObjectInfo[3].m_nSpecialCollisionResponseCases = 4;
+ ms_aObjectInfo[3].m_bCameraToAvoidThisObject = true;
CFileMgr::SetDir("");
CFileMgr::LoadFile(filename, work_buff, sizeof(work_buff), "r");
- id = 0;
+ id = 4;
p = (char*)work_buff;
while(*p != '*'){
// skip over white space and comments
@@ -44,7 +90,11 @@ CObjectData::Initialise(const char *filename)
}
if(*p == '\n')
p++;
+#ifdef FIX_BUGS
*lp = '\0'; // FIX: game wrote '\n' here
+#else
+ *lp = '\n';
+#endif
assert(id < NUMOBJECTINFO);
sscanf(line, "%s %f %f %f %f %f %f %f %d %d %d", name,
@@ -63,9 +113,23 @@ CObjectData::Initialise(const char *filename)
ms_aObjectInfo[id].m_bCameraToAvoidThisObject = camAvoid;
mi = CModelInfo::GetModelInfo(name, nil);
- if(mi)
- mi->SetObjectID(id++);
- else
+ if (mi) {
+ if (ms_aObjectInfo[0].m_fMass != ms_aObjectInfo[id].m_fMass
+ || ms_aObjectInfo[0].m_fCollisionDamageMultiplier != ms_aObjectInfo[id].m_fCollisionDamageMultiplier
+ || ms_aObjectInfo[0].m_nCollisionDamageEffect != ms_aObjectInfo[id].m_nCollisionDamageEffect
+ || ((ms_aObjectInfo[0].m_nSpecialCollisionResponseCases != ms_aObjectInfo[id].m_nSpecialCollisionResponseCases)
+ && (ms_aObjectInfo[2].m_nSpecialCollisionResponseCases != ms_aObjectInfo[id].m_nSpecialCollisionResponseCases))) {
+ mi->SetObjectID(id++);
+ } else if (ms_aObjectInfo[0].m_nSpecialCollisionResponseCases == ms_aObjectInfo[id].m_nSpecialCollisionResponseCases) {
+ if (ms_aObjectInfo[0].m_bCameraToAvoidThisObject == ms_aObjectInfo[id].m_bCameraToAvoidThisObject)
+ mi->SetObjectID(0);
+ else
+ mi->SetObjectID(1);
+ } else if (ms_aObjectInfo[2].m_bCameraToAvoidThisObject == ms_aObjectInfo[id].m_bCameraToAvoidThisObject)
+ mi->SetObjectID(2);
+ else
+ mi->SetObjectID(3);
+ } else
debug("CObjectData: Cannot find object %s\n", name);
}
}
@@ -92,6 +156,7 @@ CObjectData::SetObjectData(int32 modelId, CObject &object)
object.m_bCameraToAvoidThisObject = objinfo->m_bCameraToAvoidThisObject;
if(object.m_fMass >= 99998.0f){
object.bInfiniteMass = true;
+ object.m_phy_flagA08 = true;
object.bAffectedByGravity = false;
object.bExplosionProof = true;
}
diff --git a/src/objects/ParticleObject.cpp b/src/objects/ParticleObject.cpp
index 71f223d7..4d080d1f 100644
--- a/src/objects/ParticleObject.cpp
+++ b/src/objects/ParticleObject.cpp
@@ -53,7 +53,7 @@ CAudioHydrant::Remove(CParticleObject *particleobject)
{
DMAudio.DestroyEntity(List[i].AudioEntity);
List[i].AudioEntity = AEHANDLE_NONE;
- List[i].pParticleObject = NULL;
+ List[i].pParticleObject = nil;
}
}
}
@@ -62,8 +62,8 @@ CParticleObject::CParticleObject() :
CPlaceable(),
m_nFrameCounter(0),
m_nState(POBJECTSTATE_INITIALISED),
- m_pNext(NULL),
- m_pPrev(NULL),
+ m_pNext(nil),
+ m_pPrev(nil),
m_nRemoveTimer(0)
{
@@ -78,20 +78,20 @@ CParticleObject::~CParticleObject()
void
CParticleObject::Initialise()
{
- pCloseListHead = NULL;
- pFarListHead = NULL;
+ pCloseListHead = nil;
+ pFarListHead = nil;
pUnusedListHead = &gPObjectArray[0];
for ( int32 i = 0; i < MAX_PARTICLEOBJECTS; i++ )
{
if ( i == 0 )
- gPObjectArray[i].m_pPrev = NULL;
+ gPObjectArray[i].m_pPrev = nil;
else
gPObjectArray[i].m_pPrev = &gPObjectArray[i - 1];
if ( i == MAX_PARTICLEOBJECTS-1 )
- gPObjectArray[i].m_pNext = NULL;
+ gPObjectArray[i].m_pNext = nil;
else
gPObjectArray[i].m_pNext = &gPObjectArray[i + 1];
@@ -127,12 +127,10 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
CParticleObject *pobj = pUnusedListHead;
- ASSERT(pobj != NULL);
-
- if ( pobj == NULL )
+ if ( pobj == nil )
{
printf("Error: No particle objects available!\n");
- return NULL;
+ return nil;
}
MoveToList(&pUnusedListHead, &pCloseListHead, pobj);
@@ -150,7 +148,7 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
pobj->m_bRemove = remove;
- pobj->m_pParticle = NULL;
+ pobj->m_pParticle = nil;
if ( lifeTime != 0 )
pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds() + lifeTime;
@@ -165,229 +163,243 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
pobj->m_fSize = size;
pobj->m_fRandVal = 0.0f;
- if ( type <= POBJECT_CATALINAS_SHOTGUNFLASH )
+ switch ( type )
{
- switch ( type )
+ case POBJECT_PAVEMENT_STEAM:
{
- case POBJECT_PAVEMENT_STEAM:
- {
- pobj->m_ParticleType = PARTICLE_STEAM_NY;
- pobj->m_nNumEffectCycles = 1;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 3;
-#else
- pobj->m_nSkipFrames = 1;
-#endif
- pobj->m_nCreationChance = 8;
- break;
- }
-
- case POBJECT_PAVEMENT_STEAM_SLOWMOTION:
- {
- pobj->m_ParticleType = PARTICLE_STEAM_NY_SLOWMOTION;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 8;
- break;
- }
-
- case POBJECT_WALL_STEAM:
- {
- pobj->m_ParticleType = PARTICLE_STEAM_NY;
- pobj->m_nNumEffectCycles = 1;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 3;
-#else
- pobj->m_nSkipFrames = 1;
-#endif
- pobj->m_nCreationChance = 8;
- break;
- }
-
- case POBJECT_WALL_STEAM_SLOWMOTION:
- {
- pobj->m_ParticleType = PARTICLE_STEAM_NY_SLOWMOTION;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 8;
- break;
- }
-
- case POBJECT_DARK_SMOKE:
- {
- pobj->m_ParticleType = PARTICLE_STEAM_NY;
- pobj->m_nNumEffectCycles = 1;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 3;
-#else
- pobj->m_nSkipFrames = 1;
-#endif
- pobj->m_nCreationChance = 8;
- pobj->m_Color = CRGBA(16, 16, 16, 255);
- break;
- }
-
- case POBJECT_FIRE_HYDRANT:
- {
- pobj->m_ParticleType = PARTICLE_WATER_HYDRANT;
- pobj->m_nNumEffectCycles = 4;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 0;
- pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.3f);
- pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds() + 5000;
- CAudioHydrant::Add(pobj);
- break;
- }
-
- case POBJECT_CAR_WATER_SPLASH:
- case POBJECT_PED_WATER_SPLASH:
- {
- pobj->m_ParticleType = PARTICLE_CAR_SPLASH;
- pobj->m_nNumEffectCycles = 0;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 1;
-#else
- pobj->m_nSkipFrames = 3;
-#endif
- pobj->m_nCreationChance = 0;
+ pobj->m_ParticleType = PARTICLE_STEAM_NY;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 3;
+ pobj->m_nCreationChance = 8;
+ break;
+ }
+
+ case POBJECT_PAVEMENT_STEAM_SLOWMOTION:
+ {
+ pobj->m_ParticleType = PARTICLE_STEAM_NY_SLOWMOTION;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 8;
+ break;
+ }
+
+ case POBJECT_WALL_STEAM:
+ {
+ pobj->m_ParticleType = PARTICLE_STEAM_NY;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 3;
+ pobj->m_nCreationChance = 8;
+ break;
+ }
+
+ case POBJECT_WALL_STEAM_SLOWMOTION:
+ {
+ pobj->m_ParticleType = PARTICLE_STEAM_NY_SLOWMOTION;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 8;
+ break;
+ }
+
+ case POBJECT_DARK_SMOKE:
+ {
+ pobj->m_ParticleType = PARTICLE_STEAM_NY;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 3;
+ pobj->m_nCreationChance = 8;
+ pobj->m_Color = CRGBA(16, 16, 16, 255);
+ break;
+ }
+
+ case POBJECT_WATER_FOUNTAIN_VERT:
+ {
+ pobj->m_ParticleType = PARTICLE_WATER_HYDRANT;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.1f);
+ break;
+ }
+
+ case POBJECT_WATER_FOUNTAIN_HORIZ:
+ {
+ pobj->m_ParticleType = PARTICLE_WATER_HYDRANT;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ break;
+ }
+
+ case POBJECT_FIRE_HYDRANT:
+ {
+ pobj->m_ParticleType = PARTICLE_WATER_HYDRANT;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.3f);
+ pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ CAudioHydrant::Add(pobj);
+ break;
+ }
+
+ case POBJECT_CAR_WATER_SPLASH:
+ case POBJECT_PED_WATER_SPLASH:
+ {
+ pobj->m_ParticleType = PARTICLE_CAR_SPLASH;
+ pobj->m_nNumEffectCycles = 0;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
#ifdef SCREEN_DROPLETS
- ScreenDroplets::RegisterSplash(pobj);
-#endif
- break;
- }
-
- case POBJECT_SPLASHES_AROUND:
- {
- pobj->m_ParticleType = PARTICLE_SPLASH;
-#ifdef PC_PARTICLE
- pobj->m_nNumEffectCycles = 15;
-#else
- pobj->m_nNumEffectCycles = 30;
+ ScreenDroplets::RegisterSplash(pobj);
#endif
- pobj->m_nSkipFrames = 2;
- pobj->m_nCreationChance = 0;
- break;
- }
-
- case POBJECT_SMALL_FIRE:
- {
- pobj->m_ParticleType = PARTICLE_FLAME;
- pobj->m_nNumEffectCycles = 1;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 2;
-#else
- pobj->m_nSkipFrames = 1;
-#endif
- pobj->m_nCreationChance = 2;
- pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
- break;
- }
-
- case POBJECT_BIG_FIRE:
- {
- pobj->m_ParticleType = PARTICLE_FLAME;
- pobj->m_nNumEffectCycles = 1;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 2;
-#else
- pobj->m_nSkipFrames = 1;
-#endif
- pobj->m_nCreationChance = 4;
- pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
- break;
- }
-
- case POBJECT_DRY_ICE:
- {
- pobj->m_ParticleType = PARTICLE_SMOKE;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 0;
- pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
- break;
- }
-
- case POBJECT_DRY_ICE_SLOWMOTION:
- {
- pobj->m_ParticleType = PARTICLE_SMOKE_SLOWMOTION;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 0;
- pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
- break;
- }
-
- case POBJECT_FIRE_TRAIL:
- {
- pobj->m_ParticleType = PARTICLE_EXPLOSION_MEDIUM;
- pobj->m_nNumEffectCycles = 1;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 3;
-#else
- pobj->m_nSkipFrames = 1;
-#endif
- pobj->m_nCreationChance = 2;
- pobj->m_fRandVal = 0.01f;
- break;
- }
-
- case POBJECT_SMOKE_TRAIL:
- {
- pobj->m_ParticleType = PARTICLE_FIREBALL_SMOKE;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 2;
- pobj->m_fRandVal = 0.02f;
- break;
- }
-
- case POBJECT_FIREBALL_AND_SMOKE:
- {
- pobj->m_ParticleType = PARTICLE_FLAME;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 2;
- pobj->m_fRandVal = 0.1f;
- break;
- }
-
- case POBJECT_ROCKET_TRAIL:
- {
- pobj->m_ParticleType = PARTICLE_FLAME;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 2;
- pobj->m_nCreationChance = 8;
- pobj->m_fRandVal = 0.1f;
- break;
- }
-
- case POBJECT_EXPLOSION_ONCE:
- {
- pobj->m_ParticleType = PARTICLE_EXPLOSION_LARGE;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 0;
- pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds();
- break;
- }
-
- case POBJECT_CATALINAS_GUNFLASH:
- case POBJECT_CATALINAS_SHOTGUNFLASH:
- {
- pobj->m_ParticleType = PARTICLE_GUNFLASH_NOANIM;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 0;
- pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds();
- pobj->m_vecTarget.Normalise();
- break;
- }
+ break;
+ }
+
+ case POBJECT_SPLASHES_AROUND:
+ {
+ pobj->m_ParticleType = PARTICLE_SPLASH;
+ pobj->m_nNumEffectCycles = 15;
+ pobj->m_nSkipFrames = 2;
+ pobj->m_nCreationChance = 0;
+ break;
+ }
+
+ case POBJECT_SMALL_FIRE:
+ {
+ pobj->m_ParticleType = PARTICLE_FLAME;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 2;
+ pobj->m_nCreationChance = 2;
+ pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
+ break;
+ }
+
+ case POBJECT_BIG_FIRE:
+ {
+ pobj->m_ParticleType = PARTICLE_FLAME;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 2;
+ pobj->m_nCreationChance = 4;
+ pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
+ break;
+ }
+
+ case POBJECT_DRY_ICE:
+ {
+ pobj->m_ParticleType = PARTICLE_SMOKE;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
+ break;
+ }
+
+ case POBJECT_DRY_ICE_SLOWMOTION:
+ {
+ pobj->m_ParticleType = PARTICLE_SMOKE_SLOWMOTION;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
+ break;
+ }
+
+ case POBJECT_FIRE_TRAIL:
+ {
+ pobj->m_ParticleType = PARTICLE_EXPLOSION_MEDIUM;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 3;
+ pobj->m_nCreationChance = 2;
+ pobj->m_fRandVal = 0.01f;
+ break;
+ }
+
+ case POBJECT_SMOKE_TRAIL:
+ {
+ pobj->m_ParticleType = PARTICLE_FIREBALL_SMOKE;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 2;
+ pobj->m_fRandVal = 0.02f;
+ break;
+ }
+
+ case POBJECT_FIREBALL_AND_SMOKE:
+ {
+ pobj->m_ParticleType = PARTICLE_FLAME;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ pobj->m_fRandVal = 0.1f;
+ break;
+ }
+
+ case POBJECT_ROCKET_TRAIL:
+ {
+ pobj->m_ParticleType = PARTICLE_FLAME;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 2;
+ pobj->m_nCreationChance = 8;
+ pobj->m_fRandVal = 0.1f;
+ break;
+ }
+
+ case POBJECT_EXPLOSION_ONCE:
+ {
+ pobj->m_ParticleType = PARTICLE_EXPLOSION_LARGE;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds();
+ break;
}
}
return pobj;
}
+CParticleObject *
+CParticleObject::AddObject(tParticleType type, CVector const &pos, CVector const &target, float size, uint32 lifeTime, uint8 numEffectCycles, uint8 skipFrames, uint16 creationChance, uint8 remove)
+{
+ CParticleObject *pobj = pUnusedListHead;
+
+ ASSERT(pobj != nil);
+
+ if ( pobj == nil )
+ {
+ printf("Error: No particle objects available!\n");
+ return nil;
+ }
+
+ MoveToList(&pUnusedListHead, &pCloseListHead, pobj);
+
+ pobj->m_nState = POBJECTSTATE_UPDATE_CLOSE;
+ pobj->m_Type = (eParticleObjectType)-1;
+ pobj->m_ParticleType = type;
+
+ pobj->SetPosition(pos);
+ pobj->m_vecTarget = target;
+
+ pobj->m_nNumEffectCycles = numEffectCycles;
+ pobj->m_nSkipFrames = skipFrames;
+ pobj->m_nCreationChance = creationChance;
+ pobj->m_nFrameCounter = 0;
+
+ pobj->m_bRemove = remove;
+
+ if ( lifeTime != 0 )
+ pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds() + lifeTime;
+ else
+ pobj->m_nRemoveTimer = 0;
+
+ pobj->m_Color.alpha = 0;
+
+ pobj->m_fSize = size;
+ pobj->m_fRandVal = 0.0f;
+
+ return pobj;
+}
+
void
CParticleObject::RemoveObject(void)
{
@@ -414,7 +426,7 @@ CParticleObject::UpdateAll(void)
{
CParticleObject *pobj = pCloseListHead;
CParticleObject *nextpobj;
- if ( pobj != NULL )
+ if ( pobj != nil )
{
do
{
@@ -422,7 +434,7 @@ CParticleObject::UpdateAll(void)
pobj->UpdateClose();
pobj = nextpobj;
}
- while ( nextpobj != NULL );
+ while ( nextpobj != nil );
}
}
@@ -432,7 +444,7 @@ CParticleObject::UpdateAll(void)
CParticleObject *pobj = pFarListHead;
CParticleObject *nextpobj;
- if ( pobj != NULL )
+ if ( pobj != nil )
{
do
{
@@ -448,7 +460,7 @@ CParticleObject::UpdateAll(void)
pobj = nextpobj;
}
- while ( nextpobj != NULL );
+ while ( nextpobj != nil );
}
}
}
@@ -503,7 +515,7 @@ void CParticleObject::UpdateClose(void)
flamevel.y = vel.y;
flamevel.z = CGeneral::GetRandomNumberInRange(0.0125f*size, 0.1f*size);
- CParticle::AddParticle(PARTICLE_FLAME, pos, flamevel, NULL, size);
+ CParticle::AddParticle(PARTICLE_FLAME, pos, flamevel, nil, size);
CVector possmoke = pos;
@@ -534,7 +546,7 @@ void CParticleObject::UpdateClose(void)
float flamesize = 0.8f*size;
- CParticle::AddParticle(PARTICLE_FLAME, pos, flamevel, NULL, flamesize);
+ CParticle::AddParticle(PARTICLE_FLAME, pos, flamevel, nil, flamesize);
for ( int32 i = 0; i < 4; i++ )
@@ -553,7 +565,7 @@ void CParticleObject::UpdateClose(void)
case POBJECT_FIREBALL_AND_SMOKE:
{
- if ( this->m_pParticle == NULL )
+ if ( this->m_pParticle == nil )
{
CVector pos = this->GetPosition();
CVector vel = this->m_vecTarget;
@@ -561,7 +573,7 @@ void CParticleObject::UpdateClose(void)
CVector expvel = 1.2f*vel;
float expsize = 1.2f*size;
- this->m_pParticle = CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, expvel, NULL, expsize);
+ this->m_pParticle = CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, expvel, nil, expsize);
}
else
{
@@ -578,7 +590,7 @@ void CParticleObject::UpdateClose(void)
fireballvel.y += CGeneral::GetRandomNumberInRange(-veloffset.y, veloffset.y);
fireballvel.z += CGeneral::GetRandomNumberInRange(-veloffset.z, veloffset.z);
- CParticle::AddParticle(PARTICLE_FIREBALL_SMOKE, pos, fireballvel, NULL, size);
+ CParticle::AddParticle(PARTICLE_FIREBALL_SMOKE, pos, fireballvel, nil, size);
}
}
@@ -587,13 +599,13 @@ void CParticleObject::UpdateClose(void)
case POBJECT_ROCKET_TRAIL:
{
- if ( this->m_pParticle == NULL )
+ if ( this->m_pParticle == nil )
{
CVector pos = this->GetPosition();
CVector vel = this->m_vecTarget;
float size = this->m_fSize;
- this->m_pParticle = CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, vel, NULL, size);
+ this->m_pParticle = CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, vel, nil, size);
}
else
{
@@ -606,7 +618,7 @@ void CParticleObject::UpdateClose(void)
for ( int32 i = 0; i < this->m_nNumEffectCycles; i++ )
{
- CParticle::AddParticle(PARTICLE_FIREBALL_SMOKE, pos, fireballvel, NULL, fireballsize);
+ CParticle::AddParticle(PARTICLE_FIREBALL_SMOKE, pos, fireballvel, nil, fireballsize);
}
}
@@ -628,7 +640,7 @@ void CParticleObject::UpdateClose(void)
if ( vel.z != 0.0f )
vel.z += CGeneral::GetRandomNumberInRange(-this->m_fRandVal, this->m_fRandVal);
- CParticle::AddParticle(this->m_ParticleType, this->GetPosition(), vel, NULL, this->m_fSize,
+ CParticle::AddParticle(this->m_ParticleType, this->GetPosition(), vel, nil, this->m_fSize,
CGeneral::GetRandomNumberInRange(-6.0f, 6.0f));
}
@@ -637,7 +649,6 @@ void CParticleObject::UpdateClose(void)
case POBJECT_PED_WATER_SPLASH:
{
-#ifdef PC_PARTICLE
CRGBA colorsmoke(255, 255, 255, 196);
CVector pos = this->GetPosition();
@@ -655,9 +666,9 @@ void CParticleObject::UpdateClose(void)
splashpos = pos + CVector(0.75f*fCos, 0.75f*fSin, 0.0f);
splashvel = vel + CVector(0.05f*fCos, 0.05f*fSin, CGeneral::GetRandomNumberInRange(0.04f, 0.08f));
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.8f), colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.5f), this->m_Color);
@@ -665,9 +676,9 @@ void CParticleObject::UpdateClose(void)
splashvel = vel + CVector(0.05f*fCos, 0.05f*-fSin, CGeneral::GetRandomNumberInRange(0.04f, 0.08f));
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.8f), colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.5f), this->m_Color);
@@ -675,18 +686,18 @@ void CParticleObject::UpdateClose(void)
splashvel = vel + CVector(0.05f*-fCos, 0.05f*fSin, CGeneral::GetRandomNumberInRange(0.04f, 0.08f));
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.8f), colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.5f), this->m_Color);
splashpos = pos + CVector(0.75f*-fCos, 0.75f*-fSin, 0.0f);
splashvel = vel + CVector(0.05f*-fCos, 0.05f*-fSin, CGeneral::GetRandomNumberInRange(0.04f, 0.08f));
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.8f), colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.5f), this->m_Color);
}
@@ -706,7 +717,7 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.25f, 0.25f) * fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.4f, 1.0f), this->m_Color);
@@ -716,7 +727,7 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.25f, 0.25f) * -fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.4f, 1.0f), this->m_Color);
@@ -726,7 +737,7 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.25f, 0.25f) * fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.4f, 1.0f), this->m_Color);
@@ -736,72 +747,15 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.25f, 0.25f) * -fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.4f, 1.0f), this->m_Color);
}
-#else
- CVector pos;
- CVector vel;
-
- for ( int32 i = -2; i < 2; i++ )
- {
- pos = this->GetPosition();
- pos += CVector(-0.75f, 0.5f * float(i), 0.0f);
-
- vel = this->m_vecTarget;
- vel.x += -1.5 * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
-
- pos = this->GetPosition();
- pos += CVector(0.75f, 0.5f * float(i), 0.0f);
-
- vel = this->m_vecTarget;
- vel.x += 1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
-
- pos = this->GetPosition();
- pos += CVector(0.5f * float(i), -0.75, 0.0f);
-
- vel = this->m_vecTarget;
- vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += -1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
-
-
- pos = this->GetPosition();
- pos += CVector(0.5f * float(i), 0.75, 0.0f);
-
- vel = this->m_vecTarget;
- vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += 1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
- }
-
-
- for ( int32 i = 0; i < 4; i++ )
- {
- pos = this->GetPosition();
-
- pos.x += CGeneral::GetRandomNumberInRange(-1.5f, 1.5f);
- pos.y += CGeneral::GetRandomNumberInRange(-1.5f, 1.5f);
- pos.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- vel = this->m_vecTarget;
- CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
- }
-#endif
break;
}
case POBJECT_CAR_WATER_SPLASH:
{
-#ifdef PC_PARTICLE
CRGBA colorsmoke(255, 255, 255, 196);
CVector pos = this->GetPosition();
@@ -825,8 +779,8 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) * fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.01f, 0.03f);
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL, size, colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil, size, colorsmoke);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
splashpos = pos + CVector(2.0f*fCos, 2.0f*-fSin, 0.0f);
@@ -835,8 +789,8 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) * -fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.01f, 0.03f);
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL, size, colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil, size, colorsmoke);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
splashpos = pos + CVector(2.0f*-fCos, 2.0f*fSin, 0.0f);
splashvel = vel;
@@ -844,8 +798,8 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) * fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.01f, 0.03f);
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL, size, colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil, size, colorsmoke);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
splashpos = pos + CVector(2.0f*-fCos, 2.0f*-fSin, 0.0f);
splashvel = vel;
@@ -853,8 +807,8 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) * -fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.01f, 0.03f);
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL, size, colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil, size, colorsmoke);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
}
for ( int32 i = 0; i < 1; i++ )
@@ -873,88 +827,30 @@ void CParticleObject::UpdateClose(void)
splashvel.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * fCos;
splashvel.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.26f, 0.53f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
splashpos = pos + CVector(1.25f*fCos, 1.25f*-fSin, 0.0f);
splashvel = vel;
splashvel.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * fCos;
splashvel.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * -fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.26f, 0.53f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
splashpos = pos + CVector(1.25f*-fCos, 1.25f*fSin, 0.0f);
splashvel = vel;
splashvel.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * -fCos;
splashvel.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.26f, 0.53f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
splashpos = pos + CVector(1.25f*-fCos, 1.25f*-fSin, 0.0f);
splashvel = vel;
splashvel.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * -fCos;
splashvel.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * -fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.26f, 0.53f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
- }
-#else
- CVector pos;
- CVector vel;
-
- for ( int32 i = -3; i < 4; i++ )
- {
- pos = this->GetPosition();
- pos += CVector(-1.5f, 0.5f * float(i), 0.0f);
-
-
- vel = this->m_vecTarget;
- vel.x += -3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
-
-
- pos = this->GetPosition();
- pos += CVector(1.5f, 0.5f * float(i), 0.0f);
-
- vel = this->m_vecTarget;
- vel.x += 3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
-
-
- pos = this->GetPosition();
- pos += CVector(0.5f * float(i), -1.5f, 0.0f);
-
- vel = this->m_vecTarget;
- vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += -3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
-
-
- pos = this->GetPosition();
- pos += CVector(0.5f * float(i), 1.5f, 0.0f);
-
-
- vel = this->m_vecTarget;
- vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += 3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
- }
-
- for ( int32 i = 0; i < 8; i++ )
- {
- pos = this->GetPosition();
- pos.x += CGeneral::GetRandomNumberInRange(-3.0f, 3.0f);
- pos.y += CGeneral::GetRandomNumberInRange(-3.0f, 3.0f);
-
- vel = this->m_vecTarget;
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
}
-#endif
+
break;
}
@@ -973,75 +869,119 @@ void CParticleObject::UpdateClose(void)
if ( CGeneral::GetRandomNumber() & 1 )
{
CParticle::AddParticle(PARTICLE_RAIN_SPLASH, splashpos, CVector(0.0f, 0.0f, 0.0f),
- NULL, 0.1f, this->m_Color);
+ nil, 0.1f, this->m_Color);
}
else
{
CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, splashpos, CVector(0.0f, 0.0f, 0.0f),
- NULL, 0.12f, this->m_Color);
+ nil, 0.12f, this->m_Color);
}
}
break;
}
- case POBJECT_CATALINAS_GUNFLASH:
+ case POBJECT_FIRE_HYDRANT:
{
- CRGBA flashcolor(120, 120, 120, 255);
-
- CVector vel = this->m_vecTarget;
CVector pos = this->GetPosition();
-
- float size = 1.0f;
- if ( this->m_fSize != 0.0f )
- size = this->m_fSize;
-
- CParticle::AddParticle(PARTICLE_GUNFLASH, pos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.12f*size, flashcolor);
-
- pos += size * (0.06f * vel);
- CParticle::AddParticle(PARTICLE_GUNFLASH, pos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.08f*size, flashcolor);
-
- pos += size * (0.04f * vel);
- CParticle::AddParticle(PARTICLE_GUNFLASH, pos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.04f*size, flashcolor);
+ CVector vel = this->m_vecTarget;
- CVector smokepos = this->GetPosition();
- CVector smokevel = 0.1f * vel;
- CParticle::AddParticle(PARTICLE_GUNSMOKE2, smokepos, smokevel, NULL, 0.005f*size);
+ if ( (TheCamera.GetPosition() - pos).Magnitude() > 5.0f )
+ {
+ for ( int32 i = 0; i < 1; i++ )
+ {
+ int32 angle = 180 * i;
+
+ float fCos = CParticle::Cos(angle);
+ float fSin = CParticle::Sin(angle);
+
+ CVector splashpos, splashvel;
+
+ splashpos = pos + CVector(0.01f*fCos, 0.01f*fSin, 0.0f);
+ splashvel = vel + CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.005f, 0.0075f), this->m_Color, 0, 0, 1, 300);
+
+ splashpos = pos + CVector(0.01f*fCos, 0.01f*-fSin, 0.0f);
+ splashvel = vel + CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.005f, 0.0075f), this->m_Color, 0, 0, 1, 300);
+
+ splashpos = pos + CVector(0.01f*-fCos, 0.01f*fSin, 0.0f);
+ splashvel = vel + CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.005f, 0.0075f), this->m_Color, 0, 0, 1, 300);
+
+ splashpos = pos + CVector(0.01f*-fCos, 0.01f*-fSin, 0.0f);
+ splashvel = vel + CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.005f, 0.0075f), this->m_Color, 0, 0, 1, 300);
+ }
+ for ( int32 i = 0; i < this->m_nNumEffectCycles; i++ )
+ {
+ CParticle::AddParticle(this->m_ParticleType, pos, vel, nil, 0.0f, this->m_Color);
+ }
+ }
break;
}
- case POBJECT_CATALINAS_SHOTGUNFLASH:
+ case POBJECT_WATER_FOUNTAIN_VERT:
{
- CRGBA flashcolor(120, 120, 120, 255);
-
+ CVector pos = this->GetPosition();
CVector vel = this->m_vecTarget;
- float size = 1.0f;
- if ( this->m_fSize != 0.0f )
- size = this->m_fSize;
+ for ( int32 i = 0; i < 2; i++ )
+ {
+ int32 angle = 180 * i;
+
+ float fCos = CParticle::Cos(angle);
+ float fSin = CParticle::Sin(angle);
+
+ CVector splashpos, splashvel;
+
+ splashpos = pos + CVector(0.015f*fCos, 0.015f*fSin, 0.0f);
+ splashvel = vel + CVector(0.015f*fCos, 0.015f*fSin, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.001f, 0.005f), this->m_Color, 0, 0, 1, 1000);
+
+ splashpos = pos + CVector(0.015f*fCos, 0.015f*-fSin, 0.0f);
+ splashvel = vel + CVector(0.015f*fCos, 0.015f*-fSin, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.001f, 0.005f), this->m_Color, 0, 0, 1, 1000);
+
+ splashpos = pos + CVector(0.015f*-fCos, 0.015f*fSin, 0.0f);
+ splashvel = vel + CVector(0.015f*-fCos, 0.015f*fSin, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.001f, 0.005f), this->m_Color, 0, 0, 1, 1000);
+
+ splashpos = pos + CVector(0.015f*-fCos, 0.015f*-fSin, 0.0f);
+ splashvel = vel + CVector(0.015f*-fCos, 0.015f*-fSin, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.001f, 0.005f), this->m_Color, 0, 0, 1, 1000);
+ }
+ break;
+ }
+
+ case POBJECT_WATER_FOUNTAIN_HORIZ:
+ {
CVector pos = this->GetPosition();
-
- CVector velstep = size * (0.1f * vel);
- CVector flashpos = pos;
-
- flashpos += velstep;
- CParticle::AddParticle(PARTICLE_GUNFLASH, flashpos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.0f, flashcolor);
-
- flashpos += velstep;
- CParticle::AddParticle(PARTICLE_GUNFLASH, flashpos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.15f*size, flashcolor);
-
- flashpos += velstep;
- CParticle::AddParticle(PARTICLE_GUNFLASH, flashpos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.2f*size, flashcolor);
-
+ CVector vel = this->m_vecTarget;
- CParticle::AddParticle(PARTICLE_GUNFLASH, pos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.0f, flashcolor);
+ for ( int32 i = 0; i < 3; i++ )
+ {
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, nil, 0.001f, this->m_Color, 0, 0, 1, 1000);
+ }
- CVector smokepos = this->GetPosition();
- CVector smokevel = 0.1f*vel;
- CParticle::AddParticle(PARTICLE_GUNSMOKE2, smokepos, smokevel, NULL, 0.1f*size);
-
break;
}
@@ -1062,7 +1002,7 @@ void CParticleObject::UpdateClose(void)
if ( vel.z != 0.0f )
vel.z += CGeneral::GetRandomNumberInRange(-this->m_fRandVal, this->m_fRandVal);
- CParticle::AddParticle(this->m_ParticleType, this->GetPosition(), vel, NULL,
+ CParticle::AddParticle(this->m_ParticleType, this->GetPosition(), vel, nil,
this->m_fSize, this->m_Color);
}
}
@@ -1070,7 +1010,7 @@ void CParticleObject::UpdateClose(void)
{
for ( int32 i = 0; i < this->m_nNumEffectCycles; i++ )
{
- CParticle::AddParticle(this->m_ParticleType, this->GetPosition(), this->m_vecTarget, NULL,
+ CParticle::AddParticle(this->m_ParticleType, this->GetPosition(), this->m_vecTarget, nil,
this->m_fSize, this->m_Color);
}
}
@@ -1114,15 +1054,15 @@ CParticleObject::UpdateFar(void)
bool
CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
{
- ASSERT( buffer != NULL );
- ASSERT( length != NULL );
+ ASSERT( buffer != nil );
+ ASSERT( length != nil );
int32 numObjects = 0;
- for ( CParticleObject *p = pCloseListHead; p != NULL; p = p->m_pNext )
+ for ( CParticleObject *p = pCloseListHead; p != nil; p = p->m_pNext )
++numObjects;
- for ( CParticleObject *p = pFarListHead; p != NULL; p = p->m_pNext )
+ for ( CParticleObject *p = pFarListHead; p != nil; p = p->m_pNext )
++numObjects;
*(int32 *)buffer = numObjects;
@@ -1131,7 +1071,7 @@ CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
int32 objectsLength = sizeof(CParticleObject) * (numObjects + 1);
int32 dataLength = objectsLength + sizeof(int32);
- for ( CParticleObject *p = pCloseListHead; p != NULL; p = p->m_pNext )
+ for ( CParticleObject *p = pCloseListHead; p != nil; p = p->m_pNext )
{
#if 0 // todo better
*(CParticleObject*)buffer = *p;
@@ -1141,7 +1081,7 @@ CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
buffer += sizeof(CParticleObject);
}
- for ( CParticleObject *p = pFarListHead; p != NULL; p = p->m_pNext )
+ for ( CParticleObject *p = pFarListHead; p != nil; p = p->m_pNext )
{
#if 0 // todo better
*(CParticleObject*)buffer = *p;
@@ -1159,7 +1099,7 @@ CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
bool
CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
{
- ASSERT( buffer != NULL );
+ ASSERT( buffer != nil );
RemoveAllParticleObjects();
@@ -1180,7 +1120,7 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
CParticleObject *src = (CParticleObject *)buffer;
buffer += sizeof(CParticleObject);
- if ( dst == NULL )
+ if ( dst == nil )
return false;
MoveToList(&pUnusedListHead, &pCloseListHead, dst);
@@ -1192,7 +1132,7 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
dst->m_vecTarget = src->m_vecTarget;
dst->m_nFrameCounter = src->m_nFrameCounter;
dst->m_bRemove = src->m_bRemove;
- dst->m_pParticle = NULL;
+ dst->m_pParticle = nil;
dst->m_nRemoveTimer = src->m_nRemoveTimer;
dst->m_Color = src->m_Color;
dst->m_fSize = src->m_fSize;
@@ -1208,22 +1148,64 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
}
void
+CParticleObject::RemoveAllExpireableParticleObjects(void)
+{
+ {
+ CParticleObject *pobj = pCloseListHead;
+ CParticleObject *nextpobj;
+ if ( pobj != nil )
+ {
+ do
+ {
+ nextpobj = pobj->m_pNext;
+ if ( pobj->m_nRemoveTimer != 0 )
+ {
+ MoveToList(&pCloseListHead, &pUnusedListHead, pobj);
+ pobj->m_nState = POBJECTSTATE_FREE;
+ }
+ pobj = nextpobj;
+ }
+ while ( nextpobj != nil );
+ }
+ }
+
+ {
+ CParticleObject *pobj = pFarListHead;
+ CParticleObject *nextpobj;
+ if ( pobj != nil )
+ {
+ do
+ {
+ nextpobj = pobj->m_pNext;
+ if ( pobj->m_nRemoveTimer != 0 )
+ {
+ MoveToList(&pFarListHead, &pUnusedListHead, pobj);
+ pobj->m_nState = POBJECTSTATE_FREE;
+ }
+ pobj = nextpobj;
+ }
+ while ( nextpobj != nil );
+ }
+ }
+}
+
+void
CParticleObject::RemoveAllParticleObjects(void)
{
pUnusedListHead = &gPObjectArray[0];
- pCloseListHead = NULL;
- pFarListHead = NULL;
+ pCloseListHead = nil;
+ pFarListHead = nil;
for ( int32 i = 0; i < MAX_PARTICLEOBJECTS; i++ )
{
if ( i == 0 )
- gPObjectArray[i].m_pPrev = NULL;
+ gPObjectArray[i].m_pPrev = nil;
else
gPObjectArray[i].m_pPrev = &gPObjectArray[i - 1];
if ( i == MAX_PARTICLEOBJECTS-1 )
- gPObjectArray[i].m_pNext = NULL;
+ gPObjectArray[i].m_pNext = nil;
else
gPObjectArray[i].m_pNext = &gPObjectArray[i + 1];
@@ -1234,20 +1216,20 @@ CParticleObject::RemoveAllParticleObjects(void)
void
CParticleObject::MoveToList(CParticleObject **from, CParticleObject **to, CParticleObject *obj)
{
- ASSERT( from != NULL );
- ASSERT( to != NULL );
- ASSERT( obj != NULL );
+ ASSERT( from != nil );
+ ASSERT( to != nil );
+ ASSERT( obj != nil );
- if ( obj->m_pPrev == NULL )
+ if ( obj->m_pPrev == nil )
{
*from = obj->m_pNext;
if ( *from )
- (*from)->m_pPrev = NULL;
+ (*from)->m_pPrev = nil;
}
else
{
- if ( obj->m_pNext == NULL )
- obj->m_pPrev->m_pNext = NULL;
+ if ( obj->m_pNext == nil )
+ obj->m_pPrev->m_pNext = nil;
else
{
obj->m_pNext->m_pPrev = obj->m_pPrev;
@@ -1256,7 +1238,7 @@ CParticleObject::MoveToList(CParticleObject **from, CParticleObject **to, CParti
}
obj->m_pNext = *to;
- obj->m_pPrev = NULL;
+ obj->m_pPrev = nil;
*to = obj;
if ( obj->m_pNext )
diff --git a/src/objects/ParticleObject.h b/src/objects/ParticleObject.h
index e4e7fcd2..f199e533 100644
--- a/src/objects/ParticleObject.h
+++ b/src/objects/ParticleObject.h
@@ -4,12 +4,12 @@
#include "ParticleType.h"
#include "Placeable.h"
-#define MAX_PARTICLEOBJECTS 100
+#define MAX_PARTICLEOBJECTS 70
#define MAX_AUDIOHYDRANTS 8
enum eParticleObjectType
{
- POBJECT_PAVEMENT_STEAM,
+ POBJECT_PAVEMENT_STEAM = 0,
POBJECT_PAVEMENT_STEAM_SLOWMOTION,
POBJECT_WALL_STEAM,
POBJECT_WALL_STEAM_SLOWMOTION,
@@ -22,6 +22,8 @@ enum eParticleObjectType
POBJECT_BIG_FIRE,
POBJECT_DRY_ICE,
POBJECT_DRY_ICE_SLOWMOTION,
+ POBJECT_WATER_FOUNTAIN_VERT,
+ POBJECT_WATER_FOUNTAIN_HORIZ,
POBJECT_FIRE_TRAIL,
POBJECT_SMOKE_TRAIL,
POBJECT_FIREBALL_AND_SMOKE,
@@ -69,12 +71,13 @@ public:
~CParticleObject();
static void Initialise(void);
-
- static CParticleObject *AddObject(uint16 type, CVector const &pos, uint8 remove);
- static CParticleObject *AddObject(uint16 type, CVector const &pos, float size, uint8 remove);
- static CParticleObject *AddObject(uint16 type, CVector const &pos, CVector const &target, float size, uint8 remove);
- static CParticleObject *AddObject(uint16 type, CVector const &pos, CVector const &target, float size, uint32 lifeTime, RwRGBA const &color, uint8 remove);
-
+
+ static CParticleObject *AddObject(uint16 type, CVector const &pos, uint8 remove);
+ static CParticleObject *AddObject(uint16 type, CVector const &pos, float size, uint8 remove);
+ static CParticleObject *AddObject(uint16 type, CVector const &pos, CVector const &target, float size, uint8 remove);
+ static CParticleObject *AddObject(uint16 type, CVector const &pos, CVector const &target, float size, uint32 lifeTime, RwRGBA const &color, uint8 remove);
+ static CParticleObject *AddObject(tParticleType type, CVector const &pos, CVector const &target, float size, uint32 lifeTime, uint8 numEffectCycles, uint8 skipFrames, uint16 creationChance, uint8 remove);
+
void RemoveObject(void);
static void UpdateAll(void);
@@ -84,6 +87,7 @@ public:
static bool SaveParticle(uint8 *buffer, uint32 *length);
static bool LoadParticle(uint8 *buffer, uint32 length);
+ static void RemoveAllExpireableParticleObjects(void);
static void RemoveAllParticleObjects(void);
static void MoveToList(CParticleObject **from, CParticleObject **to, CParticleObject *obj);
};
@@ -98,7 +102,7 @@ public:
CAudioHydrant() :
AudioEntity(AEHANDLE_NONE),
- pParticleObject(NULL)
+ pParticleObject(nil)
{ }
static bool Add (CParticleObject *particleobject);
diff --git a/src/objects/Projectile.cpp b/src/objects/Projectile.cpp
index fe8b0c68..fc4b25cf 100644
--- a/src/objects/Projectile.cpp
+++ b/src/objects/Projectile.cpp
@@ -2,6 +2,8 @@
#include "Projectile.h"
+// --MIAMI: file done
+
CProjectile::CProjectile(int32 model) : CObject()
{
m_fMass = 1.0f;
diff --git a/src/objects/Stinger.cpp b/src/objects/Stinger.cpp
new file mode 100644
index 00000000..b3660881
--- /dev/null
+++ b/src/objects/Stinger.cpp
@@ -0,0 +1,232 @@
+#include "common.h"
+#include "Stinger.h"
+#include "CopPed.h"
+#include "ModelIndices.h"
+#include "RpAnimBlend.h"
+#include "World.h"
+#include "Automobile.h"
+#include "Bike.h"
+#include "Particle.h"
+#include "AnimBlendAssociation.h"
+#include "General.h"
+
+uint32 NumOfStingerSegments;
+
+/* -- CStingerSegment -- */
+
+CStingerSegment::CStingerSegment()
+{
+ m_fMass = 1.0f;
+ m_fTurnMass = 1.0f;
+ m_fAirResistance = 0.99999f;
+ m_fElasticity = 0.75f;
+ m_fBuoyancy = GRAVITY * m_fMass * 0.1f;
+ bExplosionProof = true;
+ SetModelIndex(MI_PLC_STINGER);
+ ObjectCreatedBy = CONTROLLED_SUB_OBJECT;
+ NumOfStingerSegments++;
+}
+
+CStingerSegment::~CStingerSegment()
+{
+ NumOfStingerSegments--;
+}
+
+/* -- CStinger -- */
+
+CStinger::CStinger()
+{
+ bIsDeployed = false;
+}
+
+void
+CStinger::Init(CPed *pPed)
+{
+ int32 i;
+
+ pOwner = pPed;
+ for (i = 0; i < NUM_STINGER_SEGMENTS; i++) {
+ pSpikes[i] = new CStingerSegment;
+ pSpikes[i]->bUsesCollision = false;
+ }
+ bIsDeployed = true;
+ m_vPos = pPed->GetPosition();
+ m_vPos.z -= 1.0f;
+ m_fMax_Z = Atan2(-pPed->GetForward().x, pPed->GetForward().y) + HALFPI;
+
+ for (i = 0; i < NUM_STINGER_SEGMENTS; i++) {
+ pSpikes[i]->SetOrientation(0.0f, 0.0f, Atan2(-pPed->GetForward().x, pPed->GetForward().y));
+ pSpikes[i]->SetPosition(m_vPos);
+ }
+
+ CVector2D fwd2d(pPed->GetForward().x, pPed->GetForward().y);
+
+ for (i = 0; i < ARRAY_SIZE(m_vPositions); i++)
+ m_vPositions[i] = fwd2d * 1.8f * Sin(DEGTORAD(i));
+
+ m_nSpikeState = STINGERSTATE_NONE;
+ m_nTimeOfDeploy = CTimer::GetTimeInMilliseconds();
+}
+
+void
+CStinger::Remove()
+{
+ if (!bIsDeployed) return;
+
+ for (int32 i = 0; i < NUM_STINGER_SEGMENTS; i++) {
+ CStingerSegment *spikeSegment = pSpikes[i];
+ if (spikeSegment->m_entryInfoList.first != nil)
+ spikeSegment->bRemoveFromWorld = true;
+ else
+ delete spikeSegment;
+ }
+ bIsDeployed = false;
+}
+
+void
+CStinger::Deploy(CPed *pPed)
+{
+ if (NumOfStingerSegments < NUM_STINGER_SEGMENTS*2 && !pPed->bInVehicle && pPed->IsPedInControl()) {
+ if (!bIsDeployed && RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_WEAPON_THROWU) == nil) {
+ Init(pPed);
+ pPed->SetPedState(PED_DEPLOY_STINGER);
+ CAnimManager::AddAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_THROWU);
+ }
+ }
+}
+
+void
+CStinger::CheckForBurstTyres()
+{
+ CVector firstPos = pSpikes[0]->GetPosition();
+ firstPos.z += 0.2f;
+ CVector lastPos = pSpikes[NUM_STINGER_SEGMENTS - 1]->GetPosition();
+ lastPos.z += 0.2f;
+ float dist = (lastPos - firstPos).Magnitude();
+ if (dist < 0.1f) return;
+
+ CVehicle *vehsInRange[16];
+ int16 numObjects;
+ CEntity entity;
+
+ CWorld::FindObjectsInRange((lastPos + firstPos) / 2.0f,
+ dist, true, &numObjects, 15, (CEntity**)vehsInRange,
+ false, true, false, false, false);
+
+ for (int32 i = 0; i < numObjects; i++) {
+ CAutomobile *pAutomobile = nil;
+ CBike *pBike = nil;
+
+ if (vehsInRange[i]->IsCar())
+ pAutomobile = (CAutomobile*)vehsInRange[i];
+ else if (vehsInRange[i]->IsBike())
+ pBike = (CBike*)vehsInRange[i];
+
+ if (pAutomobile == nil && pBike == nil) continue;
+
+ float maxWheelDistToSpike = sq(((CVehicleModelInfo*)CModelInfo::GetModelInfo(vehsInRange[i]->GetModelIndex()))->m_wheelScale + 0.1f);
+
+ for (int wheelId = 0; wheelId < 4; wheelId++) {
+ if ((pAutomobile != nil && pAutomobile->m_aSuspensionSpringRatioPrev[wheelId] < 1.0f) ||
+ (pBike != nil && pBike->m_aSuspensionSpringRatioPrev[wheelId] < 1.0f)) {
+ CVector vecWheelPos;
+ if (pAutomobile != nil)
+ vecWheelPos = pAutomobile->m_aWheelColPoints[wheelId].point;
+ else if (pBike != nil)
+ vecWheelPos = pBike->m_aWheelColPoints[wheelId].point;
+
+ for (int32 spike = 0; spike < NUM_STINGER_SEGMENTS; spike++) {
+ if ((pSpikes[spike]->GetPosition() - vecWheelPos).Magnitude() < maxWheelDistToSpike) {
+ if (pBike) {
+ if (wheelId < 2)
+ vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_LF, true);
+ else
+ vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_LR, true);
+ }
+ else {
+ switch (wheelId) {
+ case 0: vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_LF, true); break;
+ case 1: vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_LR, true); break;
+ case 2: vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_RF, true); break;
+ case 3: vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_RR, true); break;
+ }
+ }
+ vecWheelPos.z += 0.15f;
+ for (int j = 0; j < 4; j++)
+ CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, vecWheelPos, vehsInRange[i]->GetRight() * 0.1f);
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+CStinger::Process()
+{
+ switch (m_nSpikeState)
+ {
+ case STINGERSTATE_NONE:
+ if (pOwner != nil
+ && !pOwner->bInVehicle
+ && pOwner->GetPedState() == PED_DEPLOY_STINGER
+ && RpAnimBlendClumpGetAssociation(pOwner->GetClump(), ANIM_WEAPON_THROWU)->currentTime > 0.39f)
+ {
+ m_nSpikeState = STINGERSTATE_DEPLOYING;
+ for (int i = 0; i < NUM_STINGER_SEGMENTS; i++)
+ CWorld::Add(pSpikes[i]);
+ pOwner->SetIdle();
+ }
+ break;
+ case STINGERSTATE_DEPLOYED:
+ if (pOwner != nil && pOwner->m_nPedType == PEDTYPE_COP)
+ ((CCopPed*)pOwner)->m_bThrowsSpikeTrap = false;
+ break;
+ case STINGERSTATE_UNDEPLOYING:
+ if (CTimer::GetTimeInMilliseconds() > m_nTimeOfDeploy + 2500)
+ m_nSpikeState = STINGERSTATE_REMOVE;
+ // no break
+ case STINGERSTATE_DEPLOYING:
+ if (m_nSpikeState == STINGERSTATE_DEPLOYING && CTimer::GetTimeInMilliseconds() > m_nTimeOfDeploy + 2500)
+ m_nSpikeState = STINGERSTATE_DEPLOYED;
+ else {
+ float progress = (CTimer::GetTimeInMilliseconds() - m_nTimeOfDeploy) / 2500.0f;
+ if (m_nSpikeState != STINGERSTATE_DEPLOYING)
+ progress = 1.0f - progress;
+
+ float degangle = progress * ARRAY_SIZE(m_vPositions);
+ float angle1 = m_fMax_Z + DEGTORAD(degangle);
+ float angle2 = m_fMax_Z - DEGTORAD(degangle);
+ int pos = clamp(degangle, 0, ARRAY_SIZE(m_vPositions)-1);
+
+ CVector2D pos2d = m_vPositions[pos];
+ CVector pos3d = m_vPos;
+ CColPoint colPoint;
+ CEntity *pEntity;
+ if (CWorld::ProcessVerticalLine(CVector(pos3d.x, pos3d.y, pos3d.z - 10.0f), pos3d.z, colPoint, pEntity, true, false, false, false, true, false, nil))
+ pos3d.z = colPoint.point.z + 0.15f;
+
+ angle1 = CGeneral::LimitRadianAngle(angle1);
+ angle2 = CGeneral::LimitRadianAngle(angle2);
+
+ for (int spike = 0; spike < NUM_STINGER_SEGMENTS; spike++) {
+ if (CWorld::TestSphereAgainstWorld(pos3d + CVector(pos2d.x, pos2d.y, 0.6f), 0.3f, nil, true, false, false, true, false, false))
+ pos2d = CVector2D(0.0f, 0.0f);
+
+ if (spike % 2 == 0) {
+ pSpikes[spike]->SetOrientation(0.0f, 0.0f, angle1);
+ pos3d.x += pos2d.x;
+ pos3d.y += pos2d.y;
+ } else {
+ pSpikes[spike]->SetOrientation(0.0f, 0.0f, angle2);
+ }
+ pSpikes[spike]->SetPosition(pos3d);
+ }
+ }
+ break;
+ case STINGERSTATE_REMOVE:
+ Remove();
+ break;
+ }
+ CheckForBurstTyres();
+} \ No newline at end of file
diff --git a/src/objects/Stinger.h b/src/objects/Stinger.h
new file mode 100644
index 00000000..250cf62d
--- /dev/null
+++ b/src/objects/Stinger.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "Object.h"
+
+class CStingerSegment : public CObject
+{
+public:
+ CStingerSegment();
+ ~CStingerSegment();
+};
+
+#define NUM_STINGER_SEGMENTS (12)
+
+enum {
+ STINGERSTATE_NONE = 0,
+ STINGERSTATE_DEPLOYING,
+ STINGERSTATE_DEPLOYED,
+ STINGERSTATE_UNDEPLOYING,
+ STINGERSTATE_REMOVE,
+};
+
+class CStinger
+{
+public:
+ bool bIsDeployed;
+ uint32 m_nTimeOfDeploy;
+ CVector m_vPos;
+ float m_fMax_Z;
+ float m_fMin_Z;
+ CVector2D m_vPositions[60];
+ CStingerSegment *pSpikes[NUM_STINGER_SEGMENTS];
+ class CPed *pOwner;
+ uint8 m_nSpikeState;
+ CStinger();
+ void Init(CPed *pPed);
+ void Remove();
+ void Deploy(CPed *pPed);
+ void CheckForBurstTyres();
+ void Process();
+}; \ No newline at end of file