Ducking, shooting vehicle occupants and weapon fixes

This commit is contained in:
eray orçunus 2020-06-20 16:23:32 +03:00
parent e9e533b0cb
commit 0625954bb7
11 changed files with 240 additions and 94 deletions

View File

@ -1861,6 +1861,19 @@ CColTrianglePlane::Set(const CVector *v, CColTriangle &tri)
dir = normal.z < 0.0f ? DIR_Z_NEG : DIR_Z_POS; dir = normal.z < 0.0f ? DIR_Z_NEG : DIR_Z_POS;
} }
CColPoint&
CColPoint::operator=(const CColPoint& other)
{
point = other.point;
normal = other.normal;
surfaceA = other.surfaceA;
pieceA = other.pieceA;
surfaceB = other.surfaceB;
pieceB = other.pieceB;
// doesn't copy depth
return *this;
}
CColModel::CColModel(void) CColModel::CColModel(void)
{ {
numSpheres = 0; numSpheres = 0;

View File

@ -89,6 +89,8 @@ struct CColPoint
uint8 surfaceB; uint8 surfaceB;
uint8 pieceB; uint8 pieceB;
float depth; float depth;
CColPoint& operator=(const CColPoint& other);
}; };
struct CStoredCollPoly struct CStoredCollPoly

View File

@ -767,7 +767,7 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown_FirstPersonOnl
if (button == GetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_OUT, type)) if (button == GetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_OUT, type))
state.Cross = 255; state.Cross = 255;
if (button == GetControllerKeyAssociatedWithAction(PED_DUCK, type)) if (button == GetControllerKeyAssociatedWithAction(PED_DUCK, type))
state.RightShock = 255; state.LeftShock = 255;
} }
void CControllerConfigManager::AffectControllerStateOn_ButtonDown_ThirdPersonOnly(int32 button, eControllerType type, CControllerState &state) void CControllerConfigManager::AffectControllerStateOn_ButtonDown_ThirdPersonOnly(int32 button, eControllerType type, CControllerState &state)
@ -785,7 +785,7 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown_ThirdPersonOnl
if (button == GetControllerKeyAssociatedWithAction(PED_SPRINT, type)) if (button == GetControllerKeyAssociatedWithAction(PED_SPRINT, type))
state.Cross = 255; state.Cross = 255;
if (button == GetControllerKeyAssociatedWithAction(PED_DUCK, type)) if (button == GetControllerKeyAssociatedWithAction(PED_DUCK, type))
state.RightShock = 255; state.LeftShock = 255;
if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC) if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC)
{ {

View File

@ -2336,6 +2336,14 @@ bool CPad::TargetJustDown(void)
return false; return false;
} }
bool CPad::DuckJustDown(void)
{
if (ArePlayerControlsDisabled())
return false;
return !!(NewState.LeftShock && !OldState.LeftShock);
}
bool CPad::JumpJustDown(void) bool CPad::JumpJustDown(void)
{ {
if ( ArePlayerControlsDisabled() ) if ( ArePlayerControlsDisabled() )

View File

@ -237,6 +237,7 @@ public:
bool CycleWeaponRightJustDown(void); bool CycleWeaponRightJustDown(void);
bool GetTarget(void); bool GetTarget(void);
bool TargetJustDown(void); bool TargetJustDown(void);
bool DuckJustDown(void);
bool JumpJustDown(void); bool JumpJustDown(void);
bool GetSprint(void); bool GetSprint(void);
bool ShiftTargetLeftJustDown(void); bool ShiftTargetLeftJustDown(void);

View File

@ -1113,19 +1113,15 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg)
newAnim->SetFinishCallback(FinishedAttackCB, ped); newAnim->SetFinishCallback(FinishedAttackCB, ped);
} }
} else { } else {
if (attackAssoc && attackAssoc->animId == ANIM_MELEE_ATTACK && currentWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) if (attackAssoc && attackAssoc->animId == ANIM_MELEE_ATTACK && currentWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) {
{
attackAssoc->blendDelta = -8.0f; attackAssoc->blendDelta = -8.0f;
attackAssoc->flags |= ASSOC_DELETEFADEDOUT; attackAssoc->flags |= ASSOC_DELETEFADEDOUT;
ped->ClearAttack(); ped->ClearAttack();
return; return;
} }
if (attackAssoc) if (attackAssoc) {
{ if (currentWeapon->m_AnimToPlay == ASSOCGRP_THROW) {
if (currentWeapon->m_AnimToPlay == ASSOCGRP_THROW) if ((attackAssoc->animId == ANIM_THROWABLE_THROW || attackAssoc->animId == ANIM_THROWABLE_THROWU) && ped->GetWeapon()->m_nAmmoTotal > 0) {
{
if ((attackAssoc->animId == ANIM_THROWABLE_THROW || attackAssoc->animId == ANIM_THROWABLE_THROWU) && ped->GetWeapon()->m_nAmmoTotal > 0)
{
ped->RemoveWeaponModel(currentWeapon->m_nModelId); ped->RemoveWeaponModel(currentWeapon->m_nModelId);
ped->AddWeaponModel(currentWeapon->m_nModelId); ped->AddWeaponModel(currentWeapon->m_nModelId);
} }
@ -1661,7 +1657,6 @@ CPed::ClearDuck(bool clearTimer)
if (!animAssoc) { if (!animAssoc) {
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_LOW); animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_LOW);
} }
if (!animAssoc) { if (!animAssoc) {
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH); animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH);
} }
@ -6808,30 +6803,6 @@ CPed::Die(void)
// UNUSED: This is a perfectly empty function. // UNUSED: This is a perfectly empty function.
} }
uint8
CPed::DoesLOSBulletHitPed(CColPoint &colPoint)
{
#ifdef FIX_BUGS
return 1;
#else
uint8 retVal = 2;
float headZ = GetNodePosition(PED_HEAD).z;
if (m_nPedState == PED_FALL)
retVal = 1;
float colZ = colPoint.point.z;
if (colZ < headZ)
retVal = 1;
if (headZ + 0.2f <= colZ)
retVal = 0;
return retVal;
#endif
}
// --MIAMI: Done // --MIAMI: Done
bool bool
CPed::DuckAndCover(void) CPed::DuckAndCover(void)

