From c6bb1f5d0d70f24f02fd5967f2732c7e8be3781a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Tue, 16 Jun 2020 01:38:26 +0300 Subject: [PATCH] some cutscene opcodes and heli guns --- src/animation/CutsceneMgr.cpp | 25 ++++- src/animation/CutsceneMgr.h | 3 + src/control/Pickups.cpp | 70 +++++++----- src/control/Script.cpp | 24 ++-- src/vehicles/Automobile.h | 4 +- src/weapons/Weapon.cpp | 206 +++++++++++++++++++++++++--------- src/weapons/Weapon.h | 4 +- 7 files changed, 237 insertions(+), 99 deletions(-) diff --git a/src/animation/CutsceneMgr.cpp b/src/animation/CutsceneMgr.cpp index 8f2a9892..5cd82f6c 100644 --- a/src/animation/CutsceneMgr.cpp +++ b/src/animation/CutsceneMgr.cpp @@ -123,6 +123,7 @@ char CCutsceneMgr::ms_cutsceneName[CUTSCENENAMESIZE]; CAnimBlendAssocGroup CCutsceneMgr::ms_cutsceneAssociations; CVector CCutsceneMgr::ms_cutsceneOffset; float CCutsceneMgr::ms_cutsceneTimer; +bool CCutsceneMgr::ms_wasCutsceneSkipped; uint32 CCutsceneMgr::ms_cutsceneLoadStatus; RpAtomic * @@ -145,6 +146,7 @@ CCutsceneMgr::Initialise(void) { ms_numCutsceneObjs = 0; ms_loaded = false; + ms_wasCutsceneSkipped = false; ms_running = false; ms_animLoaded = false; ms_cutsceneProcessing = false; @@ -169,9 +171,10 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName) CPlayerPed *pPlayerPed; ms_cutsceneProcessing = true; + ms_wasCutsceneSkipped = false; if (!strcasecmp(szCutsceneName, "jb")) ms_useLodMultiplier = true; - CTimer::Stop(); + CTimer::Suspend(); ms_pCutsceneDir->numEntries = 0; ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR"); @@ -225,18 +228,19 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName) ms_cutsceneOffset = CVector(0.0f, 0.0f, 0.0f); pPlayerPed = FindPlayerPed(); - CTimer::Update(); - pPlayerPed->m_pWanted->ClearQdCrimes(); pPlayerPed->bIsVisible = false; pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina; CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80; CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(true); + + CTimer::Resume(); } void CCutsceneMgr::FinishCutscene() { + ms_wasCutsceneSkipped = true; CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f; TheCamera.FinishCutscene(); @@ -258,11 +262,14 @@ CCutsceneMgr::SetupCutsceneToStart(void) if (CAnimBlendAssociation *pAnimBlendAssoc = RpAnimBlendClumpGetFirstAssociation((RpClump*)ms_pCutsceneObjects[i]->m_rwObject)) { assert(pAnimBlendAssoc->hierarchy->sequences[0].HasTranslation()); ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0))->translation); - CWorld::Add(ms_pCutsceneObjects[i]); pAnimBlendAssoc->SetRun(); } else { ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset); } + CWorld::Add(ms_pCutsceneObjects[i]); + if (RwObjectGetType(ms_pCutsceneObjects[i]->m_rwObject) == rpCLUMP) { + ms_pCutsceneObjects[i]->UpdateRpHAnim(); + } } CTimer::Update(); @@ -289,6 +296,12 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject) pAnimBlendClumpData->link.Prepend(&pNewAnim->link); } +void +CCutsceneMgr::SetCutsceneAnimToLoop(const char* animName) +{ + ms_cutsceneAssociations.GetAnimation(animName)->flags |= ASSOC_REPEAT; +} + CCutsceneHead * CCutsceneMgr::AddCutsceneHead(CObject *pObject, int modelId) { @@ -329,6 +342,7 @@ void CCutsceneMgr::DeleteCutsceneData(void) { if (!ms_loaded) return; + CTimer::Suspend(); ms_cutsceneProcessing = false; ms_useLodMultiplier = false; @@ -359,9 +373,8 @@ CCutsceneMgr::DeleteCutsceneData(void) if (CGeneral::faststricmp(ms_cutsceneName, "bet")) DMAudio.ChangeMusicMode(MUSICMODE_GAME); } - CTimer::Stop(); CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == 2); - CTimer::Update(); + CTimer::Resume(); } void diff --git a/src/animation/CutsceneMgr.h b/src/animation/CutsceneMgr.h index 18eff0e5..97093fb1 100644 --- a/src/animation/CutsceneMgr.h +++ b/src/animation/CutsceneMgr.h @@ -21,6 +21,7 @@ class CCutsceneMgr static CAnimBlendAssocGroup ms_cutsceneAssociations; static CVector ms_cutsceneOffset; static float ms_cutsceneTimer; + static bool ms_wasCutsceneSkipped; static bool ms_cutsceneProcessing; public: static CDirectory *ms_pCutsceneDir; @@ -30,6 +31,7 @@ public: static bool IsRunning(void) { return ms_running; } static bool HasLoaded(void) { return ms_loaded; } static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; } + static bool WasCutsceneSkipped(void) { return ms_wasCutsceneSkipped; } static bool UseLodMultiplier(void) { return ms_useLodMultiplier; } static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; } static int GetCutsceneTimeInMilleseconds(void) { return 1000.0f * ms_cutsceneTimer; } @@ -43,6 +45,7 @@ public: static void FinishCutscene(void); static void SetupCutsceneToStart(void); static void SetCutsceneAnim(const char *animName, CObject *pObject); + static void SetCutsceneAnimToLoop(const char *animName); static CCutsceneHead *AddCutsceneHead(CObject *pObject, int modelId); static CCutsceneObject *CreateCutsceneObject(int modelId); static void DeleteCutsceneData(void); diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index 1ab09d52..1db6dfa2 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -699,41 +699,51 @@ CPickups::DoPickUpEffects(CEntity *entity) int16 colorId; + bool doInnerGlow = false; + bool doOuterGlow = true; - if (entity->GetModelIndex() == MI_PICKUP_ADRENALINE || entity->GetModelIndex() == MI_PICKUP_CAMERA) + if (entity->GetModelIndex() == MI_PICKUP_ADRENALINE || entity->GetModelIndex() == MI_PICKUP_CAMERA) { colorId = WEAPONTYPE_TOTALWEAPONS; - else if (entity->GetModelIndex() == MI_PICKUP_BODYARMOUR || entity->GetModelIndex() == MI_PICKUP_BRIBE) + doInnerGlow = true; + doOuterGlow = false; + } else if (entity->GetModelIndex() == MI_PICKUP_BODYARMOUR) { colorId = WEAPONTYPE_TOTALWEAPONS + 1; - else if (entity->GetModelIndex() == MI_PICKUP_INFO || entity->GetModelIndex() == MI_PICKUP_KILLFRENZY) + } else if (entity->GetModelIndex() == MI_PICKUP_BRIBE) { + doInnerGlow = true; + doOuterGlow = false; + } else if (entity->GetModelIndex() == MI_PICKUP_INFO || entity->GetModelIndex() == MI_PICKUP_KILLFRENZY) { colorId = WEAPONTYPE_TOTALWEAPONS + 2; - else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS) - colorId = WEAPONTYPE_TOTALWEAPONS + 3; - else + doInnerGlow = true; + doOuterGlow = false; + } else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS) { + colorId = WEAPONTYPE_TOTALWEAPONS; + doInnerGlow = true; + doOuterGlow = false; + } else colorId = WeaponForModel(entity->GetModelIndex()); - assert(colorId >= 0); + const CVector& pos = entity->GetPosition(); + if (doOuterGlow) { + float colorModifier = ((CGeneral::GetRandomNumber() & 0x1F) * 0.015f + 1.0f) * modifiedSin * 0.15f; + CShadows::StoreStaticShadow( + (uintptr)entity, + SHADOWTYPE_ADDITIVE, + gpShadowExplosionTex, + &pos, + 2.0f, 0.0f, 0.0f, -2.0f, + 255, // this is 0 on PC which results in no shadow + aWeaponReds[colorId] * colorModifier, aWeaponGreens[colorId] * colorModifier, aWeaponBlues[colorId] * colorModifier, + 4.0f, 1.0f, 40.0f, false, 0.0f); - const CVector &pos = entity->GetPosition(); - - float colorModifier = ((CGeneral::GetRandomNumber() & 0x1F) * 0.015f + 1.0f) * modifiedSin * 0.15f; - CShadows::StoreStaticShadow( - (uintptr)entity, - SHADOWTYPE_ADDITIVE, - gpShadowExplosionTex, - &pos, - 2.0f, 0.0f, 0.0f, -2.0f, - 255, // this is 0 on PC which results in no shadow - aWeaponReds[colorId] * colorModifier, aWeaponGreens[colorId] * colorModifier, aWeaponBlues[colorId] * colorModifier, - 4.0f, 1.0f, 40.0f, false, 0.0f); - - float radius = (CGeneral::GetRandomNumber() & 0xF) * 0.1f + 3.0f; - CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f), radius, aWeaponReds[colorId] * modifiedSin / 256.0f, aWeaponGreens[colorId] * modifiedSin / 256.0f, aWeaponBlues[colorId] * modifiedSin / 256.0f, CPointLights::FOG_NONE, true); - float size = (CGeneral::GetRandomNumber() & 0xF) * 0.0005f + 0.6f; - CCoronas::RegisterCorona( (uintptr)entity, - aWeaponReds[colorId] * modifiedSin / 2.0f, aWeaponGreens[colorId] * modifiedSin / 2.0f, aWeaponBlues[colorId] * modifiedSin / 2.0f, - 255, - pos, - size, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + float radius = (CGeneral::GetRandomNumber() & 0xF) * 0.1f + 3.0f; + CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f), radius, aWeaponReds[colorId] * modifiedSin / 256.0f, aWeaponGreens[colorId] * modifiedSin / 256.0f, aWeaponBlues[colorId] * modifiedSin / 256.0f, CPointLights::FOG_NONE, true); + float size = (CGeneral::GetRandomNumber() & 0xF) * 0.0005f + 0.6f; + CCoronas::RegisterCorona((uintptr)entity, + aWeaponReds[colorId] * modifiedSin / 2.0f, aWeaponGreens[colorId] * modifiedSin / 2.0f, aWeaponBlues[colorId] * modifiedSin / 2.0f, + 255, + pos, + size, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + } CObject *object = (CObject*)entity; if (object->bPickupObjWithMessage || object->bOutOfStock || object->m_nBonusValue) { @@ -761,6 +771,10 @@ CPickups::DoPickUpEffects(CEntity *entity) } entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), aWeaponScale[colorId]); + + if (doInnerGlow) + CCoronas::RegisterCorona((uintptr)entity + 1, 126, 69, 121, 255, entity->GetPosition(), 1.2f, 50.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.f, false); } } diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 957815fe..b1cf44c6 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -9996,7 +9996,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) continue; if (pPed->CharCreatedBy != RANDOM_CHAR) continue; - if (!pPed->IsPedInControl() && pPed->GetPedState() != PED_DRIVING /* && pPed->GetPedState() != PED_ONROPE */) // TODO(MIAMI)! + if (!pPed->IsPedInControl() && pPed->GetPedState() != PED_DRIVING && pPed->GetPedState() != PED_ABSEIL) continue; if (pPed->bRemoveFromWorld) continue; @@ -10640,7 +10640,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) char key[KEY_LENGTH_IN_SCRIPT]; CTheScripts::ReadTextLabelFromScript(&m_nIp, key); m_nIp += KEY_LENGTH_IN_SCRIPT; - debug("SET_CUTSCENE_ANIM_TO_LOOP not implemented yet, skipping\n"); + CCutsceneMgr::SetCutsceneAnimToLoop(key); return 0; } case COMMAND_MARK_CAR_AS_CONVOY_CAR: @@ -11339,6 +11339,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) { CollectParameters(&m_nIp, 2); debug("ATTACH_CUTSCENE_OBJECT_TO_COMPONENT not implemented, skipping\n"); // TODO(MIAMI) + m_nIp += KEY_LENGTH_IN_SCRIPT; return 0; } case COMMAND_SET_CHAR_STAY_IN_CAR_WHEN_JACKED: @@ -11464,7 +11465,15 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) case COMMAND_FIRE_HUNTER_GUN: { CollectParameters(&m_nIp, 1); - debug("FIRE_HUNTER_GUN is not implemented, skipping\n"); // TODO(MIAMI) + CVehicle *pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + if (CTimer::GetTimeInMilliseconds() > pVehicle->m_nGunFiringTime + 150) { + CWeapon gun(WEAPONTYPE_HELICANNON, 5000); + CVector worldGunPos = (pVehicle->GetMatrix() * vecHunterGunPos) + (CTimer::GetTimeStep() * pVehicle->m_vecMoveSpeed); + gun.FireInstantHit(pVehicle, &worldGunPos); + gun.AddGunshell(pVehicle, worldGunPos, CVector2D(0.f, 0.1f), 0.025f); + DMAudio.PlayOneShot(pVehicle->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.f); + pVehicle->m_nGunFiringTime = CTimer::GetTimeInMilliseconds(); + } return 0; } case COMMAND_SET_PROPERTY_AS_OWNED: @@ -11704,7 +11713,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) case COMMAND_SET_CHAR_IGNORE_THREATS_BEHIND_OBJECTS: { CollectParameters(&m_nIp, 2); - CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); pPed->bIgnoreThreatsBehindObjects = ScriptParams[1]; return 0; @@ -11769,12 +11778,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) } case COMMAND_WAS_CUTSCENE_SKIPPED: { - static bool bShowed = false; - if (!bShowed) { - debug("COMMAND_WAS_CUTSCENE_SKIPPED not implemented, default to TRUE\n"); - bShowed = true; - } - UpdateCompareFlag(true); + UpdateCompareFlag(CCutsceneMgr::WasCutsceneSkipped()); return 0; } case COMMAND_SET_CHAR_CROUCH_WHEN_THREATENED: diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 6c13c117..eaceef7b 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -165,4 +165,6 @@ public: static const uint32 nSaveStructSize; static void SetAllTaxiLights(bool set); -}; \ No newline at end of file +}; + +extern CVector vecHunterGunPos; \ No newline at end of file diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index ad28cc59..f4bce9d7 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -795,6 +795,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource) return true; } +// --MIAMI: Done except comments bool CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) { @@ -842,19 +843,40 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) target = threatAttack->GetPosition(); target -= *fireSource; - target *= info->m_fRange / target.Magnitude(); + float distToTarget = target.Magnitude(); + target *= info->m_fRange / distToTarget; target += *fireSource; - if ( inaccuracy != 0 ) + if (shooter == FindPlayerPed() && inaccuracy != 0.f) { + float newInaccuracy = 2.5f * FindPlayerPed()->m_fAttackButtonCounter * (inaccuracy * Min(1.f, 5.f / distToTarget)); + if (FindPlayerPed()->bIsDucking) + newInaccuracy *= 0.4f; + + target.x += CGeneral::GetRandomNumberInRange(-0.15f, 0.15f) * newInaccuracy; + target.y += CGeneral::GetRandomNumberInRange(-0.15f, 0.15f) * newInaccuracy; + target.z += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * newInaccuracy; + FindPlayerPed()->m_fAttackButtonCounter += info->m_nDamage * 0.04f; + } + else if (inaccuracy > 0.f) + { + if (threatAttack == FindPlayerPed()) + { + float speed = Min(0.33f, FindPlayerPed()->m_vecMoveSpeed.Magnitude()); + inaccuracy *= (0.3f * speed * 100.f / 33.f + 0.8f); + } target.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracy; target.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracy; target.z += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * inaccuracy; } - CWorld::bIncludeDeadPeds = true; - ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false); + if (shooter == FindPlayerPed()) + CWorld::bIncludeDeadPeds = true; + + // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami) + CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true); CWorld::bIncludeDeadPeds = false; + // bProcessPedsOnBoatsAndBikes = false; // TODO(Miami) } else { @@ -864,7 +886,9 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) shooterPed->TransformToNode(target, PED_HANDR); - ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false); + // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami) + CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true); + // bProcessPedsOnBoatsAndBikes = false; // TODO(Miami) } } else if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam() ) @@ -872,9 +896,17 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) CVector src, trgt; TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, src, trgt); + // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami) CWorld::bIncludeDeadPeds = true; - ProcessLineOfSight(src, trgt,point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false); + // bProcessVehicleWheels = true; // TODO(Miami) + 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) + + // TODO(Miami) + // if (victim) + // CWeapon::CheckForShootingVehicleOccupant(v39, victim, point, m_eWeaponType, src, trgt); int32 rotSpeed = 1; if ( m_eWeaponType == WEAPONTYPE_M4 ) @@ -889,30 +921,77 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) } else { - float shooterHeading = RADTODEG(shooter->GetForward().Heading()); - float shooterAngle = DEGTORAD(shooterHeading); - - CVector2D rotOffset(-Sin(shooterAngle), Cos(shooterAngle)); - rotOffset.Normalise(); - - target = *fireSource; - target.x += rotOffset.x * info->m_fRange; - target.y += rotOffset.y * info->m_fRange; - - if ( shooter->IsPed() ) - DoDoomAiming(shooter, fireSource, &target); - - ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false); - - int32 rotSpeed = 1; - if ( m_eWeaponType == WEAPONTYPE_M4 ) - rotSpeed = 4; - - CVector bulletPos; - if ( CHeli::TestBulletCollision(fireSource, &target, &bulletPos, 4) ) + uint32 model = shooter->GetModelIndex(); + if (model == MI_HUNTER || model == MI_SEASPAR || model == MI_SPARROW) { - for ( int32 i = 0; i < 16; i++ ) - CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, rotSpeed); + float inaccuracyMult = 0.6f; + target = shooter->GetForward(); + if (shooter->GetStatus() == STATUS_PLAYER) + { + target *= info->m_fRange; + target += *fireSource; + CWeapon::DoDriveByAutoAiming(FindPlayerPed(), (CVehicle*)shooter, fireSource, &target); + target -= *fireSource; + target.Normalise(); + if (model == MI_SEASPAR || model == MI_SPARROW) + inaccuracyMult = 0.1f; + else + inaccuracyMult = 0.3f; + } + target.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracyMult; + target.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracyMult; + target.z += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * inaccuracyMult; + + target.Normalise(); + target *= info->m_fRange; + target += *fireSource; + CWorld::pIgnoreEntity = shooter; + CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true); + CWorld::pIgnoreEntity = nil; + + int32 rotSpeed = 1; + if (m_eWeaponType == WEAPONTYPE_M4) + rotSpeed = 4; + + CVector bulletPos; + if (CHeli::TestBulletCollision(fireSource, &target, &bulletPos, 4)) + { + for (int32 i = 0; i < 16; i++) + CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, rotSpeed); + } + } + else + { + float shooterHeading = RADTODEG(shooter->GetForward().Heading()); + float shooterAngle = DEGTORAD(shooterHeading); + + CVector2D rotOffset(-Sin(shooterAngle), Cos(shooterAngle)); + rotOffset.Normalise(); + + target = *fireSource; + target.x += rotOffset.x * info->m_fRange; + target.y += rotOffset.y * info->m_fRange; + + CParticle::HandleShootableBirdsStuff(shooter, *fireSource); + if (shooter->IsPed() && ((CPed*)shooter)->bDoomAim && (shooter != FindPlayerPed() || !info->m_bCanAim)) + { + CWeapon::DoDoomAiming(shooter, fireSource, &target); + } + + // CWorld::bProcessPedsOnBoatsAndBikes = 1; // TODO(Miami) + CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true); + // CWorld::bProcessPedsOnBoatsAndBikes = 0; // TODO(Miami) + + int32 rotSpeed = 1; + if (m_eWeaponType == WEAPONTYPE_M4) + rotSpeed = 4; + + CVector bulletPos; + if (CHeli::TestBulletCollision(fireSource, &target, &bulletPos, 4)) + { + for (int32 i = 0; i < 16; i++) + CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, rotSpeed); + } } } @@ -932,7 +1011,6 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) if ( shooter == FindPlayerPed() ) { - CStats::InstantHitsFiredByPlayer++; if ( !(CTimer::GetFrameCounter() & 3) ) MakePedsJumpAtShot((CPhysical*)shooter, fireSource, &target); } @@ -1345,6 +1423,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) { @@ -1438,7 +1517,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) //bProcessVehicleWheels = true; // TODO(Miami): bProcessVehicleWheels //bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes - ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false); // TODO(Miami): New parameter: ,true); + CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true); CWorld::bIncludeDeadPeds = false; //bProcessVehicleWheels = false; // TODO(Miami): bProcessVehicleWheels } @@ -1471,7 +1550,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) CWorld::bIncludeDeadPeds = true; //bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes - ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false); // TODO(Miami): New parameter: ,true); + CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true); CWorld::bIncludeDeadPeds = false; } //bProcessPedsOnBoatsAndBikes = false; // TODO(Miami): bProcessPedsOnBoatsAndBikes @@ -2056,7 +2135,7 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right) float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f, float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f); - DoDriveByAutoAiming(FindPlayerPed(), &source, &target); + DoDriveByAutoAiming(FindPlayerPed(), shooter, &source, &target); CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, FindPlayerPed(), FindPlayerPed(), 1000); @@ -2176,6 +2255,7 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right) return true; } +// --MIAMI: Done void CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target) { @@ -2188,8 +2268,6 @@ CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target) #endif CPed *shooterPed = (CPed*)shooter; - if ( shooterPed->IsPed() && shooterPed->bCrouchWhenShooting ) - return; int16 lastEntity; CEntity *entities[16]; @@ -2208,7 +2286,8 @@ CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target) if ( !(victim->GetStatus() == STATUS_TRAIN_MOVING || victim->GetStatus() == STATUS_TRAIN_NOT_MOVING || victim->GetStatus() == STATUS_HELI - || victim->GetStatus() == STATUS_PLANE) ) + || victim->GetStatus() == STATUS_PLANE + || victim->GetStatus() == STATUS_WRECKED) ) { float distToVictim = (shooterPed->GetPosition()-victim->GetPosition()).Magnitude2D(); float distToVictimZ = Abs(shooterPed->GetPosition().z-victim->GetPosition().z); @@ -2227,7 +2306,10 @@ CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target) } } - if ( closestEntityDist < DOOMAUTOAIMING_MAXDIST ) + CColPoint foundCol; + CEntity *foundEnt; + if (closestEntityDist < DOOMAUTOAIMING_MAXDIST + && !CWorld::ProcessLineOfSight(*source, entities[closestEntity]->GetPosition(), foundCol, foundEnt, true, false, false, false, false, false, false, true)) { CEntity *victim = entities[closestEntity]; ASSERT(victim !=nil); @@ -2316,10 +2398,11 @@ CWeapon::DoTankDoomAiming(CEntity *shooter, CEntity *driver, CVector *source, CV } } +// --MIAMI: Done void -CWeapon::DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target) +CWeapon::DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source, CVector *target) { - ASSERT(shooter!=nil); + ASSERT(driver!=nil); ASSERT(source!=nil); ASSERT(target!=nil); @@ -2327,27 +2410,36 @@ CWeapon::DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target) CEntity entity; // unused #endif - CPed *shooterPed = (CPed*)shooter; - if ( shooterPed->IsPed() && shooterPed->bCrouchWhenShooting ) - return; + CPed *shooterPed = (CPed*)driver; int16 lastEntity; - CEntity *entities[16]; - CWorld::FindObjectsInRange(*source, (*target-*source).Magnitude(), true, &lastEntity, 15, entities, false, false, true, false, false); + CEntity *peds[16]; + CWorld::FindObjectsInRange(*source, (*target-*source).Magnitude(), true, &lastEntity, 15, peds, false, false, true, false, false); float closestEntityDist = 10000.0f; int16 closestEntity; for ( int32 i = 0; i < lastEntity; i++ ) { - CEntity *victim = entities[i]; + CPed *victim = (CPed*)peds[i]; ASSERT(victim!=nil); - if ( shooter != victim ) + if (driver != victim && !victim->DyingOrDead() && victim->m_attachedTo != vehicle) { float lineDist = CCollision::DistToLine(source, target, &victim->GetPosition()); - float distToVictim = (victim->GetPosition() - shooter->GetPosition()).Magnitude(); - float pedDist = 0.15f*distToVictim + lineDist; + + uint32 model = vehicle->GetModelIndex(); + float pedDist; + if (model == MI_HUNTER || model == MI_SEASPAR || model == MI_SPARROW) + { + float distToVictim = (victim->GetPosition() - vehicle->GetPosition()).Magnitude(); + pedDist = lineDist / Max(5.f, distToVictim); + } + else + { + float distToVictim = (victim->GetPosition() - driver->GetPosition()).Magnitude(); + pedDist = 0.15f * distToVictim + lineDist; + } if ( DotProduct((*target-*source), victim->GetPosition()-*source) > 0.0f && pedDist < closestEntityDist) { @@ -2356,14 +2448,24 @@ CWeapon::DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target) } } } - - if ( closestEntityDist < DRIVEBYAUTOAIMING_MAXDIST ) + uint32 model = vehicle->GetModelIndex(); + float maxAimDistance = CAR_DRIVEBYAUTOAIMING_MAXDIST; + if (model == MI_HUNTER) { - CEntity *victim = entities[closestEntity]; + maxAimDistance = Tan(DEGTORAD(30.f)); + } + else if (model == MI_SEASPAR || model == MI_SPARROW) + { + maxAimDistance = Tan(DEGTORAD(10.f)); + } + + if ( closestEntityDist < maxAimDistance ) + { + CEntity *victim = peds[closestEntity]; ASSERT(victim!=nil); float distToTarget = (*source - *target).Magnitude(); - float distToSource = (*source - victim->GetPosition()).Magnitude(); + float distToSource = (*source - victim->GetPosition()).Magnitude(); *target = (distToTarget / distToSource) * (victim->GetPosition() - *source) + *source; } } diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h index cb1d9835..5c56d9e4 100644 --- a/src/weapons/Weapon.h +++ b/src/weapons/Weapon.h @@ -2,7 +2,7 @@ #include "WeaponType.h" -#define DRIVEBYAUTOAIMING_MAXDIST (2.5f) +#define CAR_DRIVEBYAUTOAIMING_MAXDIST (2.5f) #define DOOMAUTOAIMING_MAXDIST (9000.0f) class CEntity; @@ -56,7 +56,7 @@ public: static void DoDoomAiming (CEntity *shooter, CVector *source, CVector *target); static void DoTankDoomAiming (CEntity *shooter, CEntity *driver, CVector *source, CVector *target); - static void DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target); + static void DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source, CVector *target); void Reload(void); void Update(int32 audioEntity, CPed *pedToAdjustSound);