summaryrefslogtreecommitdiffstats
path: root/src/weapons/Weapon.cpp
diff options
context:
space:
mode:
authoreray orçunus <erayorcunus@gmail.com>2020-06-20 15:23:32 +0200
committereray orçunus <erayorcunus@gmail.com>2020-06-20 15:23:32 +0200
commit0625954bb74e687ed73b496bc06e9db58407e045 (patch)
tree3ec342a96685889bf2512ececcfc76f1bdac14a0 /src/weapons/Weapon.cpp
parentbikes in garages + bugfix (diff)
downloadre3-0625954bb74e687ed73b496bc06e9db58407e045.tar
re3-0625954bb74e687ed73b496bc06e9db58407e045.tar.gz
re3-0625954bb74e687ed73b496bc06e9db58407e045.tar.bz2
re3-0625954bb74e687ed73b496bc06e9db58407e045.tar.lz
re3-0625954bb74e687ed73b496bc06e9db58407e045.tar.xz
re3-0625954bb74e687ed73b496bc06e9db58407e045.tar.zst
re3-0625954bb74e687ed73b496bc06e9db58407e045.zip
Diffstat (limited to 'src/weapons/Weapon.cpp')
-rw-r--r--src/weapons/Weapon.cpp128
1 files changed, 108 insertions, 20 deletions
diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp
index e8c5c3d1..d3b92b07 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -386,6 +386,7 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
return fired;
}
+// --MIAMI: Done
bool
CWeapon::FireFromCar(CVehicle *shooter, bool left, bool right)
{
@@ -401,8 +402,11 @@ CWeapon::FireFromCar(CVehicle *shooter, bool left, bool right)
{
DMAudio.PlayOneShot(shooter->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
- if ( m_nAmmoInClip > 0 ) m_nAmmoInClip--;
- if ( m_nAmmoTotal < 25000 && m_nAmmoTotal > 0 ) m_nAmmoTotal--;
+ if ( m_nAmmoInClip > 0 )
+ m_nAmmoInClip--;
+
+ if ( m_nAmmoTotal < 25000 && m_nAmmoTotal > 0 && (!shooter || shooter->GetStatus() != STATUS_PLAYER || CStats::GetPercentageProgress() < 100.f))
+ m_nAmmoTotal--;
m_eWeaponState = WEAPONSTATE_FIRING;
@@ -418,8 +422,6 @@ CWeapon::FireFromCar(CVehicle *shooter, bool left, bool right)
}
m_nTimer = CTimer::GetTimeInMilliseconds() + 1000;
- if ( shooter == FindPlayerVehicle() )
- CStats::RoundsFiredByPlayer++;
}
return true;
@@ -898,18 +900,17 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
// bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
CWorld::bIncludeDeadPeds = true;
- // bProcessVehicleWheels = true; // TODO(Miami)
+ CWorld::bIncludeCarTyres = true;
CWorld::ProcessLineOfSight(src, trgt, point, victim, true, true, true, true, true, false, false, true);
// bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
CWorld::bIncludeDeadPeds = false;
- // bProcessVehicleWheels = false; // TODO(Miami)
+ CWorld::bIncludeCarTyres = false;
- // TODO(Miami)
- // if (victim)
- // CWeapon::CheckForShootingVehicleOccupant(v39, victim, point, m_eWeaponType, src, trgt);
+ if (victim)
+ CheckForShootingVehicleOccupant(&victim, &point, m_eWeaponType, src, trgt);
int32 rotSpeed = 1;
- if ( m_eWeaponType == WEAPONTYPE_M4 )
+ if ( m_eWeaponType == WEAPONTYPE_M4 )
rotSpeed = 4;
CVector bulletPos;
@@ -1579,12 +1580,12 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
target *= info->m_fRange;
target += source;
CWorld::bIncludeDeadPeds = true;
- //bProcessVehicleWheels = true; // TODO(Miami): bProcessVehicleWheels
+ CWorld::bIncludeCarTyres = true;
//bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes
CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::bIncludeDeadPeds = false;
- //bProcessVehicleWheels = false; // TODO(Miami): bProcessVehicleWheels
+ CWorld::bIncludeCarTyres = false;
}
else
{
@@ -2074,7 +2075,7 @@ CWeapon::FireSniper(CEntity *shooter)
return true;
}
-// --MIAMI: Heavily TODO
+// --MIAMI: Done
bool
CWeapon::FireM16_1stPerson(CEntity *shooter)
{
@@ -2096,10 +2097,12 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
CWeaponInfo *info = GetInfo();
+ CWorld::bIncludeCarTyres = true;
+ // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
+
CColPoint point;
CEntity *victim;
- CWorld::bIncludeCarTyres = true;
CWorld::pIgnoreEntity = shooter;
CWorld::bIncludeDeadPeds = true;
@@ -2109,9 +2112,12 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
CVector source = cam->Source;
CVector target = cam->Front*info->m_fRange + source;
- ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
- CWorld::bIncludeDeadPeds = false;
+ if (CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true)) {
+ CheckForShootingVehicleOccupant(&victim, &point, m_eWeaponType, source, target);
+ }
CWorld::pIgnoreEntity = nil;
+ CWorld::bIncludeDeadPeds = false;
+ // bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
CWorld::bIncludeCarTyres = false;
CVector2D front(cam->Front.x, cam->Front.y);
@@ -2129,18 +2135,18 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
if ( shooter == FindPlayerPed() )
{
- CPad::GetPad(0)->StartShake_Distance(240, 128, FindPlayerPed()->GetPosition().x, FindPlayerPed()->GetPosition().y, FindPlayerPed()->GetPosition().z);
-
float mult;
switch (m_eWeaponType) {
case WEAPONTYPE_M4:
- case WEAPONTYPE_HELICANNON:
- case WEAPONTYPE_M60:
mult = 0.0003f;
break;
case WEAPONTYPE_RUGER:
mult = 0.00015f;
break;
+ case WEAPONTYPE_HELICANNON:
+ case WEAPONTYPE_M60:
+ mult = 0.0003f;
+ break;
default:
mult = 0.0002f;
break;
@@ -2151,6 +2157,13 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
TheCamera.Cams[TheCamera.ActiveCam].Beta += float((CGeneral::GetRandomNumber() & 127) - 64) * mult;
TheCamera.Cams[TheCamera.ActiveCam].Alpha += float((CGeneral::GetRandomNumber() & 127) - 64) * mult;
+
+ // yes, double
+ double notFiringRate = (20.0 - info->m_nFiringRate) / 80.0;
+ double raisedNotFiringRate = Max(1.0, Max(0.0, notFiringRate));
+
+ uint8 shakeFreq = 80.0 * raisedNotFiringRate + 130.0;
+ CPad::GetPad(0)->StartShake(20000.0f * CTimer::GetTimeStep() / shakeFreq, shakeFreq);
}
return true;
@@ -2957,6 +2970,81 @@ CWeapon::AddGunFlashBigGuns(CVector start, CVector end)
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)
+{
+ if (!(*victim)->IsVehicle())
+ return;
+
+ CColSphere headSphere;
+
+ CVehicle *veh = (CVehicle*)*victim;
+ CColPoint origPoint(*point);
+ float radius = 1.0f;
+ bool found = false;
+ CColLine shootLine(source, target);
+
+ if (veh->pDriver && veh->pDriver->bCanBeShotInVehicle) {
+ CVector pos(0.f, 0.f, 0.f);
+ veh->pDriver->TransformToNode(pos, PED_HEAD);
+ headSphere.Set(0.2f, pos + CVector(0.f, 0.f, 0.1f), 0, PEDPIECE_HEAD);
+ if (CCollision::ProcessLineSphere(shootLine, headSphere, *point, radius)) {
+ *victim = veh->pDriver;
+ found = true;
+ }
+ }
+
+ for(int i = 0; i < ARRAY_SIZE(veh->pPassengers); i++) {
+ CPed *passenger = veh->pPassengers[i];
+ if (passenger && passenger->bCanBeShotInVehicle) {
+ CVector pos(0.f, 0.f, 0.f);
+ passenger->TransformToNode(pos, PED_HEAD);
+ headSphere.Set(0.2f, pos + CVector(0.f, 0.f, 0.1f), 0, PEDPIECE_HEAD);
+ if (CCollision::ProcessLineSphere(shootLine, headSphere, *point, radius)) {
+ *victim = passenger;
+ found = true;
+ }
+ }
+ }
+ if (veh->IsCar()) {
+ CVector distVec = target - source;
+ if (DotProduct(distVec, veh->GetForward()) < 0.0f && DotProduct(distVec, veh->GetUp()) <= 0.0f) {
+ CColModel *colModel = veh->GetColModel();
+ if (colModel->numTriangles > 0) {
+ bool passesGlass = false;
+ CMatrix invVehMat;
+ Invert(veh->GetMatrix(), invVehMat);
+ shootLine.p0 = invVehMat * shootLine.p0;
+ shootLine.p1 = invVehMat * shootLine.p1;
+ CCollision::CalculateTrianglePlanes(colModel);
+ for (int i = 0; i < colModel->numTriangles; i++) {
+ if (colModel->triangles[i].surface == SURFACE_GLASS &&
+ CCollision::TestLineTriangle(shootLine, colModel->vertices, colModel->triangles[i], colModel->trianglePlanes[i])) {
+ passesGlass = true;
+ break;
+ }
+ }
+ CAutomobile *car = (CAutomobile*)veh;
+
+ // No need to damage windscreen if there isn't one.
+ if (passesGlass && car->Damage.ProgressPanelDamage(VEHPANEL_WINDSCREEN)) {
+ if (car->Damage.GetPanelStatus(VEHPANEL_WINDSCREEN) == PANEL_STATUS_SMASHED2)
+ car->Damage.ProgressPanelDamage(VEHPANEL_WINDSCREEN);
+
+ car->SetPanelDamage(CAR_WINDSCREEN, VEHPANEL_WINDSCREEN, true);
+ DMAudio.PlayOneShot(veh->m_audioEntityId, SOUND_CAR_WINDSHIELD_CRACK, 0.f);
+ }
+ }
+ }
+ }
+
+ if (!found) {
+ *victim = veh;
+ *point = origPoint;
+ }
+}
+
#ifdef COMPATIBLE_SAVES
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipSaveBuf(buf, sizeof(data));
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipSaveBuf(buf, sizeof(data));