diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/control/Pickups.h | 3 | ||||
-rw-r--r-- | src/control/Script.cpp | 1 | ||||
-rw-r--r-- | src/control/Script.h | 2 | ||||
-rw-r--r-- | src/core/World.cpp | 13 | ||||
-rw-r--r-- | src/core/World.h | 1 | ||||
-rw-r--r-- | src/objects/Stinger.cpp | 232 | ||||
-rw-r--r-- | src/objects/Stinger.h | 40 | ||||
-rw-r--r-- | src/peds/CopPed.cpp | 46 | ||||
-rw-r--r-- | src/peds/CopPed.h | 2 | ||||
-rw-r--r-- | src/render/Glass.h | 1 | ||||
-rw-r--r-- | src/render/SpecialFX.cpp | 1 | ||||
-rw-r--r-- | src/render/SpecialFX.h | 8 | ||||
-rw-r--r-- | src/weapons/Weapon.cpp | 723 | ||||
-rw-r--r-- | src/weapons/Weapon.h | 17 | ||||
-rw-r--r-- | src/weapons/WeaponEffects.cpp | 63 | ||||
-rw-r--r-- | src/weapons/WeaponInfo.cpp | 51 | ||||
-rw-r--r-- | src/weapons/WeaponInfo.h | 2 |
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 §or, 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 §or, 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 §or, 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; |