diff options
Diffstat (limited to 'src/vehicles/Plane.cpp')
-rw-r--r-- | src/vehicles/Plane.cpp | 273 |
1 files changed, 184 insertions, 89 deletions
diff --git a/src/vehicles/Plane.cpp b/src/vehicles/Plane.cpp index bc27ca32..ffe9ffbf 100644 --- a/src/vehicles/Plane.cpp +++ b/src/vehicles/Plane.cpp @@ -2,6 +2,7 @@ #include "main.h" #include "General.h" +#include "CutsceneMgr.h" #include "ModelIndices.h" #include "FileMgr.h" #include "Streaming.h" @@ -12,10 +13,14 @@ #include "Coronas.h" #include "Particle.h" #include "Explosion.h" +#include "Fluff.h" #include "World.h" #include "HandlingMgr.h" +#include "Heli.h" #include "Plane.h" +//--MIAMI: file done + CPlaneNode *pPathNodes; CPlaneNode *pPath2Nodes; CPlaneNode *pPath3Nodes; @@ -39,12 +44,10 @@ CPlaneInterpolationLine aPlaneLineBits[6]; float PlanePathPosition[3]; float OldPlanePathPosition[3]; float PlanePathSpeed[3]; -float PlanePath2Position[3]; -float PlanePath3Position; -float PlanePath4Position; -float PlanePath2Speed[3]; -float PlanePath3Speed; -float PlanePath4Speed; +float PlanePath2Position[5]; +float PlanePath3Position[4]; +float PlanePath2Speed[5]; +float PlanePath3Speed[4]; enum @@ -62,7 +65,6 @@ int32 DropOffCesnaMissionStatus; int32 DropOffCesnaMissionStartTime; CPlane *pDropOffCesna; - CPlane::CPlane(int32 id, uint8 CreatedBy) : CVehicle(CreatedBy) { @@ -80,13 +82,15 @@ CPlane::CPlane(int32 id, uint8 CreatedBy) m_bHasBeenHit = false; m_bIsDrugRunCesna = false; m_bIsDropOffCesna = false; + m_bTempPlane = false; SetStatus(STATUS_PLANE); bIsBIGBuilding = true; - m_level = LEVEL_NONE; + m_level = LEVEL_GENERIC; -#ifdef FIX_BUGS - m_isFarAway = true; + m_isFarAway = false; +#ifdef CPLANE_ROTORS + m_fRotorRotation = 0.0f; #endif } @@ -99,6 +103,21 @@ void CPlane::SetModelIndex(uint32 id) { CVehicle::SetModelIndex(id); +#ifdef CPLANE_ROTORS + int i; + for(i = 0; i < NUM_PLANE_NODES; i++) + m_aPlaneNodes[i] = nil; + if(GetModelIndex() == MI_CHOPPER){ + // This is surprisingly annoying... + RwFrame *heliNodes[NUM_HELI_NODES]; + for(i = 0; i < NUM_HELI_NODES; i++) + heliNodes[i] = nil; + CClumpModelInfo::FillFrameArray(GetClump(), heliNodes); + m_aPlaneNodes[PLANE_TOPROTOR] = heliNodes[HELI_TOPROTOR]; + m_aPlaneNodes[PLANE_BACKROTOR] = heliNodes[HELI_BACKROTOR]; + }else + CClumpModelInfo::FillFrameArray(GetClump(), m_aPlaneNodes); +#endif } void @@ -123,6 +142,15 @@ CPlane::ProcessControl(void) int i; CVector pos; + if(CReplay::IsPlayingBack()) + return; + + if(GetModelIndex() == MI_AIRTRAIN){ + if(GetPosition().z > 100.0f) + CPlaneTrails::RegisterPoint(GetPosition(), m_nPlaneId); + }else if(GetModelIndex() == MI_DEADDODO) + CPlaneBanners::RegisterPoint(GetPosition(), m_nPlaneId); + // Explosion if(m_bHasBeenHit){ // BUG: since this is all based on frames, you can skip the explosion processing when you go into the menu @@ -154,7 +182,7 @@ CPlane::ProcessControl(void) int f = ++nFrameGen & 3; CParticle::AddParticle(PARTICLE_HELI_DEBRIS, GetMatrix() * CVector(0.0f, 0.0f, 0.0f), dir, nil, CGeneral::GetRandomNumberInRange(0.1f, 1.0f), - colors[nFrameGen], rotSpeed, 0, f, 0); + colors[nFrameGen&7], rotSpeed, 0, f, 0); } } if(frm >= 40 && frm <= 80 && frm & 1){ @@ -197,17 +225,18 @@ CPlane::ProcessControl(void) colors[6] = CRGBA(0, 0, 0, 255); colors[7] = CRGBA(252, 66, 66, 255); + CVector dir; for(i = 0; i < 40; i++){ + dir.x = CGeneral::GetRandomNumberInRange(-2.0f, 2.0f); + dir.y = CGeneral::GetRandomNumberInRange(-2.0f, 2.0f); + dir.z = CGeneral::GetRandomNumberInRange(0.0f, 2.0f); int rotSpeed = CGeneral::GetRandomNumberInRange(30.0f, 20.0f); if(CGeneral::GetRandomNumber() & 1) rotSpeed = -rotSpeed; int f = ++nFrameGen & 3; - CParticle::AddParticle(PARTICLE_HELI_DEBRIS, GetMatrix() * CVector(0.0f, 0.0f, 0.0f), - CVector(CGeneral::GetRandomNumberInRange(-2.0f, 2.0f), - CGeneral::GetRandomNumberInRange(-2.0f, 2.0f), - CGeneral::GetRandomNumberInRange(0.0f, 2.0f)), + CParticle::AddParticle(PARTICLE_HELI_DEBRIS, GetMatrix() * CVector(0.0f, 0.0f, 0.0f), dir, nil, CGeneral::GetRandomNumberInRange(0.1f, 1.0f), - colors[nFrameGen], rotSpeed, 0, f, 0); + colors[nFrameGen&7], rotSpeed, 0, f, 0); } } if(frm >= 40 && frm <= 60 && frm & 1){ @@ -226,7 +255,7 @@ CPlane::ProcessControl(void) } if(frm == 30) bRenderScorched = true; - if(frm == 61){ + if(frm == 62){ TheCamera.SetFadeColour(200, 200, 200); TheCamera.Fade(0.0f, FADE_OUT); TheCamera.ProcessFade(); @@ -363,7 +392,7 @@ CPlane::ProcessControl(void) CVector posFront2 = (1.0f - f)*pPathNodes[curPathNodeFront2].p + f*pPathNodes[nextPathNodeFront2].p; // Now set matrix - GetMatrix().GetPosition() = (posRear + posFront) / 2.0f; + GetMatrix().SetTranslateOnly((posRear + posFront) / 2.0f); GetMatrix().GetPosition().z += 4.3f; CVector fwd = posFront - posRear; fwd.Normalise(); @@ -382,13 +411,12 @@ CPlane::ProcessControl(void) GetMatrix().GetRight() = right; GetMatrix().GetUp() = up; GetMatrix().GetForward() = fwd; - // Set speed m_vecMoveSpeed = fwd*PlanePathSpeed[m_nPlaneId]/60.0f; m_fSpeed = PlanePathSpeed[m_nPlaneId]/60.0f; m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f); - m_isFarAway = !((posFront - TheCamera.GetPosition()).Magnitude2D() < sq(300.0f)); + m_isFarAway = !((posFront - TheCamera.GetPosition()).MagnitudeSqr2D() < sq(300.0f)); }else{ float planePathPosition; float totalLengthOfFlightPath; @@ -396,26 +424,12 @@ CPlane::ProcessControl(void) float planePathSpeed; int numPathNodes; - if(m_bIsDrugRunCesna){ - planePathPosition = PlanePath3Position; + if(GetModelIndex() == MI_CHOPPER){ + planePathPosition = PlanePath3Position[m_nPlaneId]; totalLengthOfFlightPath = TotalLengthOfFlightPath3; pathNodes = pPath3Nodes; - planePathSpeed = PlanePath3Speed; + planePathSpeed = PlanePath3Speed[m_nPlaneId]; numPathNodes = NumPath3Nodes; - if(CesnaMissionStatus == CESNA_STATUS_LANDED){ - pDrugRunCesna = nil; - FlagToDestroyWhenNextProcessed(); - } - }else if(m_bIsDropOffCesna){ - planePathPosition = PlanePath4Position; - totalLengthOfFlightPath = TotalLengthOfFlightPath4; - pathNodes = pPath4Nodes; - planePathSpeed = PlanePath4Speed; - numPathNodes = NumPath4Nodes; - if(DropOffCesnaMissionStatus == CESNA_STATUS_LANDED){ - pDropOffCesna = nil; - FlagToDestroyWhenNextProcessed(); - } }else{ planePathPosition = PlanePath2Position[m_nPlaneId]; totalLengthOfFlightPath = TotalLengthOfFlightPath2; @@ -484,7 +498,7 @@ CPlane::ProcessControl(void) f = (pathPositionFront - pathNodes[curPathNodeFront].t)/dist; CVector posFront = (1.0f - f)*pathNodes[curPathNodeFront].p + f*pathNodes[nextPathNodeFront].p; - // And for another point 60 units in front of the plane, used to calculate roll + // And for another point 30 units in front of the plane, used to calculate roll float pathPositionFront2 = pathPositionFront + 30.0f; if(pathPositionFront2 > totalLengthOfFlightPath) pathPositionFront2 -= totalLengthOfFlightPath; @@ -515,7 +529,7 @@ CPlane::ProcessControl(void) CVector posFront2 = (1.0f - f)*pathNodes[curPathNodeFront2].p + f*pathNodes[nextPathNodeFront2].p; // Now set matrix - GetMatrix().GetPosition() = (posRear + posFront) / 2.0f; + GetMatrix().SetTranslateOnly((posRear + posFront) / 2.0f); GetMatrix().GetPosition().z += 1.0f; CVector fwd = posFront - posRear; fwd.Normalise(); @@ -535,7 +549,7 @@ CPlane::ProcessControl(void) m_fSpeed = planePathSpeed/60.0f; m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f); - m_isFarAway = !((posFront - TheCamera.GetPosition()).Magnitude2D() < sq(300.0f)); + m_isFarAway = !((posFront - TheCamera.GetPosition()).MagnitudeSqr2D() < sq(300.0f)); } } @@ -634,12 +648,36 @@ CPlane::PreRender(void) CCoronas::TYPE_NORMAL, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f); } + +#ifdef CPLANE_ROTORS + CMatrix mat; + CVector pos; + m_fRotorRotation += 3.14f/6.5f; + if(m_fRotorRotation > 6.28f) + m_fRotorRotation -= 6.28f; + + if(m_aPlaneNodes[PLANE_TOPROTOR]){ + mat.Attach(RwFrameGetMatrix(m_aPlaneNodes[PLANE_TOPROTOR])); + pos = mat.GetPosition(); + mat.SetRotateZ(m_fRotorRotation); + mat.Translate(pos); + mat.UpdateRW(); + } + if(m_aPlaneNodes[PLANE_BACKROTOR]){ + mat.Attach(RwFrameGetMatrix(m_aPlaneNodes[PLANE_BACKROTOR])); + pos = mat.GetPosition(); + mat.SetRotateX(m_fRotorRotation); + mat.Translate(pos); + mat.UpdateRW(); + } +#endif } void CPlane::Render(void) { - CEntity::Render(); + if(!CCutsceneMgr::IsRunning()) + CEntity::Render(); } #define CRUISE_SPEED (50.0f) @@ -657,11 +695,9 @@ CPlane::InitPlanes(void) pPathNodes = LoadPath("data\\paths\\flight.dat", NumPathNodes, TotalLengthOfFlightPath, true); // Figure out which nodes are on ground - CColPoint colpoint; - CEntity *entity; for(i = 0; i < NumPathNodes; i++){ - if(CWorld::ProcessVerticalLine(pPathNodes[i].p, 1000.0f, colpoint, entity, true, false, false, false, true, false, nil)){ - pPathNodes[i].p.z = colpoint.point.z; + if(pPathNodes[i].p.z < 14.0f){ + pPathNodes[i].p.z = 14.0f; pPathNodes[i].bOnGround = true; }else pPathNodes[i].bOnGround = false; @@ -688,7 +724,7 @@ CPlane::InitPlanes(void) aPlaneLineBits[0].position = position; aPlaneLineBits[0].speed = TAXI_SPEED; aPlaneLineBits[0].acceleration = 0.0f; - float dist = (TakeOffPoint-600.0f) - position; + float dist = (TakeOffPoint-500.0f) - position; time += dist/TAXI_SPEED; position += dist; @@ -697,9 +733,9 @@ CPlane::InitPlanes(void) aPlaneLineBits[1].time = time; aPlaneLineBits[1].position = position; aPlaneLineBits[1].speed = TAXI_SPEED; - aPlaneLineBits[1].acceleration = 33.0f/32.0f; - time += 600.0f/((CRUISE_SPEED+TAXI_SPEED)/2.0f); - position += 600.0f; + aPlaneLineBits[1].acceleration = 618.75f/500.0f; + time += 500.0f/((CRUISE_SPEED+TAXI_SPEED)/2.0f); + position += 500.0f; // Fly at cruise speed aPlaneLineBits[2].type = 1; @@ -716,9 +752,9 @@ CPlane::InitPlanes(void) aPlaneLineBits[3].time = time; aPlaneLineBits[3].position = position; aPlaneLineBits[3].speed = CRUISE_SPEED; - aPlaneLineBits[3].acceleration = -33.0f/32.0f; - time += 600.0f/((CRUISE_SPEED+TAXI_SPEED)/2.0f); - position += 600.0f; + aPlaneLineBits[3].acceleration = -618.75f/500.0f; + time += 500.0f/((CRUISE_SPEED+TAXI_SPEED)/2.0f); + position += 500.0f; // Taxi aPlaneLineBits[4].type = 1; @@ -739,24 +775,17 @@ CPlane::InitPlanes(void) TotalDurationOfFlightPath2 = TotalLengthOfFlightPath2/CRUISE_SPEED; } -/* - // Mission Cesna + // Heli if(pPath3Nodes == nil){ pPath3Nodes = LoadPath("data\\paths\\flight3.dat", NumPath3Nodes, TotalLengthOfFlightPath3, false); TotalDurationOfFlightPath3 = TotalLengthOfFlightPath3/CRUISE_SPEED; } - // Mission Cesna - if(pPath4Nodes == nil){ - pPath4Nodes = LoadPath("data\\paths\\flight4.dat", NumPath4Nodes, TotalLengthOfFlightPath4, false); - TotalDurationOfFlightPath4 = TotalLengthOfFlightPath4/CRUISE_SPEED; - } -*/ - CStreaming::LoadAllRequestedModels(false); CStreaming::RequestModel(MI_AIRTRAIN, 0); CStreaming::LoadAllRequestedModels(false); + // NB: 3 hardcoded also in CPlaneTrails for(i = 0; i < 3; i++){ CPlane *plane = new CPlane(MI_AIRTRAIN, PERMANENT_VEHICLE); plane->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f); @@ -766,20 +795,6 @@ CPlane::InitPlanes(void) plane->m_nCurPathNode = 0; CWorld::Add(plane); } - - - CStreaming::RequestModel(MI_DEADDODO, 0); - CStreaming::LoadAllRequestedModels(false); - - for(i = 0; i < 3; i++){ - CPlane *plane = new CPlane(MI_DEADDODO, PERMANENT_VEHICLE); - plane->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f); - plane->SetStatus(STATUS_ABANDONED); - plane->bIsLocked = true; - plane->m_nPlaneId = i; - plane->m_nCurPathNode = 0; - CWorld::Add(plane); - } } void @@ -811,7 +826,6 @@ CPlane::LoadPath(char const *filename, int32 &numNodes, float &totalLength, bool CPlaneNode *nodes = new CPlaneNode[numNodes]; for(i = 0; i < numNodes; i++){ - *gString = '\0'; for(lp = 0; work_buff[bp] != '\n' && work_buff[bp] != '\0'; bp++, lp++) gString[lp] = work_buff[bp]; bp++; @@ -833,6 +847,10 @@ CPlane::LoadPath(char const *filename, int32 &numNodes, float &totalLength, bool return nodes; } +int32 LastTimeInPlane, LastTimeNotInPlane; +bool bCesnasActivated; +bool bHelisActivated; + void CPlane::UpdatePlanes(void) { @@ -875,25 +893,87 @@ CPlane::UpdatePlanes(void) t = TotalDurationOfFlightPath2/0x80000; PlanePath2Position[0] = CRUISE_SPEED * (time & 0x7FFFF)*t; - PlanePath2Position[1] = CRUISE_SPEED * ((time + 0x80000/3) & 0x7FFFF)*t; - PlanePath2Position[2] = CRUISE_SPEED * ((time + 0x80000/3*2) & 0x7FFFF)*t; + PlanePath2Position[1] = CRUISE_SPEED * ((time + 0x80000/5) & 0x7FFFF)*t; + PlanePath2Position[2] = CRUISE_SPEED * ((time + 0x80000/5*2) & 0x7FFFF)*t; + PlanePath2Position[3] = CRUISE_SPEED * ((time + 0x80000/5*3) & 0x7FFFF)*t; + PlanePath2Position[4] = CRUISE_SPEED * ((time + 0x80000/5*4) & 0x7FFFF)*t; PlanePath2Speed[0] = CRUISE_SPEED*t; PlanePath2Speed[1] = CRUISE_SPEED*t; PlanePath2Speed[2] = CRUISE_SPEED*t; + PlanePath2Speed[3] = CRUISE_SPEED*t; + PlanePath2Speed[4] = CRUISE_SPEED*t; + + t = TotalDurationOfFlightPath3/0x80000; + PlanePath3Position[0] = CRUISE_SPEED * (time & 0x7FFFF)*t; + PlanePath3Position[1] = CRUISE_SPEED * ((time + 0x80000/4) & 0x7FFFF)*t; + PlanePath3Position[2] = CRUISE_SPEED * ((time + 0x80000/4*2) & 0x7FFFF)*t; + PlanePath3Position[3] = CRUISE_SPEED * ((time + 0x80000/4*3) & 0x7FFFF)*t; + PlanePath3Speed[0] = CRUISE_SPEED*t; + PlanePath3Speed[1] = CRUISE_SPEED*t; + PlanePath3Speed[2] = CRUISE_SPEED*t; + PlanePath3Speed[3] = CRUISE_SPEED*t; + + if(FindPlayerVehicle() && (FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI || + FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE)) + LastTimeInPlane = CTimer::GetTimeInMilliseconds(); + else + LastTimeNotInPlane = CTimer::GetTimeInMilliseconds(); + + if(CTimer::GetTimeInMilliseconds() - LastTimeNotInPlane > 10000){ + if(!bCesnasActivated){ + if(CStreaming::HasModelLoaded(MI_DEADDODO)){ + for(i = 0; i < 5; i++){ + CPlane *plane = new CPlane(MI_DEADDODO, PERMANENT_VEHICLE); + plane->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f); + plane->SetStatus(STATUS_ABANDONED); + plane->bIsLocked = true; + plane->m_nPlaneId = i; + plane->m_nCurPathNode = 0; + plane->m_bTempPlane = true; + CWorld::Add(plane); + } + bCesnasActivated = true; + }else + CStreaming::RequestModel(MI_DEADDODO, 0); + } - if(CesnaMissionStatus == CESNA_STATUS_FLYING){ - PlanePath3Speed = CRUISE_SPEED*TotalDurationOfFlightPath3/0x20000; - PlanePath3Position = PlanePath3Speed * ((time - CesnaMissionStartTime) & 0x1FFFF); - if(time - CesnaMissionStartTime >= 128072) - CesnaMissionStatus = CESNA_STATUS_LANDED; - } + if(!bHelisActivated){ + if(CStreaming::HasModelLoaded(MI_CHOPPER)){ + for(i = 0; i < 4; i++){ + CPlane *plane = new CPlane(MI_CHOPPER, PERMANENT_VEHICLE); + plane->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f); + plane->SetStatus(STATUS_ABANDONED); + plane->bIsLocked = true; + plane->m_nPlaneId = i; + plane->m_nCurPathNode = 0; + plane->m_bTempPlane = true; + CWorld::Add(plane); + } + bHelisActivated = true; + }else + CStreaming::RequestModel(MI_CHOPPER, 0); + } + }else if(CTimer::GetTimeInMilliseconds() - LastTimeInPlane > 10000) + RemoveTemporaryPlanes(); +} - if(DropOffCesnaMissionStatus == CESNA_STATUS_FLYING){ - PlanePath4Speed = CRUISE_SPEED*TotalDurationOfFlightPath4/0x80000; - PlanePath4Position = PlanePath4Speed * ((time - DropOffCesnaMissionStartTime) & 0x7FFFF); - if(time - DropOffCesnaMissionStartTime >= 521288) - DropOffCesnaMissionStatus = CESNA_STATUS_LANDED; +void +CPlane::RemoveTemporaryPlanes(void) +{ + int i; + if(!bHelisActivated && !bCesnasActivated) + return; + + i = CPools::GetVehiclePool()->GetSize(); + while(--i >= 0){ + CPlane *plane = (CPlane*)CPools::GetVehiclePool()->GetSlot(i); + if(plane && plane->IsPlane() && plane->m_bTempPlane){ + CWorld::Remove(plane); + delete plane; + } } + bCesnasActivated = false; + bHelisActivated = false; } bool @@ -921,6 +1001,7 @@ CPlane::TestRocketCollision(CVector *rocketPos) return false; } +//--MIAMI: unused // BUG: not in CPlane in the game void CPlane::CreateIncomingCesna(void) @@ -944,6 +1025,7 @@ CPlane::CreateIncomingCesna(void) printf("CPlane::CreateIncomingCesna(void)\n"); } +//--MIAMI: unused void CPlane::CreateDropOffCesna(void) { @@ -966,8 +1048,21 @@ CPlane::CreateDropOffCesna(void) printf("CPlane::CreateDropOffCesna(void)\n"); } +//--MIAMI: all unused const CVector CPlane::FindDrugPlaneCoordinates(void) { return pDrugRunCesna->GetPosition(); } const CVector CPlane::FindDropOffCesnaCoordinates(void) { return pDropOffCesna->GetPosition(); } bool CPlane::HasCesnaLanded(void) { return CesnaMissionStatus == CESNA_STATUS_LANDED; } bool CPlane::HasCesnaBeenDestroyed(void) { return CesnaMissionStatus == CESNA_STATUS_DESTROYED; } bool CPlane::HasDropOffCesnaBeenShotDown(void) { return DropOffCesnaMissionStatus == CESNA_STATUS_DESTROYED; } + +void +CPlane::Load(void) +{ + RemoveTemporaryPlanes(); +} + +void +CPlane::Save(void) +{ + RemoveTemporaryPlanes(); +} |