diff options
Diffstat (limited to '')
-rw-r--r-- | src/vehicles/Plane.cpp.autosave | 985 |
1 files changed, 0 insertions, 985 deletions
diff --git a/src/vehicles/Plane.cpp.autosave b/src/vehicles/Plane.cpp.autosave deleted file mode 100644 index 775cf572..00000000 --- a/src/vehicles/Plane.cpp.autosave +++ /dev/null @@ -1,985 +0,0 @@ -#include "common.h" -#include "main.h" -#include "patcher.h" -#include "General.h" -#include "ModelIndices.h" -#include "FileMgr.h" -#include "Streaming.h" -#include "Replay.h" -#include "Camera.h" -#include "Coronas.h" -#include "Particle.h" -#include "Explosion.h" -#include "World.h" -#include "HandlingMgr.h" -#include "Plane.h" - -CPlaneNode *&pPathNodes = *(CPlaneNode**)0x8F1B68; -CPlaneNode *&pPath2Nodes = *(CPlaneNode**)0x885B8C; -CPlaneNode *&pPath3Nodes = *(CPlaneNode**)0x885B78; -CPlaneNode *&pPath4Nodes = *(CPlaneNode**)0x885AD8; -int32 &NumPathNodes = *(int32*)0x8F2BE4; -int32 &NumPath2Nodes = *(int32*)0x941498; -int32 &NumPath3Nodes = *(int32*)0x9414D8; -int32 &NumPath4Nodes = *(int32*)0x9412C8; -float &TotalLengthOfFlightPath = *(float*)0x8F2C6C; -float &TotalLengthOfFlightPath2 = *(float*)0x64CFBC; -float &TotalLengthOfFlightPath3 = *(float*)0x64CFD0; -float &TotalLengthOfFlightPath4 = *(float*)0x64CFDC; -float &TotalDurationOfFlightPath = *(float*)0x64CFB8; -float &TotalDurationOfFlightPath2 = *(float*)0x64CFC0; -float &TotalDurationOfFlightPath3 = *(float*)0x64CFD4; -float &TotalDurationOfFlightPath4 = *(float*)0x64CFE0; -float &LandingPoint = *(float*)0x8F2C7C; -float &TakeOffPoint = *(float*)0x8E28A4; -CPlaneInterpolationLine *aPlaneLineBits = (CPlaneInterpolationLine*)0x734168; //[6] - -float *PlanePathPosition = (float*)0x8F5FC8; //[3] -float *OldPlanePathPosition = (float*)0x8F5FBC; //[3] -float *PlanePathSpeed = (float*)0x941538; //[3] -float *PlanePath2Position = (float*)0x64CFC4; //[3] -float &PlanePath3Position = *(float*)0x64CFD8; -float &PlanePath4Position = *(float*)0x64CFE4; -float *PlanePath2Speed = (float*)0x8F1A54; //[3] -float &PlanePath3Speed = *(float*)0x8F1A94; -float &PlanePath4Speed = *(float*)0x8F1AFC; - - -enum -{ - CESNA_STATUS_NONE, // doesn't even exist - CESNA_STATUS_FLYING, - CESNA_STATUS_DESTROYED, - CESNA_STATUS_LANDED, -}; - -int32 &CesnaMissionStatus = *(int32*)0x64CFE8; -int32 &CesnaMissionStartTime = *(int32*)0x64CFEC; -CPlane *&pDrugRunCesna = *(CPlane**)0x8F5F80; -int32 &DropOffCesnaMissionStatus = *(int32*)0x64CFF0; -int32 &DropOffCesnaMissionStartTime = *(int32*)0x64CFF4; -CPlane *&pDropOffCesna = *(CPlane**)0x8E2A38; - - -CPlane::CPlane(int32 id, uint8 CreatedBy) - : CVehicle(CreatedBy) -{ - CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id); - m_vehType = VEHICLE_TYPE_PLANE; - pHandling = mod_HandlingManager.GetHandlingData((eHandlingId)mi->m_handlingId); - SetModelIndex(id); - - m_fMass = 100000000.0f; - m_fTurnMass = 100000000.0f; - m_fAirResistance = 0.9994f; - m_fElasticity = 0.05f; - - bUsesCollision = false; - m_bHasBeenHit = false; - m_bIsDrugRunCesna = false; - m_bIsDropOffCesna = false; - - m_status = STATUS_PLANE; - bIsBIGBuilding = true; - m_level = LEVEL_NONE; -} - -CPlane::~CPlane() -{ - DeleteRwObject(); -} - -void -CPlane::SetModelIndex(uint32 id) -{ - CVehicle::SetModelIndex(id); -} - -void -CPlane::DeleteRwObject(void) -{ - if(m_rwObject && RwObjectGetType(m_rwObject) == rpATOMIC){ - m_matrix.Detach(); - if(RwObjectGetType(m_rwObject) == rpATOMIC){ // useless check - RwFrame *f = RpAtomicGetFrame((RpAtomic*)m_rwObject); - RpAtomicDestroy((RpAtomic*)m_rwObject); - RwFrameDestroy(f); - } - m_rwObject = nil; - } - CEntity::DeleteRwObject(); -} - -// There's a LOT of copy and paste in here. Maybe this could be refactored somehow -void -CPlane::ProcessControl(void) -{ - int i; - CVector pos; - - // Explosion - if(m_bHasBeenHit){ - // BUG: since this is all based on frames, you can skip the explosion processing when you go into the menu - if(GetModelIndex() == MI_AIRTRAIN){ - int frm = CTimer::GetFrameCounter() - m_nFrameWhenHit; - if(frm == 20){ - static int nFrameGen; - CRGBA colors[8]; - - CExplosion::AddExplosion(nil, FindPlayerPed(), EXPLOSION_HELI, GetMatrix() * CVector(0.0f, 0.0f, 0.0f), 0); - - colors[0] = CRGBA(0, 0, 0, 255); - colors[1] = CRGBA(224, 230, 238, 255); - colors[2] = CRGBA(224, 230, 238, 255); - colors[3] = CRGBA(0, 0, 0, 255); - colors[4] = CRGBA(224, 230, 238, 255); - colors[5] = CRGBA(0, 0, 0, 255); - colors[6] = CRGBA(0, 0, 0, 255); - colors[7] = CRGBA(224, 230, 238, 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(10, 30); - if(CGeneral::GetRandomNumber() & 1) - rotSpeed = -rotSpeed; - 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); - } - } - if(frm >= 40 && frm <= 80 && frm & 1){ - if(frm & 1){ - pos.x = ((CGeneral::GetRandomNumber() & 0x3F) - 32) * 0.2f; - pos.z = ((CGeneral::GetRandomNumber() & 0x3F) - 32) * 0.2f; - pos.y = frm - 40; - pos = GetMatrix() * pos; - }else{ - pos.x = ((CGeneral::GetRandomNumber() & 0x3F) - 32) * 0.2f; - pos.z = ((CGeneral::GetRandomNumber() & 0x3F) - 32) * 0.2f; - pos.y = 40 - frm; - pos = GetMatrix() * pos; - } - CExplosion::AddExplosion(nil, FindPlayerPed(), EXPLOSION_HELI, pos, 0); - } - if(frm == 60) - bRenderScorched = true; - if(frm == 82){ - TheCamera.SetFadeColour(255, 255, 255); - TheCamera.Fade(0.0f, FADE_OUT); - TheCamera.ProcessFade(); - TheCamera.Fade(1.0f, FADE_IN); - FlagToDestroyWhenNextProcessed(); - } - }else{ - int frm = CTimer::GetFrameCounter() - m_nFrameWhenHit; - if(frm == 20){ - static int nFrameGen; - CRGBA colors[8]; - - CExplosion::AddExplosion(nil, FindPlayerPed(), EXPLOSION_HELI, GetMatrix() * CVector(0.0f, 0.0f, 0.0f), 0); - - colors[0] = CRGBA(0, 0, 0, 255); - colors[1] = CRGBA(224, 230, 238, 255); - colors[2] = CRGBA(224, 230, 238, 255); - colors[3] = CRGBA(0, 0, 0, 255); - colors[4] = CRGBA(252, 66, 66, 255); - colors[5] = CRGBA(0, 0, 0, 255); - colors[6] = CRGBA(0, 0, 0, 255); - colors[7] = CRGBA(252, 66, 66, 255); - - for(i = 0; i < 40; i++){ - 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)), - nil, CGeneral::GetRandomNumberInRange(0.1f, 1.0f), - colors[nFrameGen], rotSpeed, 0, f, 0); - } - } - if(frm >= 40 && frm <= 60 && frm & 1){ - if(frm & 1){ - pos.x = ((CGeneral::GetRandomNumber() & 0x3F) - 32) * 0.1f; - pos.z = ((CGeneral::GetRandomNumber() & 0x3F) - 32) * 0.1f; - pos.y = (frm - 40)*0.3f; - pos = GetMatrix() * pos; - }else{ - pos.x = ((CGeneral::GetRandomNumber() & 0x3F) - 32) * 0.1f; - pos.z = ((CGeneral::GetRandomNumber() & 0x3F) - 32) * 0.1f; - pos.y = (40 - frm)*0.3f; - pos = GetMatrix() * pos; - } - CExplosion::AddExplosion(nil, FindPlayerPed(), EXPLOSION_HELI, pos, 0); - } - if(frm == 30) - bRenderScorched = true; - if(frm == 61){ - TheCamera.SetFadeColour(200, 200, 200); - TheCamera.Fade(0.0f, FADE_OUT); - TheCamera.ProcessFade(); - TheCamera.Fade(1.0f, FADE_IN); - if(m_bIsDrugRunCesna){ - CesnaMissionStatus = CESNA_STATUS_DESTROYED; - pDrugRunCesna = nil; - } - if(m_bIsDropOffCesna){ - DropOffCesnaMissionStatus = CESNA_STATUS_DESTROYED; - pDropOffCesna = nil; - } - FlagToDestroyWhenNextProcessed(); - } - } - } - - // Update plane position and speed - if(GetModelIndex() == MI_AIRTRAIN || !m_isFarAway || ((CTimer::GetFrameCounter() + m_randomSeed) & 7) == 0){ - if(GetModelIndex() == MI_AIRTRAIN){ - float pathPositionRear = PlanePathPosition[m_nPlaneId] - 30.0f; - if(pathPositionRear < 0.0f) - pathPositionRear += TotalLengthOfFlightPath; - float pathPosition = pathPositionRear + 30.0f; - - float pitch = 0.0f; - float distSinceTakeOff = pathPosition - TakeOffPoint; - if(distSinceTakeOff <= 0.0f && distSinceTakeOff > -70.0f){ - // shortly before take off - pitch = 1.0f - distSinceTakeOff/-70.0f; - }else if(distSinceTakeOff >= 0.0f && distSinceTakeOff < 100.0f){ - // shortly after take off - pitch = 1.0f - distSinceTakeOff/100.0f; - } - - float distSinceLanding = pathPosition - LandingPoint; - if(distSinceLanding <= 0.0f && distSinceLanding > -200.0f){ - // shortly before landing - pitch = 1.0f - distSinceLanding/-200.0f; - }else if(distSinceLanding >= 0.0f && distSinceLanding < 70.0f){ - // shortly after landing - pitch = 1.0f - distSinceLanding/70.0f; - } - - - // Advance current node to appropriate position - float pos1, pos2; - int nextTrackNode = m_nCurPathNode + 1; - pos1 = pPathNodes[m_nCurPathNode].t; - if(nextTrackNode < NumPathNodes) - pos2 = pPathNodes[nextTrackNode].t; - else{ - nextTrackNode = 0; - pos2 = TotalLengthOfFlightPath; - } - while(pathPositionRear < pos1 || pathPositionRear > pos2){ - m_nCurPathNode = (m_nCurPathNode+1) % NumPathNodes; - nextTrackNode = m_nCurPathNode + 1; - pos1 = pPathNodes[m_nCurPathNode].t; - if(nextTrackNode < NumPathNodes) - pos2 = pPathNodes[nextTrackNode].t; - else{ - nextTrackNode = 0; - pos2 = TotalLengthOfFlightPath; - } - } - bool bothOnGround = pPathNodes[m_nCurPathNode].bOnGround && pPathNodes[nextTrackNode].bOnGround; - if(PlanePathPosition[m_nPlaneId] >= LandingPoint && OldPlanePathPosition[m_nPlaneId] < LandingPoint) - DMAudio.PlayOneShot(m_audioEntityId, SOUND_PLANE_ON_GROUND, 0.0f); - float dist = pPathNodes[nextTrackNode].t - pPathNodes[m_nCurPathNode].t; - if(dist < 0.0f) - dist += TotalLengthOfFlightPath; - float f = (pathPositionRear - pPathNodes[m_nCurPathNode].t)/dist; - CVector posRear = (1.0f - f)*pPathNodes[m_nCurPathNode].p + f*pPathNodes[nextTrackNode].p; - - // Same for the front - float pathPositionFront = pathPositionRear + 60.0f; - if(pathPositionFront > TotalLengthOfFlightPath) - pathPositionFront -= TotalLengthOfFlightPath; - int curPathNodeFront = m_nCurPathNode; - int nextPathNodeFront = curPathNodeFront + 1; - pos1 = pPathNodes[curPathNodeFront].t; - if(nextPathNodeFront < NumPathNodes) - pos2 = pPathNodes[nextPathNodeFront].t; - else{ - nextPathNodeFront = 0; - pos2 = TotalLengthOfFlightPath; - } - while(pathPositionFront < pos1 || pathPositionFront > pos2){ - curPathNodeFront = (curPathNodeFront+1) % NumPathNodes; - nextPathNodeFront = curPathNodeFront + 1; - pos1 = pPathNodes[curPathNodeFront].t; - if(nextPathNodeFront < NumPathNodes) - pos2 = pPathNodes[nextPathNodeFront].t; - else{ - nextPathNodeFront = 0; - pos2 = TotalLengthOfFlightPath; - } - } - dist = pPathNodes[nextPathNodeFront].t - pPathNodes[curPathNodeFront].t; - if(dist < 0.0f) - dist += TotalLengthOfFlightPath; - f = (pathPositionFront - pPathNodes[curPathNodeFront].t)/dist; - CVector posFront = (1.0f - f)*pPathNodes[curPathNodeFront].p + f*pPathNodes[nextPathNodeFront].p; - - // And for another point 60 units in front of the plane, used to calculate roll - float pathPositionFront2 = pathPositionFront + 60.0f; - if(pathPositionFront2 > TotalLengthOfFlightPath) - pathPositionFront2 -= TotalLengthOfFlightPath; - int curPathNodeFront2 = m_nCurPathNode; - int nextPathNodeFront2 = curPathNodeFront2 + 1; - pos1 = pPathNodes[curPathNodeFront2].t; - if(nextPathNodeFront2 < NumPathNodes) - pos2 = pPathNodes[nextPathNodeFront2].t; - else{ - nextPathNodeFront2 = 0; - pos2 = TotalLengthOfFlightPath; - } - while(pathPositionFront2 < pos1 || pathPositionFront2 > pos2){ - curPathNodeFront2 = (curPathNodeFront2+1) % NumPathNodes; - nextPathNodeFront2 = curPathNodeFront2 + 1; - pos1 = pPathNodes[curPathNodeFront2].t; - if(nextPathNodeFront2 < NumPathNodes) - pos2 = pPathNodes[nextPathNodeFront2].t; - else{ - nextPathNodeFront2 = 0; - pos2 = TotalLengthOfFlightPath; - } - } - dist = pPathNodes[nextPathNodeFront2].t - pPathNodes[curPathNodeFront2].t; - if(dist < 0.0f) - dist += TotalLengthOfFlightPath; - f = (pathPositionFront2 - pPathNodes[curPathNodeFront2].t)/dist; - CVector posFront2 = (1.0f - f)*pPathNodes[curPathNodeFront2].p + f*pPathNodes[nextPathNodeFront2].p; - - // Now set matrix - GetPosition() = (posRear + posFront)/2.0f; - GetPosition().z += 4.3f; - CVector fwd = posFront - posRear; - fwd.Normalise(); - if(pitch != 0.0f){ - fwd.z += 0.4f*pitch; - fwd.Normalise(); - } - CVector fwd2 = posFront2 - posRear; - fwd2.Normalise(); - CVector roll = CrossProduct(fwd, fwd2); - CVector right = CrossProduct(fwd, CVector(0.0f, 0.0f, 1.0f)); - if(!bothOnGround) - right.z += 3.0f*roll.z; - right.Normalise(); - CVector up = CrossProduct(right, fwd); - GetRight() = right; - GetUp() = up; - 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)); - }else{ - float planePathPosition; - float totalLengthOfFlightPath; - CPlaneNode *pathNodes; - float planePathSpeed; - int numPathNodes; - - if(m_bIsDrugRunCesna){ - planePathPosition = PlanePath3Position; - totalLengthOfFlightPath = TotalLengthOfFlightPath3; - pathNodes = pPath3Nodes; - planePathSpeed = PlanePath3Speed; - numPathNodes = NumPath3Nodes; - if(CesnaMissionStatus == CESNA_STATUS_LANDED){ - pDrugRunCesna = false; - FlagToDestroyWhenNextProcessed(); - } - }else if(m_bIsDropOffCesna){ - planePathPosition = PlanePath4Position; - totalLengthOfFlightPath = TotalLengthOfFlightPath4; - pathNodes = pPath4Nodes; - planePathSpeed = PlanePath4Speed; - numPathNodes = NumPath4Nodes; - if(DropOffCesnaMissionStatus == CESNA_STATUS_LANDED){ - pDropOffCesna = false; - FlagToDestroyWhenNextProcessed(); - } - }else{ - planePathPosition = PlanePath2Position[m_nPlaneId]; - totalLengthOfFlightPath = TotalLengthOfFlightPath2; - pathNodes = pPath2Nodes; - planePathSpeed = PlanePath2Speed[m_nPlaneId]; - numPathNodes = NumPath2Nodes; - } - - // Advance current node to appropriate position - float pathPositionRear = planePathPosition - 10.0f; - if(pathPositionRear < 0.0f) - pathPositionRear += totalLengthOfFlightPath; - float pos1, pos2; - int nextTrackNode = m_nCurPathNode + 1; - pos1 = pathNodes[m_nCurPathNode].t; - if(nextTrackNode < numPathNodes) - pos2 = pathNodes[nextTrackNode].t; - else{ - nextTrackNode = 0; - pos2 = totalLengthOfFlightPath; - } - while(pathPositionRear < pos1 || pathPositionRear > pos2){ - m_nCurPathNode = (m_nCurPathNode+1) % numPathNodes; - nextTrackNode = m_nCurPathNode + 1; - pos1 = pathNodes[m_nCurPathNode].t; - if(nextTrackNode < numPathNodes) - pos2 = pathNodes[nextTrackNode].t; - else{ - nextTrackNode = 0; - pos2 = totalLengthOfFlightPath; - } - } - float dist = pathNodes[nextTrackNode].t - pathNodes[m_nCurPathNode].t; - if(dist < 0.0f) - dist += totalLengthOfFlightPath; - float f = (pathPositionRear - pathNodes[m_nCurPathNode].t)/dist; - CVector posRear = (1.0f - f)*pathNodes[m_nCurPathNode].p + f*pathNodes[nextTrackNode].p; - - // Same for the front - float pathPositionFront = pathPositionRear + 20.0f; - if(pathPositionFront > totalLengthOfFlightPath) - pathPositionFront -= totalLengthOfFlightPath; - int curPathNodeFront = m_nCurPathNode; - int nextPathNodeFront = curPathNodeFront + 1; - pos1 = pathNodes[curPathNodeFront].t; - if(nextPathNodeFront < numPathNodes) - pos2 = pathNodes[nextPathNodeFront].t; - else{ - nextPathNodeFront = 0; - pos2 = totalLengthOfFlightPath; - } - while(pathPositionFront < pos1 || pathPositionFront > pos2){ - curPathNodeFront = (curPathNodeFront+1) % numPathNodes; - nextPathNodeFront = curPathNodeFront + 1; - pos1 = pathNodes[curPathNodeFront].t; - if(nextPathNodeFront < numPathNodes) - pos2 = pathNodes[nextPathNodeFront].t; - else{ - nextPathNodeFront = 0; - pos2 = totalLengthOfFlightPath; - } - } - dist = pathNodes[nextPathNodeFront].t - pathNodes[curPathNodeFront].t; - if(dist < 0.0f) - dist += totalLengthOfFlightPath; - 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 - float pathPositionFront2 = pathPositionFront + 30.0f; - if(pathPositionFront2 > totalLengthOfFlightPath) - pathPositionFront2 -= totalLengthOfFlightPath; - int curPathNodeFront2 = m_nCurPathNode; - int nextPathNodeFront2 = curPathNodeFront2 + 1; - pos1 = pathNodes[curPathNodeFront2].t; - if(nextPathNodeFront2 < numPathNodes) - pos2 = pathNodes[nextPathNodeFront2].t; - else{ - nextPathNodeFront2 = 0; - pos2 = totalLengthOfFlightPath; - } - while(pathPositionFront2 < pos1 || pathPositionFront2 > pos2){ - curPathNodeFront2 = (curPathNodeFront2+1) % numPathNodes; - nextPathNodeFront2 = curPathNodeFront2 + 1; - pos1 = pathNodes[curPathNodeFront2].t; - if(nextPathNodeFront2 < numPathNodes) - pos2 = pathNodes[nextPathNodeFront2].t; - else{ - nextPathNodeFront2 = 0; - pos2 = totalLengthOfFlightPath; - } - } - dist = pathNodes[nextPathNodeFront2].t - pathNodes[curPathNodeFront2].t; - if(dist < 0.0f) - dist += totalLengthOfFlightPath; - f = (pathPositionFront2 - pathNodes[curPathNodeFront2].t)/dist; - CVector posFront2 = (1.0f - f)*pathNodes[curPathNodeFront2].p + f*pathNodes[nextPathNodeFront2].p; - - // Now set matrix - GetPosition() = (posRear + posFront)/2.0f; - GetPosition().z += 1.0f; - CVector fwd = posFront - posRear; - fwd.Normalise(); - CVector fwd2 = posFront2 - posRear; - fwd2.Normalise(); - CVector roll = CrossProduct(fwd, fwd2); - CVector right = CrossProduct(fwd, CVector(0.0f, 0.0f, 1.0f)); - right.z += 3.0f*roll.z; - right.Normalise(); - CVector up = CrossProduct(right, fwd); - GetRight() = right; - GetUp() = up; - GetForward() = fwd; - - // Set speed - m_vecMoveSpeed = fwd*planePathSpeed/60.0f; - m_fSpeed = planePathSpeed/60.0f; - m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f); - - m_isFarAway = !((posFront - TheCamera.GetPosition()).Magnitude2D() < sq(300.0f)); - } - } - - bIsInSafePosition = true; - GetMatrix().UpdateRW(); - UpdateRwFrame(); - - // Handle streaming and such - CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); - if(m_isFarAway){ - // Switch to LOD model - if(m_rwObject && RwObjectGetType(m_rwObject) == rpCLUMP){ - DeleteRwObject(); - if(mi->m_planeLodId != -1){ - m_rwObject = CModelInfo::GetModelInfo(mi->m_planeLodId)->CreateInstance(); - if(m_rwObject) - m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject))); - } - } - }else if(CStreaming::HasModelLoaded(GetModelIndex())){ - if(m_rwObject && RwObjectGetType(m_rwObject) == rpATOMIC){ - // Get rid of LOD model - m_matrix.Detach(); - if(m_rwObject){ // useless check - if(RwObjectGetType(m_rwObject) == rpATOMIC){ // useless check - RwFrame *f = RpAtomicGetFrame((RpAtomic*)m_rwObject); - RpAtomicDestroy((RpAtomic*)m_rwObject); - RwFrameDestroy(f); - } - m_rwObject = nil; - } - } - // Set high detail model - if(m_rwObject == nil){ - int id = GetModelIndex(); - m_modelIndex = -1; - SetModelIndex(id); - } - }else{ - CStreaming::RequestModel(GetModelIndex(), STREAMFLAGS_DEPENDENCY); - } -} - -void -CPlane::PreRender(void) -{ - CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); - - CVector lookVector = GetPosition() - TheCamera.GetPosition(); - float camDist = lookVector.Magnitude(); - if(camDist != 0.0f) - lookVector *= 1.0f/camDist; - else - lookVector = CVector(1.0f, 0.0f, 0.0f); - float behindness = DotProduct(lookVector, GetForward()); - - // Wing lights - if(behindness < 0.0f){ - // in front of plane - CVector lightPos = mi->m_positions[PLANE_POS_LIGHT_RIGHT]; - CVector lightR = GetMatrix() * lightPos; - CVector lightL = lightR; - lightL -= GetRight()*2.0f*lightPos.x; - - float intensity = -0.6f*behindness + 0.4f; - float size = 1.0f - behindness; - - if(behindness < -0.9f && camDist < 50.0f){ - // directly in front - CCoronas::RegisterCorona((uintptr)this + 10, 255*intensity, 255*intensity, 255*intensity, 255, - lightL, size, 240.0f, - CCoronas::TYPE_NORMAL, CCoronas::FLARE_HEADLIGHTS, CCoronas::REFLECTION_ON, - CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f); - CCoronas::RegisterCorona((uintptr)this + 11, 255*intensity, 255*intensity, 255*intensity, 255, - lightR, size, 240.0f, - CCoronas::TYPE_NORMAL, CCoronas::FLARE_HEADLIGHTS, CCoronas::REFLECTION_ON, - CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f); - }else{ - CCoronas::RegisterCorona((uintptr)this + 10, 255*intensity, 255*intensity, 255*intensity, 255, - lightL, size, 240.0f, - CCoronas::TYPE_NORMAL, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, - CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f); - CCoronas::RegisterCorona((uintptr)this + 11, 255*intensity, 255*intensity, 255*intensity, 255, - lightR, size, 240.0f, - CCoronas::TYPE_NORMAL, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, - CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f); - } - } - - // Tail light - if(CTimer::GetTimeInMilliseconds() & 0x200){ - CVector pos = GetMatrix() * mi->m_positions[PLANE_POS_LIGHT_TAIL]; - - CCoronas::RegisterCorona((uintptr)this + 12, 255, 0, 0, 255, - pos, 1.0f, 120.0f, - CCoronas::TYPE_NORMAL, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, - CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f); - } -} - -void -CPlane::Render(void) -{ - CEntity::Render(); -} - -#define CRUISE_SPEED (50.0f) -#define TAXI_SPEED (5.0f) - -void -CPlane::InitPlanes(void) -{ - int i; - - CesnaMissionStatus = CESNA_STATUS_NONE; - - // Jumbo - if(pPathNodes == nil){ - 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; - pPathNodes[i].bOnGround = true; - }else - pPathNodes[i].bOnGround = false; - } - - // Find lading and takeoff points - LandingPoint = -1.0f; - TakeOffPoint = -1.0f; - bool lastOnGround = pPathNodes[NumPathNodes-1].bOnGround; - for(i = 0; i < NumPathNodes; i++){ - if(pPathNodes[i].bOnGround && !lastOnGround) - LandingPoint = pPathNodes[i].t; - else if(!pPathNodes[i].bOnGround && lastOnGround) - TakeOffPoint = pPathNodes[i].t; - lastOnGround = pPathNodes[i].bOnGround; - } - - // Animation - float time = 0.0f; - float position = 0.0f; - // Start on ground with slow speed - aPlaneLineBits[0].type = 1; - aPlaneLineBits[0].time = time; - aPlaneLineBits[0].position = position; - aPlaneLineBits[0].speed = TAXI_SPEED; - aPlaneLineBits[0].acceleration = 0.0f; - float dist = (TakeOffPoint-600.0f) - position; - time += dist/TAXI_SPEED; - position += dist; - - // Accelerate to take off - aPlaneLineBits[1].type = 2; - 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; - - // Fly at cruise speed - aPlaneLineBits[2].type = 1; - aPlaneLineBits[2].time = time; - aPlaneLineBits[2].position = position; - aPlaneLineBits[2].speed = CRUISE_SPEED; - aPlaneLineBits[2].acceleration = 0.0f; - dist = LandingPoint - TakeOffPoint; - time += dist/CRUISE_SPEED; - position += dist; - - // Brake after landing - aPlaneLineBits[3].type = 2; - 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; - - // Taxi - aPlaneLineBits[4].type = 1; - aPlaneLineBits[4].time = time; - aPlaneLineBits[4].position = position; - aPlaneLineBits[4].speed = TAXI_SPEED; - aPlaneLineBits[4].acceleration = 0.0f; - time += (TotalLengthOfFlightPath - position)/TAXI_SPEED; - - // end - aPlaneLineBits[5].time = time; - TotalDurationOfFlightPath = time; - } - - // Dodo - if(pPath2Nodes == nil){ - pPath2Nodes = LoadPath("data\\paths\\flight2.dat", NumPath2Nodes, TotalLengthOfFlightPath2, true); - TotalDurationOfFlightPath2 = TotalLengthOfFlightPath2/CRUISE_SPEED; - } - - // Mission Cesna - 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); - - for(i = 0; i < 3; i++){ - CPlane *plane = new CPlane(MI_AIRTRAIN, PERMANENT_VEHICLE); - plane->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f); - plane->m_status = STATUS_ABANDONED; - plane->bIsLocked = true; - plane->m_nPlaneId = i; - 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->m_status = STATUS_ABANDONED; - plane->bIsLocked = true; - plane->m_nPlaneId = i; - plane->m_nCurPathNode = 0; - CWorld::Add(plane); - } -} - -void -CPlane::Shutdown(void) -{ - delete[] pPathNodes; - delete[] pPath2Nodes; - delete[] pPath3Nodes; - delete[] pPath4Nodes; - pPathNodes = nil; - pPath2Nodes = nil; - pPath3Nodes = nil; - pPath4Nodes = nil; -} - -CPlaneNode* -CPlane::LoadPath(char const *filename, int32 &numNodes, float &totalLength, bool loop) -{ - int bp, lp; - int i; - - CFileMgr::LoadFile(filename, work_buff, sizeof(work_buff), "r"); - *gString = '\0'; - for(bp = 0, lp = 0; work_buff[bp] != '\n'; bp++, lp++) - gString[lp] = work_buff[bp]; - bp++; - gString[lp] = '\0'; - sscanf(gString, "%d", &numNodes); - CPlaneNode *nodes = new CPlaneNode[numNodes]; - - for(i = 0; i < numNodes; i++){ - *gString = '\0'; - for(lp = 0; work_buff[bp] != '\n'; bp++, lp++) - gString[lp] = work_buff[bp]; - bp++; - // BUG: game doesn't terminate string - gString[lp] = '\0'; - sscanf(gString, "%f %f %f", &nodes[i].p.x, &nodes[i].p.y, &nodes[i].p.z); - } - - // Calculate length of segments and path - totalLength = 0.0f; - for(i = 0; i < numNodes; i++){ - nodes[i].t = totalLength; - float l = (nodes[(i+1) % numNodes].p - nodes[i].p).Magnitude2D(); - if(!loop && i == numNodes-1) - l = 0.0f; - totalLength += l; - } - - return nodes; -} - -void -CPlane::UpdatePlanes(void) -{ - int i, j; - uint32 time; - float t, deltaT; - - if(CReplay::IsPlayingBack()) - return; - - // Jumbo jets - time = CTimer::GetTimeInMilliseconds(); - for(i = 0; i < 3; i++){ - t = TotalDurationOfFlightPath * (float)(time & 0x7FFFF)/0x80000; - // find current frame - for(j = 0; t > aPlaneLineBits[j+1].time; j++); - - OldPlanePathPosition[i] = PlanePathPosition[i]; - deltaT = t - aPlaneLineBits[j].time; - switch(aPlaneLineBits[j].type){ - case 0: // standing still - PlanePathPosition[i] = aPlaneLineBits[j].position; - PlanePathSpeed[i] = 0.0f; - break; - case 1: // moving with constant speed - PlanePathPosition[i] = aPlaneLineBits[j].position + aPlaneLineBits[j].speed*deltaT; - PlanePathSpeed[i] = (TotalDurationOfFlightPath*1000.0f/0x80000) * aPlaneLineBits[j].speed; - break; - case 2: // accelerating/braking - PlanePathPosition[i] = aPlaneLineBits[j].position + (aPlaneLineBits[j].speed + aPlaneLineBits[j].acceleration*deltaT)*deltaT; - PlanePathSpeed[i] = (TotalDurationOfFlightPath*1000.0f/0x80000)*aPlaneLineBits[j].speed + 2.0f*aPlaneLineBits[j].acceleration*deltaT; - break; - } - - // time offset for each plane - time += 0x80000/3; - } - - time = CTimer::GetTimeInMilliseconds(); - - 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; - PlanePath2Speed[0] = CRUISE_SPEED*t; - PlanePath2Speed[1] = CRUISE_SPEED*t; - PlanePath2Speed[2] = CRUISE_SPEED*t; - - if(CesnaMissionStatus == CESNA_STATUS_FLYING){ - PlanePath3Speed = CRUISE_SPEED*TotalDurationOfFlightPath3/0x20000; - PlanePath3Position = PlanePath3Speed * ((time - CesnaMissionStartTime) & 0x1FFFF); - if(time - CesnaMissionStartTime >= 128072) - CesnaMissionStatus = CESNA_STATUS_LANDED; - } - - if(DropOffCesnaMissionStatus == CESNA_STATUS_FLYING){ - PlanePath4Speed = CRUISE_SPEED*TotalDurationOfFlightPath4/0x80000; - PlanePath4Position = PlanePath4Speed * ((time - DropOffCesnaMissionStartTime) & 0x7FFFF); - if(time - DropOffCesnaMissionStartTime >= 521288) - DropOffCesnaMissionStatus = CESNA_STATUS_LANDED; - } -} - -bool -CPlane::TestRocketCollision(CVector *rocketPos) -{ - int i; - - i = CPools::GetVehiclePool()->GetSize(); - while(--i >= 0){ - CPlane *plane = (CPlane*)CPools::GetVehiclePool()->GetSlot(i); - if(plane && -#ifdef EXPLODING_AIRTRAIN - (plane->GetModelIndex() == MI_AIRTRAIN || plane->GetModelIndex() == MI_DODO) && -#else - plane->GetModelIndex() != MI_AIRTRAIN && plane->GetModelIndex() == MI_DODO && // strange check -#endif - !plane->m_bHasBeenHit && (*rocketPos - plane->GetPosition()).Magnitude() < 25.0f){ - plane->m_nFrameWhenHit = CTimer::GetFrameCounter(); - plane->m_bHasBeenHit = true; - CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->RegisterCrime_Immediately(CRIME_DESTROYED_CESSNA, - plane->GetPosition(), i+1983, false); - return true; - } - } - return false; -} - -// BUG: not in CPlane in the game -void -CPlane::CreateIncomingCesna(void) -{ - if(CesnaMissionStatus == CESNA_STATUS_FLYING){ - CWorld::Remove(pDrugRunCesna); - delete pDrugRunCesna; - pDrugRunCesna = nil; - } - pDrugRunCesna = new CPlane(MI_DEADDODO, PERMANENT_VEHICLE); - pDrugRunCesna->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f); - pDrugRunCesna->m_status = STATUS_ABANDONED; - pDrugRunCesna->bIsLocked = true; - pDrugRunCesna->m_nPlaneId = 0; - pDrugRunCesna->m_nCurPathNode = 0; - pDrugRunCesna->m_bIsDrugRunCesna = true; - CWorld::Add(pDrugRunCesna); - - CesnaMissionStatus = CESNA_STATUS_FLYING; - CesnaMissionStartTime = CTimer::GetTimeInMilliseconds(); - printf("CPlane::CreateIncomingCesna(void)\n"); -} - -void -CPlane::CreateDropOffCesna(void) -{ - if(DropOffCesnaMissionStatus == CESNA_STATUS_FLYING){ - CWorld::Remove(pDropOffCesna); - delete pDropOffCesna; - pDropOffCesna = nil; - } - pDropOffCesna = new CPlane(MI_DEADDODO, PERMANENT_VEHICLE); - pDropOffCesna->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f); - pDropOffCesna->m_status = STATUS_ABANDONED; - pDropOffCesna->bIsLocked = true; - pDropOffCesna->m_nPlaneId = 0; - pDropOffCesna->m_nCurPathNode = 0; - pDropOffCesna->m_bIsDropOffCesna = true; - CWorld::Add(pDropOffCesna); - - DropOffCesnaMissionStatus = CESNA_STATUS_FLYING; - DropOffCesnaMissionStartTime = CTimer::GetTimeInMilliseconds(); - printf("CPlane::CreateDropOffCesna(void)\n"); -} - -CVector CPlane::FindDrugPlaneCoordinates(void) { return pDrugRunCesna->GetPosition(); } -CVector CPlane::FindDropOffCesnaCoordinates(void) { return pDrugRunCesna->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; } - - -class CPlane_ : public CPlane -{ -public: - void ctor(int32 id, uint8 CreatedBy) { ::new (this) CPlane(id, CreatedBy); } - void dtor(void) { CPlane::~CPlane(); } -}; - -STARTPATCHES - InjectHook(0x54B170, &CPlane_::ctor, PATCH_JUMP); - InjectHook(0x54B270, &CPlane_::dtor, PATCH_JUMP); - InjectHook(0x54B820, CPlane::InitPlanes, PATCH_JUMP); - InjectHook(0x54BCD0, CPlane::Shutdown, PATCH_JUMP); - InjectHook(0x54BD50, CPlane::LoadPath, PATCH_JUMP); - InjectHook(0x54BEC0, CPlane::UpdatePlanes, PATCH_JUMP); - InjectHook(0x54DE90, CPlane::TestRocketCollision, PATCH_JUMP); - InjectHook(0x54E000, CPlane::CreateIncomingCesna, PATCH_JUMP); - InjectHook(0x54E160, CPlane::CreateDropOffCesna, PATCH_JUMP); -ENDPATCHES |