diff options
-rw-r--r-- | src/animation/AnimBlendAssociation.cpp | 7 | ||||
-rw-r--r-- | src/animation/AnimBlendNode.cpp | 6 | ||||
-rw-r--r-- | src/animation/AnimManager.cpp | 5 | ||||
-rw-r--r-- | src/core/Collision.cpp | 13 | ||||
-rw-r--r-- | src/core/Collision.h | 2 | ||||
-rw-r--r-- | src/core/ControllerConfig.cpp | 4 | ||||
-rw-r--r-- | src/core/Pad.cpp | 8 | ||||
-rw-r--r-- | src/core/Pad.h | 1 | ||||
-rw-r--r-- | src/core/PlayerInfo.cpp | 2 | ||||
-rw-r--r-- | src/peds/Ped.cpp | 61 | ||||
-rw-r--r-- | src/peds/Ped.h | 1 | ||||
-rw-r--r-- | src/peds/PlayerPed.cpp | 185 | ||||
-rw-r--r-- | src/weapons/BulletInfo.cpp | 30 | ||||
-rw-r--r-- | src/weapons/Weapon.cpp | 160 | ||||
-rw-r--r-- | src/weapons/Weapon.h | 3 |
15 files changed, 341 insertions, 147 deletions
diff --git a/src/animation/AnimBlendAssociation.cpp b/src/animation/AnimBlendAssociation.cpp index 9a29601b..a6c679eb 100644 --- a/src/animation/AnimBlendAssociation.cpp +++ b/src/animation/AnimBlendAssociation.cpp @@ -133,8 +133,11 @@ CAnimBlendAssociation::SetCurrentTime(float time) int i; for(currentTime = time; currentTime >= hierarchy->totalLength; currentTime -= hierarchy->totalLength) - if(!IsRepeating()) - return; + if (!IsRepeating()) { + currentTime = hierarchy->totalLength; + break; + } + CAnimManager::UncompressAnimation(hierarchy); if(hierarchy->compressed2){ for(i = 0; i < numNodes; i++) diff --git a/src/animation/AnimBlendNode.cpp b/src/animation/AnimBlendNode.cpp index 4186e994..860046e8 100644 --- a/src/animation/AnimBlendNode.cpp +++ b/src/animation/AnimBlendNode.cpp @@ -102,8 +102,8 @@ CAnimBlendNode::FindKeyFrame(float t) // advance until t is between frameB and frameA while(t > sequence->GetKeyFrame(frameA)->deltaTime){ t -= sequence->GetKeyFrame(frameA)->deltaTime; - frameB = frameA++; - if(frameA >= sequence->numFrames){ + frameA++; + if(frameA + 1 >= sequence->numFrames){ // reached end of animation if(!association->IsRepeating()){ CalcDeltas(); @@ -111,8 +111,8 @@ CAnimBlendNode::FindKeyFrame(float t) return false; } frameA = 0; - frameB = 0; } + frameB = frameA; } remainingTime = sequence->GetKeyFrame(frameA)->deltaTime - t; diff --git a/src/animation/AnimManager.cpp b/src/animation/AnimManager.cpp index c2f1c8bc..385f1f67 100644 --- a/src/animation/AnimManager.cpp +++ b/src/animation/AnimManager.cpp @@ -237,14 +237,14 @@ AnimAssocDesc aMeleeAnimDescs[] = { { ANIM_MELEE_ATTACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_MELEE_ATTACK_2ND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_MELEE_ATTACK_START, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK }, - { ANIM_WEAPON_CROUCHRELOAD, ASSOC_REPEAT }, // TODO(Miami): Overload that name for melee/swing + { ANIM_MELEE_IDLE_FIGHTMODE, ASSOC_REPEAT }, { ANIM_WEAPON_SPECIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION }, // TODO(Miami): Overload that name for melee/swing }; AnimAssocDesc aSwingAnimDescs[] = { { ANIM_MELEE_ATTACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_MELEE_ATTACK_2ND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_MELEE_ATTACK_START, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, - { ANIM_WEAPON_CROUCHRELOAD, ASSOC_REPEAT }, // TODO(Miami): Overload that name for melee/swing + { ANIM_MELEE_IDLE_FIGHTMODE, ASSOC_REPEAT }, { ANIM_WEAPON_SPECIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, // TODO(Miami): Overload that name for melee/swing }; AnimAssocDesc aWeaponAnimDescs[] = { @@ -1006,6 +1006,7 @@ CAnimManager::UncompressAnimation(CAnimBlendHierarchy *hier) if(link == nil){ ms_animCache.tail.prev->item->RemoveUncompressedData(); ms_animCache.Remove(ms_animCache.tail.prev); + ms_animCache.tail.prev->item->linkPtr = nil; link = ms_animCache.Insert(hier); } hier->linkPtr = link; diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp index 77e28a10..76019c2f 100644 --- a/src/core/Collision.cpp +++ b/src/core/Collision.cpp @@ -1861,6 +1861,19 @@ CColTrianglePlane::Set(const CVector *v, CColTriangle &tri) 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) { numSpheres = 0; diff --git a/src/core/Collision.h b/src/core/Collision.h index 9f08ccd6..09abaa1c 100644 --- a/src/core/Collision.h +++ b/src/core/Collision.h @@ -89,6 +89,8 @@ struct CColPoint uint8 surfaceB; uint8 pieceB; float depth; + + CColPoint& operator=(const CColPoint& other); }; struct CStoredCollPoly diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp index 2a5d20f0..c3e4e872 100644 --- a/src/core/ControllerConfig.cpp +++ b/src/core/ControllerConfig.cpp @@ -767,7 +767,7 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown_FirstPersonOnl if (button == GetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_OUT, type)) state.Cross = 255; if (button == GetControllerKeyAssociatedWithAction(PED_DUCK, type)) - state.RightShock = 255; + state.LeftShock = 255; } 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)) state.Cross = 255; if (button == GetControllerKeyAssociatedWithAction(PED_DUCK, type)) - state.RightShock = 255; + state.LeftShock = 255; if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC) { diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index ab66dd9b..084fe888 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -2336,6 +2336,14 @@ bool CPad::TargetJustDown(void) return false; } +bool CPad::DuckJustDown(void) +{ + if (ArePlayerControlsDisabled()) + return false; + + return !!(NewState.LeftShock && !OldState.LeftShock); +} + bool CPad::JumpJustDown(void) { if ( ArePlayerControlsDisabled() ) diff --git a/src/core/Pad.h b/src/core/Pad.h index ccfdcbc9..2f50a164 100644 --- a/src/core/Pad.h +++ b/src/core/Pad.h @@ -237,6 +237,7 @@ public: bool CycleWeaponRightJustDown(void); bool GetTarget(void); bool TargetJustDown(void); + bool DuckJustDown(void); bool JumpJustDown(void); bool GetSprint(void); bool ShiftTargetLeftJustDown(void); diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index 0be5f73e..ed2690eb 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -146,6 +146,8 @@ CPlayerInfo::Clear(void) m_bDriveByAllowed = true; m_nPreviousTimeRewardedForExplosion = 0; m_nExplosionsSinceLastReward = 0; + m_nHavocLevel = 0; + m_fMediaAttention = 0; m_nCurrentBustedAudio = 1; m_nBustedAudioStatus = BUSTEDAUDIO_NONE; } diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index c11291b9..c3c4f864 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -1098,8 +1098,7 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) return; } - // Not for unarmed, it's for weapons using unarmed anims - if (currentWeapon->m_bUse2nd && ped->bIsAttacking && currentWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) { + if (currentWeapon->m_bUse2nd && ped->bIsAttacking && currentWeapon->m_AnimToPlay != ASSOCGRP_THROW) { AnimationId groundAnim = GetFireAnimGround(currentWeapon); CAnimBlendAssociation *groundAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), groundAnim); if (!groundAnimAssoc || groundAnimAssoc->blendAmount <= 0.95f && groundAnimAssoc->blendDelta <= 0.0f) { @@ -1113,19 +1112,15 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) newAnim->SetFinishCallback(FinishedAttackCB, ped); } } 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->flags |= ASSOC_DELETEFADEDOUT; ped->ClearAttack(); return; } - if (attackAssoc) - { - if (currentWeapon->m_AnimToPlay == ASSOCGRP_THROW) - { - if ((attackAssoc->animId == ANIM_THROWABLE_THROW || attackAssoc->animId == ANIM_THROWABLE_THROWU) && ped->GetWeapon()->m_nAmmoTotal > 0) - { + if (attackAssoc) { + if (currentWeapon->m_AnimToPlay == ASSOCGRP_THROW) { + if ((attackAssoc->animId == ANIM_THROWABLE_THROW || attackAssoc->animId == ANIM_THROWABLE_THROWU) && ped->GetWeapon()->m_nAmmoTotal > 0) { ped->RemoveWeaponModel(currentWeapon->m_nModelId); ped->AddWeaponModel(currentWeapon->m_nModelId); } @@ -1661,7 +1656,6 @@ CPed::ClearDuck(bool clearTimer) if (!animAssoc) { animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_LOW); } - if (!animAssoc) { animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH); } @@ -4075,7 +4069,8 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi bool willLinger = false; int random; - // TODO(Miami): PlayerInfo thingies here + if (damagedBy == FindPlayerPed() && damagedBy != this && damage > 3.0f) + ++CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel; if (player == this) { if (!player->m_bCanBeDamaged) @@ -4541,11 +4536,11 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi m_pMyVehicle->SetStatus(STATUS_ABANDONED); } SetDie(dieAnim, dieDelta, dieSpeed); - /* + if (damagedBy == FindPlayerPed() && damagedBy != this) { - // TODO(Miami): PlayerInfo stuff + CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 10; + CWorld::Players[CWorld::PlayerInFocus].m_fMediaAttention += 5.f; } - */ } } for (int i = 0; i < ARRAY_SIZE(pVehicle->pPassengers); i++) { @@ -4581,9 +4576,9 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi SetDie(dieAnim, dieDelta, dieSpeed); if (damagedBy == player || damagedBy && damagedBy == FindPlayerVehicle()) { - - // TODO(Miami): PlayerInfo stuff CDarkel::RegisterKillByPlayer(this, method, headShot); + CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 10; + CWorld::Players[CWorld::PlayerInFocus].m_fMediaAttention += 5.f; m_threatEntity = player; } else { CDarkel::RegisterKillNotByPlayer(this, method); @@ -6808,30 +6803,6 @@ CPed::Die(void) // 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 bool CPed::DuckAndCover(void) @@ -11421,14 +11392,6 @@ CPed::ProcessControl(void) if (m_nWaitState != WAITSTATE_FALSE) Wait(); - if (m_nPedState != PED_IDLE) { - CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_ARMED); - if(idleAssoc) { - idleAssoc->blendDelta = -8.0f; - idleAssoc->flags |= ASSOC_DELETEFADEDOUT; - } - } - switch (m_nPedState) { case PED_IDLE: Idle(); diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 1eb28239..e1795f55 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -778,7 +778,6 @@ public: void SetChat(CEntity*, uint32); void DeadPedMakesTyresBloody(void); void MakeTyresMuddySectorList(CPtrList&); - uint8 DoesLOSBulletHitPed(CColPoint &point); bool DuckAndCover(void); void EndFight(uint8); void EnterCar(void); diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index ee6891c7..887ebc11 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -330,6 +330,8 @@ CPlayerPed::SetRealMoveAnim(void) curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED); if (!curIdleAssoc) curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE); + if (!curIdleAssoc) + curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD); if ((!curRunStopAssoc || !(curRunStopAssoc->IsRunning())) && (!curRunStopRAssoc || !(curRunStopRAssoc->IsRunning()))) { @@ -346,7 +348,7 @@ CPlayerPed::SetRealMoveAnim(void) RestoreHeadingRate(); if (!curIdleAssoc) { - if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, + if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, nil, true, false, false, false, false, false)) { curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 8.0f); @@ -360,7 +362,7 @@ CPlayerPed::SetRealMoveAnim(void) } else if (m_fMoveSpeed == 0.0f && !curSprintAssoc) { if (!curIdleAssoc) { - if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, + if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, nil, true, false, false, false, false, false)) { curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f); @@ -371,11 +373,11 @@ CPlayerPed::SetRealMoveAnim(void) m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2500, 4000); } - if (m_fCurrentStamina > 0.0f && curIdleAssoc->animId == ANIM_IDLE_TIRED) { + if ((m_fCurrentStamina > 0.0f || bIsAimingGun) && curIdleAssoc->animId == ANIM_IDLE_TIRED) { CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f); } else if (m_nPedState != PED_FIGHT) { - if (m_fCurrentStamina < 0.0f && curIdleAssoc->animId != ANIM_IDLE_TIRED + if (m_fCurrentStamina < 0.0f && !bIsAimingGun && curIdleAssoc->animId != ANIM_IDLE_TIRED && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, nil, true, false, false, false, false, false)) { CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f); @@ -400,7 +402,10 @@ CPlayerPed::SetRealMoveAnim(void) delete curIdleAssoc; 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; curSprintAssoc = nil; @@ -569,6 +574,7 @@ CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed) if (distVec.Magnitude() > CWeaponInfo::GetWeaponInfo(weaponUsed->m_eWeaponType)->m_fRange) return true; +/* if (weaponUsed->m_eWeaponType != WEAPONTYPE_SHOTGUN && weaponUsed->m_eWeaponType != WEAPONTYPE_RUGER) return false; @@ -576,7 +582,7 @@ CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed) if (DotProduct(distVec,GetForward()) < 0.4f) return true; - +*/ return false; } @@ -617,21 +623,38 @@ CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect) return false; } +// --MIAMI: Done void CPlayerPed::PlayerControlSniper(CPad *padUsed) { ProcessWeaponSwitch(padUsed); TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f; - if (!padUsed->GetTarget()) { + 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() && !m_attachedTo) { RestorePreviousState(); TheCamera.ClearPlayerWeaponMode(); } - if (padUsed->WeaponJustDown()) { + int firingRate = GetWeapon()->m_eWeaponType == WEAPONTYPE_LASERSCOPE ? 333 : 266; + if (padUsed->WeaponJustDown() && CTimer::GetTimeInMilliseconds() > GetWeapon()->m_nTimer) { CVector firePos(0.0f, 0.0f, 0.6f); firePos = GetMatrix() * firePos; GetWeapon()->Fire(this, &firePos); + m_nPadDownPressedInMilliseconds = CTimer::GetTimeInMilliseconds(); + } else if (CTimer::GetTimeInMilliseconds() > m_nPadDownPressedInMilliseconds + firingRate && + CTimer::GetTimeInMilliseconds() - CTimer::GetTimeStepInMilliseconds() < m_nPadDownPressedInMilliseconds + firingRate && padUsed->GetWeapon()) { + + if (GetWeapon()->m_nAmmoTotal > 0) { + DMAudio.PlayFrontEndSound(SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType); + } } GetWeapon()->Update(m_audioEntityId, nil); } @@ -724,21 +747,39 @@ switchDetectDone: } } +// --MIAMI: Done void CPlayerPed::PlayerControlM16(CPad *padUsed) { ProcessWeaponSwitch(padUsed); 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()) { RestorePreviousState(); TheCamera.ClearPlayerWeaponMode(); } - if (padUsed->GetWeapon()) { - CVector firePos(0.0f, 0.0f, 0.6f); - firePos = GetMatrix() * firePos; - GetWeapon()->Fire(this, &firePos); + if (padUsed->GetWeapon() && CTimer::GetTimeInMilliseconds() > GetWeapon()->m_nTimer) { + if (GetWeapon()->m_eWeaponState == WEAPONSTATE_OUT_OF_AMMO) { + DMAudio.PlayFrontEndSound(SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM, 0.f); + GetWeapon()->m_nTimer = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nFiringRate + CTimer::GetTimeInMilliseconds(); + } else { + CVector firePos(0.0f, 0.0f, 0.6f); + firePos = GetMatrix() * firePos; + GetWeapon()->Fire(this, &firePos); + m_nPadDownPressedInMilliseconds = CTimer::GetTimeInMilliseconds(); + } + } else if (CTimer::GetTimeInMilliseconds() > GetWeapon()->m_nTimer && + CTimer::GetTimeInMilliseconds() - CTimer::GetTimeStepInMilliseconds() < GetWeapon()->m_nTimer && GetWeapon()->m_eWeaponState != WEAPONSTATE_OUT_OF_AMMO) { + DMAudio.PlayFrontEndSound(SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType); } GetWeapon()->Update(m_audioEntityId, nil); } @@ -803,6 +844,12 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed) m_fMoveSpeed = 0.0f; } } + + if (m_nPedState == PED_ANSWER_MOBILE) { + SetRealMoveAnim(); + return; + } + if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) && padUsed->GetSprint()) { m_nMoveState = PEDMOVE_SPRINT; @@ -1084,7 +1131,7 @@ CPlayerPed::ProcessAnimGroups(void) } } -// TODO(Miami): Hella TODO +// TODO(Miami) void CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) { @@ -1094,38 +1141,64 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) CWeaponEffects::ClearCrossHair(); 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 (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER || - GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_M4 || - GetWeapon()->m_eWeaponType == WEAPONTYPE_RUGER) { - if (padUsed->TargetJustDown()/* || TheCamera.m_bAllow1rstPersonWeaponsCamera */) { // TODO(Miami): Cam - SetStoredState(); - m_nPedState = PED_SNIPER_MODE; + eWeaponType weapon = GetWeapon()->m_eWeaponType; + if (weapon == WEAPONTYPE_ROCKETLAUNCHER || weapon == WEAPONTYPE_SNIPERRIFLE || + weapon == WEAPONTYPE_LASERSCOPE || weapon == WEAPONTYPE_M4 || + weapon == WEAPONTYPE_RUGER || weapon == WEAPONTYPE_M60 || + weapon == WEAPONTYPE_CAMERA) { + + if (padUsed->TargetJustDown() || TheCamera.m_bJustJumpedOutOf1stPersonBecauseOfTarget) { #ifdef FREE_CAM if (CCamera::bFreeCam && TheCamera.Cams[0].Using3rdPersonMouseCam()) { m_fRotationCur = CGeneral::LimitRadianAngle(-TheCamera.Orientation); SetHeading(m_fRotationCur); } #endif - if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) + if (weapon == WEAPONTYPE_ROCKETLAUNCHER) 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); + else if (weapon == WEAPONTYPE_CAMERA) + TheCamera.SetNewPlayerWeaponMode(CCam::MODE_CAMERA, 0, 0); else TheCamera.SetNewPlayerWeaponMode(CCam::MODE_M16_1STPERSON, 0, 0); m_fMoveSpeed = 0.0f; CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_STANCE, 1000.0f); - } - if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER || GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE - || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON) + SetPedState(PED_SNIPER_MODE); return; + } + if (!TheCamera.Using1stPersonWeaponMode()) + if (weapon == WEAPONTYPE_ROCKETLAUNCHER || weapon == WEAPONTYPE_SNIPERRIFLE || weapon == WEAPONTYPE_LASERSCOPE || weapon == WEAPONTYPE_CAMERA) + return; } } if (padUsed->GetWeapon() && m_nMoveState != PEDMOVE_SPRINT) { if (m_nSelectedWepSlot == m_currentWeapon) { if (m_pPointGunAt) { + if (m_nPedState == PED_ATTACK) { + m_fAttackButtonCounter *= Pow(0.94f, CTimer::GetTimeStep()); + } else { + m_fAttackButtonCounter = 0.0f; + } #ifdef FREE_CAM if (CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE && m_fMoveSpeed < 1.0f) StartFightAttack(padUsed->GetWeapon()); @@ -1220,7 +1293,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) } #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) { // what?? if (!m_pPointGunAt @@ -1228,15 +1301,26 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) || (!CCamera::bFreeCam && CCamera::m_bUseMouse3rdPerson) #else || CCamera::m_bUseMouse3rdPerson -#endif - || m_pPointGunAt->IsPed() && ((CPed*)m_pPointGunAt)->bInVehicle) { +#endif + ) { ClearWeaponTarget(); 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(); return; } + if (CPlayerPed::DoesTargetHaveToBeBroken(m_pPointGunAt->GetPosition(), GetWeapon()) || + (!bCanPointGunAtTarget && !weaponInfo->m_bCanAimWithArm)) { + ClearWeaponTarget(); + return; + } + + // TODO(Miami): RotatePlayerToTrackTarget + if (m_pPointGunAt) { if (padUsed->ShiftTargetLeftJustDown()) FindNextWeaponLockOnTarget(m_pPointGunAt, true); @@ -1247,11 +1331,11 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed) TheCamera.UpdateAimingCoors(m_pPointGunAt->GetPosition()); } #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 if (weaponInfo->m_bCanAim && !CCamera::m_bUseMouse3rdPerson) { + else if (!CCamera::m_bUseMouse3rdPerson) { #endif - if (padUsed->TargetJustDown()/* || TheCamera.m_bAllow1rstPersonWeaponsCamera */) // TODO(Miami): Cam + if (padUsed->TargetJustDown() || TheCamera.m_bJustJumpedOutOf1stPersonBecauseOfTarget) FindWeaponLockOnTarget(); } } else if (m_pPointGunAt) { @@ -1330,9 +1414,16 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed) } } + if (m_nPedState == PED_ANSWER_MOBILE) { + SetRealMoveAnim(); + return; + } + if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) && padUsed->GetSprint()) { - m_nMoveState = PEDMOVE_SPRINT; + + if (!m_pCurrentPhysSurface || !m_pCurrentPhysSurface->bInfiniteMass || m_pCurrentPhysSurface->m_phy_flagA08) + m_nMoveState = PEDMOVE_SPRINT; } if (m_nPedState != PED_FIGHT) SetRealMoveAnim(); @@ -1424,11 +1515,11 @@ CPlayerPed::ProcessControl(void) m_nMoveState = PEDMOVE_STILL; if (bIsLanding) RunningLand(padUsed); - if (padUsed && padUsed->WeaponJustDown() && m_nPedState != PED_SNIPER_MODE) { + if (padUsed && padUsed->WeaponJustDown() && !TheCamera.Using1stPersonWeaponMode()) { // ...Really? eWeaponType playerWeapon = FindPlayerPed()->GetWeapon()->m_eWeaponType; - if (playerWeapon == WEAPONTYPE_SNIPERRIFLE) { + if (playerWeapon == WEAPONTYPE_SNIPERRIFLE || playerWeapon == WEAPONTYPE_LASERSCOPE) { DMAudio.PlayFrontEndSound(SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM, 0); } else if (playerWeapon == WEAPONTYPE_ROCKETLAUNCHER) { DMAudio.PlayFrontEndSound(SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM, 0); @@ -1443,8 +1534,12 @@ CPlayerPed::ProcessControl(void) case PED_ATTACK: case PED_FIGHT: case PED_AIM_GUN: - if (!RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_BLOCK)) { - if (TheCamera.Cams[0].Using3rdPersonMouseCam()) { + case PED_ANSWER_MOBILE: + if (!RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_BLOCK) && !m_attachedTo) { + if (TheCamera.Using1stPersonWeaponMode()) { + if (padUsed) + PlayerControlFighter(padUsed); + } else if (TheCamera.Cams[0].Using3rdPersonMouseCam()) { if (padUsed) PlayerControl1stPersonRunAround(padUsed); } else if (m_nPedState == PED_FIGHT) { @@ -1454,7 +1549,7 @@ CPlayerPed::ProcessControl(void) PlayerControlZelda(padUsed); } } - if (IsPedInControl() && padUsed) + if (IsPedInControl() && m_nPedState != PED_ANSWER_MOBILE && padUsed) ProcessPlayerWeapon(padUsed); break; case PED_LOOK_ENTITY: @@ -1478,8 +1573,13 @@ CPlayerPed::ProcessControl(void) case PED_INVESTIGATE: case PED_STEP_AWAY: case PED_ON_FIRE: + case PED_SUN_BATHE: + case PED_FLASH: + case PED_JOG: case PED_UNKNOWN: case PED_STATES_NO_AI: + case PED_ABSEIL: + case PED_SIT: case PED_STAGGER: case PED_DIVE_AWAY: case PED_STATES_NO_ST: @@ -1518,11 +1618,11 @@ CPlayerPed::ProcessControl(void) } break; case PED_SNIPER_MODE: - if (FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_M4) { + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_LASERSCOPE) { if (padUsed) - PlayerControlM16(padUsed); + PlayerControlSniper(padUsed); } else if (padUsed) { - PlayerControlSniper(padUsed); + PlayerControlM16(padUsed); } break; case PED_SEEK_CAR: @@ -1571,7 +1671,7 @@ CPlayerPed::ProcessControl(void) BeingDraggedFromCar(); break; } - if (padUsed && IsPedShootable()) { + if (padUsed && IsPedShootable() && m_nPedState != PED_ANSWER_MOBILE && m_nLastPedState != PED_ANSWER_MOBILE) { ProcessWeaponSwitch(padUsed); GetWeapon()->Update(m_audioEntityId, this); } @@ -1622,6 +1722,9 @@ CPlayerPed::ProcessControl(void) m_bSpeedTimerFlag = false; } + if (m_nPedState != PED_SNIPER_MODE && (GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING || m_nPedState == PED_ATTACK)) + m_nPadDownPressedInMilliseconds = CTimer::GetTimeInMilliseconds(); + #ifdef PED_SKIN if (!bIsVisible && IsClumpSkinned(GetClump())) UpdateRpHAnim(); diff --git a/src/weapons/BulletInfo.cpp b/src/weapons/BulletInfo.cpp index 26fc459d..129e4b2b 100644 --- a/src/weapons/BulletInfo.cpp +++ b/src/weapons/BulletInfo.cpp @@ -76,7 +76,6 @@ bool CBulletInfo::AddBullet(CEntity* pSource, eWeaponType type, CVector vecPosit void CBulletInfo::Update(void) { - bool bAddSound = true; bPlayerSniperBullet = false; for (int i = 0; i < NUM_BULLETS; i++) { CBulletInfo* pBullet = &gaBulletInfo[i]; @@ -93,26 +92,23 @@ void CBulletInfo::Update(void) CWorld::pIgnoreEntity = pBullet->m_pSource; CColPoint point; 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())) CStats::InstantHitsHitByPlayer++; + + CWeapon::CheckForShootingVehicleOccupant(&pHitEntity, &point, pBullet->m_eWeaponType, vecOldPos, vecNewPos); if (pHitEntity->IsPed()) { CPed* pPed = (CPed*)pHitEntity; if (!pPed->DyingOrDead() && pPed != pBullet->m_pSource) { - if (pPed->DoesLOSBulletHitPed(point)) { - if (pPed->IsPedInControl() && !pPed->bIsDucking) { - pPed->ClearAttackByRemovingAnim(); - CAnimBlendAssociation* pAnim = CAnimManager::AddAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_SHOT_FRONT_PARTIAL); - pAnim->SetBlend(0.0f, 8.0f); - } - pPed->InflictDamage(pBullet->m_pSource, pBullet->m_eWeaponType, pBullet->m_nDamage, (ePedPieceTypes)point.pieceB, pPed->GetLocalDirection(pPed->GetPosition() - point.point)); - CEventList::RegisterEvent(pPed->m_nPedType == PEDTYPE_COP ? EVENT_SHOOT_COP : EVENT_SHOOT_PED, EVENT_ENTITY_PED, pPed, (CPed*)pBullet->m_pSource, 1000); - pBullet->m_bInUse = false; - vecNewPos = point.point; - } - else { - bAddSound = false; + if (pPed->IsPedInControl() && !pPed->bIsDucking) { + pPed->ClearAttackByRemovingAnim(); + CAnimBlendAssociation* pAnim = CAnimManager::AddAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_SHOT_FRONT_PARTIAL); + pAnim->SetBlend(0.0f, 8.0f); } + pPed->InflictDamage(pBullet->m_pSource, pBullet->m_eWeaponType, pBullet->m_nDamage, (ePedPieceTypes)point.pieceB, pPed->GetLocalDirection(pPed->GetPosition() - point.point)); + CEventList::RegisterEvent(pPed->m_nPedType == PEDTYPE_COP ? EVENT_SHOOT_COP : EVENT_SHOOT_PED, EVENT_ENTITY_PED, pPed, (CPed*)pBullet->m_pSource, 1000); + pBullet->m_bInUse = false; + vecNewPos = point.point; } if (CGame::nastyGame) { CVector vecParticleDirection = (point.point - pPed->GetPosition()) * 0.01f; @@ -170,7 +166,7 @@ void CBulletInfo::Update(void) vecNewPos = point.point; #endif } - if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE && bAddSound) { + if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || pBullet->m_eWeaponType == WEAPONTYPE_LASERSCOPE) { cAudioScriptObject* pAudio; switch (pHitEntity->GetType()) { case ENTITY_TYPE_BUILDING: @@ -210,7 +206,7 @@ void CBulletInfo::Update(void) CWorld::pIgnoreEntity = nil; CWorld::bIncludeDeadPeds = false; CWorld::bIncludeCarTyres = false; - if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE) { + if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || pBullet->m_eWeaponType == WEAPONTYPE_LASERSCOPE) { bPlayerSniperBullet = true; PlayerSniperBulletStart = pBullet->m_vecPosition; PlayerSniperBulletEnd = vecNewPos; diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index e8c5c3d1..a895315e 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -194,8 +194,12 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource) if ( GetInfo()->m_eWeaponFire != WEAPON_FIRE_MELEE ) { - if ( m_nAmmoInClip <= 0 ) - return false; + if (m_nAmmoInClip <= 0) { + if (m_nAmmoTotal <= 0 || m_eWeaponState == WEAPONSTATE_RELOADING) + return false; + + Reload(); + } switch ( m_eWeaponType ) { @@ -223,10 +227,10 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource) { if ((TheCamera.PlayerWeaponMode.Mode == CCam::MODE_HELICANNON_1STPERSON || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON) && shooter == FindPlayerPed()) { - addFireRateAsDelay = false; + addFireRateAsDelay = true; fired = FireM16_1stPerson(shooter); } else { - addFireRateAsDelay = true; + addFireRateAsDelay = false; fired = FireInstantHit(shooter, source); } break; @@ -235,8 +239,11 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource) case WEAPONTYPE_SNIPERRIFLE: case WEAPONTYPE_LASERSCOPE: { - fired = FireSniper(shooter); - + if (shooter == FindPlayerPed()) { + fired = FireSniper(shooter); + } else { + fired = FireInstantHit(shooter, source); + } break; } @@ -339,8 +346,12 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource) if (m_nAmmoInClip == 0) { - if (m_nAmmoTotal == 0) + if (m_nAmmoTotal == 0) { + if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_CAMERA) + CPad::GetPad(0)->Clear(false); + return true; + } m_eWeaponState = WEAPONSTATE_RELOADING; m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload; @@ -386,6 +397,7 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource) return fired; } +// --MIAMI: Done bool CWeapon::FireFromCar(CVehicle *shooter, bool left, bool right) { @@ -401,8 +413,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 +433,6 @@ CWeapon::FireFromCar(CVehicle *shooter, bool left, bool right) } m_nTimer = CTimer::GetTimeInMilliseconds() + 1000; - if ( shooter == FindPlayerVehicle() ) - CStats::RoundsFiredByPlayer++; } return true; @@ -898,18 +911,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; @@ -1025,7 +1037,7 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) { static uint8 counter = 0; - if ( info->m_nFiringRate >= 50 && !(++counter & 1) ) + if ( info->m_nFiringRate >= 50 || !(++counter & 1) ) { AddGunFlashBigGuns(*fireSource, *fireSource + target); @@ -1579,12 +1591,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 +2086,7 @@ CWeapon::FireSniper(CEntity *shooter) return true; } -// --MIAMI: Heavily TODO +// --MIAMI: Done bool CWeapon::FireM16_1stPerson(CEntity *shooter) { @@ -2096,10 +2108,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 +2123,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 +2146,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 +2168,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; @@ -2573,9 +2597,10 @@ CWeapon::Update(int32 audioEntity, CPed *pedToAdjustSound) if ( CTimer::GetTimeInMilliseconds() > m_nTimer ) { - if ( GetInfo()->m_eWeaponFire != WEAPON_FIRE_MELEE && m_nAmmoTotal == 0 ) + if ( GetInfo()->m_eWeaponFire != WEAPON_FIRE_MELEE && m_nAmmoTotal == 0 ) { m_eWeaponState = WEAPONSTATE_OUT_OF_AMMO; - else + // TODO(Miami): CPickups::RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo + } else m_eWeaponState = WEAPONSTATE_READY; } @@ -2957,6 +2982,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)); diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h index 5c56d9e4..cb59582f 100644 --- a/src/weapons/Weapon.h +++ b/src/weapons/Weapon.h @@ -72,8 +72,11 @@ public: 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&); + #ifdef COMPATIBLE_SAVES void Save(uint8*& buf); void Load(uint8*& buf); |