summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/control/Pickups.h3
-rw-r--r--src/control/Script.cpp1
-rw-r--r--src/control/Script.h2
-rw-r--r--src/core/World.cpp13
-rw-r--r--src/core/World.h1
-rw-r--r--src/objects/Stinger.cpp232
-rw-r--r--src/objects/Stinger.h40
-rw-r--r--src/peds/CopPed.cpp46
-rw-r--r--src/peds/CopPed.h2
-rw-r--r--src/render/Glass.h1
-rw-r--r--src/render/SpecialFX.cpp1
-rw-r--r--src/render/SpecialFX.h8
-rw-r--r--src/weapons/Weapon.cpp723
-rw-r--r--src/weapons/Weapon.h17
-rw-r--r--src/weapons/WeaponEffects.cpp63
-rw-r--r--src/weapons/WeaponInfo.cpp51
-rw-r--r--src/weapons/WeaponInfo.h2
17 files changed, 905 insertions, 301 deletions
diff --git a/src/control/Pickups.h b/src/control/Pickups.h
index 8f6ef4c3..d7d22174 100644
--- a/src/control/Pickups.h
+++ b/src/control/Pickups.h
@@ -110,6 +110,9 @@ public:
static CVehicle *pPlayerVehicle;
static CVector StaticCamCoors;
static uint32 StaticCamStartTime;
+
+//TODO(MIAMI)
+ static void RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo(eWeaponType) {}
};
extern uint16 AmmoForWeapon[20];
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index 0921d1c6..b313e308 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -2174,6 +2174,7 @@ void CRunningScript::Init()
m_anStack[i] = 0;
m_nStackPointer = 0;
m_nWakeTime = 0;
+ m_bIsActive = false;
m_bCondResult = false;
m_bIsMissionScript = false;
m_bSkipWakeTime = false;
diff --git a/src/control/Script.h b/src/control/Script.h
index 42f9cbff..4493ade3 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -122,7 +122,7 @@ struct CMissionCleanupEntity
enum {
MAX_CLEANUP = 50,
MAX_UPSIDEDOWN_CAR_CHECKS = 6,
- MAX_STUCK_CAR_CHECKS = 6
+ MAX_STUCK_CAR_CHECKS = 16
};
class CMissionCleanup
diff --git a/src/core/World.cpp b/src/core/World.cpp
index fb2dbad3..6d5e8a81 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -49,6 +49,7 @@ bool CWorld::bProcessCutsceneOnly;
bool CWorld::bDoingCarCollisions;
bool CWorld::bIncludeCarTyres;
+bool CWorld::bIncludeBikers;
CColPoint CWorld::m_aTempColPts[MAX_COLLISION_POINTS];
@@ -63,6 +64,7 @@ CWorld::Initialise()
bIncludeDeadPeds = false;
bForceProcessControl = false;
bIncludeCarTyres = false;
+ bIncludeBikers = false;
}
void
@@ -272,7 +274,9 @@ CWorld::ProcessLineOfSightSector(CSector &sector, const CColLine &line, CColPoin
{
float mindist = dist;
bool deadPeds = !!bIncludeDeadPeds;
+ bool bikers = !!bIncludeBikers;
bIncludeDeadPeds = false;
+ bIncludeBikers = false;
if(checkBuildings) {
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS], line, point, mindist, entity,
@@ -290,11 +294,13 @@ CWorld::ProcessLineOfSightSector(CSector &sector, const CColLine &line, CColPoin
if(checkPeds) {
if(deadPeds) bIncludeDeadPeds = true;
+ if(bikers) bIncludeBikers = true;
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS], line, point, mindist, entity,
ignoreSeeThrough, false, ignoreShootThrough);
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, point, mindist, entity,
ignoreSeeThrough, false, ignoreShootThrough);
bIncludeDeadPeds = false;
+ bIncludeBikers = false;
}
if(checkObjects) {
@@ -312,6 +318,7 @@ CWorld::ProcessLineOfSightSector(CSector &sector, const CColLine &line, CColPoin
}
bIncludeDeadPeds = deadPeds;
+ bIncludeBikers = bikers;
if(mindist < dist) {
dist = mindist;
@@ -325,22 +332,24 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP
CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough)
{
bool deadPeds = false;
+ bool bikers = false;
float mindist = dist;
CPtrNode *node;
CEntity *e;
CColModel *colmodel;
if(list.first && bIncludeDeadPeds && ((CEntity *)list.first->item)->IsPed()) deadPeds = true;
+ if(list.first && bIncludeBikers && ((CEntity *)list.first->item)->IsPed()) bikers = true;
for(node = list.first; node; node = node->next) {
e = (CEntity *)node->item;
- if(e->m_scanCode != GetCurrentScanCode() && e != pIgnoreEntity && (e->bUsesCollision || deadPeds) &&
+ if(e->m_scanCode != GetCurrentScanCode() && e != pIgnoreEntity && (e->bUsesCollision || deadPeds || bikers) &&
!(ignoreSomeObjects && CameraToIgnoreThisObject(e))) {
colmodel = nil;
e->m_scanCode = GetCurrentScanCode();
if(e->IsPed()) {
- if(e->bUsesCollision || deadPeds && ((CPed *)e)->m_nPedState == PED_DEAD) {
+ if(e->bUsesCollision || deadPeds && ((CPed *)e)->m_nPedState == PED_DEAD || bikers) {
colmodel = ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))->AnimatePedColModelSkinned(e->GetClump());
} else
colmodel = nil;
diff --git a/src/core/World.h b/src/core/World.h
index 8d539061..606a3466 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -71,6 +71,7 @@ public:
static bool bProcessCutsceneOnly;
static bool bDoingCarCollisions;
static bool bIncludeCarTyres;
+ static bool bIncludeBikers;
static CColPoint m_aTempColPts[MAX_COLLISION_POINTS];
static void Remove(CEntity *entity);
diff --git a/src/objects/Stinger.cpp b/src/objects/Stinger.cpp
new file mode 100644
index 00000000..f33125ee
--- /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 = ESCALATOR_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
diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp
index 6c9eb276..9160319b 100644
--- a/src/peds/CopPed.cpp
+++ b/src/peds/CopPed.cpp
@@ -18,6 +18,7 @@
#include "Camera.h"
#include "PedPlacement.h"
#include "Ropes.h"
+#include "Stinger.h"
CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
{
@@ -92,14 +93,17 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
m_nHassleTimer = 0;
field_61C = 0;
field_624 = 0;
+ m_pStinger = new CStinger;
if (m_pPointGunAt)
- m_pPointGunAt->CleanUpOldReference((CEntity**)&m_pPointGunAt);
+ m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
m_pPointGunAt = nil;
}
CCopPed::~CCopPed()
{
ClearPursuit();
+ m_pStinger->Remove();
+ delete m_pStinger;
}
// --MIAMI: Done
@@ -597,7 +601,7 @@ CCopPed::CopAI(void)
}
}
-// --MIAMI: Done except commented things
+// --MIAMI: Done
void
CCopPed::ProcessControl(void)
{
@@ -607,15 +611,13 @@ CCopPed::ProcessControl(void)
CPed::ProcessControl();
if (m_bThrowsSpikeTrap) {
- // TODO(Miami)
- /*
if (CGame::currArea != AREA_MALL)
ProcessStingerCop();
- */
return;
}
- // TODO(Miami): CStinger::Process
+ if (m_pStinger && m_pStinger->bIsDeployed && m_pStinger->m_nSpikeState == STINGERSTATE_DEPLOYED && CGame::currArea != AREA_MALL)
+ m_pStinger->Process();
if (bWasPostponed)
return;
@@ -854,4 +856,36 @@ CCopPed::ProcessHeliSwat(void)
SetInTheAir();
bKnockedUpIntoAir = true;
}
+}
+
+// --MIAMI: Done
+void
+CCopPed::ProcessStingerCop(void)
+{
+ if (m_pStinger->bIsDeployed || FindPlayerVehicle() && (FindPlayerVehicle()->IsCar() || FindPlayerVehicle()->IsBike())) {
+ if (m_pStinger->bIsDeployed) {
+ m_pStinger->Process();
+ } else {
+ CVector2D vehDist = GetPosition() - FindPlayerVehicle()->GetPosition();
+ CVector2D dirVehGoing = FindPlayerVehicle()->m_vecMoveSpeed;
+ if (vehDist.MagnitudeSqr() < sq(30.0f)) {
+ if (dirVehGoing.MagnitudeSqr() > 0.0f) {
+ vehDist.Normalise();
+ dirVehGoing.Normalise();
+ if (DotProduct2D(vehDist, dirVehGoing) > 0.8f) {
+ float angle = (CrossProduct2D(vehDist, dirVehGoing - vehDist) < 0.0f ?
+ FindPlayerVehicle()->GetForward().Heading() - HALFPI :
+ HALFPI + FindPlayerVehicle()->GetForward().Heading());
+
+ SetHeading(angle);
+ m_fRotationCur = angle;
+ m_fRotationDest = angle;
+ m_pStinger->Deploy(this);
+ }
+ }
+ }
+ }
+ } else {
+ ClearPursuit();
+ }
} \ No newline at end of file
diff --git a/src/peds/CopPed.h b/src/peds/CopPed.h
index edec145e..190d619e 100644
--- a/src/peds/CopPed.h
+++ b/src/peds/CopPed.h
@@ -30,6 +30,7 @@ public:
uintptr m_nRopeID;
uint32 m_nHassleTimer;
uint32 field_61C;
+ class CStinger *m_pStinger;
int32 field_624;
int8 field_628;
@@ -44,6 +45,7 @@ public:
void ScanForCrimes(void);
void CopAI(void);
void ProcessHeliSwat(void);
+ void ProcessStingerCop(void);
};
#ifndef PED_SKIN
diff --git a/src/render/Glass.h b/src/render/Glass.h
index 736e5205..937ab6a9 100644
--- a/src/render/Glass.h
+++ b/src/render/Glass.h
@@ -53,4 +53,5 @@ public:
//TODO(MIAMI)
static void CarWindscreenShatters(CVehicle *vehicle, bool unk) {}
+ static void BreakGlassPhysically(CVector, float) {}
}; \ No newline at end of file
diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp
index e9079bef..fa8379f0 100644
--- a/src/render/SpecialFX.cpp
+++ b/src/render/SpecialFX.cpp
@@ -32,6 +32,7 @@ RwIm3DVertex TraceVertices[6];
RwImVertexIndex TraceIndexList[12];
bool CSpecialFX::bSnapShotActive;
+int32 CSpecialFX::SnapShotFrames;
void
CSpecialFX::Init(void)
diff --git a/src/render/SpecialFX.h b/src/render/SpecialFX.h
index 8c79856b..8bd0d5e1 100644
--- a/src/render/SpecialFX.h
+++ b/src/render/SpecialFX.h
@@ -4,6 +4,7 @@ class CSpecialFX
{
public:
static bool bSnapShotActive;
+ static int32 SnapShotFrames;
static void Render(void);
static void Update(void);
@@ -56,6 +57,13 @@ public:
static void AddTrace(CVector*, CVector*);
static void Render(void);
static void Update(void);
+
+//TODO(MIAMI)
+ static void AddTrace(CVector *, CVector *, float, unsigned int, unsigned char) {}
+ static void AddTrace(CVector *a, CVector *b, int32 weapontype, class CEntity *shooter)
+ {
+ AddTrace(a, b); //TODO: temp
+ }
};
enum
diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp
index 0cd439c2..48f90897 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -32,51 +32,20 @@
#include "World.h"
#include "SurfaceTable.h"
#include "Bike.h"
+#include "Glass.h"
+#include "Sprite.h"
+#include "Pickups.h"
// TODO(Miami)
#define AUDIO_NOT_READY
-// TODO(Miami): Those are mostly placeholders!!!
-uint16 gReloadSampleTime[] =
-{
- 0, // UNARMED
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0, // GRENADE
- 0, // DETONATEGRENADE
- 0, // TEARGAS
- 0, // MOLOTOV
- 0, // ROCKET
- 250, // COLT45
- 250, // PYTHON
- 650, // SHOTGUN
- 650, // SPAS12 SHOTGUN
- 650, // STUBBY SHOTGUN
- 400, // TEC9
- 400, // UZIhec
- 400, // SILENCED_INGRAM
- 400, // MP5
- 300, // M16
- 300, // AK47
- 423, // SNIPERRIFLE
- 423, // LASERSCOPE
- 400, // ROCKETLAUNCHER
- 0, // FLAMETHROWER
- 0, // M60
- 0, // MINIGUN
- 0, // DETONATOR
- 0, // HELICANNON
- 0 // CAMERA
-};
+float fReloadAnimSampleFraction[5] = { 0.5f, 0.7f, 0.75f, 0.75f, 0.7f };
+float fSeaSparrowAimingAngle = 10.0f;
+float fHunterAimingAngle = 30.0f;
+float fPlayerAimScaleDist = 5.0f;
+float fPlayerAimScale = 2.5f;
+
+bool CWeapon::bPhotographHasBeenTaken;
CWeaponInfo *
CWeapon::GetInfo()
@@ -86,6 +55,17 @@ CWeapon::GetInfo()
return info;
}
+CWeapon::CWeapon(eWeaponType type, int32 ammo)
+{
+ m_eWeaponType = type;
+ m_eWeaponState = WEAPONSTATE_READY;
+ m_nAmmoTotal = Min(ammo, 99999);
+ m_nAmmoInClip = 0;
+ Reload();
+ m_nTimer = 0;
+ m_bAddRotOffset = false;
+}
+
void
CWeapon::InitialiseWeapons(void)
{
@@ -94,6 +74,7 @@ CWeapon::InitialiseWeapons(void)
CExplosion::Initialise();
CProjectileInfo::Initialise();
CBulletInfo::Initialise();
+ bPhotographHasBeenTaken = false;
}
void
@@ -115,19 +96,7 @@ CWeapon::UpdateWeapons(void)
CBulletInfo::Update();
}
-//--MIAMI: done
-CWeapon::CWeapon(eWeaponType type, int32 ammo)
-{
- m_eWeaponType = type;
- m_eWeaponState = WEAPONSTATE_READY;
- m_nAmmoTotal = Min(ammo, 99999);
- m_nAmmoInClip = 0;
- Reload();
- m_nTimer = 0;
- m_bAddRotOffset = false;
-}
-// --MIAMI: Done
void
CWeapon::Initialise(eWeaponType type, int32 ammo)
{
@@ -137,24 +106,23 @@ CWeapon::Initialise(eWeaponType type, int32 ammo)
m_nAmmoInClip = 0;
Reload();
m_nTimer = 0;
- int modelId = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModelId;
- if (modelId != -1)
+ int32 modelId = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModelId;
+ int32 model2Id = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModel2Id;
+
+ if ( modelId != -1 )
CModelInfo::GetModelInfo(modelId)->AddRef();
-
- int model2Id = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModel2Id;
- if (model2Id != -1)
+ if ( model2Id != -1 )
CModelInfo::GetModelInfo(model2Id)->AddRef();
}
-// --MIAMI: Done
void
CWeapon::Shutdown()
{
- int modelId = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModelId;
+ int32 modelId = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModelId;
if (modelId != -1)
CModelInfo::GetModelInfo(modelId)->RemoveRef();
- int model2Id = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModel2Id;
+ int32 model2Id = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModel2Id;
if (model2Id != -1)
CModelInfo::GetModelInfo(model2Id)->RemoveRef();
@@ -172,12 +140,18 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
CVector fireOffset(0.0f, 0.0f, 0.6f);
CVector *source = fireSource;
+#ifdef FIX_BUGS
+ static CVector shooterSource;
+#else
+ CVector shooterSource;
+#endif
- if (!fireSource) {
- static CVector tmp;
- tmp = shooter->GetMatrix() * fireOffset;
- source = &tmp;
+ if ( !fireSource )
+ {
+ shooterSource = shooter->GetMatrix() * fireOffset;
+ source = &shooterSource;
}
+
if ( m_bAddRotOffset )
{
float heading = RADTODEG(shooter->GetForward().Heading());
@@ -213,6 +187,17 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
break;
}
+ case WEAPONTYPE_SNIPERRIFLE:
+ case WEAPONTYPE_LASERSCOPE:
+ {
+ if (shooter == FindPlayerPed())
+ fired = FireSniper(shooter);
+ else
+ fired = FireInstantHit(shooter, source);
+
+ break;
+ }
+
case WEAPONTYPE_COLT45:
case WEAPONTYPE_PYTHON:
case WEAPONTYPE_UZI:
@@ -236,17 +221,6 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
break;
}
- case WEAPONTYPE_SNIPERRIFLE:
- case WEAPONTYPE_LASERSCOPE:
- {
- if (shooter == FindPlayerPed()) {
- fired = FireSniper(shooter);
- } else {
- fired = FireInstantHit(shooter, source);
- }
- break;
- }
-
case WEAPONTYPE_ROCKETLAUNCHER:
{
if ( shooter->IsPed() && ((CPed*)shooter)->m_pSeekTarget != nil )
@@ -272,8 +246,6 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
if ( shooter == FindPlayerPed() )
{
fired = FireProjectile(shooter, source, ((CPlayerPed*)shooter)->m_fAttackButtonCounter*0.0375f);
- if ( m_eWeaponType == WEAPONTYPE_GRENADE )
- CStats::KgsOfExplosivesUsed++;
}
else if ( shooter->IsPed() && ((CPed*)shooter)->m_pSeekTarget != nil )
{
@@ -309,6 +281,13 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
break;
}
+
+ case WEAPONTYPE_CAMERA:
+ {
+ fired = TakePhotograph(shooter);
+
+ break;
+ }
default:
{
@@ -324,14 +303,59 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
if (shooter->IsPed())
{
CPed* shooterPed = (CPed*)shooter;
-
- shooterPed->bIsShooting = true;
-
- if (shooterPed->IsPlayer())
- isPlayer = true;
-
+
+ if ( m_eWeaponType != WEAPONTYPE_CAMERA )
+ {
+ shooterPed->bIsShooting = true;
+
+ if (shooterPed->IsPlayer())
+ isPlayer = true;
+ }
+
DMAudio.PlayOneShot(shooterPed->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
+
+ if ( isPlayer )
+ {
+ CPed *aimPed = (CPed *)shooterPed->m_pSeekTarget;
+ if ( aimPed )
+ {
+ if ( aimPed->IsPed() )
+ shooterPed->Say(SOUND_PED_ON_FIRE);
+ }
+ }
}
+
+ switch ( m_eWeaponType )
+ {
+ case WEAPONTYPE_COLT45:
+ case WEAPONTYPE_PYTHON:
+ case WEAPONTYPE_SHOTGUN:
+ case WEAPONTYPE_SPAS12_SHOTGUN:
+ case WEAPONTYPE_STUBBY_SHOTGUN:
+ case WEAPONTYPE_TEC9:
+ case WEAPONTYPE_UZI:
+ case WEAPONTYPE_SILENCED_INGRAM:
+ case WEAPONTYPE_MP5:
+ case WEAPONTYPE_M4:
+ case WEAPONTYPE_RUGER:
+ case WEAPONTYPE_SNIPERRIFLE:
+ case WEAPONTYPE_LASERSCOPE:
+ case WEAPONTYPE_M60:
+ case WEAPONTYPE_MINIGUN:
+ CStats::RoundsFiredByPlayer++;
+ break;
+
+ case WEAPONTYPE_GRENADE:
+ case WEAPONTYPE_DETONATOR_GRENADE:
+ case WEAPONTYPE_MOLOTOV:
+ case WEAPONTYPE_ROCKET:
+ case WEAPONTYPE_ROCKETLAUNCHER:
+ case WEAPONTYPE_DETONATOR:
+ case WEAPONTYPE_HELICANNON:
+ CStats::KgsOfExplosivesUsed++;
+ break;
+ }
+
if (m_nAmmoInClip > 0)
m_nAmmoInClip--;
@@ -365,13 +389,10 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
return true;
}
- if (addFireRateAsDelay)
+ if ( addFireRateAsDelay )
m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nFiringRate;
else
m_nTimer = CTimer::GetTimeInMilliseconds();
-
- if (shooter == FindPlayerPed())
- CStats::RoundsFiredByPlayer++;
}
}
else
@@ -380,12 +401,11 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
{
m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload;
m_eWeaponState = WEAPONSTATE_FIRING;
-#ifndef AUDIO_NOT_READY
+
if (shooter->IsPed() && m_eWeaponType != WEAPONTYPE_CHAINSAW)
{
- DMAudio.PlayOneShot(((CPed*)shooter)->m_audioEntityId, 188, m_eWeaponType << 8);
+ DMAudio.PlayOneShot(((CPed*)shooter)->m_audioEntityId, SOUND_MELEE_ATTACK_START, m_eWeaponType << 8);
}
-#endif
}
fired = FireMelee(shooter, *source);
@@ -397,7 +417,6 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
return fired;
}
-// --MIAMI: Done
bool
CWeapon::FireFromCar(CVehicle *shooter, bool left, bool right)
{
@@ -438,7 +457,6 @@ CWeapon::FireFromCar(CVehicle *shooter, bool left, bool right)
return true;
}
-// --MIAMI: Done, except commented things
bool
CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
{
@@ -446,20 +464,27 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
CWeaponInfo *info = GetInfo();
- bool anim2Playing = RpAnimBlendClumpGetAssociation(shooter->GetClump(), CPed::GetFireAnimGround(info, false));
-
+ bool anim2Playing = false;
+
+ if ( CPed::GetFireAnimGround(info, false) != (AnimationId)0 )
+ {
+ if ( RpAnimBlendClumpGetAssociation(shooter->GetClump(), CPed::GetFireAnimGround(info, false)) )
+ anim2Playing = true;
+ }
+
ASSERT(shooter->IsPed());
CPed *shooterPed = (CPed*)shooter;
- if (shooterPed == FindPlayerPed()) {
+ if (shooterPed == FindPlayerPed())
+ {
if (m_eWeaponType == WEAPONTYPE_GOLFCLUB || m_eWeaponType == WEAPONTYPE_NIGHTSTICK ||
- (m_eWeaponType >= WEAPONTYPE_BASEBALLBAT && m_eWeaponType <= WEAPONTYPE_CHAINSAW)) {
+ (m_eWeaponType >= WEAPONTYPE_BASEBALLBAT && m_eWeaponType <= WEAPONTYPE_CHAINSAW))
+ {
+ CGlass::BreakGlassPhysically(fireSource, info->m_fRadius);
- // TODO(Miami): BreakGlassPhysically
- if (m_eWeaponType == WEAPONTYPE_CHAINSAW) {
+ if (m_eWeaponType == WEAPONTYPE_CHAINSAW)
CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, FindPlayerPed(), FindPlayerPed(), 1000);
- }
}
}
@@ -505,11 +530,10 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
{
CColSphere *sphere = &victimPedCol->spheres[s];
- if (useLocalPos) {
+ if (useLocalPos)
collisionDist = sphere->center - (*fireSource);
- } else {
+ else
collisionDist = victimPedPos + sphere->center - (*fireSource);
- }
if ( SQR(sphere->radius + info->m_fRadius) > collisionDist.MagnitudeSqr() )
{
@@ -532,21 +556,26 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
bool isHeavy = m_eWeaponType >= WEAPONTYPE_GOLFCLUB && m_eWeaponType <= WEAPONTYPE_KATANA && m_eWeaponType != WEAPONTYPE_HAMMER;
- if (shooterPed->m_fDamageImpulse == 0.0f) {
+ if (shooterPed->m_fDamageImpulse == 0.0f)
+ {
shooterPed->m_pDamageEntity = victimPed;
victimPed->RegisterReference(&shooterPed->m_pDamageEntity);
}
damageEntityRegistered = 3;
- if (victimPed->bInVehicle) {
+ if (victimPed->bInVehicle)
+ {
CVehicle *victimVeh = victimPed->m_pMyVehicle;
- if (victimVeh) {
- if (victimVeh->IsBike()) {
+ if (victimVeh)
+ {
+ if (victimVeh->IsBike())
+ {
CBike *victimBike = (CBike*)victimVeh;
victimBike->KnockOffRider(m_eWeaponType, localDir, victimPed, false);
- if (victimBike->pDriver) {
+ if (victimBike->pDriver)
victimBike->pDriver->ReactToAttack(shooterPed);
- } else {
+ else
+ {
if (victimVeh->pPassengers[0])
victimVeh->pPassengers[0]->ReactToAttack(shooterPed);
}
@@ -625,9 +654,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
}
if (info->m_AnimToPlay == ASSOCGRP_KNIFE)
{
- dir.x += 0.1f * shooterPed->GetUp().x + 0.05f * shooterPed->GetRight().x;
- dir.y += 0.1f * shooterPed->GetUp().y + 0.05f * shooterPed->GetRight().y;
- dir.z += 0.1f * shooterPed->GetUp().z + 0.05f * shooterPed->GetRight().z;
+ dir += 0.1f * shooterPed->GetUp() + 0.05f * shooterPed->GetRight();
CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir);
CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir);
CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir);
@@ -637,7 +664,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
if ( !victimPed->OnGround() )
{
if ( victimPed->m_fHealth > 0.0f
- && (victimPed->m_fHealth < 30.0f && victimPedHealth > 20.0f ||
+ && (victimPed->m_fHealth < 30.0f && victimPedHealth > 30.0f ||
(isHeavy || m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE) && !victimPed->IsPlayer()) )
{
posOffset.Normalise();
@@ -703,7 +730,8 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
float oldHealth = nearCar->m_fHealth;
if (m_eWeaponType == WEAPONTYPE_CHAINSAW)
{
- for(int i=0; i<4; i++) {
+ for( int32 i=0; i<4; i++ )
+ {
CParticle::AddParticle(PARTICLE_SPARK_SMALL, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.3f));
CParticle::AddParticle(PARTICLE_SPARK, gaTempSphereColPoints[0].point, gaTempSphereColPoints[0].normal * 0.1f);
}
@@ -716,7 +744,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
}
else
{
- nearCar->VehicleDamage(info->m_nDamage* (0.00075f * nearCar->pHandling->fMass), gaTempSphereColPoints[0].pieceB);
+ nearCar->VehicleDamage(info->m_nDamage* (0.01f * nearCar->pHandling->fMass), gaTempSphereColPoints[0].pieceB);
}
if (nearCar->m_fHealth < oldHealth)
{
@@ -808,7 +836,6 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
return true;
}
-// --MIAMI: Done except comments
bool
CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
{
@@ -856,13 +883,13 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
target = threatAttack->GetPosition();
target -= *fireSource;
- float distToTarget = target.Magnitude();
+ float distToTarget = Max(target.Magnitude(), 0.01f);
target *= info->m_fRange / distToTarget;
target += *fireSource;
if (shooter == FindPlayerPed() && inaccuracy != 0.f)
{
- float newInaccuracy = 2.5f * FindPlayerPed()->m_fAttackButtonCounter * (inaccuracy * Min(1.f, 5.f / distToTarget));
+ float newInaccuracy = fPlayerAimScale * FindPlayerPed()->m_fAttackButtonCounter * (inaccuracy * Min(1.f, fPlayerAimScaleDist / distToTarget));
if (FindPlayerPed()->bIsDucking)
newInaccuracy *= 0.4f;
@@ -886,10 +913,10 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
if (shooter == FindPlayerPed())
CWorld::bIncludeDeadPeds = true;
- // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
+ CWorld::bIncludeBikers = true;
CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::bIncludeDeadPeds = false;
- // bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
+ CWorld::bIncludeBikers = false;
}
else
{
@@ -899,9 +926,9 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
shooterPed->TransformToNode(target, PED_HANDR);
- // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
+ CWorld::bIncludeBikers = true;
CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
- // bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
+ CWorld::bIncludeBikers = false;
}
}
else if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam() )
@@ -909,11 +936,11 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
CVector src, trgt;
TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, src, trgt);
- // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
+ CWorld::bIncludeBikers = true;
CWorld::bIncludeDeadPeds = true;
CWorld::bIncludeCarTyres = true;
CWorld::ProcessLineOfSight(src, trgt, point, victim, true, true, true, true, true, false, false, true);
- // bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
+ CWorld::bIncludeBikers = false;
CWorld::bIncludeDeadPeds = false;
CWorld::bIncludeCarTyres = false;
@@ -990,9 +1017,9 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
CWeapon::DoDoomAiming(shooter, fireSource, &target);
}
- // CWorld::bProcessPedsOnBoatsAndBikes = 1; // TODO(Miami)
+ CWorld::bIncludeBikers = true;
CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
- // CWorld::bProcessPedsOnBoatsAndBikes = 0; // TODO(Miami)
+ CWorld::bIncludeBikers = false;
int32 rotSpeed = 1;
if (m_eWeaponType == WEAPONTYPE_M4)
@@ -1007,7 +1034,7 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
}
}
- if (victim && shooter->IsPed())
+ if ( shooter->IsPed() && victim)
{
if (victim == ((CPed*)shooter)->m_leader)
return false;
@@ -1134,6 +1161,71 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
}
void
+CWeapon::AddGunFlashBigGuns(CVector start, CVector end)
+{
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ start, CVector(0.0f, 0.0f, 0.0f), 5.0f,
+ 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
+ CVector gunflashPos = start;
+
+ CVector shootVec = end - start;
+
+ // Wtf did you do there R*?
+ shootVec.Normalise();
+ CVector2D ahead = shootVec;
+ ahead.Normalise();
+
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.08f);
+ gunflashPos += CVector(0.06f * ahead.x, 0.06f * ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.06f);
+ gunflashPos += CVector(0.06f * ahead.x, 0.06f * ahead.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.06f);
+
+ gunflashPos = start;
+ gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
+ gunflashPos.z += 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos.z += 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+ gunflashPos.z += 0.03f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ gunflashPos = start;
+ gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
+ gunflashPos.z -= 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos.z -= 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+ gunflashPos.z -= 0.03f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ CVector offset = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f));
+ offset.Normalise2D();
+
+ gunflashPos = start;
+ gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
+ gunflashPos += CVector(0.06f * offset.x, 0.06f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos += CVector(0.04f * offset.x, 0.04f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
+ gunflashPos += CVector(0.03f * offset.x, 0.03f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ gunflashPos = start;
+ gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
+ gunflashPos -= CVector(0.06f * offset.x, 0.06f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos -= CVector(0.04f * offset.x, 0.04f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
+ gunflashPos -= CVector(0.03f * offset.x, 0.03f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ CVector gunsmokePos = start;
+ float rnd = CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
+ CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x * rnd, ahead.y * rnd, 0.0f));
+}
+
+void
CWeapon::AddGunshell(CEntity *shooter, CVector const &source, CVector2D const &direction, float size)
{
ASSERT(shooter!=nil);
@@ -1162,7 +1254,7 @@ CWeapon::AddGunshell(CEntity *shooter, CVector const &source, CVector2D const &d
}
}
-// --MIAMI: Done?
+
void
CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
CVector *source, CVector *target, CColPoint *point, CVector2D ahead)
@@ -1227,7 +1319,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
CGlass::WasGlassHitByBullet(victim, point->point);
CVector traceTarget = point->point;
- CBulletTraces::AddTrace(source, &traceTarget);
+ CBulletTraces::AddTrace(source, &traceTarget, m_eWeaponType, shooter);
if (victim->IsPed() && shooter->IsVehicle() && ((CVehicle*)shooter)->pDriver)
shooter = ((CVehicle*)shooter)->pDriver;
@@ -1492,7 +1584,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
}
}
else
- CBulletTraces::AddTrace(source, target);
+ CBulletTraces::AddTrace(source, target, m_eWeaponType, shooter);
if ( shooter == FindPlayerPed() )
CPad::GetPad(0)->StartShake_Distance(240, 128, FindPlayerPed()->GetPosition().x, FindPlayerPed()->GetPosition().y, FindPlayerPed()->GetPosition().z);
@@ -1500,7 +1592,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
BlowUpExplosiveThings(victim);
}
-// --MIAMI: Done except comments, and didn't check particle coords precisely
+
bool
CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
@@ -1576,6 +1668,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
float shootAngle = DEGTORAD(RADTODEG(halfAngleRange - angleBetweenTwoShot * i) + shooterAngle);
CVector2D shootRot(-Sin(shootAngle), Cos(shootAngle));
+ shootRot.Normalise();
CVector source, target;
CColPoint point;
@@ -1590,10 +1683,9 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
target = f * Left + target - source;
target *= info->m_fRange;
target += source;
- CWorld::bIncludeDeadPeds = true;
CWorld::bIncludeCarTyres = true;
- //bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes
-
+ CWorld::bIncludeBikers = true;
+ CWorld::bIncludeDeadPeds = true;
CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::bIncludeDeadPeds = false;
CWorld::bIncludeCarTyres = false;
@@ -1626,11 +1718,11 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
if (shooter == FindPlayerPed())
CWorld::bIncludeDeadPeds = true;
- //bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes
+ CWorld::bIncludeBikers = true;
CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::bIncludeDeadPeds = false;
}
- //bProcessPedsOnBoatsAndBikes = false; // TODO(Miami): bProcessPedsOnBoatsAndBikes
+ CWorld::bIncludeBikers = false;
if ( victim )
{
@@ -1684,7 +1776,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
}
}
}
- CBulletTraces::AddTrace(fireSource, &point.point);
+ CBulletTraces::AddTrace(fireSource, &point.point, m_eWeaponType, shooter);
if ( victim->IsPed() )
{
@@ -1899,7 +1991,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
CVector traceTarget = *fireSource;
traceTarget += (target - (*fireSource)) * Min(info->m_fRange, 30.0f) / info->m_fRange;
- CBulletTraces::AddTrace(fireSource, &traceTarget);
+ CBulletTraces::AddTrace(fireSource, &traceTarget, m_eWeaponType, shooter);
}
}
@@ -1980,6 +2072,14 @@ CWeapon::FireProjectile(CEntity *shooter, CVector *fireSource, float power)
}
else
CProjectileInfo::AddProjectile(shooter, projectileType, *fireSource, power);
+
+
+ CWorld::pIgnoreEntity = nil;
+
+ if ( shooter->IsPed() )
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, shooter, (CPed *)shooter, 1000);
+ else if ( shooter->IsVehicle() && ((CVehicle*)shooter)->pDriver )
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_VEHICLE, shooter, ((CVehicle*)shooter)->pDriver, 1000);
return true;
}
@@ -2032,24 +2132,76 @@ CWeapon::FireAreaEffect(CEntity *shooter, CVector *fireSource)
CShotInfo::AddShot(shooter, m_eWeaponType, *fireSource, target);
CWeapon::GenerateFlameThrowerParticles(*fireSource, dir);
+
+ if ( shooter == (CEntity *)FindPlayerPed() )
+ {
+ for ( int32 i = 0; i < FindPlayerPed()->m_numNearPeds; i++ )
+ {
+ if ( FindPlayerPed()->m_nearPeds[i]->CharCreatedBy == RANDOM_CHAR )
+ {
+ if ( FindPlayerPed()->m_nearPeds[i]->IsPedInControl() && FindPlayerPed()->m_nearPeds[i]->m_nPedState != PED_FLEE_ENTITY )
+ FindPlayerPed()->m_nearPeds[i]->SetFlee(shooter, 10000);
+ }
+ }
+ }
return true;
}
bool
+CWeapon::LaserScopeDot(CVector *pOutPos, float *pOutSize)
+{
+ CWeaponInfo *info = GetInfo();
+
+ float range = info->m_fRange;
+
+ CVector source, target;
+ CEntity *foundEnt = nil;
+ CColPoint foundCol;
+
+ source = 0.5f * TheCamera.Cams[TheCamera.ActiveCam].Front + TheCamera.Cams[TheCamera.ActiveCam].Source;
+ target = TheCamera.Cams[TheCamera.ActiveCam].Front;
+ target.Normalise();
+ target *= range;
+ target += source;
+
+ if ( CWorld::ProcessLineOfSight(source, target, foundCol, foundEnt, true, true, true, true, false, false, false) )
+ {
+ CVector pos = foundCol.point;
+ float w, h;
+
+ if ( CSprite::CalcScreenCoors(foundCol.point, pos, &w, &h, true) )
+ {
+ *pOutPos = pos;
+ *pOutSize = w * 0.05f;
+
+ CCoronas::RegisterCorona((uintptr)this + 7, 128, 0, 0, 255, pos, 1.2f, 50.0f, CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
CWeapon::FireSniper(CEntity *shooter)
{
ASSERT(shooter!=nil);
-
- int16 mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
- if (!( mode == CCam::MODE_M16_1STPERSON
- || mode == CCam::MODE_SNIPER
- || mode == CCam::MODE_ROCKETLAUNCHER
- || mode == CCam::MODE_M16_1STPERSON_RUNABOUT
- || mode == CCam::MODE_SNIPER_RUNABOUT
- || mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT) )
+
+ if ( (CEntity *)FindPlayerPed() == shooter )
{
- return false;
+ int16 mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
+ if (!( mode == CCam::MODE_M16_1STPERSON
+ || mode == CCam::MODE_SNIPER
+ || mode == CCam::MODE_CAMERA
+ || mode == CCam::MODE_ROCKETLAUNCHER
+ || mode == CCam::MODE_M16_1STPERSON_RUNABOUT
+ || mode == CCam::MODE_SNIPER_RUNABOUT
+ || mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT) )
+ {
+ return false;
+ }
}
#ifndef FIX_BUGS
@@ -2076,14 +2228,74 @@ CWeapon::FireSniper(CEntity *shooter)
FindPlayerPed()->GetPosition().x,
FindPlayerPed()->GetPosition().y,
FindPlayerPed()->GetPosition().z);
+
+ CParticle::HandleShootableBirdsStuff(shooter, source);
CamShakeNoPos(&TheCamera, 0.2f);
}
+ if ( shooter->IsPed() )
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, shooter, (CPed*)shooter, 1000);
+ else if ( shooter->IsVehicle() && ((CVehicle*)shooter)->pDriver )
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_VEHICLE, shooter, ((CVehicle*)shooter)->pDriver, 1000);
+
return true;
}
-// --MIAMI: Done
+bool
+CWeapon::TakePhotograph(CEntity *shooter)
+{
+ if ( TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_CAMERA )
+ {
+ CSpecialFX::bSnapShotActive = true;
+ CSpecialFX::SnapShotFrames = 0;
+ CStats::PhotosTaken++;
+ bPhotographHasBeenTaken = true;
+
+ for ( int32 i = CPools::GetPedPool()->GetSize() - 1; i >= 0; i--)
+ {
+ CPed *ped = CPools::GetPedPool()->GetSlot(i);
+ if ( ped )
+ {
+ if ( (ped->GetPosition() - TheCamera.GetPosition()).Magnitude() < 125.0f )
+ {
+ CVector pedPos = ped->GetPosition();
+ pedPos.z += 0.8f;
+
+ CVector pos;
+ float w, h;
+
+ if ( CSprite::CalcScreenCoors(pedPos, pos, &w, &h, false) )
+ {
+ if ( SCREEN_WIDTH * 0.1f < pos.x && SCREEN_WIDTH * 0.9f > pos.x
+ && SCREEN_HEIGHT * 0.1f < pos.y && SCREEN_HEIGHT * 0.9f > pos.y )
+ {
+ CVector source, target;
+ CEntity *foundEnt = nil;
+ CColPoint foundCol;
+
+ target = pedPos;
+ source = TheCamera.GetForward() * 2.0f + TheCamera.GetPosition();
+
+ if ( CWorld::ProcessLineOfSight(source, target, foundCol, foundEnt, true, true, true, true, true, true, false) )
+ {
+ if ( foundEnt != (CEntity*)ped )
+ continue;
+ }
+
+ ped->bHasBeenPhotographed = true;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
bool
CWeapon::FireM16_1stPerson(CEntity *shooter)
{
@@ -2106,7 +2318,7 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
CWeaponInfo *info = GetInfo();
CWorld::bIncludeCarTyres = true;
- // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
+ CWorld::bIncludeBikers = true;
CColPoint point;
CEntity *victim;
@@ -2125,7 +2337,7 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
}
CWorld::pIgnoreEntity = nil;
CWorld::bIncludeDeadPeds = false;
- // bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
+ CWorld::bIncludeBikers = false;
CWorld::bIncludeCarTyres = false;
CVector2D front(cam->Front.x, cam->Front.y);
@@ -2180,41 +2392,81 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
bool
CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
{
-// TODO(MIAMI): bikes
CWeaponInfo *info = GetInfo();
CVehicleModelInfo *modelInfo = shooter->GetModelInfo();
-
+
CVector source, target;
- if ( left )
+
+ if ( shooter->IsBike() )
{
- source = shooter->GetMatrix() * CVector(-shooter->GetColModel()->boundingBox.max.x + -0.2f,
- float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y,
- modelInfo->GetFrontSeatPosn().z + 0.5f);
- source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
-
-
- target = shooter->GetMatrix() * CVector(-info->m_fRange,
- modelInfo->GetFrontSeatPosn().y,
+ if ( shooter->pDriver )
+ {
+ source = info->m_vecFireOffset;
+
+ shooter->pDriver->TransformToNode(source, PED_HANDR);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+ if ( left )
+ target = source - info->m_fRange * shooter->GetRight();
+ else if ( right )
+ target = source + info->m_fRange * shooter->GetRight();
+ else
+ target = source + info->m_fRange * shooter->GetForward();
+
+ }
+ else if ( left )
+ {
+ source = shooter->GetMatrix() * CVector(-shooter->GetColModel()->boundingBox.max.x + -0.25f,
+ float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y - 0.05f,
+ modelInfo->GetFrontSeatPosn().z + 0.63f);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+
+ target = shooter->GetMatrix() * CVector(-info->m_fRange,
+ modelInfo->GetFrontSeatPosn().y,
+ modelInfo->GetFrontSeatPosn().z + 0.6f);
+ }
+ else if ( right )
+ {
+ source = shooter->GetMatrix() * CVector(shooter->GetColModel()->boundingBox.max.x + 0.25f,
+ float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y - 0.18f,
+ modelInfo->GetFrontSeatPosn().z + 0.52f);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+ target = shooter->GetMatrix() * CVector(info->m_fRange,
+ modelInfo->GetFrontSeatPosn().y,
+ modelInfo->GetFrontSeatPosn().z + 0.5f);
+ }
+ else
+ {
+ source = shooter->GetMatrix() * CVector(float(CGeneral::GetRandomNumber() & 255) * 0.001f + -0.4f,
+ modelInfo->GetFrontSeatPosn().y + shooter->GetColModel()->boundingBox.max.y + 0.2f,
+ modelInfo->GetFrontSeatPosn().z + 0.55f);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+ target = shooter->GetMatrix() * CVector(0.0f,
+ info->m_fRange,
modelInfo->GetFrontSeatPosn().z + 0.5f);
+ }
}
else
{
- source = shooter->GetMatrix() * CVector(shooter->GetColModel()->boundingBox.max.x + 0.2f,
- float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y,
- modelInfo->GetFrontSeatPosn().z + 0.5f);
+ if ( left )
+ source = info->m_vecFireOffset;
+ else
+ {
+ source = 1.8f * info->m_vecFireOffset;
+ source.z -= 0.1f;
+ }
+
+ shooter->pDriver->TransformToNode(source, PED_HANDR);
source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
-
- target = shooter->GetMatrix() * CVector(info->m_fRange,
- modelInfo->GetFrontSeatPosn().y,
- modelInfo->GetFrontSeatPosn().z + 0.5f);
- }
- #undef FRONTSEATPOS
-
- if ( TheCamera.GetLookingLRBFirstPerson() && !left )
- {
- source -= 0.3f * shooter->GetForward();
- target -= 0.3f * shooter->GetForward();
+
+ if ( left )
+ target = source - info->m_fRange * shooter->GetRight();
+ else
+ target = source + info->m_fRange * shooter->GetRight();
}
target += CVector(float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f,
@@ -2226,9 +2478,14 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, FindPlayerPed(), FindPlayerPed(), 1000);
if ( !TheCamera.GetLookingLRBFirstPerson() )
- CParticle::AddParticle(PARTICLE_GUNFLASH, source, CVector(0.0f, 0.0f, 0.0f));
+ {
+ if ( !shooter->IsBike() )
+ CParticle::AddParticle(PARTICLE_GUNFLASH, source, CVector(0.0f, 0.0f, 0.0f));
+ else
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, source, 1.4f*shooter->m_vecMoveSpeed);
+ }
else
- CamShakeNoPos(&TheCamera, 0.01f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, source, 1.6f*shooter->m_vecMoveSpeed, nil, 0.18f);
CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_VEHICLE, shooter, FindPlayerPed(), 1000);
@@ -2237,7 +2494,12 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
CColPoint point;
CEntity *victim;
+
+ CWorld::bIncludeBikers = true;
+ CWorld::pIgnoreEntity = shooter;
ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ CWorld::pIgnoreEntity = NULL;
+ CWorld::bIncludeBikers = false;
if ( !(CTimer::GetFrameCounter() & 3) )
MakePedsJumpAtShot(shooter, &source, &target);
@@ -2245,7 +2507,7 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
if ( victim )
{
CVector traceTarget = point.point;
- CBulletTraces::AddTrace(&source, &traceTarget);
+ CBulletTraces::AddTrace(&source, &traceTarget, m_eWeaponType, shooter);
if ( victim->IsPed() )
{
@@ -2332,7 +2594,7 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
{
float norm = 30.0f/info->m_fRange;
CVector traceTarget = (target-source)*norm + source;
- CBulletTraces::AddTrace(&source, &traceTarget);
+ CBulletTraces::AddTrace(&source, &traceTarget, m_eWeaponType, shooter);
}
if ( shooter == FindPlayerVehicle() )
@@ -2341,7 +2603,6 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
return true;
}
-// --MIAMI: Done
void
CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target)
{
@@ -2484,7 +2745,7 @@ CWeapon::DoTankDoomAiming(CEntity *shooter, CEntity *driver, CVector *source, CV
}
}
-// --MIAMI: Done
+
void
CWeapon::DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source, CVector *target)
{
@@ -2538,11 +2799,11 @@ CWeapon::DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source
float maxAimDistance = CAR_DRIVEBYAUTOAIMING_MAXDIST;
if (model == MI_HUNTER)
{
- maxAimDistance = Tan(DEGTORAD(30.f));
+ maxAimDistance = Tan(DEGTORAD(fHunterAimingAngle));
}
else if (model == MI_SEASPAR || model == MI_SPARROW)
{
- maxAimDistance = Tan(DEGTORAD(10.f));
+ maxAimDistance = Tan(DEGTORAD(fSeaSparrowAimingAngle));
}
if ( closestEntityDist < maxAimDistance )
@@ -2587,7 +2848,7 @@ CWeapon::Update(int32 audioEntity, CPed *pedToAdjustSound)
{
if ( IsShotgun(m_eWeaponType) && AEHANDLE_IS_OK(audioEntity) )
{
- uint32 timePassed = m_nTimer - gReloadSampleTime[m_eWeaponType];
+ uint32 timePassed = m_nTimer - CWeaponInfo::ms_aReloadSampleTime[m_eWeaponType];
if ( CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed )
DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f);
}
@@ -2596,7 +2857,7 @@ CWeapon::Update(int32 audioEntity, CPed *pedToAdjustSound)
{
if ( GetInfo()->m_eWeaponFire != WEAPON_FIRE_MELEE && m_nAmmoTotal == 0 ) {
m_eWeaponState = WEAPONSTATE_OUT_OF_AMMO;
- // TODO(Miami): CPickups::RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo
+ CPickups::RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo(m_eWeaponType);
} else
m_eWeaponState = WEAPONSTATE_READY;
}
@@ -2621,20 +2882,20 @@ CWeapon::Update(int32 audioEntity, CPed *pedToAdjustSound)
float soundStart = 0.75f;
switch (info->m_AnimToPlay) {
case ASSOCGRP_PYTHON:
- soundStart = 0.5f;
+ soundStart = fReloadAnimSampleFraction[0];
break;
case ASSOCGRP_COLT:
case ASSOCGRP_TEC:
- soundStart = 0.7f;
+ soundStart = fReloadAnimSampleFraction[1];
break;
case ASSOCGRP_UZI:
- soundStart = 0.75f;
+ soundStart = fReloadAnimSampleFraction[2];
break;
case ASSOCGRP_RIFLE:
- soundStart = 0.75f;
+ soundStart = fReloadAnimSampleFraction[3];
break;
case ASSOCGRP_M60:
- soundStart = 0.7f;
+ soundStart = fReloadAnimSampleFraction[4];
break;
default:
break;
@@ -2650,8 +2911,9 @@ CWeapon::Update(int32 audioEntity, CPed *pedToAdjustSound)
m_nTimer = CTimer::GetTimeInMilliseconds();
}
} else {
- uint32 timePassed = m_nTimer - gReloadSampleTime[m_eWeaponType];
- if (CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed) {
+ uint32 timePassed = m_nTimer - CWeaponInfo::ms_aReloadSampleTime[m_eWeaponType];
+ if (CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed)
+ {
#ifdef AUDIO_NOT_READY
DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f);
#else
@@ -2745,17 +3007,20 @@ FireOneInstantHitRound(CVector *source, CVector *target, int32 damage)
}
case ENTITY_TYPE_VEHICLE:
{
+ CStats::BulletsThatHit++;
DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f);
break;
}
case ENTITY_TYPE_PED:
{
+ CStats::BulletsThatHit++;
DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f);
((CPed*)victim)->Say(SOUND_PED_BULLET_HIT);
break;
}
case ENTITY_TYPE_OBJECT:
{
+ CStats::BulletsThatHit++;
PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_2, point.point);
break;
}
@@ -2863,7 +3128,6 @@ CWeapon::HitsGround(CEntity *holder, CVector *fireSource, CEntity *aimingTo)
return false;
}
-// --MIAMI: Done
void
CWeapon::BlowUpExplosiveThings(CEntity *thing)
{
@@ -2898,11 +3162,11 @@ bool
CWeapon::HasWeaponAmmoToBeUsed(void)
{
// FIX: This is better (not bug tho)
-#if 0
+//#if 0
if (m_eWeaponType <= WEAPONTYPE_CHAINSAW)
-#else
- if (CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_eWeaponFire == WEAPON_FIRE_MELEE)
-#endif
+//#else
+// if (CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_eWeaponFire == WEAPON_FIRE_MELEE)
+//#endif
return true;
else
return m_nAmmoTotal != 0;
@@ -2914,72 +3178,7 @@ CWeapon::ProcessLineOfSight(CVector const &point1, CVector const &point2, CColPo
return CWorld::ProcessLineOfSight(point1, point2, point, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects);
}
-void
-CWeapon::AddGunFlashBigGuns(CVector start, CVector end)
-{
- CPointLights::AddLight(CPointLights::LIGHT_POINT,
- start, CVector(0.0f, 0.0f, 0.0f), 5.0f,
- 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
- CVector gunflashPos = start;
-
- CVector shootVec = end - start;
-
- // Wtf did you do there R*?
- shootVec.Normalise();
- CVector2D ahead = shootVec;
- ahead.Normalise();
-
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.08f);
- gunflashPos += CVector(0.06f * ahead.x, 0.06f * ahead.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.06f);
- gunflashPos += CVector(0.06f * ahead.x, 0.06f * ahead.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.06f);
-
- gunflashPos = start;
- gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
- gunflashPos.z += 0.04f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
- gunflashPos.z += 0.04f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
- gunflashPos.z += 0.03f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
-
- gunflashPos = start;
- gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
- gunflashPos.z -= 0.04f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
- gunflashPos.z -= 0.04f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
- gunflashPos.z -= 0.03f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
-
- CVector offset = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f));
- offset.Normalise2D();
-
- gunflashPos = start;
- gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
- gunflashPos += CVector(0.06f * offset.x, 0.06f * offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
- gunflashPos += CVector(0.04f * offset.x, 0.04f * offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
- gunflashPos += CVector(0.03f * offset.x, 0.03f * offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
-
- gunflashPos = start;
- gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
- gunflashPos -= CVector(0.06f * offset.x, 0.06f * offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
- gunflashPos -= CVector(0.04f * offset.x, 0.04f * offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
- gunflashPos -= CVector(0.03f * offset.x, 0.03f * offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
-
- CVector gunsmokePos = start;
- float rnd = CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
- CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x * rnd, ahead.y * rnd, 0.0f));
-}
-// --MIAMI: Done
void
CWeapon::CheckForShootingVehicleOccupant(CEntity **victim, CColPoint *point, eWeaponType weapon, CVector const& source, CVector const& target)
{
diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h
index cb59582f..f720b312 100644
--- a/src/weapons/Weapon.h
+++ b/src/weapons/Weapon.h
@@ -21,7 +21,9 @@ public:
int32 m_nAmmoTotal;
uint32 m_nTimer;
bool m_bAddRotOffset;
-
+
+ static bool bPhotographHasBeenTaken;
+
CWeapon() {
m_bAddRotOffset = false;
}
@@ -41,6 +43,7 @@ public:
bool FireMelee (CEntity *shooter, CVector &fireSource);
bool FireInstantHit(CEntity *shooter, CVector *fireSource);
+ static void AddGunFlashBigGuns(CVector start, CVector end);
void AddGunshell (CEntity *shooter, CVector const &source, CVector2D const &direction, float size);
void DoBulletImpact(CEntity *shooter, CEntity *victim, CVector *source, CVector *target, CColPoint *point, CVector2D ahead);
@@ -50,13 +53,15 @@ public:
static void GenerateFlameThrowerParticles(CVector pos, CVector dir);
bool FireAreaEffect (CEntity *shooter, CVector *fireSource);
+ bool LaserScopeDot (CVector *pOutPos, float *pOutSize);
bool FireSniper (CEntity *shooter);
+ bool TakePhotograph (CEntity *shooter);
bool FireM16_1stPerson (CEntity *shooter);
bool FireInstantHitFromCar(CVehicle *shooter, bool left, bool right);
- static void DoDoomAiming (CEntity *shooter, CVector *source, CVector *target);
- static void DoTankDoomAiming (CEntity *shooter, CEntity *driver, CVector *source, CVector *target);
- static void DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source, CVector *target);
+ static void DoDoomAiming (CEntity *shooter, CVector *source, CVector *target);
+ static void DoTankDoomAiming (CEntity *shooter, CEntity *driver, CVector *source, CVector *target);
+ static void DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source, CVector *target);
void Reload(void);
void Update(int32 audioEntity, CPed *pedToAdjustSound);
@@ -68,14 +73,12 @@ public:
bool HitsGround(CEntity *holder, CVector *fireSource, CEntity *aimingTo);
static void BlowUpExplosiveThings(CEntity *thing);
bool HasWeaponAmmoToBeUsed(void);
- static void AddGunFlashBigGuns(CVector, CVector);
static bool IsShotgun(int weapon) { return weapon == WEAPONTYPE_SHOTGUN || weapon == WEAPONTYPE_SPAS12_SHOTGUN || weapon == WEAPONTYPE_STUBBY_SHOTGUN; }
- // TODO(Miami): Is that still used?
static bool ProcessLineOfSight(CVector const &point1, CVector const &point2, CColPoint &point, CEntity *&entity, eWeaponType type, CEntity *shooter, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects);
- static void CheckForShootingVehicleOccupant(CEntity**, CColPoint*, eWeaponType, CVector const&, CVector const&);
+ static void CheckForShootingVehicleOccupant(CEntity **victim, CColPoint *point, eWeaponType weapon, CVector const& source, CVector const& target);
#ifdef COMPATIBLE_SAVES
void Save(uint8*& buf);
diff --git a/src/weapons/WeaponEffects.cpp b/src/weapons/WeaponEffects.cpp
index fb50bbe0..7a5be722 100644
--- a/src/weapons/WeaponEffects.cpp
+++ b/src/weapons/WeaponEffects.cpp
@@ -3,6 +3,9 @@
#include "WeaponEffects.h"
#include "TxdStore.h"
#include "Sprite.h"
+#include "PlayerPed.h"
+#include "World.h"
+#include "WeaponType.h"
RwTexture *gpCrossHairTex;
RwRaster *gpCrossHairRaster;
@@ -24,10 +27,10 @@ CWeaponEffects::Init(void)
{
gCrossHair.m_bActive = false;
gCrossHair.m_vecPos = CVector(0.0f, 0.0f, 0.0f);
- gCrossHair.m_nRed = 0;
+ gCrossHair.m_nRed = 255;
gCrossHair.m_nGreen = 0;
gCrossHair.m_nBlue = 0;
- gCrossHair.m_nAlpha = 255;
+ gCrossHair.m_nAlpha = 127;
gCrossHair.m_fSize = 1.0f;
gCrossHair.m_fRotation = 0.0f;
@@ -46,9 +49,7 @@ void
CWeaponEffects::Shutdown(void)
{
RwTextureDestroy(gpCrossHairTex);
-#ifdef GTA3_1_1_PATCH
gpCrossHairTex = nil;
-#endif
}
void
@@ -56,10 +57,6 @@ CWeaponEffects::MarkTarget(CVector pos, uint8 red, uint8 green, uint8 blue, uint
{
gCrossHair.m_bActive = true;
gCrossHair.m_vecPos = pos;
- gCrossHair.m_nRed = red;
- gCrossHair.m_nGreen = green;
- gCrossHair.m_nBlue = blue;
- gCrossHair.m_nAlpha = alpha;
gCrossHair.m_fSize = size;
}
@@ -72,12 +69,32 @@ CWeaponEffects::ClearCrossHair(void)
void
CWeaponEffects::Render(void)
{
+ static float aCrossHairSize[WEAPONTYPE_TOTALWEAPONS] =
+ {
+ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
+ 0.4f, 0.4f,
+ 0.5f,
+ 0.3f,
+ 0.9f, 0.9f, 0.9f,
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.1f, 0.1f,
+ 1.0f,
+ 0.6f,
+ 0.7f,
+ 0.0f, 0.0f
+ };
+
+
+
if ( gCrossHair.m_bActive )
{
+ float size = aCrossHairSize[FindPlayerPed()->GetWeapon()->m_eWeaponType];
+
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVDESTALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpCrossHairRaster);
RwV3d pos;
@@ -85,15 +102,25 @@ CWeaponEffects::Render(void)
if ( CSprite::CalcScreenCoors(gCrossHair.m_vecPos, &pos, &w, &h, true) )
{
float recipz = 1.0f / pos.z;
- CSprite::RenderOneXLUSprite(pos.x, pos.y, pos.z,
- gCrossHair.m_fSize * w, gCrossHair.m_fSize * h,
- gCrossHair.m_nRed, gCrossHair.m_nGreen, gCrossHair.m_nBlue, 255,
- recipz, 255);
+ CSprite::RenderOneXLUSprite_Rotate_Aspect(pos.x, pos.y, pos.z,
+ w, h,
+ 255, 88, 100, 158,
+ recipz, gCrossHair.m_fRotation, gCrossHair.m_nAlpha);
+
+ float recipz2 = 1.0f / pos.z;
+
+ CSprite::RenderOneXLUSprite_Rotate_Aspect(pos.x, pos.y, pos.z,
+ size*w, size*h,
+ 107, 134, 247, 158,
+ recipz2, TWOPI - gCrossHair.m_fRotation, gCrossHair.m_nAlpha);
+
+ gCrossHair.m_fRotation += 0.02f;
+ if ( gCrossHair.m_fRotation > TWOPI )
+ gCrossHair.m_fRotation = 0.0;
}
-
+
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
}
} \ No newline at end of file
diff --git a/src/weapons/WeaponInfo.cpp b/src/weapons/WeaponInfo.cpp
index 0f71aeda..6debf725 100644
--- a/src/weapons/WeaponInfo.cpp
+++ b/src/weapons/WeaponInfo.cpp
@@ -9,16 +9,57 @@
#include "ModelInfo.h"
#include "ModelIndices.h"
+uint16 CWeaponInfo::ms_aReloadSampleTime[WEAPONTYPE_TOTALWEAPONS] =
+{
+ 0, // UNARMED
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, // GRENADE
+ 0, // DETONATEGRENADE
+ 0, // TEARGAS
+ 0, // MOLOTOV
+ 0, // ROCKET
+ 250, // COLT45
+ 250, // PYTHON
+ 650, // SHOTGUN
+ 650, // SPAS12 SHOTGUN
+ 650, // STUBBY SHOTGUN
+ 400, // TEC9
+ 400, // UZIhec
+ 400, // SILENCED_INGRAM
+ 400, // MP5
+ 300, // M16
+ 300, // AK47
+ 423, // SNIPERRIFLE
+ 423, // LASERSCOPE
+ 400, // ROCKETLAUNCHER
+ 0, // FLAMETHROWER
+ 0, // M60
+ 0, // MINIGUN
+ 0, // DETONATOR
+ 0, // HELICANNON
+ 0 // CAMERA
+};
+
// Yeah...
-int32 CWeaponInfo::ms_aMaxAmmoForWeapon[WEAPONTYPE_TOTALWEAPONS] = {
+int32 CWeaponInfo::ms_aMaxAmmoForWeapon[WEAPONTYPE_TOTALWEAPONS] =
+{
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1
};
CWeaponInfo CWeaponInfo::ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS];
-
-// --MIAMI: Todo
-static char ms_aWeaponNames[][32] = {
+char CWeaponInfo::ms_aWeaponNames[WEAPONTYPE_TOTALWEAPONS][32] =
+{
"Unarmed",
"BrassKnuckle",
"ScrewDriver",
@@ -61,7 +102,7 @@ static char ms_aWeaponNames[][32] = {
CWeaponInfo*
CWeaponInfo::GetWeaponInfo(eWeaponType weaponType)
{
- return &CWeaponInfo::ms_apWeaponInfos[weaponType];
+ return &ms_apWeaponInfos[weaponType];
}
// --MIAMI: done except WEAPONTYPE_TOTALWEAPONS value
diff --git a/src/weapons/WeaponInfo.h b/src/weapons/WeaponInfo.h
index e7013004..7ce3d861 100644
--- a/src/weapons/WeaponInfo.h
+++ b/src/weapons/WeaponInfo.h
@@ -8,7 +8,9 @@ enum AssocGroupId;
class CWeaponInfo {
static CWeaponInfo ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS];
+ static char ms_aWeaponNames[WEAPONTYPE_TOTALWEAPONS][32];
public:
+ static uint16 ms_aReloadSampleTime[WEAPONTYPE_TOTALWEAPONS];
static int32 ms_aMaxAmmoForWeapon[WEAPONTYPE_TOTALWEAPONS];
eWeaponFire m_eWeaponFire;