From 5a961d02845670f3f647d597f4c30696d2badd24 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 10 Jun 2020 23:50:17 +0200 Subject: [PATCH 01/18] some cam cleanup; unused PS2 train cams --- src/core/Cam.cpp | 208 +++++++++++++++++++++++++++++++++------------- src/core/Camera.h | 8 +- 2 files changed, 153 insertions(+), 63 deletions(-) diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 53c49634..ee6d8845 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -211,10 +211,18 @@ CCam::Process(void) case MODE_PLAYER_FALLEN_WATER: Process_Player_Fallen_Water(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; -// case MODE_CAM_ON_TRAIN_ROOF: -// case MODE_CAM_RUNNING_SIDE_TRAIN: -// case MODE_BLOOD_ON_THE_TRACKS: -// case MODE_IM_THE_PASSENGER_WOOWOO: + case MODE_CAM_ON_TRAIN_ROOF: + Process_Cam_On_Train_Roof(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); + break; + case MODE_CAM_RUNNING_SIDE_TRAIN: + Process_Cam_Running_Side_Train(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); + break; + case MODE_BLOOD_ON_THE_TRACKS: + Process_Blood_On_The_Tracks(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); + break; + case MODE_IM_THE_PASSENGER_WOOWOO: + Process_Im_The_Passenger_Woo_Woo(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); + break; case MODE_SYPHON_CRIM_IN_FRONT: Process_Syphon_Crim_In_Front(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; @@ -1776,14 +1784,14 @@ CCam::WorkOutCamHeightWeeCar(CVector &TargetCoors, float TargetOrientation) void CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, float TargetHeight) { + float AlphaOffset = 0.0f; + bool CamClear = true; + static float LastTargetAlphaWithCollisionOn = 0.0f; static float LastTopAlphaSpeed = 0.0f; static float LastAlphaSpeedStep = 0.0f; static bool PreviousNearCheckNearClipSmall = false; - bool CamClear = true; - float ModeAlpha = 0.0f; - if(ResetStatics){ LastTargetAlphaWithCollisionOn = 0.0f; LastTopAlphaSpeed = 0.0f; @@ -1798,17 +1806,16 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa if(zoomvalue < 0.1f) zoomvalue = 0.1f; if(TheCamera.CarZoomIndicator == CAM_ZOOM_1) - ModeAlpha = CGeneral::GetATanOfXY(23.0f, zoomvalue); // near + AlphaOffset = CGeneral::GetATanOfXY(23.0f, zoomvalue); // near else if(TheCamera.CarZoomIndicator == CAM_ZOOM_2) - ModeAlpha = CGeneral::GetATanOfXY(10.8f, zoomvalue); // mid + AlphaOffset = CGeneral::GetATanOfXY(10.8f, zoomvalue); // mid else if(TheCamera.CarZoomIndicator == CAM_ZOOM_3) - ModeAlpha = CGeneral::GetATanOfXY(7.0f, zoomvalue); // far + AlphaOffset = CGeneral::GetATanOfXY(7.0f, zoomvalue); // far float Length = (Source - TargetCoors).Magnitude2D(); if(m_bCollisionChecksOn){ // there's another variable (on PC) but it's uninitialised - CVector Forward = CamTargetEntity->GetForward(); - float CarAlpha = CGeneral::GetATanOfXY(Forward.Magnitude2D(), Forward.z); + float CarAlpha = CGeneral::GetATanOfXY(CamTargetEntity->GetForward().Magnitude2D(), CamTargetEntity->GetForward().z); // this shouldn't be necessary.... while(CarAlpha >= PI) CarAlpha -= 2*PI; while(CarAlpha < -PI) CarAlpha += 2*PI; @@ -1816,11 +1823,11 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; - float deltaBeta = Beta - TargetOrientation; - while(deltaBeta >= PI) deltaBeta -= 2*PI; - while(deltaBeta < -PI) deltaBeta += 2*PI; + float DeltaBeta = Beta - TargetOrientation; + while(DeltaBeta >= PI) DeltaBeta -= 2*PI; + while(DeltaBeta < -PI) DeltaBeta += 2*PI; - float BehindCarNess = Cos(deltaBeta); // 1 if behind car, 0 if side, -1 if in front + float BehindCarNess = Cos(DeltaBeta); // 1 if behind car, 0 if side, -1 if in front CarAlpha = -CarAlpha * BehindCarNess; if(CarAlpha < -0.01f) CarAlpha = -0.01f; @@ -1830,10 +1837,10 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa while(DeltaAlpha < -PI) DeltaAlpha += 2*PI; // What's this?? wouldn't it make more sense to clamp? float AngleLimit = DEGTORAD(1.8f); - if(DeltaAlpha < -AngleLimit) - DeltaAlpha += AngleLimit; - else if(DeltaAlpha > AngleLimit) + if(DeltaAlpha > AngleLimit) DeltaAlpha -= AngleLimit; + else if(DeltaAlpha < -AngleLimit) + DeltaAlpha += AngleLimit; else DeltaAlpha = 0.0f; @@ -1852,7 +1859,7 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa float CarRoof = CWorld::FindRoofZFor3DCoord(TargetCoors.x, TargetCoors.y, CarBottom, &FoundRoofCenter); // Check sides of the car - Forward = CamTargetEntity->GetForward(); // we actually still have that... + CVector Forward = CamTargetEntity->GetForward(); Forward.Normalise(); // shouldn't be necessary float CarSideAngle = CGeneral::GetATanOfXY(Forward.x, Forward.y) + PI/2.0f; float SideX = 2.5f * Cos(CarSideAngle); @@ -1861,7 +1868,7 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa CWorld::FindRoofZFor3DCoord(TargetCoors.x - SideX, TargetCoors.y - SideY, CarBottom, &FoundRoofSide2); // Now find out at what height we'd like to place the camera - float CamGround = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, TargetCoors.z + Length*Sin(Alpha + ModeAlpha) + m_fCloseInCarHeightOffset, &FoundCamGround); + float CamGround = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, TargetCoors.z + Length*Sin(Alpha + AlphaOffset) + m_fCloseInCarHeightOffset, &FoundCamGround); float CamTargetZ = 0.0f; if(FoundCamGround){ // This is the normal case @@ -1891,15 +1898,15 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa TargetAlpha = DEGTORAD(-7.0f); // huh? - if(TargetAlpha > ModeAlpha) + if(TargetAlpha > AlphaOffset) CamClear = true; - // Camera is contrained by collision in some way + // Camera is constrained by collision in some way PreviousNearCheckNearClipSmall = false; if(!CamClear){ PreviousNearCheckNearClipSmall = true; RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); - DeltaAlpha = TargetAlpha - (Alpha + ModeAlpha); + DeltaAlpha = TargetAlpha - (Alpha + AlphaOffset); while(DeltaAlpha >= PI) DeltaAlpha -= 2*PI; while(DeltaAlpha < -PI) DeltaAlpha += 2*PI; @@ -1908,43 +1915,42 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa } // Now do things if CamClear...but what is that anyway? - float CamZ = TargetCoors.z + Length*Sin(Alpha + DeltaAlpha + ModeAlpha) + m_fCloseInCarHeightOffset; + float CamZ = TargetCoors.z + Length*Sin(Alpha + DeltaAlpha + AlphaOffset) + m_fCloseInCarHeightOffset; bool FoundGround, FoundRoof; float CamGround2 = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, CamZ, &FoundGround); - if(FoundGround){ - if(CamClear) - if(CamZ - CamGround2 < 1.5f){ - PreviousNearCheckNearClipSmall = true; - RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); + if(FoundGround && CamClear){ + if(CamZ - CamGround2 < 1.5f){ + PreviousNearCheckNearClipSmall = true; + RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); - float a; - if(Length == 0.0f || CamGround2 + 1.5f - TargetCoors.z == 0.0f) - a = Alpha; - else - a = CGeneral::GetATanOfXY(Length, CamGround2 + 1.5f - TargetCoors.z); - while(a > PI) a -= 2*PI; - while(a < -PI) a += 2*PI; - DeltaAlpha = a - Alpha; - } - }else{ - if(CamClear){ - float CamRoof2 = CWorld::FindRoofZFor3DCoord(Source.x, Source.y, CamZ, &FoundRoof); - if(FoundRoof && CamZ - CamRoof2 < 1.5f){ - PreviousNearCheckNearClipSmall = true; - RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); + float dz = CamGround2 + 1.5f - TargetCoors.z; + float a; + if(Length == 0.0f || dz == 0.0f) + a = Alpha; + else + a = CGeneral::GetATanOfXY(Length, dz); + while(a > PI) a -= 2*PI; + while(a < -PI) a += 2*PI; + DeltaAlpha = a - Alpha; + } + }else if(CamClear){ + float CamRoof2 = CWorld::FindRoofZFor3DCoord(Source.x, Source.y, CamZ, &FoundRoof); + if(FoundRoof && CamZ - CamRoof2 < 1.5f){ + PreviousNearCheckNearClipSmall = true; + RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); - if(CamRoof2 > TargetCoors.z + 3.5f) - CamRoof2 = TargetCoors.z + 3.5f; + if(CamRoof2 > TargetCoors.z + 3.5f) + CamRoof2 = TargetCoors.z + 3.5f; - float a; - if(Length == 0.0f || CamRoof2 + 1.5f - TargetCoors.z == 0.0f) - a = Alpha; - else - a = CGeneral::GetATanOfXY(Length, CamRoof2 + 1.5f - TargetCoors.z); - while(a > PI) a -= 2*PI; - while(a < -PI) a += 2*PI; - DeltaAlpha = a - Alpha; - } + float dz = CamRoof2 + 1.5f - TargetCoors.z; + float a; + if(Length == 0.0f || dz == 0.0f) + a = Alpha; + else + a = CGeneral::GetATanOfXY(Length, dz); + while(a > PI) a -= 2*PI; + while(a < -PI) a += 2*PI; + DeltaAlpha = a - Alpha; } } @@ -1958,7 +1964,7 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa WellBufferMe(LastTargetAlphaWithCollisionOn, &Alpha, &AlphaSpeed, LastTopAlphaSpeed, LastAlphaSpeedStep, true); - Source.z = TargetCoors.z + Sin(Alpha + ModeAlpha)*Length + m_fCloseInCarHeightOffset; + Source.z = TargetCoors.z + Sin(Alpha + AlphaOffset)*Length + m_fCloseInCarHeightOffset; } // Rotate cam behind the car when the car is moving forward @@ -2108,9 +2114,9 @@ CCam::Process_Cam_On_A_String(const CVector &CameraTarget, float TargetOrientati CBaseModelInfo *mi = CModelInfo::GetModelInfo(CamTargetEntity->GetModelIndex()); CVector Dimensions = mi->GetColModel()->boundingBox.max - mi->GetColModel()->boundingBox.min; + CVector TargetCoors = CameraTarget; float BaseDist = Dimensions.Magnitude2D(); - CVector TargetCoors = CameraTarget; TargetCoors.z += Dimensions.z - 0.1f; // final Beta = CGeneral::GetATanOfXY(TargetCoors.x - Source.x, TargetCoors.y - Source.y); while(Alpha >= PI) Alpha -= 2*PI; @@ -2145,6 +2151,8 @@ CCam::Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist) if(ResetStatics) Source = TargetCoors + Dist*(CA_MAX_DISTANCE + 1.0f); + Dist = Source - TargetCoors; + float Length = Dist.Magnitude2D(); if(Length < 0.001f){ // This probably shouldn't happen. reset view @@ -2172,7 +2180,7 @@ CCam::FixCamWhenObscuredByVehicle(const CVector &TargetCoors) static float HeightFixerCarsObscuring = 0.0f; static float HeightFixerCarsObscuringSpeed = 0.0f; CColPoint colPoint; - CEntity *entity; + CEntity *entity = nil; float HeightTarget = 0.0f; if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, false, true, false, false, false, false, false)){ @@ -4412,6 +4420,88 @@ CCam::Process_FollowPed_WithBinding(const CVector &CameraTarget, float TargetOri GetVectorsReadyForRW(); } +void +CCam::Process_Im_The_Passenger_Woo_Woo(const CVector &CameraTarget, float TargetOrientation, float, float) +{ + FOV = 50.0f; + + Source = CamTargetEntity->GetPosition(); + Source.z += 2.5f; + Front = CamTargetEntity->GetForward(); + Front.Normalise(); + Source += 1.35f*Front; + float heading = CGeneral::GetATanOfXY(Front.x, Front.y) + DEGTORAD(45.0f); + Front.x = Cos(heading); + Front.y = Sin(heading); + Up = CamTargetEntity->GetUp(); + + GetVectorsReadyForRW(); +} + +void +CCam::Process_Blood_On_The_Tracks(const CVector &CameraTarget, float TargetOrientation, float, float) +{ + FOV = 50.0f; + + Source = CamTargetEntity->GetPosition(); + Source.z += 5.45f; + + static CVector Test = -CamTargetEntity->GetForward(); +#ifdef FIX_BUGS + if(ResetStatics){ + Test = -CamTargetEntity->GetForward(); + ResetStatics = false; + } +#endif + + Source.x += 19.45*Test.x; + Source.y += 19.45*Test.y; + Front = Test; + Front.Normalise(); + Up = CamTargetEntity->GetUp(); + + GetVectorsReadyForRW(); +} + +void +CCam::Process_Cam_Running_Side_Train(const CVector &CameraTarget, float TargetOrientation, float, float) +{ + FOV = 60.0f; + + Source = CamTargetEntity->GetPosition(); + Source.z += 4.0f; + CVector fwd = CamTargetEntity->GetForward(); + float heading = CGeneral::GetATanOfXY(fwd.x, fwd.y) - DEGTORAD(15.0f); + Source.x -= Cos(heading)*10.0f; + Source.y -= Sin(heading)*10.0f; + heading -= DEGTORAD(5.0f); + Front = fwd; + Front.x += Cos(heading); + Front.y += Sin(heading); + Front.z -= 0.056f; + Front.Normalise(); + Up = CamTargetEntity->GetUp(); + + GetVectorsReadyForRW(); +} + +void +CCam::Process_Cam_On_Train_Roof(const CVector &CameraTarget, float TargetOrientation, float, float) +{ + static float RoofMultiplier = 1.5f; + + Source = CamTargetEntity->GetPosition(); + Source.z += 4.8f; + Front = CamTargetEntity->GetForward(); + Front.Normalise(); + Source += Front*RoofMultiplier; + Up = CamTargetEntity->GetUp(); + Up.Normalise(); + + GetVectorsReadyForRW(); +} + + #ifdef FREE_CAM void CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrientation, float, float) diff --git a/src/core/Camera.h b/src/core/Camera.h index 80fc878e..e736b6a7 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -251,10 +251,10 @@ public: // CCam::Process_CheesyZoom // CCam::Process_Aiming // CCam::Process_Bill // same as BehindCar due to unused variables - // CCam::Process_Im_The_Passenger_Woo_Woo - // CCam::Process_Blood_On_The_Tracks - // CCam::Process_Cam_Running_Side_Train - // CCam::Process_Cam_On_Train_Roof + void Process_Im_The_Passenger_Woo_Woo(const CVector &CameraTarget, float TargetOrientation, float, float); + void Process_Blood_On_The_Tracks(const CVector &CameraTarget, float TargetOrientation, float, float); + void Process_Cam_Running_Side_Train(const CVector &CameraTarget, float TargetOrientation, float, float); + void Process_Cam_On_Train_Roof(const CVector &CameraTarget, float TargetOrientation, float, float); // custom stuff void Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrientation, float, float); From 41dac0773f4e3ed2800f038340ddcb5adeee5f99 Mon Sep 17 00:00:00 2001 From: aap Date: Fri, 12 Jun 2020 21:53:39 +0200 Subject: [PATCH 02/18] little CCam cleanup; fix in CWorld sphere test --- src/core/Cam.cpp | 53 +++++++++++++++++++++------------------------ src/core/Camera.cpp | 9 +++++++- src/core/World.cpp | 4 ++++ 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index ee6d8845..567d8c79 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -40,11 +40,11 @@ CCam::Init(void) Mode = MODE_FOLLOWPED; Front = CVector(0.0f, 0.0f, -1.0f); Up = CVector(0.0f, 0.0f, 1.0f); - Rotating = 0; + Rotating = false; m_iDoCollisionChecksOnFrameNum = 1; m_iDoCollisionCheckEveryNumOfFrames = 9; m_iFrameNumWereAt = 0; - m_bCollisionChecksOn = 1; + m_bCollisionChecksOn = false; m_fRealGroundDist = 0.0f; BetaSpeed = 0.0f; AlphaSpeed = 0.0f; @@ -54,19 +54,19 @@ CCam::Init(void) DistanceSpeed = 0.0f; m_pLastCarEntered = 0; m_pLastPedLookedAt = 0; - ResetStatics = 1; + ResetStatics = true; Beta = 0.0f; - m_bFixingBeta = 0; + m_bFixingBeta = false; CA_MIN_DISTANCE = 0.0f; CA_MAX_DISTANCE = 0.0f; - LookingBehind = 0; - LookingLeft = 0; - LookingRight = 0; + LookingBehind = false; + LookingLeft = false; + LookingRight = false; m_fPlayerInFrontSyphonAngleOffSet = DEGTORAD(20.0f); m_fSyphonModeTargetZOffSet = 0.5f; m_fRadiusForDead = 1.5f; DirectionWasLooking = LOOKING_FORWARD; - LookBehindCamWasInFront = 0; + LookBehindCamWasInFront = false; f_Roll = 0.0f; f_rollSpeed = 0.0f; m_fCloseInPedHeightOffset = 0.0f; @@ -1007,6 +1007,9 @@ static float DefaultMaxStep = 0.15f; void CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, float, float) { + if(!CamTargetEntity->IsPed()) + return; + const float GroundDist = 1.85f; CVector TargetCoors, Dist, IdealSource; @@ -1023,7 +1026,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl bool GoingBehind = false; bool Obscured = false; bool BuildingCheckObscured = false; - bool HackPlayerOnStoppingTrain = false; + bool StandingInTrain = false; static int TimeIndicatedWantedToGoDown = 0; static bool StartedCountingForGoDown = false; float DeltaBeta; @@ -1032,12 +1035,6 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl bBelowMinDist = false; bBehindPlayerDesired = false; -#ifdef FIX_BUGS - if(!CamTargetEntity->IsPed()) - return; -#endif - assert(CamTargetEntity->IsPed()); - // CenterDist should be > LateralDist because we don't have an angle for safety in this case float CenterDist, LateralDist; float AngleToGoToSpeed; @@ -1103,7 +1100,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl if(FindPlayerVehicle()) if(FindPlayerVehicle()->m_vehType == VEHICLE_TYPE_TRAIN) - HackPlayerOnStoppingTrain = true; + StandingInTrain = true; if(TheCamera.m_bCamDirectlyInFront){ m_bCollisionChecksOn = true; @@ -1356,7 +1353,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl if(TheCamera.m_bCamDirectlyBehind || TheCamera.m_bCamDirectlyInFront || - HackPlayerOnStoppingTrain || Rotating){ + StandingInTrain || Rotating){ if(TheCamera.m_bCamDirectlyBehind){ Beta = TargetOrientation + PI; Source.x = TargetCoors.x + RotDistance * Cos(Beta); @@ -1367,7 +1364,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl Source.x = TargetCoors.x + RotDistance * Cos(Beta); Source.y = TargetCoors.y + RotDistance * Sin(Beta); } - if(HackPlayerOnStoppingTrain){ + if(StandingInTrain){ Beta = TargetOrientation + PI; Source.x = TargetCoors.x + RotDistance * Cos(Beta); Source.y = TargetCoors.y + RotDistance * Sin(Beta); @@ -2477,8 +2474,8 @@ CCam::Process_Rocket(const CVector &CameraTarget, float, float, float) }else{ float xdir = LookLeftRight < 0.0f ? -1.0f : 1.0f; float ydir = LookUpDown < 0.0f ? -1.0f : 1.0f; - Beta += SQR(LookLeftRight/100.0f)*xdir/17.5 * FOV/80.0f * CTimer::GetTimeStep(); - Alpha += SQR(LookUpDown/150.0f)*ydir/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Beta += SQR(LookLeftRight/100.0f)*xdir*0.8f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Alpha += SQR(LookUpDown/150.0f)*ydir*1.0f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); } while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; @@ -2579,8 +2576,8 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) }else{ float xdir = LookLeftRight < 0.0f ? -1.0f : 1.0f; float ydir = LookUpDown < 0.0f ? -1.0f : 1.0f; - Beta += SQR(LookLeftRight/100.0f)*xdir/17.5 * FOV/80.0f * CTimer::GetTimeStep(); - Alpha += SQR(LookUpDown/150.0f)*ydir/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Beta += SQR(LookLeftRight/100.0f)*xdir*0.8f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Alpha += SQR(LookUpDown/150.0f)*ydir*1.0f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); } while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; @@ -2691,8 +2688,8 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl LookUpDown = CPad::GetPad(0)->LookAroundUpDown(); float xdir = LookLeftRight < 0.0f ? -1.0f : 1.0f; float ydir = LookUpDown < 0.0f ? -1.0f : 1.0f; - Beta += SQR(LookLeftRight/100.0f)*xdir/17.5 * FOV/80.0f * CTimer::GetTimeStep(); - Alpha += SQR(LookUpDown/150.0f)*ydir/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Beta += SQR(LookLeftRight/100.0f)*xdir*0.8f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Alpha += SQR(LookUpDown/150.0f)*ydir*1.0f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f); @@ -2870,8 +2867,8 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float, }else{ float xdir = LookLeftRight < 0.0f ? -1.0f : 1.0f; float ydir = LookUpDown < 0.0f ? -1.0f : 1.0f; - Beta += SQR(LookLeftRight/100.0f)*xdir/17.5 * FOV/80.0f * CTimer::GetTimeStep(); - Alpha += SQR(LookUpDown/150.0f)*ydir/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Beta += SQR(LookLeftRight/100.0f)*xdir*0.8f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Alpha += SQR(LookUpDown/150.0f)*ydir*1.0f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); } while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; @@ -2973,8 +2970,8 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float }else{ float xdir = LookLeftRight < 0.0f ? -1.0f : 1.0f; float ydir = LookUpDown < 0.0f ? -1.0f : 1.0f; - Beta += SQR(LookLeftRight/100.0f)*xdir/17.5 * FOV/80.0f * CTimer::GetTimeStep(); - Alpha += SQR(LookUpDown/150.0f)*ydir/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Beta += SQR(LookLeftRight/100.0f)*xdir*0.8f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Alpha += SQR(LookUpDown/150.0f)*ydir*1.0f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); } while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 53bee20f..d7e52170 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -111,7 +111,7 @@ CCamera::Init(void) Cams[0].Mode = CCam::MODE_FOLLOWPED; Cams[1].Mode = CCam::MODE_FOLLOWPED; unknown = 0; - m_bJustJumpedOutOf1stPersonBecauseOfTarget = 0; + m_bJustJumpedOutOf1stPersonBecauseOfTarget = false; ClearPlayerWeaponMode(); m_bInATunnelAndABigVehicle = false; m_iModeObbeCamIsInForCar = OBBE_INVALID; @@ -2869,6 +2869,13 @@ CCamera::Process_Train_Camera_Control(void) if(node >= m_uiNumberOfTrainCamNodes) node = 0; } +#ifdef FIX_BUGS + // Not really a bug but be nice and respect the debug mode + if(DebugCamMode){ + TakeControl(target, DebugCamMode, JUMP_CUT, CAMCONTROL_SCRIPT); + return; + } +#endif if(found){ SetWideScreenOn(); diff --git a/src/core/World.cpp b/src/core/World.cpp index c3633d77..3b77db18 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -949,7 +949,11 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad if(e != entityToIgnore && e->bUsesCollision && !(ignoreSomeObjects && CameraToIgnoreThisObject(e))) { +#ifdef FIX_BUGS + CVector diff = spherePos - e->GetBoundCentre(); +#else CVector diff = spherePos - e->GetPosition(); +#endif float distance = diff.Magnitude(); if(e->GetBoundRadius() + radius > distance) { From d415c4edd363ba04c415d626c8d5bc1a99d798af Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Sat, 13 Jun 2020 00:16:10 +0300 Subject: [PATCH 03/18] minor fix --- src/control/Script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/control/Script.cpp b/src/control/Script.cpp index da321a28..089db1b4 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -7743,7 +7743,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) CollectParameters(&m_nIp, 4); CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); assert(pObject); - pObject->SetMoveSpeed(pObject->GetMoveSpeed() + 0.02f * *(CVector*)&ScriptParams[1]); + pObject->SetMoveSpeed(pObject->GetMoveSpeed() + METERS_PER_SECOND_TO_GAME_SPEED * *(CVector*)&ScriptParams[1]); return 0; } case COMMAND_DRAW_SPRITE: From beb6f3bf8057232a1b1b5a1673d22cff618e3a83 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Sat, 13 Jun 2020 13:57:25 +0300 Subject: [PATCH 04/18] small fixes --- src/render/Fluff.cpp | 35 ++++++++++++++++++----------------- src/render/Hud.cpp | 10 +++++----- src/weapons/BulletInfo.cpp | 3 ++- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp index 9f3f6929..d50bddd6 100644 --- a/src/render/Fluff.cpp +++ b/src/render/Fluff.cpp @@ -142,11 +142,11 @@ void CMovingThings::Init() void CMovingThings::Shutdown() { int i; - for (i = 0; i < 11; ++i) + for (i = 0; i < ARRAY_SIZE(aScrollBars); ++i) aScrollBars[i].SetVisibility(false); - for (i = 0; i < 2; ++i) + for (i = 0; i < ARRAY_SIZE(aTowerClocks); ++i) aTowerClocks[i].SetVisibility(false); - for (i = 0; i < 3; ++i) + for (i = 0; i < ARRAY_SIZE(aDigitalClocks); ++i) aDigitalClocks[i].SetVisibility(false); } @@ -168,17 +168,17 @@ void CMovingThings::Update() aMovingThings[i].Update(); } - for (i = 0; i < 11; ++i) + for (i = 0; i < ARRAY_SIZE(aScrollBars); ++i) { if (aScrollBars[i].IsVisible() || (CTimer::GetFrameCounter() + i) % 8 == 0) aScrollBars[i].Update(); } - for (i = 0; i < 2; ++i) + for (i = 0; i < ARRAY_SIZE(aTowerClocks); ++i) { if (aTowerClocks[i].IsVisible() || (CTimer::GetFrameCounter() + i) % 8 == 0) aTowerClocks[i].Update(); } - for (i = 0; i < 3; ++i) + for (i = 0; i < ARRAY_SIZE(aDigitalClocks); ++i) { if (aDigitalClocks[i].IsVisible() || (CTimer::GetFrameCounter() + i) % 8 == 0) aDigitalClocks[i].Update(); @@ -188,17 +188,17 @@ void CMovingThings::Update() void CMovingThings::Render() { int i; - for (i = 0; i < 11; ++i) + for (i = 0; i < ARRAY_SIZE(aScrollBars); ++i) { if (aScrollBars[i].IsVisible()) aScrollBars[i].Render(); } - for (i = 0; i < 2; ++i) + for (i = 0; i < ARRAY_SIZE(aTowerClocks); ++i) { if (aTowerClocks[i].IsVisible()) aTowerClocks[i].Render(); } - for (i = 0; i < 3; ++i) + for (i = 0; i < ARRAY_SIZE(aDigitalClocks); ++i) { if (aDigitalClocks[i].IsVisible()) aDigitalClocks[i].Render(); @@ -297,7 +297,8 @@ const char* FindDigitalClockMessage() } else { - int temperature = 13.0f - 6.0f * Cos((CClock::GetMinutes() + 60.0f * CClock::GetHours()) * 0.0043611112f - 1.0f); + // they didn't use rad2deg here because of 3.14 + int temperature = 13.0f - 6.0f * Cos((CClock::GetMinutes() + 60.0f * CClock::GetHours()) / (4.0f * 180.0f / 3.14f) - 1.0f); String_DigitalClock[0] = '0' + temperature / 10; if (String_DigitalClock[0] == '0') String_DigitalClock[0] = ' '; @@ -312,7 +313,7 @@ const char* FindDigitalClockMessage() // ---------- CScrollBar ---------- void CScrollBar::Init(CVector position, uint8 type, float sizeX, float sizeY, float sizeZ, uint8 red, uint8 green, uint8 blue, float scale) { - for (int i = 0; i < 40; ++i) + for (int i = 0; i < ARRAY_SIZE(m_MessageBar); ++i) m_MessageBar[i] = 0; m_pMessage = ". "; @@ -618,16 +619,16 @@ void CScrollBar::Update() } // Scroll - for (int i = 0; i < 39; i++) + for (int i = 0; i < ARRAY_SIZE(m_MessageBar)-1; i++) m_MessageBar[i] = m_MessageBar[i + 1]; - m_MessageBar[39] = m_Counter < 5 ? ScrollCharSet[m_pMessage[m_MessageCurrentChar] - ' '][m_Counter] : 0; + m_MessageBar[ARRAY_SIZE(m_MessageBar)-1] = m_Counter < 5 ? ScrollCharSet[m_pMessage[m_MessageCurrentChar] - ' '][m_Counter] : 0; // Introduce some random displaying glitches; signs aren't supposed to be perfect :P switch (CGeneral::GetRandomNumber() & 0xFF) { - case 0x0D: m_MessageBar[39] = 0; break; - case 0xE3: m_MessageBar[39] = 0xE3; break; - case 0x64: m_MessageBar[39] = ~m_MessageBar[39]; break; + case 0x0D: m_MessageBar[ARRAY_SIZE(m_MessageBar)-1] = 0; break; + case 0xE3: m_MessageBar[ARRAY_SIZE(m_MessageBar)-1] = 0xE3; break; + case 0x64: m_MessageBar[ARRAY_SIZE(m_MessageBar)-1] = ~m_MessageBar[ARRAY_SIZE(m_MessageBar)-1]; break; } } @@ -654,7 +655,7 @@ void CScrollBar::Render() CVector coronaCoord, screenCoord; float screenW, screenH; - for (int i = 1; i < 40; ++i) + for (int i = 1; i < ARRAY_SIZE(m_MessageBar); ++i) { for (int j = 0; j < 5; ++j) { diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index c7f61d5d..270cc07c 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -131,16 +131,16 @@ void CHud::Draw() return; if (m_Wants_To_Draw_Hud && !TheCamera.m_WideScreenOn) { - bool DrawCrossHair = 0; - bool DrawCrossHairPC = 0; + bool DrawCrossHair = false; + bool DrawCrossHairPC = false; int32 WeaponType = FindPlayerPed()->m_weapons[FindPlayerPed()->m_currentWeapon].m_eWeaponType; int32 Mode = TheCamera.Cams[TheCamera.ActiveCam].Mode; if (Mode == CCam::MODE_SNIPER || Mode == CCam::MODE_ROCKETLAUNCHER || Mode == CCam::MODE_M16_1STPERSON || Mode == CCam::MODE_HELICANNON_1STPERSON) - DrawCrossHair = 1; + DrawCrossHair = true; if (Mode == CCam::MODE_M16_1STPERSON_RUNABOUT || Mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT || Mode == CCam::MODE_SNIPER_RUNABOUT) - DrawCrossHairPC = 1; + DrawCrossHairPC = true; /* Draw Crosshairs @@ -149,7 +149,7 @@ void CHud::Draw() (!CPad::GetPad(0)->GetLookBehindForPed() || TheCamera.m_bPlayerIsInGarage) || Mode == CCam::MODE_1STPERSON_RUNABOUT) { if (FindPlayerPed() && !FindPlayerPed()->EnteringCar()) { if ((WeaponType >= WEAPONTYPE_COLT45 && WeaponType <= WEAPONTYPE_M16) || WeaponType == WEAPONTYPE_FLAMETHROWER) - DrawCrossHairPC = 1; + DrawCrossHairPC = true; } } diff --git a/src/weapons/BulletInfo.cpp b/src/weapons/BulletInfo.cpp index 389e7486..26fc459d 100644 --- a/src/weapons/BulletInfo.cpp +++ b/src/weapons/BulletInfo.cpp @@ -22,6 +22,7 @@ #include "Weapon.h" #include "WeaponInfo.h" #include "World.h" +#include "SurfaceTable.h" #define BULLET_LIFETIME (1000) #define NUM_PED_BLOOD_PARTICLES (8) @@ -228,7 +229,7 @@ bool CBulletInfo::TestForSniperBullet(float x1, float x2, float y1, float y2, fl #ifdef FIX_BUGS // original code is not going work anyway... CColLine line(PlayerSniperBulletStart, PlayerSniperBulletEnd); CColBox box; - box.Set(CVector(x1, y1, z1), CVector(x2, y2, z2), 0, 0); + box.Set(CVector(x1, y1, z1), CVector(x2, y2, z2), SURFACE_DEFAULT, 0); return CCollision::TestLineBox(line, box); #else float minP = 0.0f; From 3231c6c3dd319525eb6d3843dd1198773755c7e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Sat, 13 Jun 2020 17:33:30 +0300 Subject: [PATCH 05/18] ProcessTrainAnnouncements fix --- src/vehicles/Train.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vehicles/Train.cpp b/src/vehicles/Train.cpp index baf6bfb7..26d0dee7 100644 --- a/src/vehicles/Train.cpp +++ b/src/vehicles/Train.cpp @@ -639,8 +639,8 @@ PlayAnnouncement(uint8 sound, uint8 station) void ProcessTrainAnnouncements(void) { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { + for (int i = 0; i < ARRAY_SIZE(StationDist); i++) { + for (int j = 0; j < ARRAY_SIZE(EngineTrackPosition); j++) { if (!bTrainArrivalAnnounced[i]) { float preDist = StationDist[i] - 100.0f; if (preDist < 0.0f) From 39177cb3e3d93003c089bd5b5d3a89e5c676cab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Sat, 13 Jun 2020 18:03:26 +0300 Subject: [PATCH 06/18] update librw --- librw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librw b/librw index 6ff378bb..556f6af1 160000 --- a/librw +++ b/librw @@ -1 +1 @@ -Subproject commit 6ff378bb16007ad003b1a71996944a20f2e76556 +Subproject commit 556f6af1b5a15d5ba1a2254a95076578cd160185 From 3fe282fbe424c7aaa0b467def533eda6327b6457 Mon Sep 17 00:00:00 2001 From: aap Date: Sat, 13 Jun 2020 23:39:24 +0200 Subject: [PATCH 07/18] a few cam fixes --- src/core/Cam.cpp | 47 +++++++++++++++++++++++++-------------------- src/core/Camera.cpp | 43 ++++++++++++++++++++--------------------- src/core/Camera.h | 4 ++-- 3 files changed, 49 insertions(+), 45 deletions(-) diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 567d8c79..fc03b291 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -52,8 +52,8 @@ CCam::Init(void) f_max_role_angle = DEGTORAD(5.0f); Distance = 30.0f; DistanceSpeed = 0.0f; - m_pLastCarEntered = 0; - m_pLastPedLookedAt = 0; + m_pLastCarEntered = nil; + m_pLastPedLookedAt = nil; ResetStatics = true; Beta = 0.0f; m_bFixingBeta = false; @@ -1001,8 +1001,8 @@ CCam::GetPedBetaAngleForClearView(const CVector &Target, float Dist, float BetaO return 0.0f; } -static float DefaultAcceleration = 0.045f; -static float DefaultMaxStep = 0.15f; +float DefaultAcceleration = 0.045f; +float DefaultMaxStep = 0.15f; void CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, float, float) @@ -1473,14 +1473,14 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl ResetStatics = false; } -static float fBaseDist = 1.7f; -static float fAngleDist = 2.0f; -static float fFalloff = 3.0f; -static float fStickSens = 0.01f; -static float fTweakFOV = 1.05f; -static float fTranslateCamUp = 0.8f; -static int16 nFadeControlThreshhold = 45; -static float fDefaultAlphaOrient = -0.22f; +float fBaseDist = 1.7f; +float fAngleDist = 2.0f; +float fFalloff = 3.0f; +float fStickSens = 0.01f; +float fTweakFOV = 1.05f; +float fTranslateCamUp = 0.8f; +int16 nFadeControlThreshhold = 45; +float fDefaultAlphaOrient = -0.22f; void CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrientation, float, float) @@ -1522,8 +1522,8 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient BetaOffset = LookLeftRight * TheCamera.m_fMouseAccelHorzntl * FOV/80.0f; AlphaOffset = LookUpDown * TheCamera.m_fMouseAccelVertical * FOV/80.0f; }else{ - BetaOffset = LookLeftRight * fStickSens * (0.5f/7.0f) * FOV/80.0f * CTimer::GetTimeStep(); - AlphaOffset = LookUpDown * fStickSens * (0.3f/7.0f) * FOV/80.0f * CTimer::GetTimeStep(); + BetaOffset = LookLeftRight * fStickSens * (1.0f/14.0f) * FOV/80.0f * CTimer::GetTimeStep(); + AlphaOffset = LookUpDown * fStickSens * (0.6f/14.0f) * FOV/80.0f * CTimer::GetTimeStep(); } if(TheCamera.GetFading() && TheCamera.GetFadingDirection() == FADE_IN && nFadeControlThreshhold < CDraw::FadeValue || @@ -1545,7 +1545,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; if(Alpha > DEGTORAD(45.0f)) Alpha = DEGTORAD(45.0f); - if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); + else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); TargetCoors = CameraTarget; TargetCoors.z += fTranslateCamUp; @@ -1583,7 +1583,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, true, true, true, false, false, true)){ float PedColDist = (TargetCoors - colPoint.point).Magnitude(); float ColCamDist = CamDist - PedColDist; - if(entity->IsPed() && ColCamDist > 1.0f){ + if(entity->IsPed() && ColCamDist > DEFAULT_NEAR + 0.1f){ // Ped in the way but not clipping through if(CWorld::ProcessLineOfSight(colPoint.point, Source, colPoint, entity, true, true, true, true, false, false, true)){ PedColDist = (TargetCoors - colPoint.point).Magnitude(); @@ -1621,9 +1621,12 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient if(dist == 0.1f) Source += (TargetCoors - Source)*0.3f; + Near = RwCameraGetNearClipPlane(Scene.camera); #ifndef FIX_BUGS // this is totally wrong... radius = Tan(FOV / 2.0f) * Near; +#else + radius = ViewPlaneWidth*Near; #endif // Keep testing entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, false); @@ -2693,7 +2696,7 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f); - if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); + else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); TargetCoors.x = 3.0f * Cos(Alpha) * Cos(Beta) + Source.x; TargetCoors.y = 3.0f * Cos(Alpha) * Sin(Beta) + Source.y; @@ -2740,7 +2743,7 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(CamTargetEntity->GetModelIndex()); CVector CamPos = mi->GetFrontSeatPosn(); CamPos.x = 0.0f; - CamPos.y += -0.08f; + CamPos.y += 0.08f; CamPos.z += 0.62f; FOV = 60.0f; Source = Multiply3x3(CamTargetEntity->GetMatrix(), CamPos); @@ -4581,8 +4584,8 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient BetaOffset = LookLeftRight * TheCamera.m_fMouseAccelHorzntl * FOV/80.0f; AlphaOffset = LookUpDown * TheCamera.m_fMouseAccelVertical * FOV/80.0f; }else{ - BetaOffset = LookLeftRight * fStickSens * (0.5f/10.0f) * FOV/80.0f * CTimer::GetTimeStep(); - AlphaOffset = LookUpDown * fStickSens * (0.3f/10.0f) * FOV/80.0f * CTimer::GetTimeStep(); + BetaOffset = LookLeftRight * fStickSens * (1.0f/20.0f) * FOV/80.0f * CTimer::GetTimeStep(); + AlphaOffset = LookUpDown * fStickSens * (0.6f/20.0f) * FOV/80.0f * CTimer::GetTimeStep(); } // Stop centering once stick has been touched @@ -4654,7 +4657,7 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, true, true, true, false, false, true)){ float PedColDist = (TargetCoors - colPoint.point).Magnitude(); float ColCamDist = CamDist - PedColDist; - if(entity->IsPed() && ColCamDist > 1.0f){ + if(entity->IsPed() && ColCamDist > DEFAULT_NEAR + 0.1f){ // Ped in the way but not clipping through if(CWorld::ProcessLineOfSight(colPoint.point, Source, colPoint, entity, true, true, true, true, false, false, true)){ PedColDist = (TargetCoors - colPoint.point).Magnitude(); @@ -4693,6 +4696,8 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient Source += (TargetCoors - Source)*0.3f; // Keep testing + Near = RwCameraGetNearClipPlane(Scene.camera); + radius = ViewPlaneWidth*Near; entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, false); i++; diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index d7e52170..aa307337 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -129,8 +129,8 @@ CCamera::Init(void) Cams[1].m_fPlayerVelocity = 0.0f; Cams[2].m_fPlayerVelocity = 0.0f; m_bHeadBob = false; - m_fFractionInterToStopMovingTarget = 0.25f; - m_fFractionInterToStopCatchUpTarget = 0.75f; + m_fFractionInterToStopMoving = 0.25f; + m_fFractionInterToStopCatchUp = 0.75f; m_fGaitSwayBuffer = 0.85f; m_bScriptParametersSetForInterPol = false; m_uiCamShakeStart = 0; @@ -329,12 +329,12 @@ CCamera::Process(void) currentTime = m_uiTransitionDuration; float fractionInter = (float) currentTime / m_uiTransitionDuration; - if(fractionInter <= m_fFractionInterToStopMovingTarget){ + if(fractionInter <= m_fFractionInterToStopMoving){ float inter; - if(m_fFractionInterToStopMovingTarget == 0.0f) + if(m_fFractionInterToStopMoving == 0.0f) inter = 0.0f; else - inter = (m_fFractionInterToStopMovingTarget - fractionInter)/m_fFractionInterToStopMovingTarget; + inter = (m_fFractionInterToStopMoving - fractionInter)/m_fFractionInterToStopMoving; inter = 0.5f - 0.5*Cos(inter*PI); // smooth it m_vecSourceWhenInterPol = m_cvecStartingSourceForInterPol + inter*m_cvecSourceSpeedAtStartInter; @@ -388,12 +388,12 @@ CCamera::Process(void) } CamUp.Normalise(); FOV = m_fFOVWhenInterPol; - }else if(fractionInter > m_fFractionInterToStopMovingTarget && fractionInter <= 1.0f){ + }else if(fractionInter > m_fFractionInterToStopMoving && fractionInter <= 1.0f){ float inter; - if(m_fFractionInterToStopCatchUpTarget == 0.0f) + if(m_fFractionInterToStopCatchUp == 0.0f) inter = 0.0f; else - inter = (fractionInter - m_fFractionInterToStopMovingTarget)/m_fFractionInterToStopCatchUpTarget; + inter = (fractionInter - m_fFractionInterToStopMoving)/m_fFractionInterToStopCatchUp; inter = 0.5f - 0.5*Cos(inter*PI); // smooth it CamSource = m_vecSourceWhenInterPol + inter*(Cams[ActiveCam].Source - m_vecSourceWhenInterPol); @@ -1846,10 +1846,9 @@ CCamera::SetCamPositionForFixedMode(const CVector &Source, const CVector &UpOffS void CCamera::StartTransition(int16 newMode) { - bool foo = false; bool switchSyphonMode = false; bool switchPedToCar = false; - bool switchPedMode = false; + bool switchFromFight = false; bool switchFromFixed = false; bool switch1stPersonToVehicle = false; float betaOffset, targetBeta, camBeta, deltaBeta; @@ -1858,8 +1857,8 @@ CCamera::StartTransition(int16 newMode) // missing on PS2 m_bItsOkToLookJustAtThePlayer = false; - m_fFractionInterToStopMovingTarget = 0.25f; - m_fFractionInterToStopCatchUpTarget = 0.75f; + m_fFractionInterToStopMoving = 0.25f; + m_fFractionInterToStopCatchUp = 0.75f; if(Cams[ActiveCam].Mode == CCam::MODE_SYPHON_CRIM_IN_FRONT || Cams[ActiveCam].Mode == CCam::MODE_FOLLOWPED || @@ -1878,7 +1877,7 @@ CCamera::StartTransition(int16 newMode) if(Cams[ActiveCam].Mode == CCam::MODE_SYPHON_CRIM_IN_FRONT && newMode == CCam::MODE_SYPHON) switchSyphonMode = true; if(Cams[ActiveCam].Mode == CCam::MODE_FIGHT_CAM && newMode == CCam::MODE_FOLLOWPED) - switchPedMode = true; + switchFromFight = true; if(Cams[ActiveCam].Mode == CCam::MODE_FIXED) switchFromFixed = true; @@ -2097,19 +2096,19 @@ CCamera::StartTransition(int16 newMode) m_uiTransitionDuration = 1350; if(switchSyphonMode) m_uiTransitionDuration = 1800; - else if(switchPedMode) + else if(switchFromFight) m_uiTransitionDuration = 750; // not on PS2 else if(switchPedToCar){ - m_fFractionInterToStopMovingTarget = 0.2f; - m_fFractionInterToStopCatchUpTarget = 0.8f; + m_fFractionInterToStopMoving = 0.2f; + m_fFractionInterToStopCatchUp = 0.8f; m_uiTransitionDuration = 950; }else if(switchFromFixed){ - m_fFractionInterToStopMovingTarget = 0.05f; - m_fFractionInterToStopCatchUpTarget = 0.95f; + m_fFractionInterToStopMoving = 0.05f; + m_fFractionInterToStopCatchUp = 0.95f; }else if(switch1stPersonToVehicle){ - m_fFractionInterToStopMovingTarget = 0.0f; - m_fFractionInterToStopCatchUpTarget = 1.0f; + m_fFractionInterToStopMoving = 0.0f; + m_fFractionInterToStopCatchUp = 1.0f; m_uiTransitionDuration = 1; }else m_uiTransitionDuration = 1350; // already set above @@ -2149,8 +2148,8 @@ CCamera::StartTransition(int16 newMode) m_fFOVSpeedAtStartInter = Cams[ActiveCam].m_fFovSpeedOverOneFrame; Cams[ActiveCam].ResetStatics = true; if(!m_bLookingAtPlayer && m_bScriptParametersSetForInterPol){ - m_fFractionInterToStopMovingTarget = m_fScriptPercentageInterToStopMoving; - m_fFractionInterToStopCatchUpTarget = m_fScriptPercentageInterToCatchUp; + m_fFractionInterToStopMoving = m_fScriptPercentageInterToStopMoving; + m_fFractionInterToStopCatchUp = m_fScriptPercentageInterToCatchUp; m_uiTransitionDuration = m_fScriptTimeForInterPolation; } } diff --git a/src/core/Camera.h b/src/core/Camera.h index e736b6a7..bcaaea47 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -524,8 +524,8 @@ public: float m_fFLOATingFadeMusic; float m_fTimeToFadeOut; float m_fTimeToFadeMusic; - float m_fFractionInterToStopMovingTarget; - float m_fFractionInterToStopCatchUpTarget; + float m_fFractionInterToStopMoving; + float m_fFractionInterToStopCatchUp; float m_fGaitSwayBuffer; float m_fScriptPercentageInterToStopMoving; float m_fScriptPercentageInterToCatchUp; From b77d044729c41fb35599525b27357e1b7d7f173a Mon Sep 17 00:00:00 2001 From: aap Date: Sun, 14 Jun 2020 09:50:00 +0200 Subject: [PATCH 08/18] fixed boat wake --- librw | 2 +- src/vehicles/Boat.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/librw b/librw index 556f6af1..6ff378bb 160000 --- a/librw +++ b/librw @@ -1 +1 @@ -Subproject commit 556f6af1b5a15d5ba1a2254a95076578cd160185 +Subproject commit 6ff378bb16007ad003b1a71996944a20f2e76556 diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp index 0ed7876a..d86627de 100644 --- a/src/vehicles/Boat.cpp +++ b/src/vehicles/Boat.cpp @@ -904,6 +904,8 @@ CBoat::AddWakePoint(CVector point) } m_avec2dWakePoints[0] = point; m_afWakePointLifeTime[0] = 400.0f; + if(m_nNumWakePoints < ARRAY_SIZE(m_afWakePointLifeTime)) + m_nNumWakePoints++; } }else{ m_avec2dWakePoints[0] = point; From db6110e996756672595f3d0e69b8e96977a534e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Sat, 13 Jun 2020 23:39:14 +0300 Subject: [PATCH 09/18] Peds, mission switcher & fixes --- src/control/Script.cpp | 43 ++- src/control/Script.h | 4 + src/core/Collision.cpp | 15 + src/core/Collision.h | 1 + src/core/General.h | 12 + src/core/config.h | 3 +- src/core/re3.cpp | 15 +- src/peds/Ped.cpp | 800 ++++++++++++++++++++++++++++++++++------- src/peds/Ped.h | 29 +- src/peds/PedChat.cpp | 102 +++--- 10 files changed, 838 insertions(+), 186 deletions(-) diff --git a/src/control/Script.cpp b/src/control/Script.cpp index ec2dea87..77528b6e 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -166,6 +166,9 @@ bool doingMissionRetry; #endif +#ifdef MISSION_SWITCHER +int switchMissionTo = -1; +#endif const uint32 CRunningScript::nSaveStructSize = #ifdef COMPATIBLE_SAVES @@ -886,10 +889,18 @@ void CRunningScript::Process() int8 CRunningScript::ProcessOneCommand() { - ++CTheScripts::CommandsExecuted; - int32 command = CTheScripts::Read2BytesFromScript(&m_nIp); - m_bNotFlag = (command & 0x8000); - command &= 0x7FFF; + int32 command; +#ifdef MISSION_SWITCHER + if (switchMissionTo != -1) + command = COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL; + else +#endif + { + ++CTheScripts::CommandsExecuted; + command = CTheScripts::Read2BytesFromScript(&m_nIp); + m_bNotFlag = (command & 0x8000); + command &= 0x7FFF; + } if (command < 100) return ProcessCommands0To99(command); if (command < 200) @@ -2032,7 +2043,13 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) ped->ClearAll(); int8 path = ScriptParams[1]; if (ScriptParams[1] < 0 || ScriptParams[1] > 7) + // Max number GetRandomNumberInRange returns is max-1 +#ifdef FIX_BUGS + path = CGeneral::GetRandomNumberInRange(0, 8); +#else path = CGeneral::GetRandomNumberInRange(0, 7); +#endif + ped->SetWanderPath(path); return 0; } @@ -2051,10 +2068,11 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) eMoveState state; switch (ScriptParams[5]) { case 0: state = PEDMOVE_WALK; break; - case 1: state = PEDMOVE_SPRINT; break; + case 1: state = PEDMOVE_RUN; break; default: assert(0); } ped->ClearAll(); + ped->m_pathNodeTimer = 0; ped->SetFollowPath(pos, radius, state, nil, nil, 999999); return 0; } @@ -9125,7 +9143,14 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) return 0; case COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL: { +#ifdef MISSION_SWITCHER + if (switchMissionTo != -1) { + ScriptParams[0] = switchMissionTo; + switchMissionTo = -1; + } else +#endif CollectParameters(&m_nIp, 1); + if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && ScriptParams[0] <= UINT16_MAX - 2) return 0; #ifdef MISSION_REPLAY @@ -10676,7 +10701,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]); assert(pTargetPed); pPed->bScriptObjectiveCompleted = false; - pPed->SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING, pPed); + pPed->SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING, pTargetPed); return 0; } //case COMMAND_IS_PICKUP_IN_ZONE: @@ -14220,7 +14245,7 @@ void CTheScripts::CleanUpThisPed(CPed* pPed) pPed->CharCreatedBy = RANDOM_CHAR; if (pPed->m_nPedType == PEDTYPE_PROSTITUTE) pPed->m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 30000; - if (pPed->bInVehicle) { + if (pPed->InVehicle()) { if (pPed->m_pMyVehicle->pDriver == pPed) { if (pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR) { CCarCtrl::JoinCarWithRoadSystem(pPed->m_pMyVehicle); @@ -14245,10 +14270,14 @@ void CTheScripts::CleanUpThisPed(CPed* pPed) pPed->ClearObjective(); pPed->bRespondsToThreats = true; pPed->bScriptObjectiveCompleted = false; + pPed->bKindaStayInSamePlace = false; pPed->ClearLeader(); if (pPed->IsPedInControl()) pPed->SetWanderPath(CGeneral::GetRandomNumber() & 7); if (flees) { + if (pPed->m_nPedState == PED_FOLLOW_PATH && state != PED_FOLLOW_PATH) + pPed->ClearFollowPath(); + pPed->m_nPedState = state; pPed->SetMoveState(ms); } diff --git a/src/control/Script.h b/src/control/Script.h index 3044e770..45475e6e 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -545,4 +545,8 @@ void RetryMission(int, int); #ifdef USE_DEBUG_SCRIPT_LOADER extern int scriptToLoad; +#endif + +#ifdef MISSION_SWITCHER +extern int switchMissionTo; #endif \ No newline at end of file diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp index b68214af..77e28a10 100644 --- a/src/core/Collision.cpp +++ b/src/core/Collision.cpp @@ -1801,6 +1801,21 @@ CColSphere::Set(float radius, const CVector ¢er, uint8 surf, uint8 piece) this->piece = piece; } +bool +CColSphere::IntersectRay(CVector const& from, CVector const& dir, CVector &entry, CVector &exit) +{ + CVector distToCenter = from - center; + float distToTouchSqr = distToCenter.MagnitudeSqr() - sq(radius); + float root1, root2; + + if (!CGeneral::SolveQuadratic(1.0f, DotProduct(distToCenter, dir) * 2.f, distToTouchSqr, root1, root2)) + return false; + + entry = from + dir * root1; + exit = from + dir * root2; + return true; +} + void CColBox::Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece) { diff --git a/src/core/Collision.h b/src/core/Collision.h index 12af5225..9f08ccd6 100644 --- a/src/core/Collision.h +++ b/src/core/Collision.h @@ -31,6 +31,7 @@ struct CColSphere : public CSphere uint8 piece; void Set(float radius, const CVector ¢er, uint8 surf, uint8 piece); + bool IntersectRay(CVector const &from, CVector const &dir, CVector &entry, CVector &exit); using CSphere::Set; }; diff --git a/src/core/General.h b/src/core/General.h index 3188d82b..dbf169e9 100644 --- a/src/core/General.h +++ b/src/core/General.h @@ -134,6 +134,18 @@ public: return *str2 != '\0'; } + static bool SolveQuadratic(float a, float b, float c, float &root1, float &root2) + { + float discriminant = b * b - 4.f * a * c; + if (discriminant < 0.f) + return false; + + float discriminantSqrt = Sqrt(discriminant); + root2 = (-b + discriminantSqrt) / (2.f * a); + root1 = (-b - discriminantSqrt) / (2.f * a); + return true; + } + // not too sure about all these... static uint16 GetRandomNumber(void) { return myrand() & MYRAND_MAX; } diff --git a/src/core/config.h b/src/core/config.h index e23b0a90..ad5c0064 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -202,12 +202,11 @@ enum Config { #define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible #define FIX_HIGH_FPS_BUGS_ON_FRONTEND -// Rendering/display -#define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios // Just debug menu entries #ifdef DEBUGMENU #define TOGGLEABLE_BETA_FEATURES // not too many things #define RELOADABLES // some debug menu options to reload TXD files +#define MISSION_SWITCHER // from debug menu #endif // Rendering/display diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 13db1f6a..76865339 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -31,6 +31,7 @@ #include "Text.h" #include "WaterLevel.h" #include "main.h" +#include "Script.h" #ifndef _WIN32 #include "assert.h" @@ -309,6 +310,15 @@ ResetCamStatics(void) TheCamera.Cams[TheCamera.ActiveCam].ResetStatics = true; } +#ifdef MISSION_SWITCHER +int8 nextMissionToSwitch = 0; +static void +SwitchToMission(void) +{ + switchMissionTo = nextMissionToSwitch; +} +#endif + static const char *carnames[] = { "landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "rio", "firetruk", "trash", "stretch", "manana", "infernus", "voodoo", "pony", "mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "washing", @@ -512,7 +522,10 @@ DebugMenuPopulate(void) #ifdef TIMEBARS DebugMenuAddVarBool8("Debug", "Show Timebars", &gbShowTimebars, nil); #endif - +#ifdef MISSION_SWITCHER + DebugMenuAddInt8("Debug", "Select mission no", &nextMissionToSwitch, nil, 1, 0, 96, nil); + DebugMenuAddCmd("Debug", "Start selected mission ", SwitchToMission); +#endif extern bool PrintDebugCode; extern int16 DebugCamMode; DebugMenuAddVarBool8("Cam", "Use mouse Cam", &CCamera::m_bUseMouse3rdPerson, nil); diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 12b4ef8d..c4000975 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -102,6 +102,9 @@ bool CPed::bPedCheat2; bool CPed::bPedCheat3; CVector2D CPed::ms_vec2DFleePosition; +CVector vecNextPathNode; +bool vecNextPathNodeInitialized; + void *CPed::operator new(size_t sz) { return CPools::GetPedPool()->New(); } void *CPed::operator new(size_t sz, int handle) { return CPools::GetPedPool()->New(handle); } void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); } @@ -145,6 +148,7 @@ CPed::~CPed(void) DMAudio.DestroyEntity(m_audioEntityId); } +// --MIAMI: Done void CPed::FlagToDestroyWhenNextProcessed(void) { @@ -231,6 +235,9 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_wepSkills = 0; m_distanceToCountSeekDone = 1.0f; m_acceptableHeadingOffset = 0.1f; + m_followPathDestPos = CVector(0.f, 0.f, 0.f); + m_followPathAbortDist = 0.0f; + m_followPathMoveState = PEDMOVE_NONE; bRunningToPhone = false; m_phoneId = -1; m_lastAccident = 0; @@ -257,11 +264,20 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_fLookDirection = 0.0f; m_pCurSurface = nil; m_wanderRangeBounds = nil; - m_nPathNodes = 0; - m_nCurPathNode = 0; + + for (int i = 0; i < ARRAY_SIZE(m_pathNodesToGo); i++) { + m_pathNodesToGo[i] = nil; + } + m_nNumPathNodes = 0; + m_nCurPathNodeId = 0; m_nPathDir = 0; m_pLastPathNode = nil; m_pNextPathNode = nil; + m_followPathWalkAroundEnt = nil; + m_followPathTargetEnt = nil; + m_pathNodeTimer = 0; + m_pCurPathNode = nil; + m_routeLastPoint = -1; m_routeStartPoint = 0; m_routePointsPassed = 0; @@ -398,9 +414,6 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) for (int i = 0; i < ARRAY_SIZE(m_nearPeds); i++) { m_nearPeds[i] = nil; - if (i < ARRAY_SIZE(m_pPathNodesStates)) { - m_pPathNodesStates[i] = nil; - } } m_maxWeaponTypeAllowed = WEAPONTYPE_UNARMED; m_currentWeapon = WEAPONTYPE_UNARMED; @@ -995,7 +1008,7 @@ CPed::FinishedReloadCB(CAnimBlendAssociation *reloadAssoc, void *arg) void CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) { - CAnimBlendAssociation *newAnim, *reloadAnimAssoc; + CAnimBlendAssociation *newAnim, *reloadAnimAssoc = nil; CPed *ped = (CPed*)arg; CWeaponInfo *currentWeapon = CWeaponInfo::GetWeaponInfo(ped->GetWeapon()->m_eWeaponType); @@ -1650,65 +1663,70 @@ CPed::ClearPointGunAt(void) } } +// --MIAMI: Done void CPed::BeingDraggedFromCar(void) { - CAnimBlendAssociation *animAssoc; AnimationId enterAnim; bool dontRunAnim = false; - PedLineUpPhase lineUpType; if (!m_pVehicleAnim) { CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 100.0f); - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SIT); - if (!animAssoc) { - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSIT); - if (!animAssoc) { - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SITP); - if (!animAssoc) - animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SITPLO); - } + + AssocGroupId assocGroup; + if (m_pMyVehicle->IsBike()) { + enterAnim = ANIM_BIKE_HIT; + assocGroup = ((CBike*)m_pMyVehicle)->m_bikeAnimType; + + } else { + if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) { + if (bWillBeQuickJacked && m_vehEnterType == CAR_DOOR_LF) { + enterAnim = ANIM_CAR_QJACKED; + } else if (m_pMyVehicle->bLowVehicle) { + enterAnim = ANIM_CAR_LJACKED_LHS; + } else { + enterAnim = ANIM_CAR_JACKED_LHS; + } + } else if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) { + if (m_pMyVehicle->bLowVehicle) + enterAnim = ANIM_CAR_LJACKED_RHS; + else + enterAnim = ANIM_CAR_JACKED_RHS; + } else + dontRunAnim = true; + + assocGroup = ASSOCGRP_STD; } - if (animAssoc) - animAssoc->blendDelta = -1000.0f; - - if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) { - if (bWillBeQuickJacked) { - enterAnim = ANIM_CAR_QJACKED; - } else if (m_pMyVehicle->bLowVehicle) { - enterAnim = ANIM_CAR_LJACKED_LHS; - } else { - enterAnim = ANIM_CAR_JACKED_LHS; - } - } else if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) { - if (m_pMyVehicle->bLowVehicle) - enterAnim = ANIM_CAR_LJACKED_RHS; - else - enterAnim = ANIM_CAR_JACKED_RHS; - } else - dontRunAnim = true; - if (!dontRunAnim) - m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, enterAnim); + m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), assocGroup, enterAnim); m_pVehicleAnim->SetFinishCallback(PedSetDraggedOutCarCB, this); - lineUpType = LINE_UP_TO_CAR_START; + + if (m_pMyVehicle && m_pMyVehicle->IsBike()) { + LineUpPedWithCar(LINE_UP_TO_CAR_FALL); + } else { + LineUpPedWithCar(LINE_UP_TO_CAR_START); + } + return; + + } else if (m_pVehicleAnim->animId == ANIM_BIKE_HIT) { + LineUpPedWithCar(LINE_UP_TO_CAR_FALL); + } else if (m_pVehicleAnim->currentTime <= 1.4f) { m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); - lineUpType = LINE_UP_TO_CAR_START; + LineUpPedWithCar(LINE_UP_TO_CAR_START); + } else { - lineUpType = LINE_UP_TO_CAR_2; + LineUpPedWithCar(LINE_UP_TO_CAR_2); } - - LineUpPedWithCar(lineUpType); -#ifdef VC_PED_PORTS + + static float mult = 5.f; if (m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) { if (m_pMyVehicle) { - m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, NUM_STD_ANIMS, m_pVehicleAnim->currentTime * 5.0f); + m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, NUM_STD_ANIMS, m_pVehicleAnim->currentTime * mult); } } -#endif } void @@ -4575,6 +4593,7 @@ CPed::ClearInvestigateEvent(void) SetMoveState(PEDMOVE_WALK); } +// --MIAMI: Done void CPed::ClearLeader(void) { @@ -4836,19 +4855,15 @@ CPed::SetPointGunAt(CEntity *to) CAnimBlendAssociation *aimAssoc; - if (bCrouchWhenShooting && bIsDucking) { - if (!!curWeapon->m_bCrouchFire) { - aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(curWeapon)); - } + if (bCrouchWhenShooting && bIsDucking && GetCrouchFireAnim(curWeapon)) { + aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(curWeapon)); } else { aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE); } if (!aimAssoc || aimAssoc->blendDelta < 0.0f) { - if (bCrouchWhenShooting && bIsDucking) { - if (!!curWeapon->m_bCrouchFire) { - aimAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, GetCrouchFireAnim(curWeapon), 4.0f); - } + if (bCrouchWhenShooting && bIsDucking && GetCrouchFireAnim(curWeapon)) { + aimAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, GetCrouchFireAnim(curWeapon), 4.0f); } else { aimAssoc = CAnimManager::AddAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_WEAPON_FIRE); } @@ -5741,7 +5756,7 @@ CPed::SetWaitState(eWaitState state, void *time) if (!IsPedInControl()) return; - if (m_nWaitState == WAITSTATE_RIOT && state == WAITSTATE_FALSE) + if (m_nWaitState == WAITSTATE_RIOT && state != WAITSTATE_FALSE) return; if (state != m_nWaitState) @@ -6429,8 +6444,10 @@ CPed::SetBuyIceCream(void) void CPed::SetChat(CEntity *chatWith, uint32 time) { - if(m_nPedState != PED_CHAT) + if (m_nPedState != PED_CHAT) { + m_nLastPedState = PED_NONE; SetStoredState(); + } SetPedState(PED_CHAT); SetMoveState(PEDMOVE_STILL); @@ -6510,6 +6527,7 @@ CPed::SetDead(void) CEventList::RegisterEvent(EVENT_DEAD_PED, EVENT_ENTITY_PED, this, nil, 1000); } +// --MIAMI: Done void CPed::SetSeek(CEntity *seeking, float distanceToCountDone) { @@ -6519,24 +6537,25 @@ CPed::SetSeek(CEntity *seeking, float distanceToCountDone) if (m_nPedState == PED_SEEK_ENTITY && m_pSeekTarget == seeking) return; - if (!seeking) + if (!seeking || m_nPedState == PED_FOLLOW_PATH) return; if (m_nPedState != PED_SEEK_ENTITY) SetStoredState(); - m_nPedState = PED_SEEK_ENTITY; + SetPedState(PED_SEEK_ENTITY); m_distanceToCountSeekDone = distanceToCountDone; m_pSeekTarget = seeking; m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget); SetMoveState(PEDMOVE_STILL); } +// --MIAMI: Done void CPed::SetSeek(CVector pos, float distanceToCountDone) { if (!IsPedInControl() - || (m_nPedState == PED_SEEK_POS && m_vecSeekPos.x == pos.x && m_vecSeekPos.y == pos.y)) + || (m_nPedState == PED_SEEK_POS && m_vecSeekPos.x == pos.x && m_vecSeekPos.y == pos.y) || m_nPedState == PED_FOLLOW_PATH) return; if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm) { @@ -6546,7 +6565,7 @@ CPed::SetSeek(CVector pos, float distanceToCountDone) if (m_nPedState != PED_SEEK_POS) SetStoredState(); - m_nPedState = PED_SEEK_POS; + SetPedState(PED_SEEK_POS); m_distanceToCountSeekDone = distanceToCountDone; m_vecSeekPos = pos; } @@ -8094,6 +8113,7 @@ CPed::Wait(void) RestoreHeadingRate(); } +// --MIAMI: Done bool CPed::Seek(void) { @@ -8112,7 +8132,7 @@ CPed::Seek(void) false, true, false, false, false, false); if (obstacle) { - if (!obstacle->IsVehicle() || ((CVehicle*)obstacle)->m_vehType == VEHICLE_TYPE_CAR) { + if (!obstacle->IsVehicle() || ((CVehicle*)obstacle)->IsCar()) { distanceToCountItDone = 2.5f; } else { CVehicleModelInfo *vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(obstacle->GetModelIndex()); @@ -8128,6 +8148,13 @@ CPed::Seek(void) if (!m_pSeekTarget && m_nPedState == PED_SEEK_ENTITY) ClearSeek(); + if (m_objective == OBJECTIVE_FOLLOW_PED_IN_FORMATION && !m_pedInObjective) { + m_objective = OBJECTIVE_NONE; + ClearObjective(); + SetWanderPath(0); + return false; + } + float seekPosDist = (m_vecSeekPos - GetPosition()).Magnitude2D(); if (seekPosDist < 2.0f || m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT) { @@ -8163,7 +8190,9 @@ CPed::Seek(void) } } - if (seekPosDist >= distanceToCountItDone) { + CVector *nextNode = SeekFollowingPath(); + + if (nextNode || seekPosDist >= distanceToCountItDone) { if (bIsRunning && nextMove != PEDMOVE_SPRINT) nextMove = PEDMOVE_RUN; @@ -8200,10 +8229,17 @@ CPed::Seek(void) m_actionY = 0; } } + } else { - m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints( - m_vecSeekPos.x, m_vecSeekPos.y, - GetPosition().x, GetPosition().y); + if (nextNode) { + m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints( + nextNode->x, nextNode->y, + GetPosition().x, GetPosition().y); + } else { + m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints( + m_vecSeekPos.x, m_vecSeekPos.y, + GetPosition().x, GetPosition().y); + } float neededTurn = Abs(m_fRotationDest - m_fRotationCur); @@ -8237,7 +8273,7 @@ CPed::Seek(void) } if (m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || m_objective == OBJECTIVE_SPRINT_TO_COORD || - m_objective == OBJECTIVE_GOTO_AREA_ANY_MEANS) { + m_objective == OBJECTIVE_GOTO_AREA_ANY_MEANS || IsUseAttractorObjective(m_objective)) { if (m_pNextPathNode) m_pNextPathNode = nil; @@ -8247,16 +8283,30 @@ CPed::Seek(void) bUsePedNodeSeek = true; } - if (SeekFollowingPath(nil)) - m_nCurPathNode++; - return true; } -bool -CPed::SeekFollowingPath(CVector *unused) +CVector* +CPed::SeekFollowingPath(void) { - return m_nCurPathNode <= m_nPathNodes && m_nPathNodes; + // unused + if (!vecNextPathNodeInitialized) + vecNextPathNodeInitialized = true; + + if (m_nCurPathNodeId >= m_nNumPathNodes || m_nNumPathNodes == 0) + return nil; + + vecNextPathNode = m_pathNodesToGo[m_nCurPathNodeId]->GetPosition(); + + if ((vecNextPathNode - GetPosition()).Magnitude2D() < m_distanceToCountSeekDone) { + m_nCurPathNodeId++; + if (m_nCurPathNodeId < m_nNumPathNodes) + m_pCurPathNode = m_pathNodesToGo[m_nCurPathNodeId]; + } + if (m_nCurPathNodeId == m_nNumPathNodes) + return nil; + else + return &vecNextPathNode; } void @@ -8442,31 +8492,34 @@ CPed::Flee(void) } +// --MIAMI: Done void CPed::FollowPath(void) { - m_vecSeekPos.x = m_stPathNodeStates[m_nCurPathNode].x; - m_vecSeekPos.y = m_stPathNodeStates[m_nCurPathNode].y; - m_vecSeekPos.z = GetPosition().z; - - // Mysterious code -/* int v4 = 0; - int maxNodeIndex = m_nPathNodes - 1; - if (maxNodeIndex > 0) { - if (maxNodeIndex > 8) { - while (v4 < maxNodeIndex - 8) - v4 += 8; - } + m_pCurPathNode = m_pathNodesToGo[m_nCurPathNodeId]; + if (m_pathNodeTimer && CTimer::GetTimeInMilliseconds() > m_pathNodeTimer) { + RestorePreviousState(); + ClearFollowPath(); + m_pathNodeTimer = 0; + } else { + if (m_pathNodesToGo[m_nCurPathNodeId]) { + m_vecSeekPos.x = m_pathNodesToGo[m_nCurPathNodeId]->GetPosition().x; + m_vecSeekPos.y = m_pathNodesToGo[m_nCurPathNodeId]->GetPosition().y; + m_vecSeekPos.z = GetPosition().z; - while (v4 < maxNodeIndex) - v4++; - - } -*/ - if (Seek()) { - m_nCurPathNode++; - if (m_nCurPathNode == m_nPathNodes) + if (Seek()) { + if (m_nCurPathNodeId == m_nNumPathNodes) { + RestorePreviousState(); + ClearFollowPath(); + SetFollowPath(m_followPathDestPos, m_followPathAbortDist, m_followPathMoveState, m_followPathWalkAroundEnt, + m_followPathTargetEnt, m_pathNodeTimer - CTimer::GetTimeInMilliseconds()); + } + } + } else { RestorePreviousState(); + ClearFollowPath(); + m_pathNodeTimer = 0; + } } } @@ -10534,17 +10587,22 @@ CPed::ProcessControl(void) if (!bVehEnterDoorIsBlocked) { if (collidingVeh->GetStatus() != STATUS_PLAYER || CharCreatedBy == MISSION_CHAR) { - // VC calls SetDirectionToWalkAroundVehicle instead if ped is in PED_SEEK_CAR. - SetDirectionToWalkAroundObject(collidingVeh); - CWorld::Players[CWorld::PlayerInFocus].m_nLastBumpPlayerCarTimer = m_nPedStateTimer; + if (m_nPedState == PED_SEEK_CAR) { + SetDirectionToWalkAroundObject(collidingVeh); + CWorld::Players[CWorld::PlayerInFocus].m_nLastBumpPlayerCarTimer = m_nPedStateTimer; + } else { + SetDirectionToWalkAroundVehicle(collidingVeh); + } } else { if (CTimer::GetTimeInMilliseconds() >= CWorld::Players[CWorld::PlayerInFocus].m_nLastBumpPlayerCarTimer || m_nPedStateTimer >= CTimer::GetTimeInMilliseconds()) { - // VC calls SetDirectionToWalkAroundVehicle instead if ped is in PED_SEEK_CAR. - SetDirectionToWalkAroundObject(collidingVeh); - CWorld::Players[CWorld::PlayerInFocus].m_nLastBumpPlayerCarTimer = m_nPedStateTimer; - + if (m_nPedState == PED_SEEK_CAR) { + SetDirectionToWalkAroundObject(collidingVeh); + CWorld::Players[CWorld::PlayerInFocus].m_nLastBumpPlayerCarTimer = m_nPedStateTimer; + } else { + SetDirectionToWalkAroundVehicle(collidingVeh); + } } else if (m_fleeFrom != collidingVeh) { SetFlee(collidingVeh, 4000); bUsePedNodeSeek = false; @@ -14926,6 +14984,9 @@ CPed::SetSeekCar(CVehicle *car, uint32 doorNode) if (m_nPedState == PED_SEEK_CAR) return; + if (!CanSetPedState() || m_nPedState == PED_DRIVING) + return; + SetStoredState(); m_pSeekTarget = car; m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget); @@ -15024,7 +15085,13 @@ CanWeSeeTheCorner(CVector2D dist, CVector2D fwdOffset) } #endif -// This function looks completely same on VC. +// --MIAMI: Done +bool +CPed::SetDirectionToWalkAroundVehicle(CVehicle* veh) +{ + return SetFollowPath(m_vecSeekPos, 0.0f, m_nMoveState, veh, m_pedInObjective, m_nMoveState == PEDMOVE_WALK ? 2000 : 250); +} + void CPed::SetDirectionToWalkAroundObject(CEntity *obj) { @@ -16355,36 +16422,519 @@ CPed::SetSolicit(uint32 time) } } +// --MIAMI: Done bool -CPed::SetFollowPath(CVector dest, float radius, eMoveState state, CEntity* pFollowedPed, CEntity*, int time) +CPed::SetFollowPathStatic(void) { - // TODO(MIAMI): new follow - if (m_nPedState == PED_FOLLOW_PATH) - return false; + ClearFollowPath(); + if (sq(m_followPathAbortDist) > (GetPosition() - m_followPathDestPos).MagnitudeSqr() + && CWorld::IsWanderPathClear(GetPosition(), m_followPathDestPos, 0.5f, 4)) { - if (FindPlayerPed() != this) - return false; + RestorePreviousState(); + if (m_objective == OBJECTIVE_NONE) { + if (m_followPathMoveState == PEDMOVE_RUN) + SetObjective(OBJECTIVE_RUN_TO_AREA, m_followPathDestPos); + else + SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, m_followPathDestPos); + } + SetPedState(PED_NONE); + return true; + } else { + ThePaths.DoPathSearch(PATH_PED, GetPosition(), -1, m_followPathDestPos, m_pathNodesToGo, &m_nNumPathNodes, + ARRAY_SIZE(m_pathNodesToGo), nil, nil, 999999.0f, -1); - if ((dest - GetPosition()).Magnitude() <= 2.0f) - return false; + if (m_nNumPathNodes != 0) { + if (m_nNumPathNodes > 0 && m_pathNodesToGo[0] != m_pCurPathNode) { + for (int i = 0; i < ARRAY_SIZE(m_pathNodesToGo) - 1; i++) { + m_pathNodesToGo[i] = m_pathNodesToGo[i+1]; + } + --m_nNumPathNodes; + } + for (int i = 0; i < m_nNumPathNodes; ++i) { + CVector nodePos = m_pathNodesToGo[i]->GetPosition(); + if (sq(m_followPathAbortDist) > (nodePos - m_followPathDestPos).MagnitudeSqr() + && CWorld::IsWanderPathClear(nodePos, m_followPathDestPos, 0.5f, 4)) { - CVector pointPoses[7]; - int16 pointsFound; - CPedPath::CalcPedRoute(0, GetPosition(), dest, pointPoses, &pointsFound, 7); - for(int i = 0; i < pointsFound; i++) { - m_stPathNodeStates[i].x = pointPoses[i].x; - m_stPathNodeStates[i].y = pointPoses[i].y; + m_nNumPathNodes = i + 1; + break; + } + } + + m_nCurPathNodeId = 0; + if (m_pCurPathNode) { + for (int j = 0; j < m_nNumPathNodes; ++j) { + if (m_pathNodesToGo[j] == m_pCurPathNode) { + m_nCurPathNodeId = j; + break; + } + } + } + m_pCurPathNode = m_pathNodesToGo[m_nCurPathNodeId]; + PedState oldLastState = m_nLastPedState; + m_nLastPedState = PED_NONE; + SetStoredState(); + if (m_nLastPedState == PED_NONE) + m_nLastPedState = oldLastState; + + m_nPedState = PED_FOLLOW_PATH; + m_nMoveState = m_followPathMoveState; + return true; + } else { + RestorePreviousState(); + if (m_objective == OBJECTIVE_NONE) { + if (m_followPathMoveState == PEDMOVE_RUN) + SetObjective(OBJECTIVE_RUN_TO_AREA, m_followPathDestPos); + else + SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, m_followPathDestPos); + } + SetPedState(PED_NONE); + return true; + } + } +} + +// --MIAMI: Done +bool +CPed::SetFollowPath(CVector dest, float radius, eMoveState state, CEntity* walkAroundEnt, CEntity* targetEnt, int time) +{ + if (m_nPedState == PED_FOLLOW_PATH) { + bool stopFollow = false; + if (walkAroundEnt && walkAroundEnt != m_followPathWalkAroundEnt || !walkAroundEnt && m_followPathWalkAroundEnt + || targetEnt && targetEnt != m_followPathTargetEnt || !targetEnt && m_followPathTargetEnt) { + stopFollow = true; + + } else if (targetEnt) { + if ((targetEnt->GetPosition() - m_followPathDestPos).MagnitudeSqr() > 1.f) + stopFollow = true; + + } else if (!walkAroundEnt && !targetEnt) { + if ((dest - m_followPathDestPos).MagnitudeSqr() > 1.f) + stopFollow = true; + } + + if (!stopFollow) + return false; + } + m_pathNodeTimer = CTimer::GetTimeInMilliseconds() + time; + m_followPathWalkAroundEnt = walkAroundEnt; + m_followPathTargetEnt = targetEnt; + m_distanceToCountSeekDone = 0.5f; + + bool weHaveTargetPed = targetEnt && targetEnt->IsPed(); + bool useDestVec = !weHaveTargetPed; + + CVector targetPos; + if (useDestVec) + targetPos = dest; + else + targetPos = targetEnt->GetPosition(); + + m_followPathDestPos = targetPos; + if (targetEnt && m_nPedState == PED_SEEK_POS) { + m_followPathDestPos = m_vecSeekPos; } - m_nCurPathNode = 0; - m_nPathNodes = pointsFound; - if (m_nPathNodes < 1) - return false; + float newRadius = radius > 0.f ? radius : 20.f; + bool useGivenPedMove = true; - SetStoredState(); - m_nPedState = PED_FOLLOW_PATH; - SetMoveState(PEDMOVE_WALK); - return true; + m_followPathAbortDist = newRadius; + + if (state != PEDMOVE_RUN && state != PEDMOVE_WALK) + useGivenPedMove = false; + + if (useGivenPedMove) + m_followPathMoveState = state; + else + m_followPathMoveState = PEDMOVE_WALK; + + if (m_followPathWalkAroundEnt) + return SetFollowPathDynamic(); + else + return SetFollowPathStatic(); +} + +// --MIAMI: Done +bool +CPed::SetFollowPathDynamic(void) +{ + CVector colBoxMin = m_followPathWalkAroundEnt->GetColModel()->boundingBox.min + CVector(-0.35f, -0.35f, 0.f); + CVector colBoxMax = m_followPathWalkAroundEnt->GetColModel()->boundingBox.max + CVector(0.35f, 0.35f, 0.f); + + CVector colCornerOffsets[4]; // BL, BR, TR, TL + colCornerOffsets[0] = CVector(colBoxMin.x, colBoxMin.y, 0.f); + colCornerOffsets[1] = CVector(colBoxMax.x, colBoxMin.y, 0.f); + colCornerOffsets[2] = CVector(colBoxMax.x, colBoxMax.y, 0.f); + colCornerOffsets[3] = CVector(colBoxMin.x, colBoxMax.y, 0.f); + + if (m_followPathWalkAroundEnt->IsVehicle() && ((CVehicle*)m_followPathWalkAroundEnt)->IsUpsideDown()) { + CVector old0 = colCornerOffsets[0]; + colCornerOffsets[0] = colCornerOffsets[1]; + colCornerOffsets[1] = old0; + CVector old2 = colCornerOffsets[2]; + colCornerOffsets[2] = colCornerOffsets[3]; + colCornerOffsets[3] = old2; + } + + CVector colCornerPos[4]; // global. again BL, BR, TR, TL + float dotProdCorrection[4]; + CVector colBoxPlaneNormal[4]; + + for (int i=0; i<4; i++) { + colCornerPos[i] = m_followPathWalkAroundEnt->GetMatrix() * colCornerOffsets[i]; + colCornerPos[i].z = GetPosition().z; + } + + CVector prevColCorner = colCornerPos[3]; // top left + CVector *curCornerPos; + CVector fwdToNextCorner; + + for (int i=0; i<4; i++) { + curCornerPos = &colCornerPos[i]; + fwdToNextCorner = *curCornerPos - prevColCorner; + fwdToNextCorner.Normalise(); + colBoxPlaneNormal[i] = CrossProduct(fwdToNextCorner, CVector(0.f, 0.f, 1.f)); + dotProdCorrection[i] = -DotProduct(prevColCorner, colBoxPlaneNormal[i]); // yes, dp with global coord, as if in distance to plane calculation + prevColCorner = *curCornerPos; + } + + bool weReGoingGreat = false; + CVector startVecCandidate = GetPosition(); + CVector targetVecCandidate = m_followPathDestPos; + CVector dirToGo = targetVecCandidate - startVecCandidate; + dirToGo.Normalise(); + CVector ourPos = startVecCandidate; + + for (int i=0; i<4; i++) { + CVector curPlaneNormal = colBoxPlaneNormal[i]; + float minusGlobalCornerPos = dotProdCorrection[i]; + float startVecDistToPlane = DotProduct(curPlaneNormal, startVecCandidate) + minusGlobalCornerPos; + +#define FRONT_OF_PLANE 1 +#define ON_THE_PLANE 0 +#define BEHIND_THE_PLANE -1 + + int8 startVecStatus; + int8 targetVecStatus; + + if (startVecDistToPlane > 0.1f) + startVecStatus = FRONT_OF_PLANE; + else if (startVecDistToPlane < -0.1f) + startVecStatus = BEHIND_THE_PLANE; + else + startVecStatus = ON_THE_PLANE; + + float targetVecDistToPlane = DotProduct(curPlaneNormal, targetVecCandidate) + minusGlobalCornerPos; + if (targetVecDistToPlane > 0.1f) + targetVecStatus = FRONT_OF_PLANE; + else if (targetVecDistToPlane < -0.1f) + targetVecStatus = BEHIND_THE_PLANE; + else + targetVecStatus = ON_THE_PLANE; + + + if (startVecStatus == BEHIND_THE_PLANE || targetVecStatus == BEHIND_THE_PLANE) { + if (startVecStatus == BEHIND_THE_PLANE && targetVecStatus == FRONT_OF_PLANE) { + targetVecCandidate = -(DotProduct(ourPos, curPlaneNormal) + minusGlobalCornerPos) / DotProduct(dirToGo, curPlaneNormal) * dirToGo + ourPos; + + } else if (startVecStatus == FRONT_OF_PLANE && targetVecStatus == BEHIND_THE_PLANE) { + startVecCandidate = -(DotProduct(ourPos, curPlaneNormal) + minusGlobalCornerPos) / DotProduct(dirToGo, curPlaneNormal) * dirToGo + ourPos; + } + } else { + weReGoingGreat = true; + if (startVecStatus == ON_THE_PLANE) + startVecCandidate += (0.1f - startVecDistToPlane) * curPlaneNormal; + + if (targetVecStatus == ON_THE_PLANE) + targetVecCandidate += (0.1f - targetVecDistToPlane) * curPlaneNormal; + } +#undef FRONT_OF_PLANE +#undef ON_THE_PLANE +#undef BEHIND_THE_PLANE + } + + if (!weReGoingGreat) { + CVector avgOfColPoints = (colCornerPos[0] + colCornerPos[1] + colCornerPos[2] + colCornerPos[3]) / 4.f; + float radius = 0.0f; + + // Find radius of col box of the entity we follow + for (int i=0; i<4; i++) { + float cornerDist = (colCornerPos[i] - avgOfColPoints).MagnitudeSqr(); + + if (cornerDist > radius) + radius = cornerDist; + } + CColSphere followedEntSphere; + followedEntSphere.Set(Sqrt(radius) * 1.1f, avgOfColPoints, 0, 0); + CVector distToDest = m_followPathDestPos - GetPosition(); + distToDest.z = 0.f; + + if (distToDest.Magnitude() == 0.0f) + return false; + + distToDest.Normalise(); + + // Entity we follow doesn't go toward destination anymore, abort the following. + if (!followedEntSphere.IntersectRay(GetPosition(), distToDest, startVecCandidate, targetVecCandidate)) { + m_pathNodeTimer = 0; + if (m_nPedState == PED_FOLLOW_PATH) + RestorePreviousState(); + + return false; + } + } + + int lastPlaneBehindUs = -1; + int lastPlaneInFrontOfUs = -1; + CVector oldstartVecCandidate = startVecCandidate; + CVector oldDirToGo = targetVecCandidate - startVecCandidate; + oldDirToGo.Normalise(); + + + // At least one plane should be between target and us. + for (int i=0; i<4; i++) { + CVector curPlaneNormal = colBoxPlaneNormal[i]; + float minusGlobalCornerPos = dotProdCorrection[i]; + float startVecDistToPlane = DotProduct(curPlaneNormal, startVecCandidate) + minusGlobalCornerPos; + float targetVecDistToPlane = DotProduct(curPlaneNormal, targetVecCandidate) + minusGlobalCornerPos; + + if (startVecDistToPlane > 0.0f && targetVecDistToPlane < 0.0f) { + lastPlaneInFrontOfUs = i; + startVecCandidate = -(DotProduct(oldstartVecCandidate, curPlaneNormal) + minusGlobalCornerPos) / DotProduct(oldDirToGo, curPlaneNormal) * oldDirToGo + oldstartVecCandidate; + + } else if (startVecDistToPlane < 0.0f && targetVecDistToPlane > 0.0f) { + lastPlaneBehindUs = i; + targetVecCandidate = -(DotProduct(oldstartVecCandidate, curPlaneNormal) + minusGlobalCornerPos) / DotProduct(oldDirToGo, curPlaneNormal) * oldDirToGo + oldstartVecCandidate; + } + } + + CVector destsVariant1[5]; + CVector destsVariant2[5]; + + // If not, followed entity diverged from route and we should abort the following. + if (lastPlaneBehindUs >= 0 && lastPlaneInFrontOfUs >= 0) { + + int planeInFrontCircular = (lastPlaneInFrontOfUs + 4) % -4; + int planeInFrontCircularMinusOne = (lastPlaneInFrontOfUs + 3) % -4; + int planeInBehindCircular = (lastPlaneBehindUs + 4) % -4; + int planeInBehindCircularMinusOne = (lastPlaneBehindUs + 3) % -4; + + destsVariant1[0] = GetPosition(); + destsVariant1[1] = colCornerPos[planeInFrontCircularMinusOne]; + + int destsVar1LastNode = 2; + for(; planeInFrontCircularMinusOne != planeInBehindCircular; destsVar1LastNode++) { + planeInFrontCircularMinusOne = (planeInFrontCircularMinusOne + 3) % -4; + destsVariant1[destsVar1LastNode] = colCornerPos[planeInFrontCircularMinusOne]; + } + destsVariant1[destsVar1LastNode] = m_followPathDestPos; + + destsVariant2[0] = GetPosition(); + destsVariant2[1] = colCornerPos[planeInFrontCircular]; + + int destsVar2LastNode = 2; + for (; planeInFrontCircular != planeInBehindCircularMinusOne; destsVar2LastNode++) { + planeInFrontCircular = (planeInFrontCircular + 5) % -4; + destsVariant2[destsVar2LastNode] = colCornerPos[planeInFrontCircular]; + } + destsVariant2[destsVar2LastNode] = m_followPathDestPos; + CEntity *foundEnt1 = nil; + int dests1isOk = true; + int nodeToStopDestsVar1 = destsVar1LastNode + 1; + CVector avgOfColPoints2 = (colCornerPos[0] + colCornerPos[1] + colCornerPos[2] + colCornerPos[3]) / 4.f; + + CVector prevDestVar1 = destsVariant1[0]; + + for (int i = 1; i < destsVar1LastNode + 1; i++) { + CVector *curDestVar1 = &destsVariant1[i]; + + CVector routeNormalHalf = *curDestVar1 - prevDestVar1; + routeNormalHalf.z = 0.f; + routeNormalHalf.Normalise(); + routeNormalHalf *= 0.5f; + + float oldX = -routeNormalHalf.x; + routeNormalHalf.z = 0.0f; + routeNormalHalf.x = routeNormalHalf.y; + routeNormalHalf.y = oldX; + + if (DotProduct(*curDestVar1 - avgOfColPoints2, routeNormalHalf) < 0.0f) + routeNormalHalf *= -1.f; + + CColPoint foundCol; + bool foundObstacle = CWorld::ProcessLineOfSight(prevDestVar1, *curDestVar1, foundCol, foundEnt1, + true, true, true, true, false, false, false, false); + + if (!foundObstacle) + foundObstacle = CWorld::ProcessLineOfSight(prevDestVar1 + routeNormalHalf, *curDestVar1 + routeNormalHalf, foundCol, foundEnt1, true, true, true, true, false, false, false, false); + + if (foundObstacle) { + if (foundEnt1 == m_followPathWalkAroundEnt || foundEnt1 == this || foundEnt1 == m_pSeekTarget) { + foundEnt1 = nil; + + } else { + if (!foundEnt1->IsPed()) { + dests1isOk = false; + nodeToStopDestsVar1 = i; + break; + } + if (((CPed*)foundEnt1)->m_nPedState == PED_IDLE) { + dests1isOk = false; + nodeToStopDestsVar1 = i; + break; + } + if (DotProduct(*curDestVar1 - prevDestVar1, foundEnt1->GetForward()) < 0.f) { + dests1isOk = false; + nodeToStopDestsVar1 = i; + break; + } + if (((CPed*)foundEnt1)->m_pedInObjective == this) { + dests1isOk = false; + nodeToStopDestsVar1 = i; + break; + } + } + } + prevDestVar1 = *curDestVar1; + } + CEntity *foundEnt2 = nil; + int dests2isOk = true; + int nodeToStopDestsVar2 = destsVar2LastNode + 1; + + CVector prevDestVar2 = destsVariant2[0]; + + for (int i = 1; i < destsVar2LastNode + 1; i++) { + CVector *curDestVar2 = &destsVariant2[i]; + + CVector routeNormalHalf = *curDestVar2 - prevDestVar2; + routeNormalHalf.z = 0.f; + routeNormalHalf.Normalise(); + routeNormalHalf *= 0.5f; + + float oldX = -routeNormalHalf.x; + routeNormalHalf.z = 0.0f; + routeNormalHalf.x = routeNormalHalf.y; + routeNormalHalf.y = oldX; + + if (DotProduct(*curDestVar2 - avgOfColPoints2, routeNormalHalf) < 0.0f) + routeNormalHalf *= -1.f; + + CColPoint foundCol; + bool foundObstacle = CWorld::ProcessLineOfSight(prevDestVar2, *curDestVar2, foundCol, foundEnt2, + true, true, true, true, false, false, false, false); + + if (!foundObstacle) + foundObstacle = CWorld::ProcessLineOfSight(prevDestVar2 + routeNormalHalf, *curDestVar2 + routeNormalHalf, foundCol, foundEnt2, true, true, true, true, false, false, false, false); + + if (foundObstacle) { + if (foundEnt2 == m_followPathWalkAroundEnt || foundEnt2 == this || foundEnt2 == m_pSeekTarget) { + foundEnt2 = 0; + } else { + if (!foundEnt2->IsPed()) { + dests2isOk = false; + nodeToStopDestsVar2 = i; + break; + } + if (((CPed*)foundEnt2)->m_nPedState == PED_IDLE) { + dests2isOk = false; + nodeToStopDestsVar2 = i; + break; + } + if (DotProduct(*curDestVar2 - prevDestVar2, foundEnt2->GetForward()) < 0.f) { + dests2isOk = false; + nodeToStopDestsVar2 = i; + break; + } + if (((CPed*)foundEnt2)->m_pedInObjective == this) { + dests2isOk = false; + nodeToStopDestsVar2 = i; + break; + } + } + } + prevDestVar2 = *curDestVar2; + } + + float destTotalLengthVar1 = 0.0f; + for(int i=0; i < destsVar1LastNode; i++){ + destTotalLengthVar1 += (destsVariant1[i + 1] - destsVariant1[i]).Magnitude(); + } + + float destTotalLengthVar2 = 0.0f; + for (int i = 0; i < destsVar2LastNode; i++) { + destTotalLengthVar2 += (destsVariant2[i + 1] - destsVariant2[i]).Magnitude(); + } + + int destVariantToUse; + if (dests1isOk && dests2isOk) { + if (destTotalLengthVar1 < destTotalLengthVar2) + destVariantToUse = 1; + else + destVariantToUse = 2; + + } else if (dests1isOk) { + destVariantToUse = 1; + + } else if (dests2isOk) { + destVariantToUse = 2; + + } else if (nodeToStopDestsVar1 == 1 && nodeToStopDestsVar2 > 1) { + destVariantToUse = 2; + + } else if (nodeToStopDestsVar1 > 1 && nodeToStopDestsVar2 == 1) { + destVariantToUse = 1; + + } else if (foundEnt1 == foundEnt2) { + if (destTotalLengthVar1 < destTotalLengthVar2) + destVariantToUse = 1; + else + destVariantToUse = 2; + + } else if (foundEnt1->GetColModel()->boundingSphere.radius >= foundEnt2->GetColModel()->boundingSphere.radius) { + destVariantToUse = 2; + } else { + destVariantToUse = 1; + } + + if (destVariantToUse == 1) { + ClearFollowPath(); + for (int i = 1; i < destsVar1LastNode; i++) { + CPathNode* nextNode = &m_pathNodeObjPool[m_nNumPathNodes]; + nextNode->SetPosition(destsVariant1[i]); + m_pathNodesToGo[m_nNumPathNodes++] = nextNode; + } + } else if (destVariantToUse == 2) { + ClearFollowPath(); + for (int i = 1; i < destsVar2LastNode; i++) { + CPathNode *nextNode = &m_pathNodeObjPool[m_nNumPathNodes]; + nextNode->SetPosition(destsVariant2[i]); + m_pathNodesToGo[m_nNumPathNodes++] = nextNode; + } + } + if (m_nNumPathNodes != 0) { + PedState oldLastState = m_nLastPedState; + m_nLastPedState = PED_NONE; + SetStoredState(); + if (m_nLastPedState == PED_NONE) + m_nLastPedState = oldLastState; + + m_nPedState = PED_FOLLOW_PATH; + m_nMoveState = m_followPathMoveState; + return true; + + } else { + m_pathNodeTimer = 0; + if (m_nPedState == PED_FOLLOW_PATH) + RestorePreviousState(); + + return false; + } + } else { + m_pathNodeTimer = 0; + if (m_nPedState == PED_FOLLOW_PATH) + RestorePreviousState(); + + return false; + } } void @@ -18942,11 +19492,11 @@ CPed::RequestDelayedWeapon() void CPed::ClearFollowPath() { - for (int i = 0; i < ARRAY_SIZE(m_pPathNodesStates); i++) { - m_pPathNodesStates[i] = nil; + for (int i = 0; i < ARRAY_SIZE(m_pathNodesToGo); i++) { + m_pathNodesToGo[i] = nil; } - m_nPathNodes = 0; - m_nCurPathNode = 0; + m_nNumPathNodes = 0; + m_nCurPathNodeId = 0; } // --MIAMI: Done @@ -19303,7 +19853,7 @@ CPed::DriveVehicle(void) (0.0f == bike->m_aWheelTimer[2] && 0.0f == bike->m_aWheelTimer[3])) { if (0.0f == bike->m_aWheelTimer[2] && 0.0f == bike->m_aWheelTimer[3] && - (bike->GetForward().y < 0.0f && (bike->m_aWheelTimer[0] != 0.0f || bike->m_aWheelTimer[1] != 0.0f))) { + (bike->GetForward().z < 0.0f && (bike->m_aWheelTimer[0] != 0.0f || bike->m_aWheelTimer[1] != 0.0f))) { stoppieAng = bike->pBikeHandling->fStoppieAng; if (stoppieAng - bike->GetForward().z > 0.6f * stoppieAng) diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 6338b889..6fd96b66 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -10,11 +10,11 @@ #include "Weapon.h" #include "WeaponInfo.h" #include "AnimationId.h" +#include "PathFind.h" #define FEET_OFFSET 1.04f #define CHECK_NEARBY_THINGS_MAX_DIST 15.0f -struct CPathNode; class CAccident; class CObject; class CFire; @@ -346,6 +346,9 @@ enum eMoveState { PEDMOVE_NONE, PEDMOVE_STILL, PEDMOVE_WALK, + + PEDMOVE_UNK, + PEDMOVE_RUN, PEDMOVE_SPRINT, }; @@ -521,13 +524,20 @@ public: int32 m_nPrevMoveState; eWaitState m_nWaitState; uint32 m_nWaitTimer; - void *m_pPathNodesStates[8]; // unused, probably leftover from VC - CVector2D m_stPathNodeStates[10]; - uint16 m_nPathNodes; - int16 m_nCurPathNode; - int8 m_nPathDir; - CPathNode *m_pLastPathNode; - CPathNode *m_pNextPathNode; + CPathNode* m_pathNodesToGo[8]; + int16 m_nNumPathNodes; + int16 m_nCurPathNodeId; + CEntity* m_followPathWalkAroundEnt; + CEntity* m_followPathTargetEnt; + uint32 m_pathNodeTimer; + CPathNode m_pathNodeObjPool[8]; + CPathNode* m_pCurPathNode; + char m_nPathDir; + CPathNode* m_pLastPathNode; + CPathNode* m_pNextPathNode; + CVector m_followPathDestPos; + float m_followPathAbortDist; + eMoveState m_followPathMoveState; float m_fHealth; float m_fArmour; uint32 m_nExtendedRangeTimer; @@ -756,6 +766,7 @@ public: void RemoveInCarAnims(void); void CollideWithPed(CPed*); void SetDirectionToWalkAroundObject(CEntity*); + bool SetDirectionToWalkAroundVehicle(CVehicle*); void RemoveWeaponAnims(int, float); void CreateDeadPedMoney(void); void CreateDeadPedWeaponPickups(void); @@ -778,7 +789,7 @@ public: bool FindBestCoordsFromNodes(CVector, CVector*); void Wait(void); void ProcessObjective(void); - bool SeekFollowingPath(CVector*); + CVector *SeekFollowingPath(void); void Flee(void); void FollowPath(void); CVector GetFormationPosition(void); diff --git a/src/peds/PedChat.cpp b/src/peds/PedChat.cpp index 78302844..ee639a50 100644 --- a/src/peds/PedChat.cpp +++ b/src/peds/PedChat.cpp @@ -4,47 +4,65 @@ #include "General.h" #include "Ped.h" +// --MIAMI: Done // Corresponds to ped sounds (from SOUND_PED_DEATH to SOUND_PED_TAXI_CALL) -PedAudioData CommentWaitTime[39] = { - {500, 800, 500, 2}, - {500, 800, 500, 2}, - {500, 800, 500, 2}, - {500, 800, 500, 2}, - {100, 2, 100, 2}, - {700, 500, 1000, 500}, - {700, 500, 1000, 500}, - {5000, 2000, 15000, 3000}, - {5000, 2000, 15000, 3000}, - {5000, 2000, 15000, 3000}, - {6000, 6000, 6000, 6000}, - {1000, 1000, 2000, 2000}, - {1000, 500, 2000, 1500}, - {1000, 500, 2000, 1500}, - {800, 200, 1000, 500}, - {800, 200, 1000, 500}, - {800, 400, 2000, 1000}, - {800, 400, 2000, 1000}, - {400, 300, 2000, 1000}, - {2000, 1000, 2500, 1500}, - {200, 200, 200, 200}, - {6000, 3000, 5000, 6000}, - {6000, 3000, 9000, 5000}, - {6000, 3000, 9000, 5000}, - {6000, 3000, 9000, 5000}, - {400, 300, 4000, 1000}, - {400, 300, 4000, 1000}, - {400, 300, 4000, 1000}, - {1000, 500, 3000, 1000}, - {1000, 500, 1000, 1000}, - {3000, 2000, 3000, 2000}, - {1000, 500, 3000, 6000}, - {1000, 500, 2000, 4000}, - {1000, 500, 2000, 5000}, - {1000, 500, 3000, 2000}, - {1600, 1000, 2000, 2000}, - {3000, 2000, 5000, 3000}, - {1000, 1000, 1000, 1000}, - {1000, 1000, 5000, 5000}, +PedAudioData CommentWaitTime[56] = { + { 500, 800, 500, 2 }, + { 500, 800, 500, 2 }, + { 500, 800, 500, 2 }, + { 500, 800, 500, 2 }, + { 100, 2, 100, 2 }, + { 500, 500, 2000, 1000 }, + { 2000, 50, 2050, 1000 }, + { 5000, 2000, 7000, 3000 }, + { 5000, 2000, 7000, 3000 }, + { 300, 200, 500, 200 }, + { 3000, 1000, 4000, 1000 }, + { 6000, 6000, 6000, 6000 }, + { 4000, 1000, 5000, 1000 }, + { 3000, 1000, 4000, 1000 }, + { 1000, 1000, 2000, 2000 }, + { 1000, 500, 2000, 1500 }, + { 1700, 1000, 3000, 1000 }, + { 800, 200, 1000, 500 }, + { 800, 200, 1000, 500 }, + { 800, 400, 2000, 1000 }, + { 800, 400, 2000, 1000 }, + { 2000, 2000, 4000, 4000 }, + { 2000, 2000, 4000, 1000 }, + { 4000, 1000, 5000, 1000 }, + { 800, 400, 1200, 500 }, + { 5000, 1000, 6000, 2000 }, + { 5000, 1000, 6000, 2000 }, + { 5000, 1000, 6000, 2000 }, + { 5000, 1000, 6000, 2000 }, + { 5000, 1000, 6000, 2000 }, + { 5000, 1000, 6000, 2000 }, + { 5000, 1000, 6000, 2000 }, + { 4000, 2000, 7000, 2000 }, + { 1000, 300, 2000, 1000 }, + { 1500, 1000, 2500, 1000 }, + { 200, 200, 200, 200 }, + { 2000, 1000, 4000, 1000 }, + { 2000, 1000, 4000, 1000 }, + { 1000, 500, 3000, 1000 }, + { 1000, 500, 1000, 1000 }, + { 3000, 2000, 5000, 1000 }, + { 3000, 2000, 5000, 1000 }, + { 3000, 2000, 3000, 2000 }, + { 2000, 1000, 3000, 1000 }, + { 2500, 1000, 5000, 5000 }, + { 2000, 1000, 3000, 2000 }, + { 4000, 1000, 5000, 1000 }, + { 1000, 500, 2000, 4000 }, + { 1000, 500, 2000, 5000 }, + { 2000, 500, 2500, 500 }, + { 1000, 500, 3000, 2000 }, + { 1600, 1000, 2000, 2000 }, + { 2000, 1000, 4000, 2000 }, + { 1500, 1000, 2500, 1000 }, + { 1000, 1000, 5000, 5000 }, + { 0, 0, 0, 0 } }; // --MIAMI: Done @@ -54,7 +72,7 @@ CPed::ServiceTalkingWhenDead(void) return m_queuedSound == SOUND_PED_DEATH; } -// --MIAMI: Done except ifdef +// --MIAMI: Done void CPed::ServiceTalking(void) { @@ -84,7 +102,7 @@ CPed::ServiceTalking(void) } } -// --MIAMI: Done except ifdef +// --MIAMI: Done void CPed::Say(uint16 audio) { From 0741fd5b1d9bd0249f40daa85e679b6e9180602c Mon Sep 17 00:00:00 2001 From: aap Date: Sun, 14 Jun 2020 23:15:56 +0200 Subject: [PATCH 10/18] some more camera stuff --- src/core/Cam.cpp | 898 ++++++++++++++++------------------- src/core/Camera.h | 23 +- src/core/World.cpp | 34 +- src/core/World.h | 4 +- src/modelinfo/ModelIndices.h | 15 + 5 files changed, 453 insertions(+), 521 deletions(-) diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 954e8282..62ea950e 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -39,6 +39,7 @@ bool CCamera::bFreeCam; int nPreviousMode = -1; #endif +//--MIAMI: done void CCam::Init(void) { @@ -86,9 +87,12 @@ CCam::Init(void) m_fBufferedTargetOrientation = 0.0f; m_fBufferedTargetOrientationSpeed = 0.0f; m_fDimensionOfHighestNearCar = 0.0f; - m_fRoadOffSet = 0.0f; } +float PLAYERPED_LEVEL_SMOOTHING_CONST_INV = 0.6f; +float PLAYERPED_TREND_SMOOTHING_CONST_INV = 0.8f; + +//--MIAMI: done void CCam::Process(void) { @@ -96,6 +100,9 @@ CCam::Process(void) float TargetSpeedVar = 0.0f; float TargetOrientation = 0.0f; + static CVector SmoothedPos(0.0f, 0.0f, 10000.0f); + static CVector SmoothedSpeed(0.0f, 0.0f, 0.0f); + if(CamTargetEntity == nil) CamTargetEntity = TheCamera.pTargetEntity; @@ -118,7 +125,11 @@ CCam::Process(void) Fwd.x = CamTargetEntity->GetForward().x; Fwd.y = CamTargetEntity->GetForward().y; Fwd.Normalise(); - // Game normalizes again here manually. useless, so skipped + float FwdLength = Fwd.Magnitude2D(); + if(FwdLength != 0.0f){ + Fwd.x /= FwdLength; + Fwd.y /= FwdLength; + } float FwdSpeedX = ((CVehicle*)CamTargetEntity)->GetMoveSpeed().x * Fwd.x; float FwdSpeedY = ((CVehicle*)CamTargetEntity)->GetMoveSpeed().y * Fwd.y; @@ -128,7 +139,27 @@ CCam::Process(void) TargetSpeedVar = -Min(Sqrt(SQR(FwdSpeedX) + SQR(FwdSpeedY))/1.8f, 0.5f); SpeedVar = 0.895f*SpeedVar + 0.105*TargetSpeedVar; }else{ - CameraTarget = CamTargetEntity->GetPosition(); + if(CamTargetEntity == FindPlayerPed()){ + // Some fancy smoothing of player position and speed + float LevelSmoothing = 1.0f - Pow(PLAYERPED_LEVEL_SMOOTHING_CONST_INV, CTimer::GetTimeStep()); + float TrendSmoothing = 1.0f - Pow(PLAYERPED_TREND_SMOOTHING_CONST_INV, CTimer::GetTimeStep()); + + CVector NewSmoothedPos, NewSmoothedSpeed; + if((SmoothedPos - CamTargetEntity->GetPosition()).MagnitudeSqr() > SQR(3.0f) || + CTimer::GetTimeStep() < 0.2f || Using3rdPersonMouseCam()){ + // Reset values + NewSmoothedPos = CamTargetEntity->GetPosition(); + NewSmoothedSpeed = CVector(0.0f, 0.0f, 0.0f); + }else{ + NewSmoothedPos = LevelSmoothing*CamTargetEntity->GetPosition() + (1.0f-LevelSmoothing)*(SmoothedPos + SmoothedSpeed*CTimer::GetTimeStep()); + NewSmoothedSpeed = TrendSmoothing*(NewSmoothedPos-SmoothedPos)/CTimer::GetTimeStep() + (1.0f-TrendSmoothing)*SmoothedSpeed; + } + + CameraTarget = NewSmoothedPos; + SmoothedPos = NewSmoothedPos; + SmoothedSpeed = NewSmoothedSpeed; + }else + CameraTarget = CamTargetEntity->GetPosition(); if(CamTargetEntity->GetForward().x == 0.0f && CamTargetEntity->GetForward().y == 0.0f) TargetOrientation = 0.0f; @@ -141,7 +172,7 @@ CCam::Process(void) switch(Mode){ case MODE_TOPDOWN: case MODE_GTACLASSIC: - Process_TopDown(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); + // Process_TopDown(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; case MODE_BEHINDCAR: Process_BehindCar(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); @@ -162,6 +193,7 @@ CCam::Process(void) Process_Debug(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; case MODE_SNIPER: + case MODE_CAMERA: Process_Sniper(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; case MODE_ROCKETLAUNCHER: @@ -175,7 +207,7 @@ CCam::Process(void) Process_Syphon(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; case MODE_CIRCLE: - Process_Circle(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); +// Process_Circle(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; // case MODE_CHEESYZOOM: case MODE_WHEELCAM: @@ -198,15 +230,9 @@ CCam::Process(void) #endif Process_Cam_On_A_String(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; - case MODE_REACTION: - Process_ReactionCam(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); - break; - case MODE_FOLLOW_PED_WITH_BIND: - Process_FollowPed_WithBinding(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); - break; - case MODE_CHRIS: - Process_Chris_With_Binding_PlusRotation(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); - break; +// case MODE_REACTION: +// case MODE_FOLLOW_PED_WITH_BIND: +// case MODE_CHRIS: case MODE_BEHINDBOAT: #ifdef FREE_CAM if (CCamera::bFreeCam) @@ -246,8 +272,11 @@ CCam::Process(void) case MODE_FIGHT_CAM: Process_Fight_Cam(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; + case MODE_LIGHTHOUSE: + Process_LightHouse(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); + break; case MODE_TOP_DOWN_PED: - Process_TopDownPed(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); + // Process_TopDownPed(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; case MODE_SNIPER_RUNABOUT: case MODE_ROCKETLAUNCHER_RUNABOUT: @@ -271,7 +300,7 @@ CCam::Process(void) CVector TargetToCam = Source - m_cvecTargetCoorsForFudgeInter; float DistOnGround = TargetToCam.Magnitude2D(); m_fTrueBeta = CGeneral::GetATanOfXY(TargetToCam.x, TargetToCam.y); - m_fTrueAlpha = CGeneral::GetATanOfXY(TargetToCam.z, DistOnGround); + m_fTrueAlpha = CGeneral::GetATanOfXY(DistOnGround, TargetToCam.z); if(TheCamera.m_uiTransitionState == 0) KeepTrackOfTheSpeed(Source, m_cvecTargetCoorsForFudgeInter, Up, m_fTrueAlpha, m_fTrueBeta, FOV); @@ -281,19 +310,25 @@ CCam::Process(void) LookingRight = false; SourceBeforeLookBehind = Source; if(&TheCamera.Cams[TheCamera.ActiveCam] == this){ - if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_1STPERSON || Mode == MODE_BEHINDBOAT) && + if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_1STPERSON || Mode == MODE_BEHINDBOAT || Mode == MODE_BEHINDCAR) && CamTargetEntity->IsVehicle()){ + bool bDisableLR = CamTargetEntity && + (((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI || CamTargetEntity->GetModelIndex() == MI_RCBARON); if(CPad::GetPad(0)->GetLookBehindForCar()){ LookBehind(); if(DirectionWasLooking != LOOKING_BEHIND) TheCamera.m_bJust_Switched = true; DirectionWasLooking = LOOKING_BEHIND; - }else if(!((CVehicle*)CamTargetEntity)->IsRealHeli() && CPad::GetPad(0)->GetLookLeft()){ + }else if(bDisableLR){ + if(DirectionWasLooking != LOOKING_FORWARD) + TheCamera.m_bJust_Switched = true; + DirectionWasLooking = LOOKING_FORWARD; + }else if(CPad::GetPad(0)->GetLookLeft()){ LookLeft(); if(DirectionWasLooking != LOOKING_LEFT) TheCamera.m_bJust_Switched = true; DirectionWasLooking = LOOKING_LEFT; - }else if(!((CVehicle*)CamTargetEntity)->IsRealHeli() && CPad::GetPad(0)->GetLookRight()){ + }else if(CPad::GetPad(0)->GetLookRight()){ LookRight(); if(DirectionWasLooking != LOOKING_RIGHT) TheCamera.m_bJust_Switched = true; @@ -388,7 +423,7 @@ CCam::ProcessSpecialHeightRoutines(void) StandingOnBoat = true; // Move up the camera if there is a ped close to it - if(Mode == MODE_FOLLOWPED || Mode == MODE_FIGHT_CAM){ + if(Mode == MODE_FOLLOWPED || Mode == MODE_FIGHT_CAM || Mode == MODE_PILLOWS_PAPS){ // Find ped closest to camera while(i < Player->m_numNearPeds){ if(Player->m_nearPeds[i] && Player->m_nearPeds[i]->GetPedState() != PED_DEAD){ @@ -503,96 +538,9 @@ CCam::ProcessSpecialHeightRoutines(void) }else m_fDimensionOfHighestNearCar = 0.0f; } - - // Move up for road - if(Mode == MODE_FOLLOWPED || Mode == MODE_FIGHT_CAM || - Mode == MODE_SYPHON || Mode == MODE_SYPHON_CRIM_IN_FRONT || Mode == MODE_SPECIAL_FIXED_FOR_SYPHON){ - bool Inside = false; - bool OnRoad = false; - - switch(((CPhysical*)CamTargetEntity)->m_nSurfaceTouched) - case SURFACE_GRASS: - case SURFACE_GRAVEL: - case SURFACE_MUD_DRY: - case SURFACE_THICK_METAL_PLATE: - case SURFACE_RUBBER: - case SURFACE_STEEP_CLIFF: - OnRoad = true; - - if(CCullZones::PlayerNoRain()) - Inside = true; - - if((m_bCollisionChecksOn || PreviouslyFailedRoadHeightCheck || OnRoad) && - m_fCloseInPedHeightOffset < 0.0001f && !Inside){ - CVector TestPoint; - CEntity *road; - float GroundZ = 0.0f; - bool FoundGround = false; - float RoofZ = 0.0f; - bool FoundRoof = false; - static float MinHeightAboveRoad = 0.9f; - - TestPoint = CamTargetEntity->GetPosition() - DistOnGround * CVector(Cos(BetaAngle), Sin(BetaAngle), 0.0f); - m_fRoadOffSet = 0.0f; - - if(CWorld::ProcessVerticalLine(TestPoint, -1000.0f, colPoint, road, true, false, false, false, false, false, nil)){ - FoundGround = true; - GroundZ = colPoint.point.z; - } - // Move up if too close to ground - if(FoundGround){ - if(TestPoint.z - GroundZ < MinHeightAboveRoad){ - m_fRoadOffSet = GroundZ + MinHeightAboveRoad - TestPoint.z; - PreviouslyFailedRoadHeightCheck = true; - }else{ - if(m_bCollisionChecksOn) - PreviouslyFailedRoadHeightCheck = false; - else - m_fRoadOffSet = 0.0f; - } - }else{ - if(CWorld::ProcessVerticalLine(TestPoint, 1000.0f, colPoint, road, true, false, false, false, false, false, nil)){ - FoundRoof = true; - RoofZ = colPoint.point.z; - } - if(FoundRoof){ - if(TestPoint.z - RoofZ < MinHeightAboveRoad){ - m_fRoadOffSet = RoofZ + MinHeightAboveRoad - TestPoint.z; - PreviouslyFailedRoadHeightCheck = true; - }else{ - if(m_bCollisionChecksOn) - PreviouslyFailedRoadHeightCheck = false; - else - m_fRoadOffSet = 0.0f; - } - } - } - } - } - - if(PreviouslyFailedRoadHeightCheck && m_fCloseInPedHeightOffset < 0.0001f){ - if(colPoint.surfaceB != SURFACE_TARMAC && - colPoint.surfaceB != SURFACE_GRASS && - colPoint.surfaceB != SURFACE_GRAVEL && - colPoint.surfaceB != SURFACE_MUD_DRY && - colPoint.surfaceB != SURFACE_STEEP_CLIFF){ - if(m_fRoadOffSet > 1.4f) - m_fRoadOffSet = 1.4f; - }else{ - if(Mode == MODE_FOLLOWPED){ - if(TheCamera.PedZoomIndicator == CAM_ZOOM_1) - m_fRoadOffSet += 0.2f; - if(TheCamera.PedZoomIndicator == CAM_ZOOM_2) - m_fRoadOffSet += 0.5f; - if(TheCamera.PedZoomIndicator == CAM_ZOOM_3) - m_fRoadOffSet += 0.95f; - } - } - } } if(StandingOnBoat){ - m_fRoadOffSet = 0.0f; m_fDimensionOfHighestNearCar = 1.0f; m_fPedBetweenCameraHeightOffset = 0.0f; } @@ -1400,6 +1348,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient BetaOffset = TargetOrientation + PI; else BetaOffset = Atan2(ToCam.y, ToCam.x); + BetaOffset -= Beta; AlphaOffset = 0.0f; }else{ // Look around @@ -1466,8 +1415,8 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient if(OnTrain) Beta = TargetOrientation; - Front.x = Cos(Alpha) * Cos(Beta); - Front.y = Cos(Alpha) * Sin(Beta); + Front.x = Cos(Alpha) * -Cos(Beta); + Front.y = Cos(Alpha) * -Sin(Beta); Front.z = Sin(Alpha); Source = TargetCoors - Front*CamDist; m_cvecTargetCoorsForFudgeInter = TargetCoors; @@ -2277,7 +2226,7 @@ CCam::Process_Rocket(const CVector &CameraTarget, float, float, float) while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f); - if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); + else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); TargetCoors.x = 3.0f * Cos(Alpha) * Cos(Beta) + Source.x; TargetCoors.y = 3.0f * Cos(Alpha) * Sin(Beta) + Source.y; @@ -2385,7 +2334,7 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f); - if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); + else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); if(((CPed*)CamTargetEntity)->bIsDucking) BackOffset = 0.8f; @@ -2834,17 +2783,16 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float, RwCameraSetNearClipPlane(Scene.camera, 0.05f); } +float fCameraNearClipMult = 0.15f; + +//--MIAMI: done void CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float, float) { - if(CamTargetEntity->m_rwObject == nil) - return; - -#ifdef FIX_BUGS if(!CamTargetEntity->IsPed()) return; -#endif + float BackOffset = 0.19f; static bool FailedTestTwelveFramesAgo = false; RwV3d HeadPos; CVector TargetCoors; @@ -2853,9 +2801,9 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float static float TargetFOV = 0.0f; if(ResetStatics){ - Beta = TargetOrientation; + Beta = ((CPed*)CamTargetEntity)->m_fRotationCur + HALFPI; Alpha = 0.0f; - m_fInitialPlayerOrientation = TargetOrientation; + m_fInitialPlayerOrientation = ((CPed*)CamTargetEntity)->m_fRotationCur + HALFPI; FailedTestTwelveFramesAgo = false; // static DPadVertical unused // static DPadHorizontal unused @@ -2865,11 +2813,23 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float ResetStatics = false; } + if(((CPed*)CamTargetEntity)->bIsDucking) + BackOffset = 0.8f; + CamTargetEntity->GetMatrix().UpdateRW(); + CamTargetEntity->UpdateRwFrame(); + CamTargetEntity->UpdateRpHAnim(); ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; - Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); - Source.y -= 0.19f*Sin(m_fInitialPlayerOrientation); + if(((CPed*)CamTargetEntity)->bIsDucking){ + Source.x -= fDuckingBackOffset*CamTargetEntity->GetForward().x; + Source.y -= fDuckingBackOffset*CamTargetEntity->GetForward().y; + Source.x -= fDuckingRightOffset*CamTargetEntity->GetRight().x; + Source.y -= fDuckingRightOffset*CamTargetEntity->GetRight().y; + }else{ + Source.x -= BackOffset*CamTargetEntity->GetForward().x; + Source.y -= BackOffset*CamTargetEntity->GetForward().y; + } // Look around bool UseMouse = false; @@ -2896,7 +2856,7 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f); - if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); + else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); TargetCoors.x = 3.0f * Cos(Alpha) * Cos(Beta) + Source.x; TargetCoors.y = 3.0f * Cos(Alpha) * Sin(Beta) + Source.y; @@ -2939,8 +2899,13 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float if(FOV > DefaultFOV) FOV = DefaultFOV; - if(FOV < 15.0f) - FOV = 15.0f; + if(Mode == MODE_CAMERA){ + if(FOV < 3.0f) + FOV = 3.0f; + }else{ + if(FOV < 15.0f) + FOV = 15.0f; + } Front = TargetCoors - Source; Front.Normalise(); @@ -2973,6 +2938,8 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float if(FailedTestTwelveFramesAgo) RwCameraSetNearClipPlane(Scene.camera, 0.4f); + else if(Mode == MODE_CAMERA) + RwCameraSetNearClipPlane(Scene.camera, ((15.0f - Min(FOV, 15.0f))*fCameraNearClipMult + 1.0f)*DEFAULT_NEAR); Source -= Front*0.4f; GetVectorsReadyForRW(); @@ -3295,6 +3262,10 @@ CCam::Process_BehindBoat(const CVector &CameraTarget, float TargetOrientation, f ResetStatics = false; } +float FIGHT_HORIZ_DIST = 3.0f; +float FIGHT_VERT_DIST = 1.0f; +float FIGHT_BETA_ANGLE = 125.0f; + void CCam::Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, float, float) { @@ -3302,26 +3273,25 @@ CCam::Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, fl return; FOV = DefaultFOV; + float HorizDist = FIGHT_HORIZ_DIST; + float VertDist = FIGHT_VERT_DIST; float BetaLeft, BetaRight, DeltaBetaLeft, DeltaBetaRight; - float BetaFix; - float Dist; - float BetaMaxSpeed = 0.015f; - float BetaAcceleration = 0.007f; static bool PreviouslyFailedBuildingChecks = false; float TargetCamHeight; CVector TargetCoors; - m_fMinDistAwayFromCamWhenInterPolating = 4.0f; + m_fMinDistAwayFromCamWhenInterPolating = FIGHT_HORIZ_DIST; Front = Source - CameraTarget; - Beta = CGeneral::GetATanOfXY(Front.x, Front.y); + if(ResetStatics) + Beta = CGeneral::GetATanOfXY(Front.x, Front.y); while(TargetOrientation >= PI) TargetOrientation -= 2*PI; while(TargetOrientation < -PI) TargetOrientation += 2*PI; while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; // Figure out Beta - BetaLeft = TargetOrientation - HALFPI; - BetaRight = TargetOrientation + HALFPI; + BetaLeft = TargetOrientation - DEGTORAD(FIGHT_BETA_ANGLE); + BetaRight = TargetOrientation + DEGTORAD(FIGHT_BETA_ANGLE); DeltaBetaLeft = Beta - BetaLeft; DeltaBetaRight = Beta - BetaRight; while(DeltaBetaLeft >= PI) DeltaBetaLeft -= 2*PI; @@ -3345,32 +3315,15 @@ CCam::Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, fl m_fTargetBeta = DeltaBetaRight; } - // Check collisions - BetaFix = 0.0f; - Dist = Front.Magnitude2D(); - if(m_bCollisionChecksOn || PreviouslyFailedBuildingChecks){ - BetaFix = GetPedBetaAngleForClearView(CameraTarget, Dist+0.25f, 0.0f, true, false, false, true, false); - if(BetaFix == 0.0f){ - BetaFix = GetPedBetaAngleForClearView(CameraTarget, Dist+0.5f, DEGTORAD(24.0f), true, false, false, true, false); - if(BetaFix == 0.0f) - BetaFix = GetPedBetaAngleForClearView(CameraTarget, Dist+0.5f, -DEGTORAD(24.0f), true, false, false, true, false); - } - } - if(BetaFix != 0.0f){ - BetaMaxSpeed = 0.1f; - PreviouslyFailedBuildingChecks = true; - BetaAcceleration = 0.025f; - m_fTargetBeta = Beta + BetaFix; - } - WellBufferMe(m_fTargetBeta, &Beta, &BetaSpeed, BetaMaxSpeed, BetaAcceleration, true); + WellBufferMe(m_fTargetBeta, &Beta, &BetaSpeed, 0.015f, 0.007f, true); - Source = CameraTarget + 4.0f*CVector(Cos(Beta), Sin(Beta), 0.0f); - Source.z -= 0.5f; + Source = CameraTarget + HorizDist*CVector(Cos(Beta), Sin(Beta), 0.0f); + Source.z += VertDist; WellBufferMe(TargetOrientation, &m_fBufferedTargetOrientation, &m_fBufferedTargetOrientationSpeed, 0.07f, 0.004f, true); - TargetCoors = CameraTarget + 0.5f*CVector(Cos(m_fBufferedTargetOrientation), Sin(m_fBufferedTargetOrientation), 0.0f); + TargetCoors = CameraTarget + 0.1f*CVector(Cos(m_fBufferedTargetOrientation), Sin(m_fBufferedTargetOrientation), 0.0f); - TargetCamHeight = CameraTarget.z - Source.z + Max(m_fPedBetweenCameraHeightOffset, m_fRoadOffSet + m_fDimensionOfHighestNearCar) - 0.5f; + TargetCamHeight = CameraTarget.z - Source.z + Max(m_fPedBetweenCameraHeightOffset, m_fDimensionOfHighestNearCar) + VertDist; if(TargetCamHeight > m_fCamBufferedHeight) WellBufferMe(TargetCamHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.15f, 0.04f, false); else @@ -3378,6 +3331,8 @@ CCam::Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, fl Source.z += m_fCamBufferedHeight; m_cvecTargetCoorsForFudgeInter = TargetCoors; + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV); Front = TargetCoors - Source; Front.Normalise(); GetVectorsReadyForRW(); @@ -3592,12 +3547,12 @@ CCam::Process_WheelCam(const CVector&, float, float, float) } CVector NewUp(0.0f, 0.0f, 1.0f); - CVector Left = CrossProduct(Front, NewUp); - Left.Normalise(); - NewUp = CrossProduct(Left, Front); + CVector Right = CrossProduct(Front, NewUp); + Right.Normalise(); + NewUp = CrossProduct(Right, Front); float Roll = Cos((CTimer::GetTimeInMilliseconds()&0x1FFFF)/(float)0x1FFFF * TWOPI); - Up = Cos(Roll*0.4f)*NewUp + Sin(Roll*0.4f)*Left; + Up = Cos(Roll*0.4f)*NewUp + Sin(Roll*0.4f)*Right; return true; } @@ -3653,20 +3608,6 @@ CCam::Process_Player_Fallen_Water(const CVector &CameraTarget, float TargetOrien Front.Normalise(); } -// unused -void -CCam::Process_Circle(const CVector &CameraTarget, float, float, float) -{ - FOV = DefaultFOV; - - Front.x = Cos(0.7f) * Cos((CTimer::GetTimeInMilliseconds()&0xFFF)/(float)0xFFF * TWOPI); - Front.y = Cos(0.7f) * Sin((CTimer::GetTimeInMilliseconds()&0xFFF)/(float)0xFFF * TWOPI); - Front.z = -Sin(0.7f); - Source = CameraTarget - 4.0f*Front; - Source.z += 1.0f; - GetVectorsReadyForRW(); -} - void CCam::Process_SpecialFixedForSyphon(const CVector &CameraTarget, float, float, float) { @@ -3687,6 +3628,12 @@ CCam::Process_SpecialFixedForSyphon(const CVector &CameraTarget, float, float, f FOV = DefaultFOV; } +void +CCam::Process_LightHouse(const CVector &CameraTarget, float, float, float) +{ + // TODO +} + #ifdef IMPROVED_CAMERA #define KEYJUSTDOWN(k) ControlsManager.GetIsKeyboardKeyJustDown((RsKeyCodes)k) @@ -3719,7 +3666,7 @@ CCam::Process_Debug(const CVector&, float, float, float) TargetCoors.z = Source.z + Sin(Alpha) * 3.0f; if(Alpha > DEGTORAD(89.5f)) Alpha = DEGTORAD(89.5f); - if(Alpha < DEGTORAD(-89.5f)) Alpha = DEGTORAD(-89.5f); + else if(Alpha < DEGTORAD(-89.5f)) Alpha = DEGTORAD(-89.5f); if(CPad::GetPad(1)->GetSquare() || KEYDOWN('W')) Speed += 0.1f; @@ -3812,7 +3759,7 @@ CCam::Process_Debug(const CVector&, float, float, float) TargetCoors.z = Source.z + Sin(Alpha) * 3.0f; if(Alpha > DEGTORAD(89.5f)) Alpha = DEGTORAD(89.5f); - if(Alpha < DEGTORAD(-89.5f)) Alpha = DEGTORAD(-89.5f); + else if(Alpha < DEGTORAD(-89.5f)) Alpha = DEGTORAD(-89.5f); if(CPad::GetPad(1)->GetSquare() || CPad::GetPad(1)->GetLeftMouse()) Speed += 0.1f; @@ -3891,7 +3838,7 @@ CCam::Process_Editor(const CVector&, float, float, float) CSceneEdit::m_vecCamHeading = TargetCoors - Source; if(Alpha > DEGTORAD(89.5f)) Alpha = DEGTORAD(89.5f); - if(Alpha < DEGTORAD(-89.5f)) Alpha = DEGTORAD(-89.5f); + else if(Alpha < DEGTORAD(-89.5f)) Alpha = DEGTORAD(-89.5f); if(CPad::GetPad(1)->GetSquare() || CPad::GetPad(1)->GetLeftMouse()) Speed += 0.1f; @@ -4018,55 +3965,308 @@ CCam::ProcessPedsDeadBaby(void) GetVectorsReadyForRW(); } +float ARRESTDIST_BEHIND_COP = 5.0f; +float ARRESTDIST_RIGHTOF_COP = 3.0f; +float ARRESTDIST_ABOVE_COP = 1.4f; // unused +float ARRESTDIST_MINFROM_PLAYER = 8.0f; +float ARRESTCAM_LAMP_BEST_DIST = 17.0f; +float ARRESTCAM_ROTATION_SPEED = 0.1f; +float ARRESTCAM_ROTATION_UP = 0.05f; +float ARRESTCAM_S_ROTATION_UP = 0.1f; +float ARRESTDIST_ALONG_GROUND = 5.0f; +float ARRESTDIST_SIDE_GROUND = 10.0f; +float ARRESTDIST_ABOVE_GROUND = 0.7f; +float ARRESTCAM_LAMPPOST_ROTATEDIST = 10.0f; +float ARRESTCAM_LAMPPOST_TRANSLATE = 0.1f; + +//--MIAMI: done +bool +CCam::GetLookAlongGroundPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut) +{ + if(Target == nil || Cop == nil) + return false; + CVector CopToTarget = TargetCoors - Cop->GetPosition(); + CopToTarget.z = 0.0f; + CopToTarget.Normalise(); + SourceOut = TargetCoors + ARRESTDIST_ALONG_GROUND*CopToTarget; + CVector Side = CrossProduct(CopToTarget, CVector(0.0f, 0.0f, 1.0f)); + SourceOut += ARRESTDIST_SIDE_GROUND*Side; + SourceOut.z += 5.0f; + bool found = false; + float ground = CWorld::FindGroundZFor3DCoord(SourceOut.x, SourceOut.y, SourceOut.z, &found); + if(found) + SourceOut.z = ground + ARRESTDIST_ABOVE_GROUND; + return true; +} + +//--MIAMI: done +bool +CCam::GetLookFromLampPostPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut) +{ + int i; + int16 NumObjects; + CEntity *Objects[16]; + CEntity *NearestLampPost = nil; + CWorld::FindObjectsInRange(TargetCoors, 30.0f, true, &NumObjects, 15, Objects, false, false, false, true, true); + float NearestDist = 10000.0f; + for(i = 0; i < NumObjects; i++){ + if(Objects[i]->IsStatic() && Objects[i]->GetUp().z > 0.9f && IsLampPost(Objects[i]->GetModelIndex())){ + float Dist = (Objects[i]->GetPosition() - TargetCoors).Magnitude2D(); + if(Abs(ARRESTCAM_LAMP_BEST_DIST - Dist) < NearestDist){ + CVector TestStart = Objects[i]->GetColModel()->boundingBox.max; + TestStart = Objects[i]->GetMatrix() * TestStart; + CVector TestEnd = TestStart - TargetCoors; + TestEnd.Normalise(); + TestEnd += TargetCoors; + if(CWorld::GetIsLineOfSightClear(TestStart, TestEnd, true, false, false, false, false, true, true)){ + NearestDist = Abs(ARRESTCAM_LAMP_BEST_DIST - Dist); + NearestLampPost = Objects[i]; + SourceOut = TestStart; + } + } + } + } + return NearestLampPost != nil; +} + +//--MIAMI: done +bool +CCam::GetLookOverShoulderPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut) +{ + if(Target == nil || Cop == nil) + return false; + CVector CopCoors = Cop->GetPosition(); + CVector CopToTarget = TargetCoors - CopCoors; + CVector Side = CrossProduct(CopToTarget, CVector(0.0f, 0.0f, 1.0f)); + Side.Normalise(); + CopCoors += ARRESTDIST_RIGHTOF_COP * Side; + CopToTarget.Normalise(); + if(CopToTarget.z < -0.7071f){ + CopToTarget.z = -0.7071f; + float GroundDist = CopToTarget.Magnitude2D(); + if(GroundDist > 0.0f){ + CopToTarget.x *= 0.7071f/GroundDist; + CopToTarget.y *= 0.7071f/GroundDist; + } + CopToTarget.Normalise(); + }else{ + if(CopToTarget.z > 0.0f){ + CopToTarget.z = 0.0f; + CopToTarget.Normalise(); + } + } + CopCoors -= ARRESTDIST_BEHIND_COP * CopToTarget; + CopToTarget = TargetCoors - CopCoors; + float Dist = CopToTarget.Magnitude(); + if(Dist < ARRESTDIST_MINFROM_PLAYER && Dist > 0.0f) + CopToTarget *= ARRESTDIST_MINFROM_PLAYER/Dist; + SourceOut = TargetCoors - CopToTarget; + return true; +} + +enum { + ARRESTCAM_OVERSHOULDER = 1, + ARRESTCAM_ALONGGROUND, + ARRESTCAM_ALONGGROUND_RIGHT, + ARRESTCAM_ALONGGROUND_RIGHT_UP, + ARRESTCAM_ALONGGROUND_LEFT, + ARRESTCAM_ALONGGROUND_LEFT_UP, + ARRESTCAM_LAMPPOST, +}; + +int nUsingWhichCamera; +CPed *pStoredCopPed; + +//--MIAMI: done bool CCam::ProcessArrestCamOne(void) { + CVector TargetPos; + CVector CamSource; + CPed *cop = nil; FOV = 45.0f; - if(ResetStatics) - return true; + bool foundPos = false; + int ArrestModes[5] = { -1, -1, -1, -1, -1 }; -#ifdef FIX_BUGS - if(!CamTargetEntity->IsPed()) - return true; -#endif + if(ResetStatics){ + CPed *targetPed = (CPed*)TheCamera.pTargetEntity; + nUsingWhichCamera = 0; + if(TheCamera.pTargetEntity->IsPed()){ + ((CPed*)TheCamera.pTargetEntity)->m_pedIK.GetComponentPosition(*(RwV3d*)&TargetPos, PED_MID); + if(FindPlayerPed() && FindPlayerPed()->m_pArrestingCop) + cop = FindPlayerPed()->m_pArrestingCop; + if(cop && CGeneral::GetRandomNumberInRange(0.0f, 0.1f) > 0.5f){ + ArrestModes[0] = ARRESTCAM_OVERSHOULDER; + ArrestModes[1] = ARRESTCAM_ALONGGROUND; + ArrestModes[2] = ARRESTCAM_OVERSHOULDER; + ArrestModes[3] = ARRESTCAM_LAMPPOST; + }else{ + ArrestModes[0] = ARRESTCAM_ALONGGROUND; + ArrestModes[1] = ARRESTCAM_OVERSHOULDER; + ArrestModes[2] = ARRESTCAM_LAMPPOST; + } + }else if(TheCamera.pTargetEntity->IsVehicle()){ + CVehicle *targetVehicle = (CVehicle*)TheCamera.pTargetEntity; + if(targetVehicle->pDriver && targetVehicle->pDriver->IsPlayer()){ + targetPed = targetVehicle->pDriver; + targetPed->m_pedIK.GetComponentPosition(*(RwV3d*)&TargetPos, PED_MID); + }else{ + targetPed = nil; + TargetPos = targetVehicle->GetPosition(); + } - bool found; - float Ground; - CVector PlayerCoors = TheCamera.pTargetEntity->GetPosition(); - CVector CopCoors = ((CPlayerPed*)TheCamera.pTargetEntity)->m_pArrestingCop->GetPosition(); - Beta = CGeneral::GetATanOfXY(PlayerCoors.x - CopCoors.x, PlayerCoors.y - CopCoors.y); - - Source = PlayerCoors + 9.5f*CVector(Cos(Beta), Sin(Beta), 0.0f); - Source.z += 6.0f; - Ground = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, Source.z, &found); - if(!found){ - Ground = CWorld::FindRoofZFor3DCoord(Source.x, Source.y, Source.z, &found); - if(!found) + if(FindPlayerPed() && FindPlayerPed()->m_pArrestingCop) + cop = FindPlayerPed()->m_pArrestingCop; + if(cop && CGeneral::GetRandomNumberInRange(0.0f, 0.1f) > 0.65f){ + ArrestModes[0] = ARRESTCAM_OVERSHOULDER; + ArrestModes[1] = ARRESTCAM_LAMPPOST; + ArrestModes[2] = ARRESTCAM_ALONGGROUND; + ArrestModes[3] = ARRESTCAM_OVERSHOULDER; + }else{ + ArrestModes[0] = ARRESTCAM_LAMPPOST; + ArrestModes[1] = ARRESTCAM_ALONGGROUND; + ArrestModes[2] = ARRESTCAM_OVERSHOULDER; + } + }else return false; - } - Source.z = Ground + 0.25f; - if(!CWorld::GetIsLineOfSightClear(Source, CopCoors, true, true, false, true, false, true, true)){ - Beta += DEGTORAD(115.0f); - Source = PlayerCoors + 9.5f*CVector(Cos(Beta), Sin(Beta), 0.0f); - Source.z += 6.0f; - Ground = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, Source.z, &found); - if(!found){ - Ground = CWorld::FindRoofZFor3DCoord(Source.x, Source.y, Source.z, &found); - if(!found) - return false; + + for(int i = 0; nUsingWhichCamera == 0 && i < ARRAY_SIZE(ArrestModes) && ArrestModes[i] > 0; i++){ + switch(ArrestModes[i]){ + case ARRESTCAM_OVERSHOULDER: + if(cop){ + foundPos = GetLookOverShoulderPos(TheCamera.pTargetEntity, cop, TargetPos, CamSource); + pStoredCopPed = cop; + cop = nil; + }else if(targetPed){ + for(int j = 0; j < targetPed->m_numNearPeds; j++){ + CPed *nearPed = targetPed->m_nearPeds[j]; + if(nearPed->GetPedState() == PED_ARREST_PLAYER) + foundPos = GetLookOverShoulderPos(TheCamera.pTargetEntity, nearPed, TargetPos, CamSource); + if(foundPos){ + pStoredCopPed = nearPed; + break; + } + } + } + break; + case ARRESTCAM_ALONGGROUND: + if(cop){ + foundPos = GetLookAlongGroundPos(TheCamera.pTargetEntity, cop, TargetPos, CamSource); + pStoredCopPed = cop; + cop = nil; + }else if(targetPed){ + for(int j = 0; j < targetPed->m_numNearPeds; j++){ + CPed *nearPed = targetPed->m_nearPeds[j]; + if(nearPed->GetPedState() == PED_ARREST_PLAYER) + foundPos = GetLookAlongGroundPos(TheCamera.pTargetEntity, nearPed, TargetPos, CamSource); + if(foundPos){ + pStoredCopPed = nearPed; + break; + } + } + } + break; + case ARRESTCAM_LAMPPOST: + foundPos = GetLookFromLampPostPos(TheCamera.pTargetEntity, cop, TargetPos, CamSource); + break; + } + + if(foundPos){ + if(pStoredCopPed) + pStoredCopPed->RegisterReference((CEntity**)&pStoredCopPed); + nUsingWhichCamera = ArrestModes[i]; + if(ArrestModes[i] == ARRESTCAM_ALONGGROUND){ + float rnd = CGeneral::GetRandomNumberInRange(0.0f, 5.0f); + if(rnd < 1.0f) nUsingWhichCamera = ARRESTCAM_ALONGGROUND; + else if(rnd < 2.0f) nUsingWhichCamera = ARRESTCAM_ALONGGROUND_RIGHT; + else if(rnd < 3.0f) nUsingWhichCamera = ARRESTCAM_ALONGGROUND_RIGHT_UP; + else if(rnd < 4.0f) nUsingWhichCamera = ARRESTCAM_ALONGGROUND_LEFT; + else nUsingWhichCamera = ARRESTCAM_ALONGGROUND_LEFT_UP; + } + }else + pStoredCopPed = nil; } - Source.z = Ground + 0.25f; - CopCoors.z += 0.35f; - Front = CopCoors - Source; - if(!CWorld::GetIsLineOfSightClear(Source, CopCoors, true, true, false, true, false, true, true)) - return false; + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, TargetPos, Source, FOV); + Front = TargetPos - Source; + Front.Normalise(); + Up = CVector(0.0f, 0.0f, 1.0f); + CVector Right = CrossProduct(Front, Up); + Right.Normalise(); + Up = CrossProduct(Right, Front); + if(nUsingWhichCamera != 0) + ResetStatics = false; + return true; } - CopCoors.z += 0.35f; - m_cvecTargetCoorsForFudgeInter = CopCoors; - Front = CopCoors - Source; - ResetStatics = false; - GetVectorsReadyForRW(); + + if(TheCamera.pTargetEntity->IsPed()){ + ((CPed*)TheCamera.pTargetEntity)->m_pedIK.GetComponentPosition(*(RwV3d*)&TargetPos, PED_MID); + }else if(TheCamera.pTargetEntity->IsVehicle()){ + CPed *driver = ((CVehicle*)TheCamera.pTargetEntity)->pDriver; + if(driver && driver->IsPlayer()) + driver->m_pedIK.GetComponentPosition(*(RwV3d*)&TargetPos, PED_MID); + else + TargetPos = TheCamera.pTargetEntity->GetPosition(); + }else + return false; + + if(nUsingWhichCamera == ARRESTCAM_OVERSHOULDER && pStoredCopPed){ + foundPos = GetLookOverShoulderPos(TheCamera.pTargetEntity, pStoredCopPed, TargetPos, CamSource); + if(CamSource.z > Source.z + ARRESTCAM_S_ROTATION_UP*CTimer::GetTimeStep()) + CamSource.z = Source.z + ARRESTCAM_S_ROTATION_UP*CTimer::GetTimeStep(); + }else if(nUsingWhichCamera >= ARRESTCAM_ALONGGROUND_RIGHT && nUsingWhichCamera <= ARRESTCAM_ALONGGROUND_LEFT_UP){ + CamSource = Source; + Front = TargetPos - CamSource; + Front.Normalise(); + Up = CVector(0.0f, 0.0f, 1.0f); + CVector Right = CrossProduct(Front, Up); + if(nUsingWhichCamera == ARRESTCAM_ALONGGROUND_LEFT || nUsingWhichCamera == ARRESTCAM_ALONGGROUND_LEFT_UP) + Right *= -1.0f; + if(CWorld::TestSphereAgainstWorld(CamSource + 0.5f*Right, 0.4f, TheCamera.pTargetEntity, true, true, false, true, false, true) == nil){ + foundPos = true; + CamSource += Right*ARRESTCAM_ROTATION_SPEED*CTimer::GetTimeStep(); + if(nUsingWhichCamera == ARRESTCAM_ALONGGROUND_RIGHT_UP || nUsingWhichCamera == ARRESTCAM_ALONGGROUND_LEFT_UP){ + CamSource.z += ARRESTCAM_ROTATION_UP*CTimer::GetTimeStep(); + }else{ + bool found = false; + float ground = CWorld::FindGroundZFor3DCoord(CamSource.x, CamSource.y, CamSource.z, &found); + if(found) + CamSource.z = ground + ARRESTDIST_ABOVE_GROUND; + } + } + }else if(nUsingWhichCamera == ARRESTCAM_LAMPPOST){ + CamSource = Source; + Front = TargetPos - CamSource; + Front.z = 0.0f; + Front.Normalise(); + Up = CVector(0.0f, 0.0f, 1.0f); + CVector Right = CrossProduct(Front, Up); + Right.Normalise(); + Front = TargetPos - CamSource + Right*ARRESTCAM_LAMPPOST_ROTATEDIST; + Front.z = 0.0f; + Front.Normalise(); + if(CWorld::TestSphereAgainstWorld(CamSource + 0.5f*Front, 0.4f, TheCamera.pTargetEntity, true, true, false, true, false, true) == nil){ + foundPos = true; + CamSource += Front*ARRESTCAM_LAMPPOST_TRANSLATE*CTimer::GetTimeStep(); + } + } + + if(foundPos){ + Source = CamSource; + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, TargetPos, Source, FOV); + Front = TargetPos - Source; + Front.Normalise(); + Up = CVector(0.0f, 0.0f, 1.0f); + CVector Right = CrossProduct(Front, Up); + Right.Normalise(); + Up = CrossProduct(Right, Front); + }else{ + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, TargetPos, Source, FOV); + } + return true; } @@ -4116,276 +4316,6 @@ CCam::ProcessArrestCamTwo(void) } -/* - * Unused PS2 cams - */ - -void -CCam::Process_Chris_With_Binding_PlusRotation(const CVector &CameraTarget, float TargetOrientation, float, float) -{ - static float AngleToBinned = 0.0f; - static float StartingAngleLastChange = 0.0f; - static float FixedTargetOrientation = 0.0f; - static float DeadZoneReachedOnePrevious; - - FOV = DefaultFOV; // missing in game - - bool FixOrientation = true; - if(ResetStatics){ - Rotating = false; - DeadZoneReachedOnePrevious = 0.0f; - FixedTargetOrientation = 0.0f; - ResetStatics = false; - } - - CVector TargetCoors = CameraTarget; - - float StickX = CPad::GetPad(0)->GetRightStickX(); - float StickY = CPad::GetPad(0)->GetRightStickY(); - float StickAngle; - if(StickX != 0.0 || StickY != 0.0f) // BUG: game checks StickX twice - StickAngle = CGeneral::GetATanOfXY(StickX, StickY); // result unused? - else - FixOrientation = false; - - CVector Dist = Source - TargetCoors; - Source.z = TargetCoors.z + 0.75f; - float Length = Dist.Magnitude2D(); - if(Length > 2.5f){ - Source.x = TargetCoors.x + Dist.x/Length * 2.5f; - Source.y = TargetCoors.y + Dist.y/Length * 2.5f; - }else if(Length < 2.4f){ - Source.x = TargetCoors.x + Dist.x/Length * 2.4f; - Source.y = TargetCoors.y + Dist.y/Length * 2.4f; - } - - Beta = CGeneral::GetATanOfXY(Dist.x, Dist.y); - if(CPad::GetPad(0)->GetLeftShoulder1()){ - FixedTargetOrientation = TargetOrientation; - Rotating = true; - } - - if(FixOrientation){ - Rotating = true; - FixedTargetOrientation = StickX/128.0f + Beta - PI; - } - - if(Rotating){ - Dist = Source - TargetCoors; - Length = Dist.Magnitude2D(); - // inlined - WellBufferMe(FixedTargetOrientation+PI, &Beta, &BetaSpeed, 0.1f, 0.06f, true); - - Source.x = TargetCoors.x + Length*Cos(Beta); - Source.y = TargetCoors.y + Length*Sin(Beta); - - float DeltaBeta = FixedTargetOrientation+PI - Beta; - while(DeltaBeta >= PI) DeltaBeta -= 2*PI; - while(DeltaBeta < -PI) DeltaBeta += 2*PI; - if(Abs(DeltaBeta) < 0.06f) - Rotating = false; - } - - Front = TargetCoors - Source; - Front.Normalise(); - CVector Front2 = Front; - Front2.Normalise(); // What? - // FIX: the meaning of this value must have changed somehow - Source -= Front2 * TheCamera.m_fPedZoomValueSmooth*1.5f; -// Source += Front2 * TheCamera.m_fPedZoomValueSmooth; - - GetVectorsReadyForRW(); -} - -void -CCam::Process_ReactionCam(const CVector &CameraTarget, float TargetOrientation, float, float) -{ - static float AngleToBinned = 0.0f; - static float StartingAngleLastChange = 0.0f; - static float FixedTargetOrientation; - static float DeadZoneReachedOnePrevious; - static uint32 TimeOfLastChange; - uint32 Time; - bool DontBind = false; // BUG: left uninitialized - - FOV = DefaultFOV; // missing in game - - if(ResetStatics){ - Rotating = false; - DeadZoneReachedOnePrevious = 0.0f; - FixedTargetOrientation = 0.0f; - ResetStatics = false; - DontBind = false; - } - - CVector TargetCoors = CameraTarget; - - CVector Dist = Source - TargetCoors; - Source.z = TargetCoors.z + 0.75f; - float Length = Dist.Magnitude2D(); - if(Length > 2.5f){ - Source.x = TargetCoors.x + Dist.x/Length * 2.5f; - Source.y = TargetCoors.y + Dist.y/Length * 2.5f; - }else if(Length < 2.4f){ - Source.x = TargetCoors.x + Dist.x/Length * 2.4f; - Source.y = TargetCoors.y + Dist.y/Length * 2.4f; - } - - Beta = CGeneral::GetATanOfXY(Dist.x, Dist.y); - - float StickX = CPad::GetPad(0)->GetLeftStickX(); - float StickY = CPad::GetPad(0)->GetLeftStickY(); - float StickAngle; - if(StickX != 0.0 || StickY != 0.0f){ - StickAngle = CGeneral::GetATanOfXY(StickX, StickY); - while(StickAngle >= PI) StickAngle -= 2*PI; - while(StickAngle < -PI) StickAngle += 2*PI; - }else - StickAngle = 1000.0f; - - if(Abs(StickAngle-AngleToBinned) > DEGTORAD(15.0f)){ - DontBind = true; - Time = CTimer::GetTimeInMilliseconds(); - } - - if(CTimer::GetTimeInMilliseconds()-TimeOfLastChange > 200){ - if(Abs(HALFPI-StickAngle) > DEGTORAD(50.0f)){ - FixedTargetOrientation = TargetOrientation; - Rotating = true; - TimeOfLastChange = CTimer::GetTimeInMilliseconds(); - } - } - - // These two together don't make much sense. - // Only prevents rotation for one frame - AngleToBinned = StickAngle; - if(DontBind) - TimeOfLastChange = Time; - - if(Rotating){ - Dist = Source - TargetCoors; - Length = Dist.Magnitude2D(); - // inlined - WellBufferMe(FixedTargetOrientation+PI, &Beta, &BetaSpeed, 0.1f, 0.06f, true); - - Source.x = TargetCoors.x + Length*Cos(Beta); - Source.y = TargetCoors.y + Length*Sin(Beta); - - float DeltaBeta = FixedTargetOrientation+PI - Beta; - while(DeltaBeta >= PI) DeltaBeta -= 2*PI; - while(DeltaBeta < -PI) DeltaBeta += 2*PI; - if(Abs(DeltaBeta) < 0.06f) - Rotating = false; - } - - Front = TargetCoors - Source; - Front.Normalise(); - CVector Front2 = Front; - Front2.Normalise(); // What? - // FIX: the meaning of this value must have changed somehow - Source -= Front2 * TheCamera.m_fPedZoomValueSmooth*1.5f; -// Source += Front2 * TheCamera.m_fPedZoomValueSmooth; - - GetVectorsReadyForRW(); -} - -void -CCam::Process_FollowPed_WithBinding(const CVector &CameraTarget, float TargetOrientation, float, float) -{ - static float AngleToBinned = 0.0f; - static float StartingAngleLastChange = 0.0f; - static float FixedTargetOrientation; - static float DeadZoneReachedOnePrevious; - static uint32 TimeOfLastChange; - uint32 Time; - bool DontBind = false; - - FOV = DefaultFOV; // missing in game - - if(ResetStatics){ - Rotating = false; - DeadZoneReachedOnePrevious = 0.0f; - FixedTargetOrientation = 0.0f; - ResetStatics = false; - } - - CVector TargetCoors = CameraTarget; - - CVector Dist = Source - TargetCoors; - Source.z = TargetCoors.z + 0.75f; - float Length = Dist.Magnitude2D(); - if(Length > 2.5f){ - Source.x = TargetCoors.x + Dist.x/Length * 2.5f; - Source.y = TargetCoors.y + Dist.y/Length * 2.5f; - }else if(Length < 2.4f){ - Source.x = TargetCoors.x + Dist.x/Length * 2.4f; - Source.y = TargetCoors.y + Dist.y/Length * 2.4f; - } - - Beta = CGeneral::GetATanOfXY(Dist.x, Dist.y); - - float StickX = CPad::GetPad(0)->GetLeftStickX(); - float StickY = CPad::GetPad(0)->GetLeftStickY(); - float StickAngle; - if(StickX != 0.0 || StickY != 0.0f){ - StickAngle = CGeneral::GetATanOfXY(StickX, StickY); - while(StickAngle >= PI) StickAngle -= 2*PI; - while(StickAngle < -PI) StickAngle += 2*PI; - }else - StickAngle = 1000.0f; - - if(Abs(StickAngle-AngleToBinned) > DEGTORAD(15.0f)){ - DontBind = true; - Time = CTimer::GetTimeInMilliseconds(); - } - - if(CTimer::GetTimeInMilliseconds()-TimeOfLastChange > 200){ - if(Abs(HALFPI-StickAngle) > DEGTORAD(50.0f)){ - FixedTargetOrientation = TargetOrientation; - Rotating = true; - TimeOfLastChange = CTimer::GetTimeInMilliseconds(); - } - } - - if(CPad::GetPad(0)->GetLeftShoulder1JustDown()){ - FixedTargetOrientation = TargetOrientation; - Rotating = true; - TimeOfLastChange = CTimer::GetTimeInMilliseconds(); - } - - // These two together don't make much sense. - // Only prevents rotation for one frame - AngleToBinned = StickAngle; - if(DontBind) - TimeOfLastChange = Time; - - if(Rotating){ - Dist = Source - TargetCoors; - Length = Dist.Magnitude2D(); - // inlined - WellBufferMe(FixedTargetOrientation+PI, &Beta, &BetaSpeed, 0.1f, 0.06f, true); - - Source.x = TargetCoors.x + Length*Cos(Beta); - Source.y = TargetCoors.y + Length*Sin(Beta); - - float DeltaBeta = FixedTargetOrientation+PI - Beta; - while(DeltaBeta >= PI) DeltaBeta -= 2*PI; - while(DeltaBeta < -PI) DeltaBeta += 2*PI; - if(Abs(DeltaBeta) < 0.06f) - Rotating = false; - } - - Front = TargetCoors - Source; - Front.Normalise(); - CVector Front2 = Front; - Front2.Normalise(); // What? - // FIX: the meaning of this value must have changed somehow - Source -= Front2 * TheCamera.m_fPedZoomValueSmooth*1.5f; -// Source += Front2 * TheCamera.m_fPedZoomValueSmooth; - - GetVectorsReadyForRW(); -} - #ifdef FREE_CAM void CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrientation, float, float) @@ -4481,7 +4411,7 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient while(Beta >= PI) Beta -= 2.0f*PI; while(Beta < -PI) Beta += 2.0f*PI; if(Alpha > DEGTORAD(45.0f)) Alpha = DEGTORAD(45.0f); - if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); + else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); float BetaDiff = TargetOrientation+PI - Beta; diff --git a/src/core/Camera.h b/src/core/Camera.h index 9cb35636..73e1a15f 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -121,9 +121,8 @@ public: float f_max_role_angle; //=DEGTORAD(5.0f); float f_Roll; //used for adding a slight roll to the camera in the - float f_rollSpeed; //TODO(MIAMI): remove + float f_rollSpeed; float m_fSyphonModeTargetZOffSet; - float m_fRoadOffSet; float m_fAmountFractionObscured; float m_fAlphaSpeedOverOneFrame; float m_fBetaSpeedOverOneFrame; @@ -246,26 +245,14 @@ public: bool Process_WheelCam(const CVector&, float, float, float); void Process_Fixed(const CVector &CameraTarget, float, float, float); void Process_Player_Fallen_Water(const CVector &CameraTarget, float TargetOrientation, float, float); - void Process_Circle(const CVector &CameraTarget, float, float, float); void Process_SpecialFixedForSyphon(const CVector &CameraTarget, float, float, float); + void Process_LightHouse(const CVector &CameraTarget, float, float, float); void ProcessPedsDeadBaby(void); bool ProcessArrestCamOne(void); bool ProcessArrestCamTwo(void); - - /* Some of the unused PS2 cams */ - void Process_Chris_With_Binding_PlusRotation(const CVector &CameraTarget, float, float, float); - void Process_ReactionCam(const CVector &CameraTarget, float TargetOrientation, float, float); - void Process_FollowPed_WithBinding(const CVector &CameraTarget, float TargetOrientation, float, float); - // TODO: - // CCam::Process_CushyPillows_Arse - // CCam::Process_Look_At_Cars - // CCam::Process_CheesyZoom - // CCam::Process_Aiming - // CCam::Process_Bill // same as BehindCar due to unused variables - // CCam::Process_Im_The_Passenger_Woo_Woo - // CCam::Process_Blood_On_The_Tracks - // CCam::Process_Cam_Running_Side_Train - // CCam::Process_Cam_On_Train_Roof + bool GetLookAlongGroundPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut); + bool GetLookFromLampPostPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut); + bool GetLookOverShoulderPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut); // custom stuff void Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrientation, float, float); diff --git a/src/core/World.cpp b/src/core/World.cpp index ecf17575..a44d3efc 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -649,8 +649,8 @@ CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bo } void -CWorld::FindObjectsInRangeSectorList(CPtrList &list, Const CVector ¢re, float radius, bool ignoreZ, short *nextObject, - short lastObject, CEntity **objects) +CWorld::FindObjectsInRangeSectorList(CPtrList &list, Const CVector ¢re, float radius, bool ignoreZ, int16 *numObjects, + int16 lastObject, CEntity **objects) { float radiusSqr = radius * radius; float objDistSqr; @@ -666,16 +666,16 @@ CWorld::FindObjectsInRangeSectorList(CPtrList &list, Const CVector ¢re, floa else objDistSqr = diff.MagnitudeSqr(); - if(objDistSqr < radiusSqr && *nextObject < lastObject) { - if(objects) { objects[*nextObject] = object; } - (*nextObject)++; + if(objDistSqr < radiusSqr && *numObjects < lastObject) { + if(objects) { objects[*numObjects] = object; } + (*numObjects)++; } } } } void -CWorld::FindObjectsInRange(Const CVector ¢re, float radius, bool ignoreZ, short *nextObject, short lastObject, +CWorld::FindObjectsInRange(Const CVector ¢re, float radius, bool ignoreZ, int16 *numObjects, int16 lastObject, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies) { @@ -701,39 +701,39 @@ CWorld::FindObjectsInRange(Const CVector ¢re, float radius, bool ignoreZ, sh AdvanceCurrentScanCode(); - *nextObject = 0; + *numObjects = 0; for(int curY = minY; curY <= maxY; curY++) { for(int curX = minX; curX <= maxX; curX++) { CSector *sector = GetSector(curX, curY); if(checkBuildings) { FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, radius, - ignoreZ, nextObject, lastObject, objects); + ignoreZ, numObjects, lastObject, objects); FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre, - radius, ignoreZ, nextObject, lastObject, objects); + radius, ignoreZ, numObjects, lastObject, objects); } if(checkVehicles) { FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, radius, - ignoreZ, nextObject, lastObject, objects); + ignoreZ, numObjects, lastObject, objects); FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre, - radius, ignoreZ, nextObject, lastObject, objects); + radius, ignoreZ, numObjects, lastObject, objects); } if(checkPeds) { FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, radius, ignoreZ, - nextObject, lastObject, objects); + numObjects, lastObject, objects); FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, radius, - ignoreZ, nextObject, lastObject, objects); + ignoreZ, numObjects, lastObject, objects); } if(checkObjects) { FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, radius, - ignoreZ, nextObject, lastObject, objects); + ignoreZ, numObjects, lastObject, objects); FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre, - radius, ignoreZ, nextObject, lastObject, objects); + radius, ignoreZ, numObjects, lastObject, objects); } if(checkDummies) { FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, radius, - ignoreZ, nextObject, lastObject, objects); + ignoreZ, numObjects, lastObject, objects); FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre, - radius, ignoreZ, nextObject, lastObject, objects); + radius, ignoreZ, numObjects, lastObject, objects); } } } diff --git a/src/core/World.h b/src/core/World.h index 3da774ba..8d539061 100644 --- a/src/core/World.h +++ b/src/core/World.h @@ -103,8 +103,8 @@ public: static CEntity *TestSphereAgainstWorld(CVector centre, float radius, CEntity *entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects); static CEntity *TestSphereAgainstSectorList(CPtrList&, CVector, float, CEntity*, bool); - static void FindObjectsInRangeSectorList(CPtrList&, Const CVector&, float, bool, short*, short, CEntity**); - static void FindObjectsInRange(Const CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool); + static void FindObjectsInRangeSectorList(CPtrList &list, Const CVector ¢re, float radius, bool ignoreZ, int16 *numObjects, int16 lastObject, CEntity **objects); + static void FindObjectsInRange(Const CVector ¢re, float radius, bool ignoreZ, int16 *numObjects, int16 lastObject, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies); static void FindObjectsOfTypeInRangeSectorList(uint32 modelId, CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities); static void FindObjectsOfTypeInRange(uint32 modelId, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies); static float FindGroundZForCoord(float x, float y); diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h index ad7b4aaf..7b67c199 100644 --- a/src/modelinfo/ModelIndices.h +++ b/src/modelinfo/ModelIndices.h @@ -436,6 +436,21 @@ IsLightObject(int16 id) id == MI_TRAFFICLIGHTS_TWOVERTICAL; } +inline bool +IsLampPost(int16 id) +{ + return id == MI_SINGLESTREETLIGHTS1 || + id == MI_SINGLESTREETLIGHTS2 || + id == MI_SINGLESTREETLIGHTS3 || + id == MI_BOLLARDLIGHT || + id == MI_MLAMPPOST || + id == MI_STREETLAMP1 || + id == MI_STREETLAMP2 || + id == MI_TELPOLE02 || + id == MI_TRAFFICLIGHTS_MIAMI || + id == MI_TRAFFICLIGHTS_TWOVERTICAL; +} + inline bool IsBodyPart(int16 id) { From e6d2b49121a8cc03e69be7c9cfa451603332ffc9 Mon Sep 17 00:00:00 2001 From: aap Date: Sun, 14 Jun 2020 23:16:22 +0200 Subject: [PATCH 11/18] more cleanup --- src/core/Cam.cpp | 43 +++++++++++++++++++++---------------------- src/core/World.cpp | 34 +++++++++++++++++----------------- src/core/World.h | 4 ++-- 3 files changed, 40 insertions(+), 41 deletions(-) diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index fc03b291..a9d0e474 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -111,7 +111,11 @@ CCam::Process(void) Fwd.x = CamTargetEntity->GetForward().x; Fwd.y = CamTargetEntity->GetForward().y; Fwd.Normalise(); - // Game normalizes again here manually. useless, so skipped + float FwdLength = Fwd.Magnitude2D(); + if(FwdLength != 0.0f){ + Fwd.x /= FwdLength; + Fwd.y /= FwdLength; + } float FwdSpeedX = ((CVehicle*)CamTargetEntity)->GetMoveSpeed().x * Fwd.x; float FwdSpeedY = ((CVehicle*)CamTargetEntity)->GetMoveSpeed().y * Fwd.y; @@ -272,7 +276,7 @@ CCam::Process(void) CVector TargetToCam = Source - m_cvecTargetCoorsForFudgeInter; float DistOnGround = TargetToCam.Magnitude2D(); m_fTrueBeta = CGeneral::GetATanOfXY(TargetToCam.x, TargetToCam.y); - m_fTrueAlpha = CGeneral::GetATanOfXY(TargetToCam.z, DistOnGround); + m_fTrueAlpha = CGeneral::GetATanOfXY(DistOnGround, TargetToCam.z); if(TheCamera.m_uiTransitionState == 0) KeepTrackOfTheSpeed(Source, m_cvecTargetCoorsForFudgeInter, Up, m_fTrueAlpha, m_fTrueBeta, FOV); @@ -2585,7 +2589,7 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f); - if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); + else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); #ifdef GTA3_1_1_PATCH HeadPos.x = 0.0f; @@ -2876,7 +2880,7 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float, while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f); - if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); + else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); TargetCoors.x = 3.0f * Cos(Alpha) * Cos(Beta) + Source.x; TargetCoors.y = 3.0f * Cos(Alpha) * Sin(Beta) + Source.y; @@ -2920,13 +2924,8 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float, void CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float, float) { - if(CamTargetEntity->m_rwObject == nil) - return; - -#ifdef FIX_BUGS if(!CamTargetEntity->IsPed()) return; -#endif static bool FailedTestTwelveFramesAgo = false; RwV3d HeadPos; @@ -2936,9 +2935,9 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float static float TargetFOV = 0.0f; if(ResetStatics){ - Beta = TargetOrientation; + Beta = ((CPed*)CamTargetEntity)->m_fRotationCur + HALFPI; Alpha = 0.0f; - m_fInitialPlayerOrientation = TargetOrientation; + m_fInitialPlayerOrientation = ((CPed*)CamTargetEntity)->m_fRotationCur + HALFPI; FailedTestTwelveFramesAgo = false; // static DPadVertical unused // static DPadHorizontal unused @@ -2979,7 +2978,7 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f); - if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); + else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); TargetCoors.x = 3.0f * Cos(Alpha) * Cos(Beta) + Source.x; TargetCoors.y = 3.0f * Cos(Alpha) * Sin(Beta) + Source.y; @@ -3627,12 +3626,12 @@ CCam::Process_WheelCam(const CVector&, float, float, float) } CVector NewUp(0.0f, 0.0f, 1.0f); - CVector Left = CrossProduct(Front, NewUp); - Left.Normalise(); - NewUp = CrossProduct(Left, Front); + CVector Right = CrossProduct(Front, NewUp); + Right.Normalise(); + NewUp = CrossProduct(Right, Front); float Roll = Cos((CTimer::GetTimeInMilliseconds()&0x1FFFF)/(float)0x1FFFF * TWOPI); - Up = Cos(Roll*0.4f)*NewUp + Sin(Roll*0.4f)*Left; + Up = Cos(Roll*0.4f)*NewUp + Sin(Roll*0.4f)*Right; } void @@ -3753,7 +3752,7 @@ CCam::Process_Debug(const CVector&, float, float, float) TargetCoors.z = Source.z + Sin(Alpha) * 3.0f; if(Alpha > DEGTORAD(89.5f)) Alpha = DEGTORAD(89.5f); - if(Alpha < DEGTORAD(-89.5f)) Alpha = DEGTORAD(-89.5f); + else if(Alpha < DEGTORAD(-89.5f)) Alpha = DEGTORAD(-89.5f); if(CPad::GetPad(1)->GetSquare() || KEYDOWN('W')) Speed += 0.1f; @@ -3846,7 +3845,7 @@ CCam::Process_Debug(const CVector&, float, float, float) TargetCoors.z = Source.z + Sin(Alpha) * 3.0f; if(Alpha > DEGTORAD(89.5f)) Alpha = DEGTORAD(89.5f); - if(Alpha < DEGTORAD(-89.5f)) Alpha = DEGTORAD(-89.5f); + else if(Alpha < DEGTORAD(-89.5f)) Alpha = DEGTORAD(-89.5f); if(CPad::GetPad(1)->GetSquare() || CPad::GetPad(1)->GetLeftMouse()) Speed += 0.1f; @@ -3925,7 +3924,7 @@ CCam::Process_Editor(const CVector&, float, float, float) CSceneEdit::m_vecCamHeading = TargetCoors - Source; if(Alpha > DEGTORAD(89.5f)) Alpha = DEGTORAD(89.5f); - if(Alpha < DEGTORAD(-89.5f)) Alpha = DEGTORAD(-89.5f); + else if(Alpha < DEGTORAD(-89.5f)) Alpha = DEGTORAD(-89.5f); if(CPad::GetPad(1)->GetSquare() || CPad::GetPad(1)->GetLeftMouse()) Speed += 0.1f; @@ -4056,11 +4055,11 @@ bool CCam::ProcessArrestCamOne(void) { FOV = 45.0f; - if(ResetStatics) + if(!ResetStatics) return true; #ifdef FIX_BUGS - if(!CamTargetEntity->IsPed()) + if(!CamTargetEntity->IsPed() || ((CPlayerPed*)TheCamera.pTargetEntity)->m_pArrestingCop == nil) return true; #endif @@ -4597,7 +4596,7 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient while(Beta >= PI) Beta -= 2.0f*PI; while(Beta < -PI) Beta += 2.0f*PI; if(Alpha > DEGTORAD(45.0f)) Alpha = DEGTORAD(45.0f); - if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); + else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); float BetaDiff = TargetOrientation+PI - Beta; diff --git a/src/core/World.cpp b/src/core/World.cpp index 3b77db18..8bcce8e7 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -659,8 +659,8 @@ CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bo } void -CWorld::FindObjectsInRangeSectorList(CPtrList &list, Const CVector ¢re, float radius, bool ignoreZ, short *nextObject, - short lastObject, CEntity **objects) +CWorld::FindObjectsInRangeSectorList(CPtrList &list, Const CVector ¢re, float radius, bool ignoreZ, int16 *numObjects, + int16 lastObject, CEntity **objects) { float radiusSqr = radius * radius; float objDistSqr; @@ -676,16 +676,16 @@ CWorld::FindObjectsInRangeSectorList(CPtrList &list, Const CVector ¢re, floa else objDistSqr = diff.MagnitudeSqr(); - if(objDistSqr < radiusSqr && *nextObject < lastObject) { - if(objects) { objects[*nextObject] = object; } - (*nextObject)++; + if(objDistSqr < radiusSqr && *numObjects < lastObject) { + if(objects) { objects[*numObjects] = object; } + (*numObjects)++; } } } } void -CWorld::FindObjectsInRange(Const CVector ¢re, float radius, bool ignoreZ, short *nextObject, short lastObject, +CWorld::FindObjectsInRange(Const CVector ¢re, float radius, bool ignoreZ, int16 *numObjects, int16 lastObject, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies) { @@ -711,39 +711,39 @@ CWorld::FindObjectsInRange(Const CVector ¢re, float radius, bool ignoreZ, sh AdvanceCurrentScanCode(); - *nextObject = 0; + *numObjects = 0; for(int curY = minY; curY <= maxY; curY++) { for(int curX = minX; curX <= maxX; curX++) { CSector *sector = GetSector(curX, curY); if(checkBuildings) { FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, radius, - ignoreZ, nextObject, lastObject, objects); + ignoreZ, numObjects, lastObject, objects); FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre, - radius, ignoreZ, nextObject, lastObject, objects); + radius, ignoreZ, numObjects, lastObject, objects); } if(checkVehicles) { FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, radius, - ignoreZ, nextObject, lastObject, objects); + ignoreZ, numObjects, lastObject, objects); FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre, - radius, ignoreZ, nextObject, lastObject, objects); + radius, ignoreZ, numObjects, lastObject, objects); } if(checkPeds) { FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, radius, ignoreZ, - nextObject, lastObject, objects); + numObjects, lastObject, objects); FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, radius, - ignoreZ, nextObject, lastObject, objects); + ignoreZ, numObjects, lastObject, objects); } if(checkObjects) { FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, radius, - ignoreZ, nextObject, lastObject, objects); + ignoreZ, numObjects, lastObject, objects); FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre, - radius, ignoreZ, nextObject, lastObject, objects); + radius, ignoreZ, numObjects, lastObject, objects); } if(checkDummies) { FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, radius, - ignoreZ, nextObject, lastObject, objects); + ignoreZ, numObjects, lastObject, objects); FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre, - radius, ignoreZ, nextObject, lastObject, objects); + radius, ignoreZ, numObjects, lastObject, objects); } } } diff --git a/src/core/World.h b/src/core/World.h index 2bcc4e43..9465a914 100644 --- a/src/core/World.h +++ b/src/core/World.h @@ -102,8 +102,8 @@ public: static CEntity *TestSphereAgainstWorld(CVector centre, float radius, CEntity *entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects); static CEntity *TestSphereAgainstSectorList(CPtrList&, CVector, float, CEntity*, bool); - static void FindObjectsInRangeSectorList(CPtrList&, Const CVector&, float, bool, short*, short, CEntity**); - static void FindObjectsInRange(Const CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool); + static void FindObjectsInRangeSectorList(CPtrList &list, Const CVector ¢re, float radius, bool ignoreZ, int16 *numObjects, int16 lastObject, CEntity **objects); + static void FindObjectsInRange(Const CVector ¢re, float radius, bool ignoreZ, int16 *numObjects, int16 lastObject, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies); static void FindObjectsOfTypeInRangeSectorList(uint32 modelId, CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities); static void FindObjectsOfTypeInRange(uint32 modelId, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies); static float FindGroundZForCoord(float x, float y); From 2d976827ddf6fb43e64bf34555cf9175f867494b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Mon, 15 Jun 2020 00:26:19 +0300 Subject: [PATCH 12/18] much better mission switcher --- src/control/Script.cpp | 77 ++++++++++++++++++++++++++++++------------ src/control/Script.h | 11 +++--- src/core/re3.cpp | 2 +- 3 files changed, 63 insertions(+), 27 deletions(-) diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 77528b6e..957815fe 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -166,10 +166,6 @@ bool doingMissionRetry; #endif -#ifdef MISSION_SWITCHER -int switchMissionTo = -1; -#endif - const uint32 CRunningScript::nSaveStructSize = #ifdef COMPATIBLE_SAVES 136; @@ -889,18 +885,10 @@ void CRunningScript::Process() int8 CRunningScript::ProcessOneCommand() { - int32 command; -#ifdef MISSION_SWITCHER - if (switchMissionTo != -1) - command = COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL; - else -#endif - { - ++CTheScripts::CommandsExecuted; - command = CTheScripts::Read2BytesFromScript(&m_nIp); - m_bNotFlag = (command & 0x8000); - command &= 0x7FFF; - } + ++CTheScripts::CommandsExecuted; + int32 command = CTheScripts::Read2BytesFromScript(&m_nIp); + m_bNotFlag = (command & 0x8000); + command &= 0x7FFF; if (command < 100) return ProcessCommands0To99(command); if (command < 200) @@ -9143,12 +9131,6 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) return 0; case COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL: { -#ifdef MISSION_SWITCHER - if (switchMissionTo != -1) { - ScriptParams[0] = switchMissionTo; - switchMissionTo = -1; - } else -#endif CollectParameters(&m_nIp, 1); if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && ScriptParams[0] <= UINT16_MAX - 2) @@ -14480,3 +14462,54 @@ void RetryMission(int type, int unk) } #endif + +#ifdef MISSION_SWITCHER +void +CTheScripts::SwitchToMission(int32 mission) +{ + for (CRunningScript* pScript = CTheScripts::pActiveScripts; pScript != nil; pScript = pScript->GetNext()) { + if (!pScript->m_bIsMissionScript || !pScript->m_bDeatharrestEnabled) { + continue; + } + while (pScript->m_nStackPointer > 0) + --pScript->m_nStackPointer; + + pScript->m_nIp = pScript->m_anStack[pScript->m_nStackPointer]; + *(int32*)&CTheScripts::ScriptSpace[CTheScripts::OnAMissionFlag] = 0; + pScript->m_nWakeTime = 0; + pScript->m_bDeatharrestExecuted = true; + + while (!pScript->ProcessOneCommand()); + + CMessages::ClearMessages(); + } + + if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && mission <= UINT16_MAX - 2) + return; + +#ifdef MISSION_REPLAY + missionRetryScriptIndex = mission; + if (missionRetryScriptIndex == 19) + CStats::LastMissionPassedName[0] = '\0'; +#endif + CTimer::Suspend(); + int offset = CTheScripts::MultiScriptArray[mission]; +#ifdef USE_DEBUG_SCRIPT_LOADER + CFileMgr::ChangeDir("\\data\\"); + int handle = CFileMgr::OpenFile(scriptfile, "rb"); + CFileMgr::ChangeDir("\\"); +#else + CFileMgr::ChangeDir("\\"); + int handle = CFileMgr::OpenFile("data\\main.scm", "rb"); +#endif + CFileMgr::Seek(handle, offset, 0); + CFileMgr::Read(handle, (const char*)&CTheScripts::ScriptSpace[SIZE_MAIN_SCRIPT], SIZE_MISSION_SCRIPT); + CFileMgr::CloseFile(handle); + CRunningScript* pMissionScript = CTheScripts::StartNewScript(SIZE_MAIN_SCRIPT); + CTimer::Resume(); + pMissionScript->m_bIsMissionScript = true; + pMissionScript->m_bMissionFlag = true; + CTheScripts::bAlreadyRunningAMissionScript = true; + CGameLogic::ClearShortCut(); +} +#endif \ No newline at end of file diff --git a/src/control/Script.h b/src/control/Script.h index 45475e6e..9b2de580 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -375,6 +375,11 @@ private: static void RemoveScriptTextureDictionary(); static void RemoveThisPed(CPed* pPed); +#ifdef MISSION_SWITCHER +public: + static void SwitchToMission(int32 mission); +#endif + friend class CRunningScript; friend class CHud; friend void CMissionCleanup::Process(); @@ -526,6 +531,8 @@ private: bool CheckDamagedWeaponType(int32 actual, int32 type); static bool ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami); + + friend class CTheScripts; }; #ifdef USE_DEBUG_SCRIPT_LOADER @@ -545,8 +552,4 @@ void RetryMission(int, int); #ifdef USE_DEBUG_SCRIPT_LOADER extern int scriptToLoad; -#endif - -#ifdef MISSION_SWITCHER -extern int switchMissionTo; #endif \ No newline at end of file diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 76865339..5ee67195 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -315,7 +315,7 @@ int8 nextMissionToSwitch = 0; static void SwitchToMission(void) { - switchMissionTo = nextMissionToSwitch; + CTheScripts::SwitchToMission(nextMissionToSwitch); } #endif From 686d6e9834b21a5acc37123f3913cd83e670d241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Mon, 15 Jun 2020 16:17:22 +0300 Subject: [PATCH 13/18] Fix vehicle cam. zoom values --- src/core/Cam.cpp | 12 +++---- src/core/Camera.cpp | 84 ++++++++++++++++++++++++++++++--------------- src/core/Camera.h | 14 -------- 3 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 62ea950e..5b784947 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -4550,7 +4550,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, // We may need those later bool isPlane = car->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE; bool isHeli = car->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI; - bool isBike = car->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE || car->IsBike(); + bool isBike = car->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE; bool isCar = car->IsCar() && !isPlane && !isHeli && !isBike; CPad* pad = CPad::GetPad(0); @@ -4623,11 +4623,11 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, // Taken from VC CCam::Cam_On_A_String_Unobscured. If we don't this, we will end up seeing the world from the inside of RC Goblin/Raider. // I couldn't find where SA does that. It's possible that they've increased the size of these veh.'s collision bounding box. - if (car->m_modelIndex == MI_RCRAIDER || car->m_modelIndex == MI_RCBANDIT) { - newDistance += 6.0f; - } else if (car->m_modelIndex == MI_RCBARON) { - newDistance += 9.5f; - } + + if (car->m_modelIndex == MI_RCRAIDER || car->m_modelIndex == MI_RCGOBLIN) + newDistance += INIT_RC_HELI_HORI_EXTRA; + else if (car->m_modelIndex == MI_RCBARON) + newDistance += INIT_RC_PLANE_HORI_EXTRA; float minDistForThisCar = approxCarLength * CARCAM_SET[camSetArrPos][3]; diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 423a3da6..6d25c6d1 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -76,6 +76,16 @@ float CCamera::m_f3rdPersonCHairMultY; #define CTRLDOWN(key) ((KEYDOWN(rsLCTRL) || KEYDOWN(rsRCTRL)) && KEYDOWN((RsKeyCodes)key)) #endif +const float ZOOM_ONE_DISTANCE[] = { -0.6f, 0.05f, -3.2f, 0.05f, -2.41f }; +const float ZOOM_TWO_DISTANCE[] = { 1.9f, 1.4f, 0.65f, 1.9f, 6.49f }; +const float ZOOM_THREE_DISTANCE[] = { 15.9f, 15.9f, 15.9f, 15.9f, 25.25f }; + +#ifdef FREE_CAM +const float LCS_ZOOM_ONE_DISTANCE[] = { -1.0f, -0.2f, -3.2f, 0.05f, -2.41f }; +const float LCS_ZOOM_TWO_DISTANCE[] = { 2.0f, 2.2f, 1.65f, 2.9f, 6.49f }; +const float LCS_ZOOM_THREE_DISTANCE[] = { 6.0f, 6.0f, 15.9f, 15.9f, 15.0f }; +#endif + CCamera::CCamera(void) { Init(); @@ -670,6 +680,10 @@ CCamera::CamControl(void) if(CarZoomIndicator != CAM_ZOOM_1STPRS && CarZoomIndicator != CAM_ZOOM_TOPDOWN) ReqMode = CCam::MODE_CAM_ON_A_STRING; + int vehApp = ((CVehicle*)pTargetEntity)->GetVehicleAppearance(); + int vehArrPos = 0; + GetArrPosForVehicleType(vehApp, vehArrPos); + switch(((CVehicle*)pTargetEntity)->m_vehType){ case VEHICLE_TYPE_CAR: case VEHICLE_TYPE_BIKE: @@ -758,26 +772,26 @@ CCamera::CamControl(void) } // Car zoom value - if(CarZoomIndicator == CAM_ZOOM_1STPRS && !m_bPlayerIsInGarage){ + if (CarZoomIndicator == CAM_ZOOM_1STPRS && !m_bPlayerIsInGarage) { CarZoomValue = 0.0f; ReqMode = CCam::MODE_1STPERSON; } #ifdef FREE_CAM else if (bFreeCam) { if (CarZoomIndicator == CAM_ZOOM_1) - CarZoomValue = ((CVehicle*)pTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_1 : FREE_CAR_ZOOM_VALUE_1; + CarZoomValue = LCS_ZOOM_ONE_DISTANCE[vehArrPos]; else if (CarZoomIndicator == CAM_ZOOM_2) - CarZoomValue = ((CVehicle*)pTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_2 : FREE_CAR_ZOOM_VALUE_2; + CarZoomValue = LCS_ZOOM_TWO_DISTANCE[vehArrPos]; else if (CarZoomIndicator == CAM_ZOOM_3) - CarZoomValue = ((CVehicle*)pTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_3 : FREE_CAR_ZOOM_VALUE_3; + CarZoomValue = LCS_ZOOM_THREE_DISTANCE[vehArrPos]; } #endif - else if(CarZoomIndicator == CAM_ZOOM_1) - CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_1; + else if (CarZoomIndicator == CAM_ZOOM_1) + CarZoomValue = ZOOM_ONE_DISTANCE[vehArrPos]; else if(CarZoomIndicator == CAM_ZOOM_2) - CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_2; + CarZoomValue = ZOOM_TWO_DISTANCE[vehArrPos]; else if(CarZoomIndicator == CAM_ZOOM_3) - CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_3; + CarZoomValue = ZOOM_THREE_DISTANCE[vehArrPos]; if(CarZoomIndicator == CAM_ZOOM_TOPDOWN && !m_bPlayerIsInGarage){ CarZoomValue = 1.0f; @@ -3103,26 +3117,42 @@ CCamera::SetZoomValueFollowPedScript(int16 dist) void CCamera::SetZoomValueCamStringScript(int16 dist) { -#ifdef FREE_CAM - if (bFreeCam) { - switch (dist) { - case 0: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_1 : FREE_CAR_ZOOM_VALUE_1; break; - case 1: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_2 : FREE_CAR_ZOOM_VALUE_2; break; - case 2: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_3 : FREE_CAR_ZOOM_VALUE_3; break; - default: break; - } - } else -#endif - { - switch (dist) { - case 0: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_1; break; - case 1: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_2; break; - case 2: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_3; break; - default: break; - } - } + if (Cams[ActiveCam].CamTargetEntity->IsVehicle()) { + int vehApp = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->GetVehicleAppearance(); + int vehArrPos = 0; + GetArrPosForVehicleType(vehApp, vehArrPos); - m_bUseScriptZoomValueCar = true; +#ifdef FREE_CAM + if (bFreeCam) { + switch (dist) { + case 0: m_fCarZoomValueScript = LCS_ZOOM_ONE_DISTANCE[vehArrPos]; break; + case 1: m_fCarZoomValueScript = LCS_ZOOM_TWO_DISTANCE[vehArrPos]; break; + case 2: m_fCarZoomValueScript = LCS_ZOOM_THREE_DISTANCE[vehArrPos]; break; + default: break; + } + } + else +#endif + { + switch (dist) { + case 0: m_fCarZoomValueScript = ZOOM_ONE_DISTANCE[vehArrPos]; break; + case 1: m_fCarZoomValueScript = ZOOM_TWO_DISTANCE[vehArrPos]; break; + case 2: m_fCarZoomValueScript = ZOOM_THREE_DISTANCE[vehArrPos]; break; + default: break; + } + } + + m_bUseScriptZoomValueCar = true; + } else { + switch (dist) { + case 0: m_fPedZoomValueScript = 0.25f; break; + case 1: m_fPedZoomValueScript = 1.5f; break; + case 2: m_fPedZoomValueScript = 2.9f; break; + default: break; + } + + m_bUseScriptZoomValuePed = true; + } } void diff --git a/src/core/Camera.h b/src/core/Camera.h index 73e1a15f..7a95f75a 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -26,20 +26,6 @@ enum CAM_ZOOM_CINEMATIC, }; -#ifdef FREE_CAM // LCS values -#define FREE_CAR_ZOOM_VALUE_1 (-1.0f) -#define FREE_CAR_ZOOM_VALUE_2 (2.0f) -#define FREE_CAR_ZOOM_VALUE_3 (6.0f) - -#define FREE_BOAT_ZOOM_VALUE_1 (-2.41f) -#define FREE_BOAT_ZOOM_VALUE_2 (6.49f) -#define FREE_BOAT_ZOOM_VALUE_3 (15.0f) -#endif - -#define DEFAULT_CAR_ZOOM_VALUE_1 (0.05f) -#define DEFAULT_CAR_ZOOM_VALUE_2 (1.9f) -#define DEFAULT_CAR_ZOOM_VALUE_3 (3.9f) - const float DefaultFOV = 70.0f; // beta: 80.0f class CCam From 62024217b78b3a20b93da0e3b2d5957c6c354bbf Mon Sep 17 00:00:00 2001 From: aap Date: Mon, 15 Jun 2020 20:50:01 +0200 Subject: [PATCH 14/18] more CCam --- src/core/Cam.cpp | 702 +++++++++++++++++++++++++--------------------- src/core/Camera.h | 7 +- src/peds/PedIK.h | 1 + 3 files changed, 379 insertions(+), 331 deletions(-) diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 4bbfbcca..b045b38f 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -14,6 +14,7 @@ #include "Pad.h" #include "Frontend.h" #include "General.h" +#include "Timecycle.h" #include "Renderer.h" #include "Shadows.h" #include "Hud.h" @@ -244,18 +245,10 @@ CCam::Process(void) case MODE_PLAYER_FALLEN_WATER: Process_Player_Fallen_Water(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; -/* case MODE_CAM_ON_TRAIN_ROOF: - Process_Cam_On_Train_Roof(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); - break; - case MODE_CAM_RUNNING_SIDE_TRAIN: - Process_Cam_Running_Side_Train(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); - break; - case MODE_BLOOD_ON_THE_TRACKS: - Process_Blood_On_The_Tracks(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); - break; - case MODE_IM_THE_PASSENGER_WOOWOO: - Process_Im_The_Passenger_Woo_Woo(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); - break;*/ +// case MODE_CAM_ON_TRAIN_ROOF: +// case MODE_CAM_RUNNING_SIDE_TRAIN: +// case MODE_BLOOD_ON_THE_TRACKS: +// case MODE_IM_THE_PASSENGER_WOOWOO: case MODE_SYPHON_CRIM_IN_FRONT: Process_Syphon_Crim_In_Front(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; @@ -400,25 +393,23 @@ MakeAngleLessThan180(float &Angle) while(Angle < -PI) Angle += 2*PI; } +//--MIAMI: done void CCam::ProcessSpecialHeightRoutines(void) { - int i = 0; + int i; bool StandingOnBoat = false; static bool PreviouslyFailedRoadHeightCheck = false; CVector CamToTarget, CamToPed; float DistOnGround, BetaAngle; CPed *Player; - int ClosestPed = 0; - bool FoundPed = false; - float ClosestPedDist, PedZDist; + float PedZDist; CColPoint colPoint; CamToTarget = TheCamera.pTargetEntity->GetPosition() - TheCamera.GetGameCamPosition(); DistOnGround = CamToTarget.Magnitude2D(); BetaAngle = CGeneral::GetATanOfXY(CamToTarget.x, CamToTarget.y); m_bTheHeightFixerVehicleIsATrain = false; - ClosestPedDist = 0.0f; // CGeneral::GetATanOfXY(TheCamera.GetForward().x, TheCamera.GetForward().y); Player = CWorld::Players[CWorld::PlayerInFocus].m_pPed; @@ -430,65 +421,61 @@ CCam::ProcessSpecialHeightRoutines(void) ((CVehicle*)FindPlayerPed()->m_pCurSurface)->IsBoat()) StandingOnBoat = true; + float FoundPedZ = -100.0f; + // Move up the camera if there is a ped close to it if(Mode == MODE_FOLLOWPED || Mode == MODE_FIGHT_CAM || Mode == MODE_PILLOWS_PAPS){ - // Find ped closest to camera - while(i < Player->m_numNearPeds){ - if(Player->m_nearPeds[i] && Player->m_nearPeds[i]->GetPedState() != PED_DEAD){ - CamToPed = Player->m_nearPeds[i]->GetPosition() - TheCamera.GetGameCamPosition(); - if(FoundPed){ - if(CamToPed.Magnitude2D() < ClosestPedDist){ - ClosestPed = i; - ClosestPedDist = CamToPed.Magnitude2D(); + // Find highest ped close to camera + for(i = 0; i < Player->m_numNearPeds; i++){ + CPed *nearPed = Player->m_nearPeds[i]; + if(nearPed && nearPed->GetPedState() != PED_DEAD){ + CamToPed = nearPed->GetPosition() - TheCamera.GetGameCamPosition(); + if(Abs(CamToPed.z) < 1.0f){ + float DistSq = CamToPed.MagnitudeSqr(); + if(DistSq < SQR(2.1f)){ + if(nearPed->GetPosition().z > FoundPedZ) + FoundPedZ = nearPed->GetPosition().z; + }else{ + float Dist = Sqrt(DistSq); + CamToPed /= Dist; + // strange calculation + CVector PlayerCamSpeed = DotProduct(Front, Player->m_vecMoveSpeed)*Front; + float SpeedDiff = DotProduct(PlayerCamSpeed - nearPed->m_vecMoveSpeed, CamToPed); + if(SpeedDiff > 0.01f && + (m_fPedBetweenCameraHeightOffset > 0.0f && (Dist-2.1f)/SpeedDiff < 75.0f || + m_fPedBetweenCameraHeightOffset <= 0.0f && (Dist-2.1f)/SpeedDiff < 75.0f * 0.1f)) + if(nearPed->GetPosition().z > FoundPedZ) + FoundPedZ = nearPed->GetPosition().z; } - }else{ - FoundPed = true; - ClosestPed = i; - ClosestPedDist = CamToPed.Magnitude2D(); } } - i++; } - if(FoundPed){ + if(FoundPedZ > -99.0f){ float Offset = 0.0f; - CPed *Ped = Player->m_nearPeds[ClosestPed]; - CamToPed = Ped->GetPosition() - TheCamera.GetGameCamPosition(); PedZDist = 0.0f; - float dist = CamToPed.Magnitude2D(); // should be same as ClosestPedDist - if(dist < 2.1f){ - // Ped is close to camera, move up + if(FoundPedZ > Player->GetPosition().z) + PedZDist = FoundPedZ - Player->GetPosition().z; - // Z Distance between player and close ped - PedZDist = 0.0f; - if(Ped->bIsStanding) - PedZDist = Ped->GetPosition().z - Player->GetPosition().z; - // Ignore if too distant - if(PedZDist > 1.2f || PedZDist < -1.2f) - PedZDist = 0.0f; - - float DistScale = (2.1f - dist)/2.1f; - if(Mode == MODE_FOLLOWPED){ - if(TheCamera.PedZoomIndicator == CAM_ZOOM_1) - Offset = 0.45*DistScale + PedZDist; - if(TheCamera.PedZoomIndicator == CAM_ZOOM_2) - Offset = 0.35*DistScale + PedZDist; - if(TheCamera.PedZoomIndicator == CAM_ZOOM_3) - Offset = 0.25*DistScale + PedZDist; - if(Abs(CGeneral::GetRadianAngleBetweenPoints(CamToPed.x, CamToPed.y, CamToTarget.x, CamToTarget.y)) > HALFPI) - Offset += 0.3f; - m_fPedBetweenCameraHeightOffset = Offset + 1.3f; - PedZDist = 0.0f; - }else if(Mode == MODE_FIGHT_CAM) - m_fPedBetweenCameraHeightOffset = PedZDist + 1.3f + 0.5f; - }else - m_fPedBetweenCameraHeightOffset = 0.0f; + if(Mode == MODE_FOLLOWPED){ + if(TheCamera.PedZoomIndicator == CAM_ZOOM_1 && + ((CPed*)CamTargetEntity)->GetPedState() != PED_ENTER_CAR && + ((CPed*)CamTargetEntity)->GetPedState() != PED_CARJACK) + Offset = 0.45f + PedZDist; + // BUG: overrides this ^ case + if(TheCamera.PedZoomIndicator == CAM_ZOOM_2 || TheCamera.PedZoomIndicator == CAM_ZOOM_1) + Offset = 0.35f + PedZDist; + if(TheCamera.PedZoomIndicator == CAM_ZOOM_3) + Offset = 0.25f + PedZDist; + m_fPedBetweenCameraHeightOffset = Offset + 1.3f; + }else if(Mode == MODE_FIGHT_CAM) + m_fPedBetweenCameraHeightOffset = PedZDist + 1.3f + 0.5f; + else if(Mode == MODE_PILLOWS_PAPS) + m_fPedBetweenCameraHeightOffset = PedZDist + 1.3f + 0.45f; }else{ - PedZDist = 0.0f; m_fPedBetweenCameraHeightOffset = 0.0f; } - }else - PedZDist = 0.0f; + } // Move camera up for vehicles in the way @@ -497,6 +484,8 @@ CCam::ProcessSpecialHeightRoutines(void) CEntity *vehicle = nil; float TestDist = DistOnGround + 1.25f; float HighestCar = 0.0f; + if(m_fDimensionOfHighestNearCar > 0.0f) + TestDist += 0.3f; CVector TestBase = CamTargetEntity->GetPosition(); CVector TestPoint; TestBase.z -= 0.15f; @@ -569,18 +558,32 @@ CCam::GetVectorsReadyForRW(void) Up = CrossProduct(right, Front); } +bool +CCam::GetBoatLook_L_R_HeightOffset(float &Offset) +{ + if(CamTargetEntity == nil) + return false; + CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(CamTargetEntity->GetModelIndex()); + tBoatHandlingData *handling = mod_HandlingManager.GetBoatPointer(mi->m_handlingId); + if(handling){ + Offset = handling->fLook_L_R_BehindCamHeight; + return true; + } + return false; // can't happen, we always get a boat pointer back +} + +//--MIAMI: done void CCam::LookBehind(void) { float Dist, DeltaBeta, TargetOrientation, Angle; CVector TargetCoors, TargetFwd, TestCoors; CColPoint colPoint; - CEntity *entity; TargetCoors = CamTargetEntity->GetPosition(); Front = CamTargetEntity->GetPosition() - Source; - if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_BEHINDBOAT) && CamTargetEntity->IsVehicle()){ + if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_BEHINDBOAT || Mode == MODE_BEHINDCAR) && CamTargetEntity->IsVehicle()){ LookingBehind = true; Dist = Mode == MODE_CAM_ON_A_STRING ? CA_MAX_DISTANCE : 15.5f; TargetFwd = CamTargetEntity->GetForward(); @@ -595,12 +598,8 @@ CCam::LookBehind(void) TargetOrientation += PI; Source.x = Dist*Cos(TargetOrientation) + TargetCoors.x; Source.y = Dist*Sin(TargetOrientation) + TargetCoors.y; - Source.z -= 1.0f; - if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, false, false, true, false, true, true)){ - RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); - Source = colPoint.point; - } - Source.z += 1.0f; + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV); Front = CamTargetEntity->GetPosition() - Source; GetVectorsReadyForRW(); } @@ -611,55 +610,78 @@ CCam::LookBehind(void) Front.Normalise(); if(((CVehicle*)CamTargetEntity)->IsBoat()) Source.z -= 0.5f; - Source += 0.25f*Front; - Front = -Front; -#ifdef FIX_BUGS - // not sure if this is a bug... - GetVectorsReadyForRW(); -#endif + if(((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE){ + float FrontDist = 1.1f; + if(((CVehicle*)CamTargetEntity)->pDriver){ + CVector ExtraFwd(0.0f, 0.0f, 0.0f); + ((CVehicle*)CamTargetEntity)->pDriver->m_pedIK.GetComponentPosition(ExtraFwd, PED_HEAD); + ExtraFwd += ((CVehicle*)CamTargetEntity)->m_vecMoveSpeed*CTimer::GetTimeStep() - CamTargetEntity->GetPosition(); + FrontDist += 0.2f + Max(DotProduct(ExtraFwd, CamTargetEntity->GetForward()), 0.0f); + } + Source += FrontDist*Front; + Front = -Front; + }else if(((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI){ + Front = -1.0f*CamTargetEntity->GetUp(); + Up = CamTargetEntity->GetForward(); + Source += 0.25f*Front; + }else{ + Source += 0.25f*Front; + Front = -Front; + } } if(CamTargetEntity->IsPed()){ Angle = CGeneral::GetATanOfXY(Source.x - TargetCoors.x, Source.y - TargetCoors.y) + PI; Source.x = 4.5f*Cos(Angle) + TargetCoors.x; Source.y = 4.5f*Sin(Angle) + TargetCoors.y; Source.z = 1.15f + TargetCoors.z; - TestCoors = TargetCoors; - TestCoors.z = Source.z; - if(CWorld::ProcessLineOfSight(TestCoors, Source, colPoint, entity, true, true, false, true, false, true, true)){ - Source.x = colPoint.point.x; - Source.y = colPoint.point.y; - if((TargetCoors - Source).Magnitude2D() < 1.15f) - RwCameraSetNearClipPlane(Scene.camera, 0.05f); - } + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV); Front = TargetCoors - Source; GetVectorsReadyForRW(); } } +float BOAT_1STPERSON_L_OFFSETX = 0.7f; +float BOAT_1STPERSON_R_OFFSETX = 0.3f; +float BOAT_1STPERSON_LR_OFFSETZ = 0.2f; + +//--MIAMI: done void CCam::LookLeft(void) { float Dist, TargetOrientation; CVector TargetCoors, TargetFwd; CColPoint colPoint; - CEntity *entity; - if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_BEHINDBOAT) && CamTargetEntity->IsVehicle()){ + if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_BEHINDBOAT || Mode == MODE_BEHINDCAR) && CamTargetEntity->IsVehicle()){ LookingLeft = true; TargetCoors = CamTargetEntity->GetPosition(); Front = CamTargetEntity->GetPosition() - Source; - Dist = Mode == MODE_CAM_ON_A_STRING ? CA_MAX_DISTANCE : 9.0f; + if(Mode == MODE_CAM_ON_A_STRING) + Dist = CA_MAX_DISTANCE; + else if(Mode == MODE_BEHINDBOAT){ + Dist = 9.0f; + float Offset = 0.0f; + if(GetBoatLook_L_R_HeightOffset(Offset) && !CCullZones::Cam1stPersonForPlayer()) + Source.z = TargetCoors.z + Offset; + }else + Dist = 9.0f; TargetFwd = CamTargetEntity->GetForward(); TargetFwd.Normalise(); TargetOrientation = CGeneral::GetATanOfXY(TargetFwd.x, TargetFwd.y); Source.x = Dist*Cos(TargetOrientation - HALFPI) + TargetCoors.x; Source.y = Dist*Sin(TargetOrientation - HALFPI) + TargetCoors.y; - Source.z -= 1.0f; - if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, false, false, true, false, true, true)){ - RwCameraSetNearClipPlane(Scene.camera, 0.4f); - Source = colPoint.point; - } - Source.z += 1.0f; + + CColModel *colModel = CamTargetEntity->GetColModel(); + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV); + + CVector TopRight = CamTargetEntity->GetPosition() + + CamTargetEntity->GetRight()*colModel->boundingBox.max.x + + CamTargetEntity->GetUp()*colModel->boundingBox.max.z; + float Height = Min(Max(m_cvecTargetCoorsForFudgeInter.z, TopRight.z)+0.1f, OrigSource.z); + Source.z = Max(Height, Source.z); + Front = CamTargetEntity->GetPosition() - Source; Front.z += 1.1f; if(Mode == MODE_BEHINDBOAT) @@ -669,8 +691,21 @@ CCam::LookLeft(void) if(Mode == MODE_1STPERSON && CamTargetEntity->IsVehicle()){ LookingLeft = true; RwCameraSetNearClipPlane(Scene.camera, 0.25f); - if(((CVehicle*)CamTargetEntity)->IsBoat()) - Source.z -= 0.5f; + if(((CVehicle*)CamTargetEntity)->IsBoat()){ + if(((CVehicle*)CamTargetEntity)->pDriver){ + CVector neck(0.0f, 0.0f, 0.0f); + CPed *driver = ((CVehicle*)CamTargetEntity)->pDriver; + driver->SetPedPositionInCar(); + driver->GetMatrix().UpdateRW(); + driver->UpdateRwFrame(); + driver->UpdateRpHAnim(); + driver->m_pedIK.GetComponentPosition(neck, PED_NECK); + Source = neck + + BOAT_1STPERSON_L_OFFSETX*CamTargetEntity->GetRight() + + BOAT_1STPERSON_LR_OFFSETZ*CamTargetEntity->GetUp(); + }else + Source.z -= 0.5f; + } Up = CamTargetEntity->GetUp(); Up.Normalise(); @@ -678,37 +713,48 @@ CCam::LookLeft(void) Front.Normalise(); Front = -CrossProduct(Front, Up); Front.Normalise(); -#ifdef FIX_BUGS - // not sure if this is a bug... - GetVectorsReadyForRW(); -#endif + if(((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE) + Source -= 1.45f*Front; } } +//--MIAMI: done void CCam::LookRight(void) { float Dist, TargetOrientation; CVector TargetCoors, TargetFwd; CColPoint colPoint; - CEntity *entity; if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_BEHINDBOAT) && CamTargetEntity->IsVehicle()){ LookingRight = true; TargetCoors = CamTargetEntity->GetPosition(); Front = CamTargetEntity->GetPosition() - Source; - Dist = Mode == MODE_CAM_ON_A_STRING ? CA_MAX_DISTANCE : 9.0f; + if(Mode == MODE_CAM_ON_A_STRING) + Dist = CA_MAX_DISTANCE; + else if(Mode == MODE_BEHINDBOAT){ + Dist = 9.0f; + float Offset = 0.0f; + if(GetBoatLook_L_R_HeightOffset(Offset) && !CCullZones::Cam1stPersonForPlayer()) + Source.z = TargetCoors.z + Offset; + }else + Dist = 9.0f; TargetFwd = CamTargetEntity->GetForward(); TargetFwd.Normalise(); TargetOrientation = CGeneral::GetATanOfXY(TargetFwd.x, TargetFwd.y); Source.x = Dist*Cos(TargetOrientation + HALFPI) + TargetCoors.x; Source.y = Dist*Sin(TargetOrientation + HALFPI) + TargetCoors.y; - Source.z -= 1.0f; - if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, false, false, true, false, true, true)){ - RwCameraSetNearClipPlane(Scene.camera, 0.4f); - Source = colPoint.point; - } - Source.z += 1.0f; + + CColModel *colModel = CamTargetEntity->GetColModel(); + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV); + + CVector TopLeft = CamTargetEntity->GetPosition() + + CamTargetEntity->GetRight()*colModel->boundingBox.min.x + + CamTargetEntity->GetUp()*colModel->boundingBox.max.z; + float Height = Min(Max(m_cvecTargetCoorsForFudgeInter.z, TopLeft.z)+0.1f, OrigSource.z); + Source.z = Max(Height, Source.z); + Front = CamTargetEntity->GetPosition() - Source; Front.z += 1.1f; if(Mode == MODE_BEHINDBOAT) @@ -718,8 +764,21 @@ CCam::LookRight(void) if(Mode == MODE_1STPERSON && CamTargetEntity->IsVehicle()){ LookingRight = true; RwCameraSetNearClipPlane(Scene.camera, 0.25f); - if(((CVehicle*)CamTargetEntity)->IsBoat()) - Source.z -= 0.5f; + if(((CVehicle*)CamTargetEntity)->IsBoat()){ + if(((CVehicle*)CamTargetEntity)->pDriver){ + CVector neck(0.0f, 0.0f, 0.0f); + CPed *driver = ((CVehicle*)CamTargetEntity)->pDriver; + driver->SetPedPositionInCar(); + driver->GetMatrix().UpdateRW(); + driver->UpdateRwFrame(); + driver->UpdateRpHAnim(); + driver->m_pedIK.GetComponentPosition(neck, PED_NECK); + Source = neck + + BOAT_1STPERSON_R_OFFSETX*CamTargetEntity->GetRight() + + BOAT_1STPERSON_LR_OFFSETZ*CamTargetEntity->GetUp(); + }else + Source.z -= 0.5f; + } Up = CamTargetEntity->GetUp(); Up.Normalise(); @@ -727,13 +786,12 @@ CCam::LookRight(void) Front.Normalise(); Front = CrossProduct(Front, Up); Front.Normalise(); -#ifdef FIX_BUGS - // not sure if this is a bug... - GetVectorsReadyForRW(); -#endif + if(((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE) + Source -= 1.45f*Front; } } +//--MIAMI: done void CCam::ClipIfPedInFrontOfPlayer(void) { @@ -759,7 +817,7 @@ CCam::ClipIfPedInFrontOfPlayer(void) while(DeltaAngle >= PI) DeltaAngle -= 2*PI; while(DeltaAngle < -PI) DeltaAngle += 2*PI; if(Abs(DeltaAngle) < HALFPI){ - fDist = Sqrt(SQR(vDist.x) + SQR(vDist.y)); + fDist = vDist.Magnitude2D(); if(fDist < 1.25f){ Near = DEFAULT_NEAR - (1.25f - fDist); if(Near < 0.05f) @@ -770,6 +828,7 @@ CCam::ClipIfPedInFrontOfPlayer(void) } } +//--MIAMI: done void CCam::KeepTrackOfTheSpeed(const CVector &source, const CVector &target, const CVector &up, const float &alpha, const float &beta, const float &fov) { @@ -786,9 +845,9 @@ CCam::KeepTrackOfTheSpeed(const CVector &source, const CVector &target, const CV PreviousUp = up; } - m_cvecSourceSpeedOverOneFrame = PreviousSource - source; - m_cvecTargetSpeedOverOneFrame = PreviousTarget - target; - m_cvecUpOverOneFrame = PreviousUp - up; + m_cvecSourceSpeedOverOneFrame = source - PreviousSource; + m_cvecTargetSpeedOverOneFrame = target - PreviousTarget; + m_cvecUpOverOneFrame = up - PreviousUp; m_fFovSpeedOverOneFrame = fov - PreviousFov; m_fBetaSpeedOverOneFrame = beta - PreviousBeta; MakeAngleLessThan180(m_fBetaSpeedOverOneFrame); @@ -803,39 +862,40 @@ CCam::KeepTrackOfTheSpeed(const CVector &source, const CVector &target, const CV PreviousFov = fov; } +//--MIAMI: done bool CCam::Using3rdPersonMouseCam(void) { - return CCamera::m_bUseMouse3rdPerson && - (Mode == MODE_FOLLOWPED || - TheCamera.m_bPlayerIsInGarage && - FindPlayerPed() && FindPlayerPed()->m_nPedState != PED_DRIVING && - Mode != MODE_TOPDOWN && this->CamTargetEntity == FindPlayerPed()); + return CCamera::m_bUseMouse3rdPerson && Mode == MODE_FOLLOWPED; } +//--MIAMI: done bool CCam::GetWeaponFirstPersonOn(void) { - CEntity *target = this->CamTargetEntity; - if (target && target->IsPed()) - return ((CPed*)target)->GetWeapon()->m_bAddRotOffset; - - return false; + return CamTargetEntity && CamTargetEntity->IsPed() && ((CPed*)CamTargetEntity)->GetWeapon()->m_bAddRotOffset; } +//--MIAMI: done bool CCam::IsTargetInWater(const CVector &CamCoors) { - if(CamTargetEntity == nil) - return false; - if(CamTargetEntity->IsPed()){ - if(!((CPed*)CamTargetEntity)->bIsInWater) - return false; - if(!((CPed*)CamTargetEntity)->bIsStanding) - return true; - return false; + if(CamTargetEntity){ + float WaterZ = -6000.0f; + CWaterLevel::GetWaterLevel(CamTargetEntity->GetPosition(), &WaterZ, false); + if(CamTargetEntity->IsPed()){ + if(((CPed*)CamTargetEntity)->bIsDrowning || + ((CPed*)CamTargetEntity)->bIsInWater && CamTargetEntity->GetPosition().z < WaterZ) + return true; + }else{ + assert(CamTargetEntity->IsVehicle()); + if(((CVehicle*)CamTargetEntity)->bIsDrowning || + ((CVehicle*)CamTargetEntity)->bIsInWater && CamTargetEntity->GetPosition().z < WaterZ) + return true; + } } - return ((CPhysical*)CamTargetEntity)->bIsInWater; + m_vecLastAboveWaterCamPosition = Source; + return false; } void @@ -923,39 +983,6 @@ CCam::DoAverageOnVector(const CVector &vec) return Average; } -// Rotate Beta in direction opposite of BetaOffset in 5 deg. steps. -// Return the first angle for which Beta + BetaOffset + Angle has a clear view. -// i.e. BetaOffset is a safe zone so that Beta + Angle is really clear. -// If BetaOffset == 0, try both directions. -float -CCam::GetPedBetaAngleForClearView(const CVector &Target, float Dist, float BetaOffset, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies) -{ - CColPoint point; - CEntity *ent = nil; - CVector ToSource; - float a; - - // This would be so much nicer if we just got the step variable before the loop...R* - - for(a = 0.0f; a <= PI; a += DEGTORAD(5.0f)){ - if(BetaOffset <= 0.0f){ - ToSource = CVector(Cos(Beta + BetaOffset + a), Sin(Beta + BetaOffset + a), 0.0f)*Dist; - if(!CWorld::ProcessLineOfSight(Target, Target + ToSource, - point, ent, checkBuildings, checkVehicles, checkPeds, - checkObjects, checkDummies, true, true)) - return a; - } - if(BetaOffset >= 0.0f){ - ToSource = CVector(Cos(Beta + BetaOffset - a), Sin(Beta + BetaOffset - a), 0.0f)*Dist; - if(!CWorld::ProcessLineOfSight(Target, Target + ToSource, - point, ent, checkBuildings, checkVehicles, checkPeds, - checkObjects, checkDummies, true, true)) - return -a; - } - } - return 0.0f; -} - float DefaultAcceleration = 0.045f; float DefaultMaxStep = 0.15f; float fDefaultSpeedStep = 0.025f; @@ -967,6 +994,7 @@ float fDefaultSpeedLimit4Avoid = 0.25f; float fAvoidGeomThreshhold = 1.5f; float fMiniGunBetaOffset = 0.3f; +//--MIAMI: done void CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, float, float) { @@ -1323,6 +1351,7 @@ int16 nFadeControlThreshhold = 45; float fDefaultAlphaOrient = -0.22f; float fMouseAvoidGeomReturnRate = 0.92f; +//--MIAMI: done void CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrientation, float, float) { @@ -2620,7 +2649,7 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl Source.z += 0.5f; else if(((CVehicle*)CamTargetEntity)->IsBike() && ((CVehicle*)CamTargetEntity)->pDriver){ CVector Neck(0.0f, 0.0f, 0.0f); - ((CVehicle*)CamTargetEntity)->pDriver->m_pedIK.GetComponentPosition(*(RwV3d*)&Neck, PED_NECK); + ((CVehicle*)CamTargetEntity)->pDriver->m_pedIK.GetComponentPosition(Neck, PED_NECK); Neck += ((CVehicle*)CamTargetEntity)->m_vecMoveSpeed * CTimer::GetTimeStep(); Source.z = Neck.z + fBike1stPersonOffsetZ; } @@ -3093,6 +3122,7 @@ CCam::Process_Syphon(const CVector &CameraTarget, float, float, float) GetVectorsReadyForRW(); } +//--MIAMI: done void CCam::Process_Syphon_Crim_In_Front(const CVector &CameraTarget, float, float, float) { @@ -3107,7 +3137,6 @@ CCam::Process_Syphon_Crim_In_Front(const CVector &CameraTarget, float, float, fl float zOffset; float AimingAngle; CColPoint colPoint; - CEntity *entity; TargetDist = TheCamera.m_fPedZoomValueSmooth * 0.5f + 4.0f; vDist = Source - TargetCoors; @@ -3124,6 +3153,12 @@ CCam::Process_Syphon_Crim_In_Front(const CVector &CameraTarget, float, float, fl while(AimingAngle >= PI) AimingAngle -= 2*PI; while(AimingAngle < -PI) AimingAngle += 2*PI; + if(ResetStatics){ + if(AimingAngle > 0.0f) + m_fPlayerInFrontSyphonAngleOffSet = -m_fPlayerInFrontSyphonAngleOffSet; + ResetStatics = false; + } + if(TheCamera.PlayerWeaponMode.Mode == MODE_SYPHON) Beta = AimingAngle + m_fPlayerInFrontSyphonAngleOffSet; @@ -3132,18 +3167,13 @@ CCam::Process_Syphon_Crim_In_Front(const CVector &CameraTarget, float, float, fl Source.x += Cos(Beta) * TargetDist; Source.y += Sin(Beta) * TargetDist; - if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, false, false, true, false, true, true)){ - Beta = CGeneral::GetATanOfXY(Source.x - TargetCoors.x, Source.y - TargetCoors.y); - fDist = (TargetCoors - colPoint.point).Magnitude2D(); - Source.x = TargetCoors.x; - Source.y = TargetCoors.y; - Source.x += Cos(Beta) * fDist; - Source.y += Sin(Beta) * fDist; - } - TargetCoors = CameraTarget; TargetCoors.z += m_fSyphonModeTargetZOffSet; m_cvecTargetCoorsForFudgeInter = TargetCoors; + + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV); + Front = TargetCoors - Source; GetVectorsReadyForRW(); } @@ -3274,6 +3304,7 @@ float FIGHT_HORIZ_DIST = 3.0f; float FIGHT_VERT_DIST = 1.0f; float FIGHT_BETA_ANGLE = 125.0f; +//--MIAMI: done void CCam::Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, float, float) { @@ -3564,11 +3595,19 @@ CCam::Process_WheelCam(const CVector&, float, float, float) return true; } +int BOAT_UNDERWATER_CAM_BLUR = 20; +float BOAT_UNDERWATER_CAM_COLORMAG_LIMIT = 10.0f; + +//--MIAIM: done void CCam::Process_Fixed(const CVector &CameraTarget, float, float, float) { + if(DirectionWasLooking != LOOKING_FORWARD) + DirectionWasLooking = LOOKING_FORWARD; + Source = m_cvecCamFixedModeSource; Front = CameraTarget - Source; + Front.Normalise(); m_cvecTargetCoorsForFudgeInter = CameraTarget; GetVectorsReadyForRW(); @@ -3582,7 +3621,22 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float) if(TheCamera.m_bUseSpecialFovTrain) FOV = TheCamera.m_fFovForTrain; - if(FrontEndMenuManager.m_ControlMethod == 0 && Using3rdPersonMouseCam()){ + float WaterZ = 0.0f; + if(CWaterLevel::GetWaterLevel(Source, &WaterZ, true) && Source.z < WaterZ){ + float WaterLum = Sqrt(SQR(CTimeCycle::GetWaterRed()) + SQR(CTimeCycle::GetWaterGreen()) + SQR(CTimeCycle::GetWaterBlue())); + if(WaterLum > BOAT_UNDERWATER_CAM_COLORMAG_LIMIT){ + float f = BOAT_UNDERWATER_CAM_COLORMAG_LIMIT/WaterLum; + TheCamera.SetMotionBlur(CTimeCycle::GetWaterRed()*f, + CTimeCycle::GetWaterGreen()*f, + CTimeCycle::GetWaterBlue()*f, BOAT_UNDERWATER_CAM_BLUR, MBLUR_NORMAL); + }else{ + TheCamera.SetMotionBlur(CTimeCycle::GetWaterRed(), + CTimeCycle::GetWaterGreen(), + CTimeCycle::GetWaterBlue(), BOAT_UNDERWATER_CAM_BLUR, MBLUR_NORMAL); + } + } + + if(FrontEndMenuManager.m_ControlMethod == CONTROL_STANDARD && Using3rdPersonMouseCam()){ CPed *player = FindPlayerPed(); if(player && player->CanStrafeOrMouseControl()){ float Heading = Front.Heading(); @@ -3594,6 +3648,75 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float) } } +//--MIAMI: done +void +CCam::Process_LightHouse(const CVector &CameraTarget, float, float, float) +{ + static float Timer; + + Source = CameraTarget; + Source.x = 474.3f; + Source.y = -1717.6f; + + int CamMode; + if(CameraTarget.z > 57.0f && (CameraTarget-Source).Magnitude2D() > 3.2f){ + // Outside at top + if(Timer > 0.0f){ + Timer -= CTimer::GetTimeStep(); + CamMode = 1; + }else{ + Timer = -24.0f; + CamMode = 2; + } + }else if(CameraTarget.z > 57.0f){ + // Inside at top + if(Timer < 0.0f){ + Timer += CTimer::GetTimeStep(); + CamMode = 2; + }else{ + Timer = 24.0f; + CamMode = 1; + } + }else{ + Timer = 0.0f; + CamMode = 0; + } + + if(CamMode == 2){ + Source.z = 57.5f; + Front = Source - CameraTarget; + Front.Normalise(); + Source.x = CameraTarget.x - 5.0f*Front.x; + Source.y = CameraTarget.y - 5.0f*Front.y; + }else if(CamMode == 1){ + Front = CameraTarget - Source; + Front.Normalise(); + Source.x = CameraTarget.x - 2.0f*Front.x; + Source.y = CameraTarget.y - 2.0f*Front.y; + }else{ + Source.z += 4.0f; + Front = CameraTarget - Source; + Front.Normalise(); + Source -= 4.0f*Front; + Source.z = Min(Source.z, 55.0f); + Front = CameraTarget - Source; + } + + m_cvecTargetCoorsForFudgeInter = CameraTarget; + GetVectorsReadyForRW(); + + Up = CVector(0.0f, 0.0f, 1.0f) + m_cvecCamFixedModeUpOffSet; + Up.Normalise(); + CVector Right = CrossProduct(Front, Up); + Right.Normalise(); + Up = CrossProduct(Right, Front); + + FOV = DefaultFOV; + if(TheCamera.m_bUseSpecialFovTrain) // uh, sure... + FOV = TheCamera.m_fFovForTrain; +} + +//--MIAMI: done void CCam::Process_Player_Fallen_Water(const CVector &CameraTarget, float TargetOrientation, float, float) { @@ -3601,10 +3724,8 @@ CCam::Process_Player_Fallen_Water(const CVector &CameraTarget, float TargetOrien CEntity *entity = nil; FOV = DefaultFOV; - Source = CameraTarget; - Source.x += -4.5f*Cos(TargetOrientation); - Source.y += -4.5f*Sin(TargetOrientation); - Source.z = m_vecLastAboveWaterCamPosition.z + 4.0f; + Source = m_vecLastAboveWaterCamPosition; + Source.z += 4.0f; m_cvecTargetCoorsForFudgeInter = CameraTarget; Front = CameraTarget - Source; @@ -3616,6 +3737,7 @@ CCam::Process_Player_Fallen_Water(const CVector &CameraTarget, float TargetOrien Front.Normalise(); } +//--MIAMI: done void CCam::Process_SpecialFixedForSyphon(const CVector &CameraTarget, float, float, float) { @@ -3623,6 +3745,8 @@ CCam::Process_SpecialFixedForSyphon(const CVector &CameraTarget, float, float, f m_cvecTargetCoorsForFudgeInter = CameraTarget; m_cvecTargetCoorsForFudgeInter.z += m_fSyphonModeTargetZOffSet; Front = CameraTarget - Source; + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, m_cvecTargetCoorsForFudgeInter, Source, FOV); Front.z += m_fSyphonModeTargetZOffSet; GetVectorsReadyForRW(); @@ -3636,12 +3760,6 @@ CCam::Process_SpecialFixedForSyphon(const CVector &CameraTarget, float, float, f FOV = DefaultFOV; } -void -CCam::Process_LightHouse(const CVector &CameraTarget, float, float, float) -{ - // TODO -} - #ifdef IMPROVED_CAMERA #define KEYJUSTDOWN(k) ControlsManager.GetIsKeyboardKeyJustDown((RsKeyCodes)k) @@ -3919,58 +4037,73 @@ CCam::Process_ModelView(const CVector &CameraTarget, float, float, float) GetVectorsReadyForRW(); } +float DEADCAM_HEIGHT_START = 2.0f; +float DEADCAM_HEIGHT_RATE = 0.04f; +float DEADCAM_WAFT_AMPLITUDE = 2.0f; +float DEADCAM_WAFT_RATE = 600.0f; +float DEADCAM_WAFT_TILT_AMP = -0.35f; + +//--MIAMI: done void CCam::ProcessPedsDeadBaby(void) { - float Distance = 0.0f; - static bool SafeToRotate = false; - CVector TargetDist, TestPoint; + CVector TargetCoors; + CVector CamPos; - FOV = DefaultFOV; - TargetDist = Source - CamTargetEntity->GetPosition(); - Distance = TargetDist.Magnitude(); - Beta = CGeneral::GetATanOfXY(TargetDist.x, TargetDist.y); - while(Beta >= PI) Beta -= 2*PI; - while(Beta < -PI) Beta += 2*PI; + if(TheCamera.pTargetEntity->IsPed()) + ((CPed*)TheCamera.pTargetEntity)->m_pedIK.GetComponentPosition(TargetCoors, PED_MID); + else if(TheCamera.pTargetEntity->IsVehicle()){ + TargetCoors = TheCamera.pTargetEntity->GetPosition(); + TargetCoors.z += TheCamera.pTargetEntity->GetColModel()->boundingBox.max.z; + }else + return; if(ResetStatics){ - TestPoint = CamTargetEntity->GetPosition() + - CVector(4.0f * Cos(Alpha) * Cos(Beta), - 4.0f * Cos(Alpha) * Sin(Beta), - 4.0f * Sin(Alpha)); - bool Safe1 = CWorld::GetIsLineOfSightClear(TestPoint, CamTargetEntity->GetPosition(), true, false, false, true, false, true, true); - - TestPoint = CamTargetEntity->GetPosition() + - CVector(4.0f * Cos(Alpha) * Cos(Beta + DEGTORAD(120.0f)), - 4.0f * Cos(Alpha) * Sin(Beta + DEGTORAD(120.0f)), - 4.0f * Sin(Alpha)); - bool Safe2 = CWorld::GetIsLineOfSightClear(TestPoint, CamTargetEntity->GetPosition(), true, false, false, true, false, true, true); - - TestPoint = CamTargetEntity->GetPosition() + - CVector(4.0f * Cos(Alpha) * Cos(Beta - DEGTORAD(120.0f)), - 4.0f * Cos(Alpha) * Sin(Beta - DEGTORAD(120.0f)), - 4.0f * Sin(Alpha)); - bool Safe3 = CWorld::GetIsLineOfSightClear(TestPoint, CamTargetEntity->GetPosition(), true, false, false, true, false, true, true); - - SafeToRotate = Safe1 && Safe2 && Safe3; - + TheCamera.m_uiTimeLastChange = CTimer::GetTimeInMilliseconds(); + CamPos = TargetCoors; + CamPos.z += DEADCAM_HEIGHT_START; + float WaterZ = 0.0f; + if(CWaterLevel::GetWaterLevelNoWaves(TargetCoors.x, TargetCoors.y, TargetCoors.z, &WaterZ)){ + if(WaterZ + 1.5f > CamPos.z) + CamPos.z = WaterZ + 1.5f; + } + CVector Right = CrossProduct(TheCamera.pTargetEntity->GetForward(), CVector(0.0f, 0.0f, 1.0f)); + Right.z = 0.0f; + Right.Normalise(); + Front = TargetCoors - CamPos; + Front.Normalise(); + Up = CrossProduct(Right, Front); + Up.Normalise(); ResetStatics = false; + }else{ + CamPos = Source; + if(CWorld::TestSphereAgainstWorld(CamPos+CVector(0.0f, 0.0f, 0.2f), 0.3f, TheCamera.pTargetEntity, true, true, false, true, false, true) == nil) + CamPos.z += DEADCAM_HEIGHT_RATE*CTimer::GetTimeStep(); + CVector Right = CrossProduct(TheCamera.pTargetEntity->GetForward(), CVector(0.0f, 0.0f, 1.0f)); + Right.z = 0.0f; + Right.Normalise(); + + float Time = CTimer::GetTimeInMilliseconds() - TheCamera.m_uiTimeLastChange; + CVector WaftOffset = DEADCAM_WAFT_AMPLITUDE * Min(1000.0f,Time)/1000.0f * Sin(Time/DEADCAM_WAFT_RATE) * Right; + CVector WaftPos = TargetCoors + WaftOffset; + WaftPos.z = CamPos.z; + CVector WaftFront = WaftPos - CamPos; + WaftFront.Normalise(); + if(CWorld::TestSphereAgainstWorld(CamPos+0.2f*WaftFront, 0.3f, TheCamera.pTargetEntity, true, true, false, true, false, true) == nil) + CamPos = WaftPos; + + Front = CVector(0.0f, 0.0f, -1.0f); + Front += Cos(Time/DEADCAM_WAFT_RATE) * DEADCAM_WAFT_TILT_AMP * Min(2000.0f,Time)/2000.0f * Right; + + Front.Normalise(); + Up = CrossProduct(Right, Front); + Up.Normalise(); } - if(SafeToRotate) - WellBufferMe(Beta + DEGTORAD(175.0f), &Beta, &BetaSpeed, 0.015f, 0.007f, true); - - WellBufferMe(DEGTORAD(89.5f), &Alpha, &AlphaSpeed, 0.015f, 0.07f, true); - WellBufferMe(35.0f, &Distance, &DistanceSpeed, 0.006f, 0.007f, false); - - Source = CamTargetEntity->GetPosition() + - CVector(Distance * Cos(Alpha) * Cos(Beta), - Distance * Cos(Alpha) * Sin(Beta), - Distance * Sin(Alpha)); - m_cvecTargetCoorsForFudgeInter = CamTargetEntity->GetPosition(); - Front = CamTargetEntity->GetPosition() - Source; - Front.Normalise(); - GetVectorsReadyForRW(); + Source = CamPos; + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV); + TheCamera.m_bMoveCamToAvoidGeom = false; } float ARRESTDIST_BEHIND_COP = 5.0f; @@ -4100,7 +4233,7 @@ CCam::ProcessArrestCamOne(void) CPed *targetPed = (CPed*)TheCamera.pTargetEntity; nUsingWhichCamera = 0; if(TheCamera.pTargetEntity->IsPed()){ - ((CPed*)TheCamera.pTargetEntity)->m_pedIK.GetComponentPosition(*(RwV3d*)&TargetPos, PED_MID); + ((CPed*)TheCamera.pTargetEntity)->m_pedIK.GetComponentPosition(TargetPos, PED_MID); if(FindPlayerPed() && FindPlayerPed()->m_pArrestingCop) cop = FindPlayerPed()->m_pArrestingCop; if(cop && CGeneral::GetRandomNumberInRange(0.0f, 0.1f) > 0.5f){ @@ -4117,7 +4250,7 @@ CCam::ProcessArrestCamOne(void) CVehicle *targetVehicle = (CVehicle*)TheCamera.pTargetEntity; if(targetVehicle->pDriver && targetVehicle->pDriver->IsPlayer()){ targetPed = targetVehicle->pDriver; - targetPed->m_pedIK.GetComponentPosition(*(RwV3d*)&TargetPos, PED_MID); + targetPed->m_pedIK.GetComponentPosition(TargetPos, PED_MID); }else{ targetPed = nil; TargetPos = targetVehicle->GetPosition(); @@ -4209,11 +4342,11 @@ CCam::ProcessArrestCamOne(void) } if(TheCamera.pTargetEntity->IsPed()){ - ((CPed*)TheCamera.pTargetEntity)->m_pedIK.GetComponentPosition(*(RwV3d*)&TargetPos, PED_MID); + ((CPed*)TheCamera.pTargetEntity)->m_pedIK.GetComponentPosition(TargetPos, PED_MID); }else if(TheCamera.pTargetEntity->IsVehicle()){ CPed *driver = ((CVehicle*)TheCamera.pTargetEntity)->pDriver; if(driver && driver->IsPlayer()) - driver->m_pedIK.GetComponentPosition(*(RwV3d*)&TargetPos, PED_MID); + driver->m_pedIK.GetComponentPosition(TargetPos, PED_MID); else TargetPos = TheCamera.pTargetEntity->GetPosition(); }else @@ -4278,6 +4411,7 @@ CCam::ProcessArrestCamOne(void) return true; } +//--MIAMI: done bool CCam::ProcessArrestCamTwo(void) { @@ -4289,18 +4423,18 @@ CCam::ProcessArrestCamTwo(void) CVector TargetCoors, ToCamera; float BetaOffset; float SourceX, SourceY; - CCam *ActiveCam = &TheCamera.Cams[TheCamera.ActiveCam]; - if(&ActiveCam[1] == this){ + if(&TheCamera.Cams[TheCamera.ActiveCam] == this){ SourceX = TheCamera.Cams[(TheCamera.ActiveCam + 1) % 2].Source.x; SourceY = TheCamera.Cams[(TheCamera.ActiveCam + 1) % 2].Source.y; }else{ - SourceX = ActiveCam[1].Source.x; - SourceY = ActiveCam[1].Source.y; + SourceX = TheCamera.Cams[TheCamera.ActiveCam].Source.x; + SourceY = TheCamera.Cams[TheCamera.ActiveCam].Source.y; } for(int i = 0; i <= 1; i++){ int Dir = i == 0 ? 1 : -1; + FOV = 60.0f; TargetCoors = player->GetPosition(); Beta = CGeneral::GetATanOfXY(TargetCoors.x-SourceX, TargetCoors.y-SourceY); BetaOffset = DEGTORAD(Dir*80); @@ -4324,88 +4458,6 @@ CCam::ProcessArrestCamTwo(void) } -void -CCam::Process_Im_The_Passenger_Woo_Woo(const CVector &CameraTarget, float TargetOrientation, float, float) -{ - FOV = 50.0f; - - Source = CamTargetEntity->GetPosition(); - Source.z += 2.5f; - Front = CamTargetEntity->GetForward(); - Front.Normalise(); - Source += 1.35f*Front; - float heading = CGeneral::GetATanOfXY(Front.x, Front.y) + DEGTORAD(45.0f); - Front.x = Cos(heading); - Front.y = Sin(heading); - Up = CamTargetEntity->GetUp(); - - GetVectorsReadyForRW(); -} - -void -CCam::Process_Blood_On_The_Tracks(const CVector &CameraTarget, float TargetOrientation, float, float) -{ - FOV = 50.0f; - - Source = CamTargetEntity->GetPosition(); - Source.z += 5.45f; - - static CVector Test = -CamTargetEntity->GetForward(); -#ifdef FIX_BUGS - if(ResetStatics){ - Test = -CamTargetEntity->GetForward(); - ResetStatics = false; - } -#endif - - Source.x += 19.45*Test.x; - Source.y += 19.45*Test.y; - Front = Test; - Front.Normalise(); - Up = CamTargetEntity->GetUp(); - - GetVectorsReadyForRW(); -} - -void -CCam::Process_Cam_Running_Side_Train(const CVector &CameraTarget, float TargetOrientation, float, float) -{ - FOV = 60.0f; - - Source = CamTargetEntity->GetPosition(); - Source.z += 4.0f; - CVector fwd = CamTargetEntity->GetForward(); - float heading = CGeneral::GetATanOfXY(fwd.x, fwd.y) - DEGTORAD(15.0f); - Source.x -= Cos(heading)*10.0f; - Source.y -= Sin(heading)*10.0f; - heading -= DEGTORAD(5.0f); - Front = fwd; - Front.x += Cos(heading); - Front.y += Sin(heading); - Front.z -= 0.056f; - Front.Normalise(); - Up = CamTargetEntity->GetUp(); - - GetVectorsReadyForRW(); -} - -void -CCam::Process_Cam_On_Train_Roof(const CVector &CameraTarget, float TargetOrientation, float, float) -{ - static float RoofMultiplier = 1.5f; - - Source = CamTargetEntity->GetPosition(); - Source.z += 4.8f; - Front = CamTargetEntity->GetForward(); - Front.Normalise(); - Source += Front*RoofMultiplier; - Up = CamTargetEntity->GetUp(); - Up.Normalise(); - - GetVectorsReadyForRW(); -} - - #ifdef FREE_CAM void CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrientation, float, float) diff --git a/src/core/Camera.h b/src/core/Camera.h index e56fcd9d..2066ebf1 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -193,11 +193,11 @@ public: void ProcessSpecialHeightRoutines(void); void GetVectorsReadyForRW(void); CVector DoAverageOnVector(const CVector &vec); - float GetPedBetaAngleForClearView(const CVector &Target, float Dist, float BetaOffset, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies); void WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, float TargetHeight); bool RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation); void Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist); void FixCamWhenObscuredByVehicle(const CVector &TargetCoors); + bool GetBoatLook_L_R_HeightOffset(float &Offset); void LookBehind(void); void LookLeft(void); void LookRight(void); @@ -240,11 +240,6 @@ public: bool GetLookFromLampPostPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut); bool GetLookOverShoulderPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut); - void Process_Im_The_Passenger_Woo_Woo(const CVector& CameraTarget, float TargetOrientation, float, float); - void Process_Blood_On_The_Tracks(const CVector& CameraTarget, float TargetOrientation, float, float); - void Process_Cam_Running_Side_Train(const CVector& CameraTarget, float TargetOrientation, float, float); - void Process_Cam_On_Train_Roof(const CVector& CameraTarget, float TargetOrientation, float, float); - // custom stuff void Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrientation, float, float); void Process_FollowCar_SA(const CVector &CameraTarget, float TargetOrientation, float, float); diff --git a/src/peds/PedIK.h b/src/peds/PedIK.h index ee719fea..7dcf0ef3 100644 --- a/src/peds/PedIK.h +++ b/src/peds/PedIK.h @@ -52,6 +52,7 @@ public: bool PointGunInDirectionUsingArm(float targetYaw, float targetPitch); bool PointGunAtPosition(CVector const& position); void GetComponentPosition(RwV3d &pos, uint32 node); + void GetComponentPosition(CVector &pos, uint32 node) { GetComponentPosition(*(RwV3d*)pos, node); } void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll); void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch); void ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, float *pitch); From c4e129509b9ca8eb8136807a3d36cf93b5498390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Mon, 15 Jun 2020 23:43:20 +0300 Subject: [PATCH 15/18] Peds & fixes continues --- src/animation/AnimationId.h | 1 + src/peds/Ped.cpp | 723 +++++++++++++++++++++++------------- src/peds/Ped.h | 11 +- src/peds/PlayerPed.cpp | 14 +- src/peds/PlayerPed.h | 3 +- src/vehicles/Bike.cpp | 6 +- src/weapons/Weapon.cpp | 20 +- 7 files changed, 490 insertions(+), 288 deletions(-) diff --git a/src/animation/AnimationId.h b/src/animation/AnimationId.h index 9cf470e0..ddf36b23 100644 --- a/src/animation/AnimationId.h +++ b/src/animation/AnimationId.h @@ -233,6 +233,7 @@ enum AnimationId ANIM_MELEE_ATTACK = ANIM_WEAPON_FIRE, ANIM_MELEE_ATTACK_2ND, ANIM_MELEE_ATTACK_START, + ANIM_MELEE_IDLE_FIGHTMODE, ANIM_THROWABLE_THROW = ANIM_WEAPON_FIRE, ANIM_THROWABLE_THROWU, ANIM_THROWABLE_START_THROW, diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 2e0e4599..79a6202f 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -78,8 +78,40 @@ uint16 nPlayerInComboMove; RpClump *flyingClumpTemp; -FightMove tFightMoves[NUM_FIGHTMOVES] = { - // TODO(Miami) +FightMove tFightMoves[NUM_FIGHTMOVES] = +{ + { NUM_STD_ANIMS, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }, + { ANIM_PUNCH_R, 0.2f, 8.f/30.f, 0.0f, 0.3f, 1.0f, HITLEVEL_HIGH, 1, 0 }, + { ANIM_FIGHT_IDLE, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }, + { ANIM_FIGHT_SH_F, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }, + { ANIM_FIGHT_KNEE, 4.f/30.f, 0.2f, 0.0f, 0.6f, 1.0f, HITLEVEL_LOW, 2, 0 }, + { ANIM_FIGHT_LHOOK, 8.f/30.f, 10.f/30.f, 0.0f, 0.4f, 1.0f, HITLEVEL_HIGH, 3, 0 }, + { ANIM_FIGHT_JAB, 4.f/30.f, 0.2f, 0.0f, 0.7f, 1.0f, HITLEVEL_HIGH, 3, 0 }, + { ANIM_FIGHT_PUNCH, 4.f/30.f, 7.f/30.f, 10.f/30.f, 0.4f, 1.0f, HITLEVEL_HIGH, 1, 0 }, + { ANIM_FIGHT_LONGKICK, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_MEDIUM, 4, 0 }, + { ANIM_FIGHT_ROUNDHOUSE, 8.f/30.f, 10.f/30.f, 0.0f, 0.6f, 1.0f, HITLEVEL_MEDIUM, 4, 0 }, + { ANIM_FIGHT_KICK, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_HIGH, 2, 0 }, + { ANIM_FIGHT_HEAD, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_MEDIUM, 2, 0 }, + { ANIM_FIGHT_BKICK_L, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_LOW, 2, 0 }, + { ANIM_FIGHT_BKICK_L, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_LOW, 2, 0 }, + { ANIM_FIGHT_ELBOW_L, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_MEDIUM, 2, 0 }, + { ANIM_FIGHT_BKICK_R, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_MEDIUM, 2, 0 }, + { ANIM_FIGHT_ELBOW_R, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_HIGH, 2, 0 }, + { ANIM_KICK_FLOOR, 10.f/30.f, 14.f/30.f, 0.0f, 0.4f, 1.0f, HITLEVEL_GROUND, 1, 0 }, + { ANIM_HIT_FRONT, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }, + { ANIM_HIT_BACK, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }, + { ANIM_HIT_RIGHT, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }, + { ANIM_HIT_LEFT, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }, + { ANIM_HIT_BODYBLOW, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }, + { ANIM_HIT_CHEST, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }, + { ANIM_HIT_HEAD, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }, + { ANIM_HIT_WALK, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }, + { ANIM_FLOOR_HIT, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }, + { ANIM_HIT_BEHIND, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }, + { ANIM_WEAPON_FIRE, 4.f/30.f, 7.f/30.f, 10.f/30.f, 0.4f, 1.0f, HITLEVEL_HIGH, 1, 0 }, + { ANIM_WEAPON_CROUCHFIRE, 4.f/30.f, 7.f/30.f, 10.f/30.f, 0.4f, 1.0f, HITLEVEL_HIGH, 1, 0 }, + { ANIM_WEAPON_SPECIAL, 4.f / 30.f, 7.f / 30.f, 10.f / 30.f, 0.4f, 1.0f, HITLEVEL_HIGH, 1, 0 }, + { ANIM_FIGHT2_IDLE, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 } }; uint16 CPed::nThreatReactionRangeMultiplier = 1; @@ -115,6 +147,7 @@ bool CPed::bPopHeadsOnHeadshot = false; bool CPed::bMakePedsRunToPhonesToReportCrimes = false; #endif +// --MIAMI: Done CPed::~CPed(void) { CWorld::Remove(this); @@ -126,7 +159,7 @@ CPed::~CPed(void) if (m_pMyVehicle->pDriver == this) m_pMyVehicle->pDriver = nil; else { - // FIX: Passenger counter now decreasing after removing ourself from vehicle. + // FIX: Passenger counter now being decreased after removing ourself from vehicle. m_pMyVehicle->RemovePassenger(this); } if (m_nPedState == PED_EXIT_CAR || m_nPedState == PED_DRAG_FROM_CAR) @@ -429,7 +462,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) weapon.m_nTimer = 0; } - m_lastFightMove = FIGHTMOVE_NULL; + m_lastFightMove = m_lastHitState = 0; GiveWeapon(WEAPONTYPE_UNARMED, 0, true); m_wepAccuracy = 60; m_lastWepDam = -1; @@ -960,6 +993,7 @@ CPed::ClearLookFlag(void) { } } +// --MIAMI: Done bool CPed::IsPedHeadAbovePos(float zOffset) { @@ -1802,6 +1836,7 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg) ped->bVehExitWillBeInstant = false; } +// --MIAMI: Done CVector CPed::GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatPosMult) { @@ -1811,83 +1846,138 @@ CPed::GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatP float seatOffset; vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(veh->GetModelIndex()); - if (veh->bIsVan && (component == CAR_DOOR_LR || component == CAR_DOOR_RR)) { - seatOffset = 0.0f; - vehDoorOffset = vecPedVanRearDoorAnimOffset; - } else { - seatOffset = veh->pHandling->fSeatOffsetDistance * seatPosMult; - if (veh->bLowVehicle) { - vehDoorOffset = vecPedCarDoorLoAnimOffset; + + if (veh->IsBike()) { + CBike *bike = (CBike*)veh; + vehDoorPos = vehModel->GetFrontSeatPosn(); + + if (component == CAR_WINDSCREEN) { + return bike->GetMatrix() * (vehDoorPos + vecPedBikeKickAnimOffset); } else { - vehDoorOffset = vecPedCarDoorAnimOffset; + switch (bike->m_bikeAnimType) { + case ASSOCGRP_BIKE_VESPA: + vehDoorOffset = vecPedVespaBikeJumpRhsAnimOffset; + break; + case ASSOCGRP_BIKE_HARLEY: + vehDoorOffset = vecPedHarleyBikeJumpRhsAnimOffset; + break; + case ASSOCGRP_BIKE_DIRT: + vehDoorOffset = vecPedDirtBikeJumpRhsAnimOffset; + break; + default: + vehDoorOffset = vecPedStdBikeJumpRhsAnimOffset; + break; + } + float xOffsetFromAnim = vehDoorOffset.x + seatPosMult * bike->pHandling->fSeatOffsetDistance; + if (component == CAR_DOOR_LR || component == CAR_DOOR_RR) { + vehDoorPos = vehModel->m_positions[CAR_POS_BACKSEAT]; + } + + if (component == CAR_DOOR_LR || component == CAR_DOOR_LF) + xOffsetFromAnim *= -1.f; + + return bike->GetMatrix() * (vehDoorPos + CVector(xOffsetFromAnim, vehDoorOffset.y, vehDoorOffset.z)); } + } else { + if (veh->bIsVan && (component == CAR_DOOR_LR || component == CAR_DOOR_RR)) { + seatOffset = 0.0f; + vehDoorOffset = vecPedVanRearDoorAnimOffset; + } else { + seatOffset = veh->pHandling->fSeatOffsetDistance * seatPosMult; + if (veh->bLowVehicle) { + vehDoorOffset = vecPedCarDoorLoAnimOffset; + } else { + vehDoorOffset = vecPedCarDoorAnimOffset; + } + } + + switch (component) { + case CAR_DOOR_RF: + vehDoorPos = vehModel->GetFrontSeatPosn(); + vehDoorPos.x += seatOffset; + vehDoorOffset.x = -vehDoorOffset.x; + break; + + case CAR_DOOR_RR: + vehDoorPos = vehModel->m_positions[CAR_POS_BACKSEAT]; + vehDoorPos.x += seatOffset; + vehDoorOffset.x = -vehDoorOffset.x; + break; + + case CAR_DOOR_LF: + vehDoorPos = vehModel->GetFrontSeatPosn(); + vehDoorPos.x = -(vehDoorPos.x + seatOffset); + break; + + case CAR_DOOR_LR: + vehDoorPos = vehModel->m_positions[CAR_POS_BACKSEAT]; + vehDoorPos.x = -(vehDoorPos.x + seatOffset); + break; + + default: + vehDoorPos = vehModel->GetFrontSeatPosn(); + vehDoorOffset = CVector(0.0f, 0.0f, 0.0f); + } + return vehDoorPos - vehDoorOffset; } - - switch (component) { - case CAR_DOOR_RF: - vehDoorPos = vehModel->GetFrontSeatPosn(); - vehDoorPos.x += seatOffset; - vehDoorOffset.x = -vehDoorOffset.x; - break; - - case CAR_DOOR_RR: - vehDoorPos = vehModel->m_positions[CAR_POS_BACKSEAT]; - vehDoorPos.x += seatOffset; - vehDoorOffset.x = -vehDoorOffset.x; - break; - - case CAR_DOOR_LF: - vehDoorPos = vehModel->GetFrontSeatPosn(); - vehDoorPos.x = -(vehDoorPos.x + seatOffset); - break; - - case CAR_DOOR_LR: - vehDoorPos = vehModel->m_positions[CAR_POS_BACKSEAT]; - vehDoorPos.x = -(vehDoorPos.x + seatOffset); - break; - - default: - vehDoorPos = vehModel->GetFrontSeatPosn(); - vehDoorOffset = CVector(0.0f, 0.0f, 0.0f); - } - return vehDoorPos - vehDoorOffset; } -// This function was mostly duplicate of GetLocalPositionToOpenCarDoor, so I've used it. +// --MIAMI: Done CVector CPed::GetPositionToOpenCarDoor(CVehicle *veh, uint32 component) { - CVector localPos; - CVector vehDoorPos; - - localPos = GetLocalPositionToOpenCarDoor(veh, component, 1.0f); - vehDoorPos = Multiply3x3(veh->GetMatrix(), localPos) + veh->GetPosition(); + CVector vehDoorPos = GetPositionToOpenCarDoor(veh, component, 1.0f); /* - // Not used. - CVector localVehDoorOffset; - - if (veh->bIsVan && (component == VEHICLE_ENTER_REAR_LEFT || component == VEHICLE_ENTER_REAR_RIGHT)) { - localVehDoorOffset = vecPedVanRearDoorAnimOffset; - } else { - if (veh->bIsLow) { - localVehDoorOffset = vecPedCarDoorLoAnimOffset; - } else { - localVehDoorOffset = vecPedCarDoorAnimOffset; - } - } - - vehDoorPosWithoutOffset = Multiply3x3(veh->GetMatrix(), localPos + localVehDoorOffset) + veh->GetPosition(); + // Unused + vehDoorPosWithoutOffset = veh->GetMatrix() * localVehDoorPos; */ return vehDoorPos; } +// --MIAMI: Done CVector CPed::GetPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset) { CVector doorPos; CMatrix vehMat(veh->GetMatrix()); + if (veh->IsBike()) { + CVehicleModelInfo* vehModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(veh->GetModelIndex()); + CVector vehDoorOffset; + CBike* bike = (CBike*)veh; + doorPos = vehModel->GetFrontSeatPosn(); + + if (component == CAR_WINDSCREEN) { + return bike->GetMatrix() * (doorPos + vecPedBikeKickAnimOffset); + } else { + switch (bike->m_bikeAnimType) { + case ASSOCGRP_BIKE_VESPA: + vehDoorOffset = vecPedVespaBikeJumpRhsAnimOffset; + break; + case ASSOCGRP_BIKE_HARLEY: + vehDoorOffset = vecPedHarleyBikeJumpRhsAnimOffset; + break; + case ASSOCGRP_BIKE_DIRT: + vehDoorOffset = vecPedDirtBikeJumpRhsAnimOffset; + break; + default: + vehDoorOffset = vecPedStdBikeJumpRhsAnimOffset; + break; + } + vehDoorOffset.x += offset * bike->pHandling->fSeatOffsetDistance; + if (component == CAR_DOOR_LR || component == CAR_DOOR_RR) { + doorPos = vehModel->m_positions[CAR_POS_BACKSEAT]; + } + + if (component == CAR_DOOR_LR || component == CAR_DOOR_LF) + vehDoorOffset.x *= -1.f; + + CVector correctedPos; + bike->GetCorrectedWorldDoorPosition(correctedPos, vehDoorOffset, doorPos); + return correctedPos; + } + } doorPos = Multiply3x3(vehMat, GetLocalPositionToOpenCarDoor(veh, component, offset)); return veh->GetPosition() + doorPos; @@ -2470,21 +2560,25 @@ CPed::SortPeds(CPed **list, int min, int max) SortPeds(list, right, max); } +// --MIAMI: Done void CPed::BuildPedLists(void) { - if ((CTimer::GetFrameCounter() + (m_randomSeed % 256)) % 16) { + if ((CTimer::GetFrameCounter() + m_randomSeed) % 16) { for(int i = 0; i < ARRAY_SIZE(m_nearPeds); ) { + bool removePed = false; if (m_nearPeds[i]) { if (m_nearPeds[i]->IsPointerValid()) { float distSqr = (GetPosition() - m_nearPeds[i]->GetPosition()).MagnitudeSqr2D(); - if (distSqr < 900.0f) { - i++; - continue; + if (distSqr > sq(nThreatReactionRangeMultiplier * 30.f)) { + removePed = true; } + } else { + removePed = true; } - + } + if (removePed) { // If we arrive here, the ped we're checking isn't "near", so we should remove it. for (int j = i; j < ARRAY_SIZE(m_nearPeds) - 1; j++) { m_nearPeds[j] = m_nearPeds[j + 1]; @@ -2498,10 +2592,11 @@ CPed::BuildPedLists(void) } } else { CVector centre = CEntity::GetBoundCentre(); - CRect rect(centre.x - 20.0f, - centre.y - 20.0f, - centre.x + 20.0f, - centre.y + 20.0f); + int deadsRegistered = 0; + CRect rect(centre.x - 20.f * nThreatReactionRangeMultiplier, + centre.y - 20.f * nThreatReactionRangeMultiplier, + centre.x + 20.f * nThreatReactionRangeMultiplier, + centre.y + 20.f * nThreatReactionRangeMultiplier); int xstart = CWorld::GetSectorIndexX(rect.left); int ystart = CWorld::GetSectorIndexY(rect.top); int xend = CWorld::GetSectorIndexX(rect.right); @@ -2512,9 +2607,14 @@ CPed::BuildPedLists(void) for(int x = xstart; x <= xend; x++) { for (CPtrNode *pedPtrNode = CWorld::GetSector(x,y)->m_lists[ENTITYLIST_PEDS].first; pedPtrNode; pedPtrNode = pedPtrNode->next) { CPed *ped = (CPed*)pedPtrNode->item; - if (ped != this && !ped->bInVehicle) { - float dist = (ped->GetPosition() - GetPosition()).Magnitude2D(); - if (nThreatReactionRangeMultiplier * 30.0f > dist) { + if (ped != this && (!ped->bInVehicle || (ped->m_pMyVehicle && ped->m_pMyVehicle->IsBike()))) { + + if (nThreatReactionRangeMultiplier * 30.0f > (ped->GetPosition() - GetPosition()).Magnitude2D()) { + if (ped->m_nPedState == PED_DEAD) { + if (deadsRegistered > 3) + continue; + deadsRegistered++; + } gapTempPedList[gnNumTempPedList] = ped; gnNumTempPedList++; assert(gnNumTempPedList < ARRAY_SIZE(gapTempPedList)); @@ -5454,6 +5554,7 @@ CPed::LoadFightData(void) } } +// --MIAMI: Done // Actually GetLocalDirectionTo(Turn/Look) int CPed::GetLocalDirection(const CVector2D &posOffset) @@ -5468,32 +5569,35 @@ CPed::GetLocalDirection(const CVector2D &posOffset) return direction; } +// --MIAMI: Done bool -CPed::FightStrike(CVector &touchedNodePos) +CPed::FightStrike(CVector &touchedNodePos, bool unk = false) { CColModel *hisCol; CVector attackDistance; - ePedPieceTypes closestPedPiece = PEDPIECE_TORSO; - float maxDistanceToBeBeaten; + float maxDistanceToBeat; CPed *nearPed; - int state = m_fightState; - bool pedFound = false; + CVector extendedTouchPoint; - if (state == FIGHTSTATE_JUST_ATTACKED) + CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); + float radius = tFightMoves[m_lastFightMove].strikeRadius; + if (unk) + radius = weaponInfo->m_fRadius; + + if (m_fightState == FIGHTSTATE_JUST_ATTACKED) return false; - - // Pointless code - if (state > FIGHTSTATE_NO_MOVE) - attackDistance = touchedNodePos - m_vecHitLastPos; + + // TODO(Miami): BreakGlassPhysically for (int i = 0; i < m_numNearPeds; i++) { + int8 pedFound = 0; nearPed = m_nearPeds[i]; - if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) - maxDistanceToBeBeaten = nearPed->GetBoundRadius() + tFightMoves[m_lastFightMove].strikeRadius + 0.1f; + if (!unk && GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE) + maxDistanceToBeat = nearPed->GetBoundRadius() + radius + 0.1f; else - maxDistanceToBeBeaten = nearPed->GetBoundRadius() + tFightMoves[m_lastFightMove].strikeRadius; + maxDistanceToBeat = nearPed->GetBoundRadius() + radius; - if (nearPed->bUsesCollision || nearPed->m_nPedState == PED_DEAD) { + if ((nearPed->bUsesCollision || nearPed->m_nPedState == PED_DEAD) && (m_pedInObjective != FindPlayerPed() || nearPed == FindPlayerPed())) { CVector nearPedCentre; // Have to animate a skinned clump because the initial col model is useless @@ -5503,116 +5607,57 @@ CPed::FightStrike(CVector &touchedNodePos) CVector potentialAttackDistance = nearPedCentre - touchedNodePos; // He can beat us - if (sq(maxDistanceToBeBeaten) > potentialAttackDistance.MagnitudeSqr()) { + if (sq(maxDistanceToBeat) > potentialAttackDistance.MagnitudeSqr()) { for (int j = 0; j < hisCol->numSpheres; j++) { attackDistance = hisCol->spheres[j].center; attackDistance -= touchedNodePos; CColSphere *hisPieces = hisCol->spheres; - float maxDistanceToBeat = hisPieces[j].radius + tFightMoves[m_lastFightMove].strikeRadius; + maxDistanceToBeat = hisPieces[j].radius + radius; // We can beat him too if (sq(maxDistanceToBeat) > attackDistance.MagnitudeSqr()) { - pedFound = true; - closestPedPiece = (ePedPieceTypes) hisPieces[j].piece; + FightHitPed(nearPed, touchedNodePos, attackDistance, hisPieces[j].piece); + pedFound = 1; break; } } } - } - if (pedFound) - break; - } - - if (pedFound) { - if (nearPed->IsPlayer() && nearPed->m_nPedState == PED_GETUP) - return false; - - float oldVictimHealth = nearPed->m_fHealth; - CVector bloodPos = 0.5f * attackDistance + touchedNodePos; - int damageMult = tFightMoves[m_lastFightMove].damage * ((CGeneral::GetRandomNumber() & 1) + 2) + 1; - - CVector2D diff (GetPosition() - nearPed->GetPosition()); - int direction = nearPed->GetLocalDirection(diff); - if (IsPlayer()) { - if (((CPlayerPed*)this)->m_bAdrenalineActive) - damageMult = 20; - } else { - damageMult *= m_pedStats->m_attackStrength; - } - - /* - // Change direction if we used kick. - if (m_lastFightMove == FIGHTMOVE_KICK) { - if (CGeneral::GetRandomNumber() & 1) { - direction++; - if (direction > 3) - direction -= 4; - } - } */ - nearPed->ReactToAttack(this); - - // Mostly unused. if > 5, ANIM_HIT_WALK will be run, that's it. - int unk2; - if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && !nearPed->IsPlayer()) - unk2 = 101; - else - unk2 = damageMult; - - nearPed->StartFightDefend(direction, tFightMoves[m_lastFightMove].hitLevel, unk2); - PlayHitSound(nearPed); - m_fightState = FIGHTSTATE_JUST_ATTACKED; - RpAnimBlendClumpGetAssociation(GetClump(), tFightMoves[m_lastFightMove].animId)->speed = 0.6f; - if (!nearPed->DyingOrDead()) { - nearPed->InflictDamage(this, WEAPONTYPE_UNARMED, damageMult * 3.0f, closestPedPiece, direction); - } - - if (CGame::nastyGame - && tFightMoves[m_lastFightMove].hitLevel > HITLEVEL_MEDIUM - && nearPed->m_nPedState == PED_DIE - && nearPed->GetIsOnScreen()) { - - // Just for blood particle. We will restore it below. - attackDistance /= (10.0f * attackDistance.Magnitude()); - for(int i=0; i<4; i++) { - CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, attackDistance, nil, 0.0f, 0, 0, 0, 0); - } - } - if (nearPed->m_nPedState != PED_FALL && nearPed->m_nPedState != PED_DIE && nearPed->m_nPedState != PED_DEAD) { - float curVictimHealth = nearPed->m_fHealth; - if (curVictimHealth > 0.0f - && (curVictimHealth < 40.0f && oldVictimHealth > 40.0f && !nearPed->IsPlayer() - || nearPed->m_fHealth < 20.0f && oldVictimHealth > 20.0f - || GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && IsPlayer() - || nearPed->m_pedStats->m_flags & STAT_ONE_HIT_KNOCKDOWN)) { - - nearPed->SetFall(0, (AnimationId)(direction + ANIM_KO_SKID_FRONT), 0); - if (nearPed->m_nPedState == PED_FALL) - nearPed->bIsStanding = false; - } - } - if (nearPed->m_nPedState == PED_DIE || !nearPed->bIsStanding) { - attackDistance = nearPed->GetPosition() - GetPosition(); - attackDistance.Normalise(); - attackDistance.z = 1.0f; - nearPed->bIsStanding = false; - - float moveMult; - if (m_lastFightMove == FIGHTMOVE_GROUNDKICK) { - moveMult = Min(damageMult * 0.6f, 4.0f); - } else { - if (nearPed->m_nPedState != PED_DIE || damageMult >= 20) { - moveMult = damageMult; - } else { - moveMult = Min(damageMult * 2.0f, 14.0f); + if (!pedFound && !unk) { + extendedTouchPoint = touchedNodePos - GetPosition(); + if (DotProduct(touchedNodePos - GetPosition(), nearPed->GetPosition() - GetPosition()) > 0.f) { + if (m_lastFightMove == FIGHTMOVE_GROUNDKICK) { + extendedTouchPoint += tFightMoves[FIGHTMOVE_GROUNDKICK].extendReachMultiplier * GetForward(); + } else { + extendedTouchPoint.x *= tFightMoves[m_lastFightMove].extendReachMultiplier; + extendedTouchPoint.y *= tFightMoves[m_lastFightMove].extendReachMultiplier; + } + pedFound = -1; + extendedTouchPoint += GetPosition(); } } + if (pedFound == -1) { + CVector nearPedCentre = nearPed->GetBoundCentre(); + if (sq(maxDistanceToBeat) > (nearPedCentre - extendedTouchPoint).MagnitudeSqr()) { - nearPed->ApplyMoveForce(moveMult * 0.6f * attackDistance); + for (int j = 0; j < hisCol->numSpheres; j++) { + attackDistance = hisCol->spheres[j].center; + attackDistance -= extendedTouchPoint; + CColSphere* hisPieces = hisCol->spheres; + float maxDistanceToBeat2 = hisPieces[j].radius + tFightMoves[m_lastFightMove].strikeRadius; + + // We can beat him too + if (sq(maxDistanceToBeat2) > attackDistance.MagnitudeSqr()) { + FightHitPed(nearPed, extendedTouchPoint, attackDistance, hisPieces[j].piece); + break; + } + } + } + } } - CEventList::RegisterEvent(nearPed->m_nPedType == PEDTYPE_COP ? EVENT_ASSAULT_POLICE : EVENT_ASSAULT, EVENT_ENTITY_PED, nearPed, this, 2000); } + if (m_fightState == FIGHTSTATE_NO_MOVE) m_fightState = FIGHTSTATE_1; @@ -5620,6 +5665,129 @@ CPed::FightStrike(CVector &touchedNodePos) return false; } +// TODO(Miami) +void +CPed::FightHitPed(CPed *victim, CVector &touchPoint, CVector &dist, int16 piece) +{ + if (victim->IsPlayer() && victim->m_nPedState == PED_GETUP) + return; + + CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); + bool fightingWithWeapon = false; + int damageMult = tFightMoves[m_lastFightMove].damage * ((CGeneral::GetRandomNumber() & 1) + 2) + 1; + + if (weaponInfo->m_bFightMode) { + fightingWithWeapon = true; + if (m_lastFightMove >= FIGHTMOVE_MELEE1) { + damageMult = weaponInfo->m_nDamage; + if (m_lastFightMove == FIGHTMOVE_MELEE3 && GetWeapon()->m_eWeaponType != WEAPONTYPE_SCREWDRIVER) + damageMult *= 5; + } + } + + if (IsPlayer()) { + if (((CPlayerPed*)this)->m_bAdrenalineActive) + damageMult = 20; + } else if (!fightingWithWeapon) { + damageMult *= m_pedStats->m_attackStrength; + } + + float oldVictimHealth = victim->m_fHealth; + CVector bloodPos = 0.5f * dist + touchPoint; + CVector2D diff(GetPosition() - victim->GetPosition()); + int direction = victim->GetLocalDirection(diff); + + /* + // Change direction if we used kick. + if (m_lastFightMove == FIGHTMOVE_KICK) { + if (CGeneral::GetRandomNumber() & 1) { + direction++; + if (direction > 3) + direction -= 4; + } + } */ + victim->ReactToAttack(this); + + // Mostly unused. if > 5, ANIM_HIT_WALK will be run, that's it. + int unk2; + if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && !victim->IsPlayer()) + unk2 = 101; + else + unk2 = damageMult; + + victim->StartFightDefend(direction, tFightMoves[m_lastFightMove].hitLevel, unk2); + PlayHitSound(victim); + m_fightState = FIGHTSTATE_JUST_ATTACKED; + RpAnimBlendClumpGetAssociation(GetClump(), tFightMoves[m_lastFightMove].animId)->speed = 0.6f; + if (!victim->DyingOrDead()) { + victim->InflictDamage(this, WEAPONTYPE_UNARMED, damageMult * 3.0f, (ePedPieceTypes)piece, direction); + } + + if (CGame::nastyGame + && tFightMoves[m_lastFightMove].hitLevel > HITLEVEL_MEDIUM + && victim->m_nPedState == PED_DIE + && victim->GetIsOnScreen()) { + + // Just for blood particle. We will restore it below. + dist /= (10.0f * dist.Magnitude()); + for(int i=0; i<4; i++) { + CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dist, nil, 0.0f, 0, 0, 0, 0); + } + } + + eWeaponType weaponType = GetWeapon()->m_eWeaponType; + if (!fightingWithWeapon) { + if (victim->m_nPedState != PED_FALL && victim->m_nPedState != PED_DIE && victim->m_nPedState != PED_DEAD) { + float curVictimHealth = victim->m_fHealth; + if (curVictimHealth > 0.0f + && (curVictimHealth < 30.0f && oldVictimHealth > 30.0f + || weaponType != WEAPONTYPE_UNARMED && weaponType != WEAPONTYPE_BRASSKNUCKLE && IsPlayer() + || victim->m_pedStats->m_flags & STAT_ONE_HIT_KNOCKDOWN)) { + + victim->SetFall(0, (AnimationId)(direction + ANIM_KO_SKID_FRONT), 0); + if (victim->m_nPedState == PED_FALL) + victim->bIsStanding = false; + } + } + } + + if (victim->m_nPedState == PED_DIE || !victim->bIsStanding) { + dist = victim->GetPosition() - GetPosition(); + dist.Normalise(); + dist.z = 1.0f; + victim->bIsStanding = false; + + float moveMult; + if (fightingWithWeapon) { + moveMult = Min(damageMult * 0.02f, 1.0f); + } else if (m_lastFightMove == FIGHTMOVE_GROUNDKICK) { + moveMult = Min(damageMult * 0.6f, 4.0f); + } else { + if (victim->m_nPedState != PED_DIE || damageMult >= 20) { + moveMult = damageMult; + } else { + moveMult = Min(damageMult * 2.0f, 14.0f); + } + } + + victim->ApplyMoveForce(moveMult * 0.6f * dist); + } + + if (weaponType != WEAPONTYPE_KNIFE && weaponType != WEAPONTYPE_MACHETE + && weaponType != WEAPONTYPE_KATANA && weaponType != WEAPONTYPE_CHAINSAW) { + + if (victim->m_nPedType == PEDTYPE_COP) + CEventList::RegisterEvent(EVENT_ASSAULT_POLICE, EVENT_ENTITY_PED, victim, this, 2000); + else + CEventList::RegisterEvent(EVENT_ASSAULT, EVENT_ENTITY_PED, victim, this, 2000); + } else { + if (victim->m_nPedType == PEDTYPE_COP) + CEventList::RegisterEvent(EVENT_ASSAULT_NASTYWEAPON_POLICE, EVENT_ENTITY_PED, victim, this, 2000); + else + CEventList::RegisterEvent(EVENT_ASSAULT_NASTYWEAPON, EVENT_ENTITY_PED, victim, this, 2000); + } +} + // --MIAMI: Done void CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl) @@ -6002,6 +6170,7 @@ CPed::PlayHitSound(CPed *hitTo) DMAudio.PlayOneShot(m_audioEntityId, soundId, 0.0f); } +// --MIAMI: Done void CPed::CollideWithPed(CPed *collideWith) { @@ -6014,6 +6183,15 @@ CPed::CollideWithPed(CPed *collideWith) int waitTime = 0; if (weAreMissionChar || !collideWith->IsPlayer() || collideWith->m_nPedState != PED_MAKE_CALL) { + if (m_nWaitState == WAITSTATE_SUN_BATHE_IDLE) { + SetGetUp(); + return; + } + if (collideWith->m_nWaitState == WAITSTATE_SUN_BATHE_IDLE) { + collideWith->SetGetUp(); + return; + } + bool weDontLookToHim = DotProduct(posDiff, GetForward()) > 0.0f; bool heLooksToUs = DotProduct(posDiff, collideWith->GetForward()) < 0.0f; @@ -6021,10 +6199,8 @@ CPed::CollideWithPed(CPed *collideWith) if ((!IsPlayer() || ((CPlayerPed*)this)->m_fMoveSpeed <= 1.8f) && (IsPlayer() || heIsMissionChar && weAreMissionChar || m_nMoveState != PEDMOVE_RUN && m_nMoveState != PEDMOVE_SPRINT -#ifdef VC_PED_PORTS || m_objective == OBJECTIVE_FOLLOW_PED_IN_FORMATION && m_pedInObjective == collideWith - || collideWith->m_objective == OBJECTIVE_FOLLOW_PED_IN_FORMATION && collideWith->m_pedInObjective == this -#endif + || collideWith->m_objective == OBJECTIVE_FOLLOW_PED_IN_FORMATION && collideWith->m_pedInObjective == this )) { if (m_objective != OBJECTIVE_FOLLOW_PED_IN_FORMATION && m_objective != OBJECTIVE_GOTO_CHAR_ON_FOOT) { @@ -6053,11 +6229,10 @@ CPed::CollideWithPed(CPed *collideWith) SetDirectionToWalkAroundObject(collideWith); } } else { -#ifdef VC_PED_PORTS if (FindPlayerPed() != m_pedInObjective || m_objective != OBJECTIVE_KILL_CHAR_ANY_MEANS && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT || collideWith == m_pedInObjective) { -#endif + if (weAreMissionChar || m_pedStats->m_fear <= 100 - collideWith->m_pedStats->m_temper || (collideWith->IsPlayer() || collideWith->m_nMoveState == PEDMOVE_NONE || collideWith->m_nMoveState == PEDMOVE_STILL) && (!collideWith->IsPlayer() || ((CPlayerPed*)collideWith)->m_fMoveSpeed <= 1.0f)) { @@ -6067,47 +6242,43 @@ CPed::CollideWithPed(CPed *collideWith) } else { SetEvasiveStep(collideWith, 2); } -#ifdef VC_PED_PORTS } else if (collideWith->m_nMoveState != PEDMOVE_STILL && GetWeapon()->IsTypeMelee() && collideWith->m_pedInObjective == m_pedInObjective) { - int colliderIsAtPlayerSafePosID = -1; - int weAreAtPlayerSafePosID = -1; - for (int i = 0; i < ARRAY_SIZE(((CPlayerPed*)m_pedInObjective)->m_pPedAtSafePos); i++) { - CPed *pedAtSafePos = ((CPlayerPed*)m_pedInObjective)->m_pPedAtSafePos[i]; - if (pedAtSafePos == this) { - weAreAtPlayerSafePosID = i; - } else if (pedAtSafePos == collideWith) { - colliderIsAtPlayerSafePosID = i; + int colliderIndexAtPlayersKillList = -1; + int ourIndexAtPlayersKillList = -1; + for (int i = 0; i < ARRAY_SIZE(((CPlayerPed*)m_pedInObjective)->m_pMeleeList); i++) { + CPed *pedInKillList = ((CPlayerPed*)m_pedInObjective)->m_pMeleeList[i]; + if (pedInKillList == this) { + ourIndexAtPlayersKillList = i; + } else if (pedInKillList == collideWith) { + colliderIndexAtPlayersKillList = i; } } bool weAreCloserToTargetThenCollider = false; if ((GetPosition() - m_vecSeekPos).MagnitudeSqr2D() < (collideWith->GetPosition() - m_vecSeekPos).MagnitudeSqr2D()) weAreCloserToTargetThenCollider = true; - if (weAreAtPlayerSafePosID <= 0 || weAreCloserToTargetThenCollider) { - if (!weAreCloserToTargetThenCollider) { + if (ourIndexAtPlayersKillList > 0 && !weAreCloserToTargetThenCollider) { + if (colliderIndexAtPlayersKillList > 0) { int time = 300; SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &time); m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + time; - } - } else if (colliderIsAtPlayerSafePosID <= 0) { - if (collideWith->m_pedInObjective == FindPlayerPed()) { - // VC specific - // ((CPlayerPed*)m_pedInObjective)->RemovePedFromMeleeList(this); + + } else if (collideWith->m_pedInObjective == FindPlayerPed()) { + ((CPlayerPed*)m_pedInObjective)->RemovePedFromMeleeList(this); int time = 500; SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &time); m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + time; } - } else { + } else if (!weAreCloserToTargetThenCollider) { int time = 300; SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &time); m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + time; - } + } } else { SetDirectionToWalkAroundObject(collideWith); } -#endif } } else { if (m_pedStats->m_temper <= m_pedStats->m_fear @@ -6121,12 +6292,14 @@ CPed::CollideWithPed(CPed *collideWith) } else { TurnBody(); SetAttack(collideWith); + m_fRotationCur = 0.3f + m_fRotationCur; + m_fRotationDest = m_fRotationCur; } m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(250, 450); } } } else { - if (m_pedInObjective && collideWith == m_pedInObjective && CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) { + if (m_pedInObjective && (collideWith == m_pedInObjective || collideWith->m_pedInObjective == m_pedInObjective) && CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) { if (heLooksToUs) { SetEvasiveStep(collideWith, 1); m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 3000; @@ -6135,7 +6308,8 @@ CPed::CollideWithPed(CPed *collideWith) if (m_pedStats != collideWith->m_pedStats) { - if (collideWith->m_pedStats->m_fear <= 100 - m_pedStats->m_temper) { + if (collideWith->m_pedStats->m_fear <= 100 - m_pedStats->m_temper || collideWith->IsPlayer() + || CTimer::GetTimeInMilliseconds() < m_nPedStateTimer) { if (collideWith->IsPlayer()) { // He's on our right side @@ -6145,16 +6319,17 @@ CPed::CollideWithPed(CPed *collideWith) m_fRotationCur += m_headingRate; } else { // He's on our right side - if (DotProduct(posDiff, GetRight()) <= 0.0f) - m_fRotationCur -= m_headingRate; + if (DotProduct(posDiff, collideWith->GetRight()) <= 0.0f) + collideWith->m_fRotationCur -= collideWith->m_headingRate; else - m_fRotationCur += m_headingRate; + collideWith->m_fRotationCur += collideWith->m_headingRate; } } else { SetLookFlag(collideWith, false); TurnBody(); animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_PPUNCH, 8.0f); animAssoc->flags |= ASSOC_FADEOUTWHENDONE; + m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 2000; if (!heIsMissionChar) { CVector2D posDiff2D(posDiff); int direction = collideWith->GetLocalDirection(posDiff2D); @@ -6164,11 +6339,9 @@ CPed::CollideWithPed(CPed *collideWith) } } } - } else if (collideWith->m_pedStats->m_defendWeakness <= 1.5f || heIsMissionChar -#ifdef VC_PED_PORTS - || m_pedStats->m_defendWeakness <= collideWith->m_pedStats->m_defendWeakness -#endif - ) { + } else if (collideWith->m_pedStats->m_defendWeakness <= 1.5f || heIsMissionChar || + m_pedStats->m_defendWeakness <= collideWith->m_pedStats->m_defendWeakness) { + // He looks us and we're not at his right side if (heLooksToUs && DotProduct(posDiff,collideWith->GetRight()) > 0.0f) { CVector moveForce = GetRight(); @@ -6221,7 +6394,7 @@ CPed::CollideWithPed(CPed *collideWith) } if (m_nPedState == PED_ATTACK && collideWith->IsPedInControl()) - DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, 0.0f); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_49, 0.0f); collideWith->SetFall(3000, animToPlay, 0); } @@ -6370,6 +6543,7 @@ CPed::SetAttackTimer(uint32 time) m_attackTimer = Max(m_shootTimer, CTimer::GetTimeInMilliseconds()) + time; } +// --MIAMI: Done void CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack) { @@ -6382,7 +6556,17 @@ CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack) SetMoveState(PEDMOVE_STILL); m_pSeekTarget = veh; m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget); - m_vehEnterType = vehEnterType; + + if (veh->IsBike()) { + ((CBike*)veh)->bIsBeingPickedUp = true; + if (veh->pPassengers[0] != this && (vehEnterType != CAR_WINDSCREEN || veh->pPassengers[0])) + m_vehEnterType = CAR_DOOR_LF; + else + m_vehEnterType = CAR_DOOR_LR; + } else { + m_vehEnterType = vehEnterType; + } + if (m_vehEnterType == CAR_DOOR_LF) { if (veh->pDriver && veh->pDriver->IsPlayer()) veh->SetStatus(STATUS_PLAYER_DISABLED); @@ -6391,9 +6575,9 @@ CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack) } RemoveInCarAnims(); SetMoveState(PEDMOVE_NONE); - LineUpPedWithCar(LINE_UP_TO_CAR_START); + LineUpPedWithCar(veh->IsBike() ? LINE_UP_TO_CAR_FALL : LINE_UP_TO_CAR_START); m_pVehicleAnim = nil; - m_nPedState = PED_DRAG_FROM_CAR; + SetPedState(PED_DRAG_FROM_CAR); bChangedSeat = false; bWillBeQuickJacked = quickJack; @@ -7498,6 +7682,7 @@ CPed::Fight(void) } } +// --MIAMI: Done // Some helper function which doesn't exist in og game. inline void SelectClosestNodeForSeek(CPed *ped, CPathNode *node, CVector2D closeDist, CVector2D farDist, CPathNode *closeNode, CPathNode *closeNode2, int runCount = 3) @@ -7527,6 +7712,7 @@ SelectClosestNodeForSeek(CPed *ped, CPathNode *node, CVector2D closeDist, CVecto } } +// --MIAMI: Done bool CPed::FindBestCoordsFromNodes(CVector unused, CVector *bestCoords) { @@ -7552,12 +7738,14 @@ CPed::FindBestCoordsFromNodes(CVector unused, CVector *bestCoords) SelectClosestNodeForSeek(this, closestNode, closeDist, seekPosDist, closestNode, nil); - // Above function decided that going to the next node is more logical than seeking the object. if (m_pNextPathNode) { - CVector pathToNextNode = m_pNextPathNode->GetPosition() - ourPos; - if (pathToNextNode.MagnitudeSqr2D() < seekPosDist.MagnitudeSqr()) { - *bestCoords = m_pNextPathNode->GetPosition(); + // Function above decided that directly going to next node makes more sense then seeking the object. + CVector correctedCoords = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed); + + if ((correctedCoords - ourPos).MagnitudeSqr2D() < seekPosDist.MagnitudeSqr()) { + correctedCoords = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed); + *bestCoords = correctedCoords; return true; } m_pNextPathNode = nil; @@ -8523,11 +8711,15 @@ CPed::FollowPath(void) } } +// --MIAMI: Done CVector CPed::GetFormationPosition(void) { CPed *referencePed = m_pedInObjective; + if (!referencePed) + return GetPosition(); + if (referencePed->m_nPedState == PED_DEAD) { CPed *referencePedOfReference = referencePed->m_pedInObjective; if (!referencePedOfReference) { @@ -8538,36 +8730,37 @@ CPed::GetFormationPosition(void) } CVector formationOffset; + float offset = CGeneral::GetRandomNumberInRange(1.f, 1.25f) * 1.75f; switch (m_pedFormation) { case FORMATION_REAR: - formationOffset = CVector(0.0f, -1.5f, 0.0f); + formationOffset = CVector(0.0f, -offset, 0.0f); break; case FORMATION_REAR_LEFT: - formationOffset = CVector(-1.5f, -1.5f, 0.0f); + formationOffset = CVector(-offset, -offset, 0.0f); break; case FORMATION_REAR_RIGHT: - formationOffset = CVector(1.5f, -1.5f, 0.0f); + formationOffset = CVector(offset, -offset, 0.0f); break; case FORMATION_FRONT_LEFT: - formationOffset = CVector(-1.5f, 1.5f, 0.0f); + formationOffset = CVector(-offset, offset, 0.0f); break; case FORMATION_FRONT_RIGHT: - formationOffset = CVector(1.5f, 1.5f, 0.0f); + formationOffset = CVector(offset, offset, 0.0f); break; case FORMATION_LEFT: - formationOffset = CVector(-1.5f, 0.0f, 0.0f); + formationOffset = CVector(-offset, 0.0f, 0.0f); break; case FORMATION_RIGHT: - formationOffset = CVector(1.5f, 0.0f, 0.0f); + formationOffset = CVector(offset, 0.0f, 0.0f); break; case FORMATION_FRONT: - formationOffset = CVector(0.0f, 1.5f, 0.0f); + formationOffset = CVector(0.0f, offset, 0.0f); break; default: formationOffset = CVector(0.0f, 0.0f, 0.0f); break; } - return formationOffset + referencePed->GetPosition(); + return m_pedInObjective->GetMatrix() * formationOffset; } // --MIAMI: Done @@ -9320,7 +9513,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse) CPad::GetPad(0)->StartShake(40000 / shakeFreq, shakeFreq); } bIsStanding = false; - damageDir = CPed::GetLocalDirection(-m_vecMoveSpeed); + damageDir = GetLocalDirection(-m_vecMoveSpeed); vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(car->GetModelIndex()); vehColModel = vehModel->GetColModel(); float carRightAndDistDotProd = DotProduct(distVec, car->GetRight()); @@ -17761,6 +17954,7 @@ CPed::SeekCar(void) } } +// --MIAMI: Done void CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk) { @@ -17801,13 +17995,9 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk) } else if (IsPedInControl()) { if ((IsPlayer() && m_nPedState != PED_FIGHT && ((CPlayerPed*)this)->m_fMoveSpeed > 1.0f) || (!IsPlayer() && m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE)) { -#ifndef VC_PED_PORTS - if (hitLevel != HITLEVEL_HIGH && hitLevel != HITLEVEL_LOW || (IsPlayer() || CGeneral::GetRandomNumber() & 3) && CGeneral::GetRandomNumber() & 7) { - if (IsPlayer() || CGeneral::GetRandomNumber() & 3) { -#else + if (hitLevel != HITLEVEL_HIGH && hitLevel != HITLEVEL_LOW || (IsPlayer() || CGeneral::GetRandomNumber() & 1) && CGeneral::GetRandomNumber() & 7) { if (IsPlayer() || CGeneral::GetRandomNumber() & 1) { -#endif AnimationId shotAnim; switch (direction) { case 1: @@ -17835,22 +18025,6 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk) SetWaitState(WAITSTATE_PLAYANIM_DUCK, &time); } } else { -#ifndef VC_PED_PORTS - switch (direction) { - case 1: - SetFall(500, ANIM_KO_SPIN_R, false); - break; - case 2: - SetFall(500, ANIM_KO_SKID_BACK, false); - break; - case 3: - SetFall(500, ANIM_KO_SPIN_L, false); - break; - default: - SetFall(500, ANIM_KO_SHOT_STOM, false); - break; - } -#else bool fall = true; AnimationId hitAnim; switch (direction) { @@ -17893,7 +18067,6 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk) hitAssoc->SetRun(); hitAssoc->flags |= ASSOC_FADEOUTWHENDONE; } -#endif } Say(SOUND_PED_DEFEND); } else { @@ -17903,20 +18076,15 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk) m_lastFightMove = FIGHTMOVE_HITONFLOOR; break; case HITLEVEL_LOW: -#ifndef VC_PED_PORTS - if (direction == 2) { - CPed::SetFall(1000, ANIM_KO_SKID_BACK, false); - return; - } -#else if (direction == 2 && (!IsPlayer() || ((CGeneral::GetRandomNumber() & 1) && m_fHealth < 30.0f))) { - CPed::SetFall(1000, ANIM_KO_SKID_BACK, false); + SetFall(1000, ANIM_KO_SKID_BACK, false); + Say(SOUND_PED_DEFEND); return; } else if (direction != 2 && !IsPlayer() && (CGeneral::GetRandomNumber() & 1) && m_fHealth < 30.0f) { - CPed::SetFall(1000, ANIM_KO_SHOT_STOM, false); + SetFall(1000, ANIM_KO_SHOT_STOM, false); + Say(SOUND_PED_DEFEND); return; } -#endif m_lastFightMove = FIGHTMOVE_HITBODY; break; case HITLEVEL_HIGH: @@ -17966,24 +18134,28 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk) moveAssoc->SetCurrentTime(0.0f); moveAssoc->SetFinishCallback(FinishFightMoveCB, this); if (IsPlayer()) - moveAssoc->speed = 1.3f; + moveAssoc->speed = 1.2f; m_takeAStepAfterAttack = 0; m_fightButtonPressure = 0; - } else if (IsPlayer() && m_currentWeapon != WEAPONTYPE_UNARMED) { + + } else if (IsPlayer() && GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE && + !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bFightMode) { CAnimBlendAssociation *moveAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[m_lastFightMove].animId, 4.0f); moveAssoc->SetCurrentTime(0.0f); - moveAssoc->speed = 1.3f; + moveAssoc->speed = 1.2f; + } else { if (m_nPedState != PED_AIM_GUN && m_nPedState != PED_ATTACK) SetStoredState(); if (m_nWaitState != WAITSTATE_FALSE) { - m_nWaitState = WAITSTATE_FALSE; + ClearWaitState(); RestoreHeadingRate(); } - m_nPedState = PED_FIGHT; + SetPedState(PED_FIGHT); m_fightButtonPressure = 0; + m_lastHitState = 2; RpAnimBlendClumpRemoveAssociations(GetClump(), ASSOC_REPEAT); CAnimBlendAssociation *walkStartAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK_START); if (walkStartAssoc) { @@ -18000,13 +18172,28 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk) } SetMoveState(PEDMOVE_NONE); m_nStoredMoveState = PEDMOVE_NONE; - CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_IDLE)->blendAmount = 1.0f; + CAnimBlendAssociation *fightIdleAssoc; + + if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) { + CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); + if (GetFightIdleWithMeleeAnim(weaponInfo)) { + fightIdleAssoc = CAnimManager::AddAnimation(GetClump(), weaponInfo->m_AnimToPlay, GetFightIdleWithMeleeAnim(weaponInfo)); + } else { + fightIdleAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_IDLE); + } + } else { + fightIdleAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_IDLE); + } + fightIdleAssoc->blendAmount = 1.0f; CAnimBlendAssociation *moveAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[m_lastFightMove].animId, 8.0f); moveAssoc->SetFinishCallback(FinishFightMoveCB, this); m_fightState = FIGHTSTATE_NO_MOVE; m_takeAStepAfterAttack = false; bIsAttacking = true; } + + if (m_pedInObjective && m_pedInObjective->IsPlayer() && !IsPlayer()) + ((CPlayerPed*)m_pedInObjective)->RemovePedFromMeleeList(this); } } } diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 6fd96b66..69d1ba5a 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -594,6 +594,7 @@ public: CEntity *m_pPointGunAt; CVector m_vecHitLastPos; uint32 m_lastFightMove; + uint32 m_lastHitState; // TODO(Miami): What's this? uint8 m_fightButtonPressure; FightState m_fightState; bool m_takeAStepAfterAttack; @@ -756,7 +757,8 @@ public: void SetAttack(CEntity*); void StartFightAttack(uint8); void SetWaitState(eWaitState, void*); - bool FightStrike(CVector&); + bool FightStrike(CVector&, bool); + void FightHitPed(CPed*, CVector&, CVector&, int16); int GetLocalDirection(const CVector2D &); void StartFightDefend(uint8, uint8, uint8); void PlayHitSound(CPed*); @@ -1020,6 +1022,13 @@ public: else return (AnimationId)0; } + + static AnimationId GetFightIdleWithMeleeAnim(CWeaponInfo* weapon) { + if (!!weapon->m_bFightMode) + return ANIM_MELEE_IDLE_FIGHTMODE; + else + return (AnimationId)0; + } // -- // My additions, because there were many, many instances of that. diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 08f79c7e..ee6891c7 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -81,7 +81,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) for (int i = 0; i < 6; i++) { m_vecSafePos[i] = CVector(0.0f, 0.0f, 0.0f); m_pPedAtSafePos[i] = nil; - m_pCheckPlayers[i] = nil; + m_pMeleeList[i] = nil; } m_nCheckPlayersIndex = 0; m_nPadUpPressedInMilliseconds = 0; @@ -1711,6 +1711,18 @@ CPlayerPed::PlayIdleAnimations(CPad *padUsed) } } +void +CPlayerPed::RemovePedFromMeleeList(CPed *ped) +{ + int i = 0; + for (; m_pMeleeList[i] != ped; i++) { + if (i >= ARRAY_SIZE(m_pMeleeList)) + return; + } + m_pMeleeList[i] = nil; + ped->m_attackTimer = 0; +} + #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/peds/PlayerPed.h b/src/peds/PlayerPed.h index cc56af9f..7ff95ff3 100644 --- a/src/peds/PlayerPed.h +++ b/src/peds/PlayerPed.h @@ -34,7 +34,7 @@ public: bool m_bDrunkVisualsWearOff; // TODO(Miami): That may be something else CVector m_vecSafePos[6]; // safe places from the player, for example behind a tree CPed *m_pPedAtSafePos[6]; - CPlayerPed* m_pCheckPlayers[6]; //checks something with players, could be a leftover from original multiplayer + CPlayerPed* m_pMeleeList[6]; char unused1; int16 m_nCheckPlayersIndex; float m_fWalkAngle; //angle between heading and walking direction @@ -84,6 +84,7 @@ public: void PlayerControlZelda(CPad*); bool DoesPlayerWantNewWeapon(eWeaponType, bool); void PlayIdleAnimations(CPad*); + void RemovePedFromMeleeList(CPed*); static void SetupPlayerPed(int32); static void DeactivatePlayerPed(int32); diff --git a/src/vehicles/Bike.cpp b/src/vehicles/Bike.cpp index 01b489b2..6f52c33f 100644 --- a/src/vehicles/Bike.cpp +++ b/src/vehicles/Bike.cpp @@ -411,13 +411,13 @@ CBike::ProcessControl(void) fDx = fDAxisXExtra; if(!(m_aWheelTimer[BIKESUSP_R1] == 0.0f && m_aWheelTimer[BIKESUSP_R2] == 0.0f) && GetForward().z > 0.0f) - res.x -= Max(0.25f*Abs(pBikeHandling->fWheelieAng-GetForward().z), 0.07f); + res.x -= Min(0.25f*Abs(pBikeHandling->fWheelieAng-GetForward().z), 0.07f); else res.x = fInAirXRes; }else if(m_aWheelTimer[BIKESUSP_R1] == 0.0f && m_aWheelTimer[BIKESUSP_R2] == 0.0f){ fDx = fDAxisXExtra; if(GetForward().z < 0.0f) - res.x *= Max(0.3f*Abs(pBikeHandling->fStoppieAng-GetForward().z), 0.1f) + 0.9f; + res.x *= Min(0.3f*Abs(pBikeHandling->fStoppieAng-GetForward().z), 0.1f) + 0.9f; } } @@ -1014,7 +1014,7 @@ CBike::ProcessControl(void) m_vecAvgSurfaceRight.Normalise(); float lean; if(m_nWheelsOnGround == 0) - lean = -m_fSteerAngle/DEGTORAD(pHandling->fSteeringLock)*0.5f*GRAVITY*CTimer::GetTimeStep(); + lean = -(m_fSteerAngle/DEGTORAD(pHandling->fSteeringLock))*0.5f*GRAVITY*CTimer::GetTimeStep(); else lean = DotProduct(m_vecMoveSpeed-initialMoveSpeed, m_vecAvgSurfaceRight); lean /= GRAVITY*Max(CTimer::GetTimeStep(), 0.01f); diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index 8aa3db39..ad28cc59 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -603,18 +603,12 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource) newDir.z = 0.01f; CParticle::AddParticle(PARTICLE_DEBRIS2, bloodPos, newDir); - // TODO(Miami): New particle - /* - v116.z = 0.0; - v116.x = CGeneral::GetRandomNumberInRange(-0.15f, 0.15f); - v116.y = CGeneral::GetRandomNumberInRange(0.1f, 0.35f); - v115.x = CGeneral::GetRandomNumberInRange(SCREEN_STRETCH_X(50.0f), SCREEN_STRETCH_FROM_RIGHT(50.0f)); - v115.z = 1.0; - v115.y = CGeneral::GetRandomNumberInRange(SCREEN_STRETCH_Y(50.0f), SCREEN_STRETCH_FROM_BOTTOM(50.0f)); - CParticle::AddParticle(41, v115, v116, nil, CGeneral::GetRandomNumberInRange(0.1f, 0.15f), + CVector dropDir(CGeneral::GetRandomNumberInRange(-0.15f, 0.15f), CGeneral::GetRandomNumberInRange(0.1f, 0.35f), 0.f); + CVector dropPos(CGeneral::GetRandomNumberInRange(SCREEN_STRETCH_X(50.0f), SCREEN_STRETCH_FROM_RIGHT(50.0f)), + CGeneral::GetRandomNumberInRange(SCREEN_STRETCH_Y(50.0f), SCREEN_STRETCH_FROM_BOTTOM(50.0f)), 1.f); + CParticle::AddParticle(PARTICLE_BLOODDROP, dropPos, dropDir, nil, CGeneral::GetRandomNumberInRange(0.1f, 0.15f), CRGBA(0, 0, 0, 0), 0, 0, CGeneral::GetRandomNumber() & 1, 0); - */ } if (info->m_AnimToPlay == ASSOCGRP_KNIFE) { @@ -705,8 +699,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource) { nearCar->VehicleDamage(info->m_nDamage * (0.00075f * nearCar->pHandling->fMass), gaTempSphereColPoints[0].pieceB); - // TODO(Miami): Particle not in III - // CParticle::AddParticle(81, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0); + CParticle::AddParticle(PARTICLE_HEATHAZE, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0); } else { @@ -783,8 +776,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource) CParticle::AddParticle(PARTICLE_SPARK, gaTempSphereColPoints[0].point, 0.1f * gaTempSphereColPoints[0].normal, 0, 0.0f, 0, 0, 0, 0); } - // TODO(Miami): Particle not in III - //CParticle::AddParticle(81, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0); + CParticle::AddParticle(PARTICLE_HEATHAZE, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0); if (!damageEntityRegistered) { From 3a600b46849f4ce9161da94c19ca61cb397a2257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Tue, 16 Jun 2020 00:20:08 +0300 Subject: [PATCH 16/18] Bike anim. fix --- src/peds/Ped.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 79a6202f..1b98dad6 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -10237,6 +10237,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, enterDoor == DOOR_FRONT_LEFT || enterDoor == DOOR_REAR_LEFT ? ANIM_BIKE_JUMPON_R : ANIM_BIKE_JUMPON_L); ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped); + ((CBike*)veh)->bIsBeingPickedUp = true; } } else if (ped->m_vehEnterType == CAR_WINDSCREEN) { if (veh->pDriver->m_nPedState != PED_DRIVING || veh->pDriver->bDontDragMeOutCar) { @@ -10246,6 +10247,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped); pedToDragOut = veh->pDriver; } + ((CBike*)veh)->bIsBeingPickedUp = true; } else { if (enterDoor == DOOR_FRONT_LEFT || enterDoor == DOOR_FRONT_RIGHT) { if (veh->pDriver) { @@ -10266,6 +10268,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) } else { ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, enterDoor == DOOR_FRONT_LEFT ? ANIM_BIKE_JUMPON_R : ANIM_BIKE_JUMPON_L); ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped); + ((CBike*)veh)->bIsBeingPickedUp = true; } } else { if (veh->pPassengers[0]) { @@ -10288,10 +10291,10 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg) ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, enterDoor == DOOR_REAR_LEFT ? ANIM_BIKE_JUMPON_R : ANIM_BIKE_JUMPON_L); ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped); + ((CBike*)veh)->bIsBeingPickedUp = true; } } } - ((CBike*)veh)->bIsBeingPickedUp = true; // TODO(Miami): This looks like something inlined if (pedToDragOut) { 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 17/18] 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); From a822692c2647964c8dba6c8ea12168c5f80e335e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Tue, 16 Jun 2020 22:55:28 +0300 Subject: [PATCH 18/18] fix crash-VC pickup scaling --- src/control/Pickups.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index 1db6dfa2..95abe2c5 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -71,11 +71,6 @@ uint8 aWeaponBlues[] = { 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 128, 255, 0, 0 }; -float aWeaponScale[] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -2.0f, 1.5f, 1.0f, 1.0f, 1.5f, 1.0f, 2.0f, 1.0f, 2.0f, 2.5f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f }; - void CPickup::RemoveKeepType() { @@ -770,7 +765,15 @@ CPickups::DoPickUpEffects(CEntity *entity) } } - entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), aWeaponScale[colorId]); + uint32 model = entity->GetModelIndex(); + CColModel* colModel = entity->GetColModel(); + CVector colLength = colModel->boundingBox.max - colModel->boundingBox.min; + + float scale = (Max(1.f, 1.2f / Max(colLength.x, Max(colLength.y, colLength.z))) - 1.0f) * 0.6f + 1.0f; + if (model == MI_MINIGUN || model == MI_MINIGUN2) + scale = 1.2f; + + entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), scale); if (doInnerGlow) CCoronas::RegisterCorona((uintptr)entity + 1, 126, 69, 121, 255, entity->GetPosition(), 1.2f, 50.0f,