View File

@ -778,7 +778,6 @@ public:
void SetChat(CEntity*, uint32); void SetChat(CEntity*, uint32);
void DeadPedMakesTyresBloody(void); void DeadPedMakesTyresBloody(void);
void MakeTyresMuddySectorList(CPtrList&); void MakeTyresMuddySectorList(CPtrList&);
uint8 DoesLOSBulletHitPed(CColPoint &point);
bool DuckAndCover(void); bool DuckAndCover(void);
void EndFight(uint8); void EndFight(uint8);
void EnterCar(void); void EnterCar(void);

View File

@ -330,6 +330,8 @@ CPlayerPed::SetRealMoveAnim(void)
curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED); curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
if (!curIdleAssoc) if (!curIdleAssoc)
curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE); curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
if (!curIdleAssoc)
curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD);
if ((!curRunStopAssoc || !(curRunStopAssoc->IsRunning())) && (!curRunStopRAssoc || !(curRunStopRAssoc->IsRunning()))) { if ((!curRunStopAssoc || !(curRunStopAssoc->IsRunning())) && (!curRunStopRAssoc || !(curRunStopRAssoc->IsRunning()))) {
@ -400,7 +402,10 @@ CPlayerPed::SetRealMoveAnim(void)
delete curIdleAssoc; delete curIdleAssoc;
delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED); delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE); CAnimBlendAssociation *fightIdleAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
if (!fightIdleAnim)
fightIdleAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD);
delete fightIdleAnim;
delete curSprintAssoc; delete curSprintAssoc;
curSprintAssoc = nil; curSprintAssoc = nil;
@ -569,6 +574,7 @@ CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed)
if (distVec.Magnitude() > CWeaponInfo::GetWeaponInfo(weaponUsed->m_eWeaponType)->m_fRange) if (distVec.Magnitude() > CWeaponInfo::GetWeaponInfo(weaponUsed->m_eWeaponType)->m_fRange)
return true; return true;
/*
if (weaponUsed->m_eWeaponType != WEAPONTYPE_SHOTGUN && weaponUsed->m_eWeaponType != WEAPONTYPE_RUGER) if (weaponUsed->m_eWeaponType != WEAPONTYPE_SHOTGUN && weaponUsed->m_eWeaponType != WEAPONTYPE_RUGER)
return false; return false;
@ -576,7 +582,7 @@ CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed)
if (DotProduct(distVec,GetForward()) < 0.4f) if (DotProduct(distVec,GetForward()) < 0.4f)
return true; return true;
*/
return false; return false;
} }
@ -623,6 +629,14 @@ CPlayerPed::PlayerControlSniper(CPad *padUsed)
ProcessWeaponSwitch(padUsed); ProcessWeaponSwitch(padUsed);
TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f; TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f;
if (padUsed->DuckJustDown() && !bIsDucking && m_nMoveState != PEDMOVE_SPRINT) {
bCrouchWhenShooting = true;
SetDuck(60000, true);
} else if (bIsDucking && (padUsed->DuckJustDown() || m_nMoveState == PEDMOVE_SPRINT)) {
ClearDuck(true);
bCrouchWhenShooting = false;
}
if (!padUsed->GetTarget()) { if (!padUsed->GetTarget()) {
RestorePreviousState(); RestorePreviousState();
TheCamera.ClearPlayerWeaponMode(); TheCamera.ClearPlayerWeaponMode();
@ -730,6 +744,14 @@ CPlayerPed::PlayerControlM16(CPad *padUsed)
ProcessWeaponSwitch(padUsed); ProcessWeaponSwitch(padUsed);
TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f; TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f;
if (padUsed->DuckJustDown() && !bIsDucking && m_nMoveState != PEDMOVE_SPRINT) {
bCrouchWhenShooting = true;
SetDuck(60000, true);
} else if (bIsDucking && (padUsed->DuckJustDown() || m_nMoveState == PEDMOVE_SPRINT)) {
ClearDuck(true);
bCrouchWhenShooting = false;
}
if (!padUsed->GetTarget()) { if (!padUsed->GetTarget()) {
RestorePreviousState(); RestorePreviousState();
TheCamera.ClearPlayerWeaponMode(); TheCamera.ClearPlayerWeaponMode();
@ -803,6 +825,12 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
m_fMoveSpeed = 0.0f; m_fMoveSpeed = 0.0f;
} }
} }
if (m_nPedState == PED_ANSWER_MOBILE) {
SetRealMoveAnim();
return;
}
if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
&& padUsed->GetSprint()) { && padUsed->GetSprint()) {
m_nMoveState = PEDMOVE_SPRINT; m_nMoveState = PEDMOVE_SPRINT;
@ -1084,7 +1112,7 @@ CPlayerPed::ProcessAnimGroups(void)
} }
} }
// TODO(Miami): Hella TODO // TODO(Miami)
void void
CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
{ {
@ -1094,31 +1122,52 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
CWeaponEffects::ClearCrossHair(); CWeaponEffects::ClearCrossHair();
ClearPointGunAt(); ClearPointGunAt();
} }
if (padUsed->DuckJustDown() && !bIsDucking && m_nMoveState != PEDMOVE_SPRINT) {
bCrouchWhenShooting = true;
SetDuck(60000, true);
} else if (bIsDucking && (padUsed->DuckJustDown() || m_nMoveState == PEDMOVE_SPRINT ||
padUsed->GetSprint() || padUsed->JumpJustDown() || padUsed->ExitVehicleJustDown())) {
ClearDuck(true);
bCrouchWhenShooting = false;
}
if(weaponInfo->m_bCanAim)
m_wepAccuracy = 95;
else
m_wepAccuracy = 100;
if (!m_pFire) { if (!m_pFire) {
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER || eWeaponType weapon = GetWeapon()->m_eWeaponType;
GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_M4 || if (weapon == WEAPONTYPE_ROCKETLAUNCHER || weapon == WEAPONTYPE_SNIPERRIFLE ||
GetWeapon()->m_eWeaponType == WEAPONTYPE_RUGER) { weapon == WEAPONTYPE_LASERSCOPE || weapon == WEAPONTYPE_M4 ||
if (padUsed->TargetJustDown()/* || TheCamera.m_bAllow1rstPersonWeaponsCamera */) { // TODO(Miami): Cam weapon == WEAPONTYPE_RUGER || weapon == WEAPONTYPE_M60 ||
SetStoredState(); weapon == WEAPONTYPE_CAMERA) {
m_nPedState = PED_SNIPER_MODE;
if (padUsed->TargetJustDown() || TheCamera.m_bJustJumpedOutOf1stPersonBecauseOfTarget) {
#ifdef FREE_CAM #ifdef FREE_CAM
if (CCamera::bFreeCam && TheCamera.Cams[0].Using3rdPersonMouseCam()) { if (CCamera::bFreeCam && TheCamera.Cams[0].Using3rdPersonMouseCam()) {
m_fRotationCur = CGeneral::LimitRadianAngle(-TheCamera.Orientation); m_fRotationCur = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
SetHeading(m_fRotationCur); SetHeading(m_fRotationCur);
} }
#endif #endif
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) if (weapon == WEAPONTYPE_ROCKETLAUNCHER)
TheCamera.SetNewPlayerWeaponMode(CCam::MODE_ROCKETLAUNCHER, 0, 0); TheCamera.SetNewPlayerWeaponMode(CCam::MODE_ROCKETLAUNCHER, 0, 0);
else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE) else if (weapon == WEAPONTYPE_SNIPERRIFLE || weapon == WEAPONTYPE_LASERSCOPE)
TheCamera.SetNewPlayerWeaponMode(CCam::MODE_SNIPER, 0, 0); TheCamera.SetNewPlayerWeaponMode(CCam::MODE_SNIPER, 0, 0);
else if (weapon == WEAPONTYPE_CAMERA)
TheCamera.SetNewPlayerWeaponMode(CCam::MODE_CAMERA, 0, 0);
else else
TheCamera.SetNewPlayerWeaponMode(CCam::MODE_M16_1STPERSON, 0, 0); TheCamera.SetNewPlayerWeaponMode(CCam::MODE_M16_1STPERSON, 0, 0);
m_fMoveSpeed = 0.0f; m_fMoveSpeed = 0.0f;
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_STANCE, 1000.0f); CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_STANCE, 1000.0f);
SetPedState(PED_SNIPER_MODE);
return;
} }
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER || GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE if (!TheCamera.Using1stPersonWeaponMode())
|| TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON) if (weapon == WEAPONTYPE_ROCKETLAUNCHER || weapon == WEAPONTYPE_SNIPERRIFLE || weapon == WEAPONTYPE_LASERSCOPE || weapon == WEAPONTYPE_CAMERA)
return; return;
} }
} }
@ -1126,6 +1175,11 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
if (padUsed->GetWeapon() && m_nMoveState != PEDMOVE_SPRINT) { if (padUsed->GetWeapon() && m_nMoveState != PEDMOVE_SPRINT) {
if (m_nSelectedWepSlot == m_currentWeapon) { if (m_nSelectedWepSlot == m_currentWeapon) {
if (m_pPointGunAt) { if (m_pPointGunAt) {
if (m_nPedState == PED_ATTACK) {
m_fAttackButtonCounter *= Pow(0.94f, CTimer::GetTimeStep());
} else {
m_fAttackButtonCounter = 0.0f;
}
#ifdef FREE_CAM #ifdef FREE_CAM
if (CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE && m_fMoveSpeed < 1.0f) if (CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE && m_fMoveSpeed < 1.0f)
StartFightAttack(padUsed->GetWeapon()); StartFightAttack(padUsed->GetWeapon());
@ -1220,7 +1274,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
} }
#endif #endif
if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) { if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT && !TheCamera.Using1stPersonWeaponMode() && weaponInfo->m_bCanAim) {
if (m_pPointGunAt) { if (m_pPointGunAt) {
// what?? // what??
if (!m_pPointGunAt if (!m_pPointGunAt
@ -1229,14 +1283,25 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
#else #else
|| CCamera::m_bUseMouse3rdPerson || CCamera::m_bUseMouse3rdPerson
#endif #endif
|| m_pPointGunAt->IsPed() && ((CPed*)m_pPointGunAt)->bInVehicle) { ) {
ClearWeaponTarget(); ClearWeaponTarget();
return; return;
} }
if (CPlayerPed::DoesTargetHaveToBeBroken(m_pPointGunAt->GetPosition(), GetWeapon())) {
CPed *gunPointed = (CPed*)m_pPointGunAt;
if (gunPointed && gunPointed->IsPed() &&
((gunPointed->bInVehicle && (!gunPointed->m_pMyVehicle || !gunPointed->m_pMyVehicle->IsBike())) || !CGame::nastyGame && gunPointed->DyingOrDead())) {
ClearWeaponTarget(); ClearWeaponTarget();
return; return;
} }
if (CPlayerPed::DoesTargetHaveToBeBroken(m_pPointGunAt->GetPosition(), GetWeapon()) ||
(!bCanPointGunAtTarget && !weaponInfo->m_bCanAimWithArm)) {
ClearWeaponTarget();
return;
}
// TODO(Miami): RotatePlayerToTrackTarget
if (m_pPointGunAt) { if (m_pPointGunAt) {
if (padUsed->ShiftTargetLeftJustDown()) if (padUsed->ShiftTargetLeftJustDown())
FindNextWeaponLockOnTarget(m_pPointGunAt, true); FindNextWeaponLockOnTarget(m_pPointGunAt, true);
@ -1247,11 +1312,11 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
TheCamera.UpdateAimingCoors(m_pPointGunAt->GetPosition()); TheCamera.UpdateAimingCoors(m_pPointGunAt->GetPosition());
} }
#ifdef FREE_CAM #ifdef FREE_CAM
else if ((CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE) || (weaponInfo->m_bCanAim && !CCamera::m_bUseMouse3rdPerson)) { else if ((CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE) || !CCamera::m_bUseMouse3rdPerson) {
#else #else
else if (weaponInfo->m_bCanAim && !CCamera::m_bUseMouse3rdPerson) { else if (!CCamera::m_bUseMouse3rdPerson) {
#endif #endif
if (padUsed->TargetJustDown()/* || TheCamera.m_bAllow1rstPersonWeaponsCamera */) // TODO(Miami): Cam if (padUsed->TargetJustDown() || TheCamera.m_bJustJumpedOutOf1stPersonBecauseOfTarget)
FindWeaponLockOnTarget(); FindWeaponLockOnTarget();
} }
} else if (m_pPointGunAt) { } else if (m_pPointGunAt) {

View File

@ -76,7 +76,6 @@ bool CBulletInfo::AddBullet(CEntity* pSource, eWeaponType type, CVector vecPosit
void CBulletInfo::Update(void) void CBulletInfo::Update(void)
{ {
bool bAddSound = true;
bPlayerSniperBullet = false; bPlayerSniperBullet = false;
for (int i = 0; i < NUM_BULLETS; i++) { for (int i = 0; i < NUM_BULLETS; i++) {
CBulletInfo* pBullet = &gaBulletInfo[i]; CBulletInfo* pBullet = &gaBulletInfo[i];
@ -93,13 +92,14 @@ void CBulletInfo::Update(void)
CWorld::pIgnoreEntity = pBullet->m_pSource; CWorld::pIgnoreEntity = pBullet->m_pSource;
CColPoint point; CColPoint point;
CEntity* pHitEntity; CEntity* pHitEntity;
if (CWorld::ProcessLineOfSight(vecOldPos, vecNewPos, point, pHitEntity, true, true, true, true, true, true)) { if (CWorld::ProcessLineOfSight(vecOldPos, vecNewPos, point, pHitEntity, true, true, true, true, true, false, false, true)) {
if (pBullet->m_pSource && (pHitEntity->IsPed() || pHitEntity->IsVehicle())) if (pBullet->m_pSource && (pHitEntity->IsPed() || pHitEntity->IsVehicle()))
CStats::InstantHitsHitByPlayer++; CStats::InstantHitsHitByPlayer++;
CWeapon::CheckForShootingVehicleOccupant(&pHitEntity, &point, pBullet->m_eWeaponType, vecOldPos, vecNewPos);
if (pHitEntity->IsPed()) { if (pHitEntity->IsPed()) {
CPed* pPed = (CPed*)pHitEntity; CPed* pPed = (CPed*)pHitEntity;
if (!pPed->DyingOrDead() && pPed != pBullet->m_pSource) { if (!pPed->DyingOrDead() && pPed != pBullet->m_pSource) {
if (pPed->DoesLOSBulletHitPed(point)) {
if (pPed->IsPedInControl() && !pPed->bIsDucking) { if (pPed->IsPedInControl() && !pPed->bIsDucking) {
pPed->ClearAttackByRemovingAnim(); pPed->ClearAttackByRemovingAnim();
CAnimBlendAssociation* pAnim = CAnimManager::AddAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_SHOT_FRONT_PARTIAL); CAnimBlendAssociation* pAnim = CAnimManager::AddAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_SHOT_FRONT_PARTIAL);
@ -110,10 +110,6 @@ void CBulletInfo::Update(void)
pBullet->m_bInUse = false; pBullet->m_bInUse = false;
vecNewPos = point.point; vecNewPos = point.point;
} }
else {
bAddSound = false;
}
}
if (CGame::nastyGame) { if (CGame::nastyGame) {
CVector vecParticleDirection = (point.point - pPed->GetPosition()) * 0.01f; CVector vecParticleDirection = (point.point - pPed->GetPosition()) * 0.01f;
vecParticleDirection.z = 0.01f; vecParticleDirection.z = 0.01f;
@ -170,7 +166,7 @@ void CBulletInfo::Update(void)
vecNewPos = point.point; vecNewPos = point.point;
#endif #endif
} }
if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE && bAddSound) { if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || pBullet->m_eWeaponType == WEAPONTYPE_LASERSCOPE) {
cAudioScriptObject* pAudio; cAudioScriptObject* pAudio;
switch (pHitEntity->GetType()) { switch (pHitEntity->GetType()) {
case ENTITY_TYPE_BUILDING: case ENTITY_TYPE_BUILDING:
@ -210,7 +206,7 @@ void CBulletInfo::Update(void)
CWorld::pIgnoreEntity = nil; CWorld::pIgnoreEntity = nil;
CWorld::bIncludeDeadPeds = false; CWorld::bIncludeDeadPeds = false;
CWorld::bIncludeCarTyres = false; CWorld::bIncludeCarTyres = false;
if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE) { if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || pBullet->m_eWeaponType == WEAPONTYPE_LASERSCOPE) {
bPlayerSniperBullet = true; bPlayerSniperBullet = true;
PlayerSniperBulletStart = pBullet->m_vecPosition; PlayerSniperBulletStart = pBullet->m_vecPosition;
PlayerSniperBulletEnd = vecNewPos; PlayerSniperBulletEnd = vecNewPos;

View File

@ -386,6 +386,7 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
return fired; return fired;
} }
// --MIAMI: Done
bool bool
CWeapon::FireFromCar(CVehicle *shooter, bool left, bool right) 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); DMAudio.PlayOneShot(shooter->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
if ( m_nAmmoInClip > 0 ) m_nAmmoInClip--; if ( m_nAmmoInClip > 0 )
if ( m_nAmmoTotal < 25000 && m_nAmmoTotal > 0 ) m_nAmmoTotal--; m_nAmmoInClip--;
if ( m_nAmmoTotal < 25000 && m_nAmmoTotal > 0 && (!shooter || shooter->GetStatus() != STATUS_PLAYER || CStats::GetPercentageProgress() < 100.f))
m_nAmmoTotal--;
m_eWeaponState = WEAPONSTATE_FIRING; m_eWeaponState = WEAPONSTATE_FIRING;
@ -418,8 +422,6 @@ CWeapon::FireFromCar(CVehicle *shooter, bool left, bool right)
} }
m_nTimer = CTimer::GetTimeInMilliseconds() + 1000; m_nTimer = CTimer::GetTimeInMilliseconds() + 1000;
if ( shooter == FindPlayerVehicle() )
CStats::RoundsFiredByPlayer++;
} }
return true; return true;
@ -898,15 +900,14 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
// bProcessPedsOnBoatsAndBikes = true; // TODO(Miami) // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
CWorld::bIncludeDeadPeds = true; CWorld::bIncludeDeadPeds = true;
// bProcessVehicleWheels = true; // TODO(Miami) CWorld::bIncludeCarTyres = true;
CWorld::ProcessLineOfSight(src, trgt, point, victim, true, true, true, true, true, false, false, true); CWorld::ProcessLineOfSight(src, trgt, point, victim, true, true, true, true, true, false, false, true);
// bProcessPedsOnBoatsAndBikes = false; // TODO(Miami) // bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
CWorld::bIncludeDeadPeds = false; CWorld::bIncludeDeadPeds = false;
// bProcessVehicleWheels = false; // TODO(Miami) CWorld::bIncludeCarTyres = false;
// TODO(Miami) if (victim)
// if (victim) CheckForShootingVehicleOccupant(&victim, &point, m_eWeaponType, src, trgt);
// CWeapon::CheckForShootingVehicleOccupant(v39, victim, point, m_eWeaponType, src, trgt);
int32 rotSpeed = 1; int32 rotSpeed = 1;
if ( m_eWeaponType == WEAPONTYPE_M4 ) if ( m_eWeaponType == WEAPONTYPE_M4 )
@ -1579,12 +1580,12 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
target *= info->m_fRange; target *= info->m_fRange;
target += source; target += source;
CWorld::bIncludeDeadPeds = true; CWorld::bIncludeDeadPeds = true;
//bProcessVehicleWheels = true; // TODO(Miami): bProcessVehicleWheels CWorld::bIncludeCarTyres = true;
//bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes //bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes
CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true); CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::bIncludeDeadPeds = false; CWorld::bIncludeDeadPeds = false;
//bProcessVehicleWheels = false; // TODO(Miami): bProcessVehicleWheels CWorld::bIncludeCarTyres = false;
} }
else else
{ {
@ -2074,7 +2075,7 @@ CWeapon::FireSniper(CEntity *shooter)
return true; return true;
} }
// --MIAMI: Heavily TODO // --MIAMI: Done
bool bool
CWeapon::FireM16_1stPerson(CEntity *shooter) CWeapon::FireM16_1stPerson(CEntity *shooter)
{ {
@ -2096,10 +2097,12 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
CWeaponInfo *info = GetInfo(); CWeaponInfo *info = GetInfo();
CWorld::bIncludeCarTyres = true;
// bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
CColPoint point; CColPoint point;
CEntity *victim; CEntity *victim;
CWorld::bIncludeCarTyres = true;
CWorld::pIgnoreEntity = shooter; CWorld::pIgnoreEntity = shooter;
CWorld::bIncludeDeadPeds = true; CWorld::bIncludeDeadPeds = true;
@ -2109,9 +2112,12 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
CVector source = cam->Source; CVector source = cam->Source;
CVector target = cam->Front*info->m_fRange + source; CVector target = cam->Front*info->m_fRange + source;
ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false); if (CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true)) {
CWorld::bIncludeDeadPeds = false; CheckForShootingVehicleOccupant(&victim, &point, m_eWeaponType, source, target);
}
CWorld::pIgnoreEntity = nil; CWorld::pIgnoreEntity = nil;
CWorld::bIncludeDeadPeds = false;
// bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
CWorld::bIncludeCarTyres = false; CWorld::bIncludeCarTyres = false;
CVector2D front(cam->Front.x, cam->Front.y); CVector2D front(cam->Front.x, cam->Front.y);
@ -2129,18 +2135,18 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
if ( shooter == FindPlayerPed() ) if ( shooter == FindPlayerPed() )
{ {
CPad::GetPad(0)->StartShake_Distance(240, 128, FindPlayerPed()->GetPosition().x, FindPlayerPed()->GetPosition().y, FindPlayerPed()->GetPosition().z);
float mult; float mult;
switch (m_eWeaponType) { switch (m_eWeaponType) {
case WEAPONTYPE_M4: case WEAPONTYPE_M4:
case WEAPONTYPE_HELICANNON:
case WEAPONTYPE_M60:
mult = 0.0003f; mult = 0.0003f;
break; break;
case WEAPONTYPE_RUGER: case WEAPONTYPE_RUGER:
mult = 0.00015f; mult = 0.00015f;
break; break;
case WEAPONTYPE_HELICANNON:
case WEAPONTYPE_M60:
mult = 0.0003f;
break;
default: default:
mult = 0.0002f; mult = 0.0002f;
break; 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].Beta += float((CGeneral::GetRandomNumber() & 127) - 64) * mult;
TheCamera.Cams[TheCamera.ActiveCam].Alpha += 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; 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)); 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 #ifdef COMPATIBLE_SAVES
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipSaveBuf(buf, sizeof(data)); #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)); #define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipSaveBuf(buf, sizeof(data));

View File

@ -72,8 +72,11 @@ public:
static bool IsShotgun(int weapon) { return weapon == WEAPONTYPE_SHOTGUN || weapon == WEAPONTYPE_SPAS12_SHOTGUN || weapon == WEAPONTYPE_STUBBY_SHOTGUN; } 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 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&);
#ifdef COMPATIBLE_SAVES #ifdef COMPATIBLE_SAVES
void Save(uint8*& buf); void Save(uint8*& buf);
void Load(uint8*& buf); void Load(uint8*& buf);