コード例 #1
0
void CTranscendenceWnd::DestroyIntroShips (void)

//	DestroyIntroShips
//
//	Destroys all ships of the same class as the POV

	{
	int i;

	CShip *pShip = g_pUniverse->GetPOV()->AsShip();
	if (pShip == NULL)
		return;

	//	Destroy all ships of the current class

	CSystem *pSystem = pShip->GetSystem();
	CShipClass *pClassToDestroy = pShip->GetClass();
	TArray<CSpaceObject *> ShipsToDestroy;
	CSpaceObject *pOtherShip = NULL;
	for (i = 0; i < pSystem->GetObjectCount(); i++)
		{
		CSpaceObject *pObj = pSystem->GetObject(i);
		CShip *pShip;
		if (pObj 
				&& !pObj->IsInactive()
				&& !pObj->IsVirtual()
				&& (pShip = pObj->AsShip()))
			{
			if (pShip->GetClass() == pClassToDestroy)
				ShipsToDestroy.Insert(pObj);
			else if (pOtherShip == NULL)
				pOtherShip = pObj;
			}
		}

	//	Destroy ships

	for (i = 0; i < ShipsToDestroy.GetCount(); i++)
		ShipsToDestroy[i]->Destroy(removedFromSystem, CDamageSource());
	}
コード例 #2
0
void CTranscendenceWnd::Animate (bool bTopMost)

//	Animate
//
//	Called on each frame

	{
	bool bFailed = false;
	CG16bitImage &TheScreen = g_pHI->GetScreen();

	try
		{
		SetProgramState(psAnimating);

		//	Do the appropriate thing

		switch (m_State)
			{
			case gsIntro:
				AnimateIntro(bTopMost);
				break;

			case gsProlog:
				AnimateProlog(bTopMost);
				break;

			case gsInGame:
			case gsDestroyed:
				{
				DWORD dwStartTimer;
				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					dwStartTimer = ::GetTickCount();

				//	Figure out some stats

				bool bBlind = false;
				bool bSRSEnhanced = false;
				bool bShowMapHUD = false;
				CShip *pShip = NULL;
				if (GetPlayer())
					{
					pShip = GetPlayer()->GetShip();
					bBlind = pShip->IsBlind();
					bSRSEnhanced = pShip->IsSRSEnhanced();
					bShowMapHUD = GetPlayer()->IsMapHUDActive();
					}

				//	Update some displays

				if ((m_iTick % 7) == 0)
					{
					SetProgramState(psUpdatingReactorDisplay);
					m_ReactorDisplay.Update();
					SetProgramState(psAnimating);
					}

				//	If we're showing damage flash, fill the screen

				if (m_iDamageFlash > 0 && (m_iDamageFlash % 2) == 0)
					{
					TheScreen.Fill(0, 0, g_cxScreen, g_cyScreen, CG16bitImage::RGBValue(128,0,0));
					if (pShip && pShip->GetSystem())
						{
						if (m_bShowingMap)
							g_pUniverse->PaintObjectMap(TheScreen, m_rcMainScreen, pShip);
						else
							g_pUniverse->PaintObject(TheScreen, m_rcMainScreen, pShip);
						}
					}

				//	Otherwise, if we're in map mode, paint the map

				else if (m_bShowingMap)
					{
					SetProgramState(psPaintingMap);
					PaintMap();
					SetProgramState(psAnimating);
					}

				//	Otherwise, if we're blind, paint scramble

				else if (bBlind 
						&& (m_iTick % (20 + (((m_iTick / 100) * pShip->GetDestiny()) % 100))) > 15)
					PaintSRSSnow();

				//	Otherwise, paint the normal SRS screen

				else
					{
					SetProgramState(psPaintingSRS);
					g_pUniverse->PaintPOV(TheScreen, m_rcMainScreen, bSRSEnhanced);
					SetProgramState(psAnimating);

					PaintMainScreenBorder();
					}

				if (m_iDamageFlash > 0)
					m_iDamageFlash--;

				//	Paint various displays

				SetProgramState(psPaintingLRS);
				PaintLRS();

				if (!m_bShowingMap || bShowMapHUD)
					{
					SetProgramState(psPaintingArmorDisplay);
					m_ArmorDisplay.Paint(TheScreen);

					SetProgramState(psPaintingReactorDisplay);
					m_ReactorDisplay.Paint(TheScreen);

					SetProgramState(psPaintingTargetDisplay);
					m_TargetDisplay.Paint(TheScreen);

					SetProgramState(psPaintingDeviceDisplay);
					m_DeviceDisplay.Paint(TheScreen);
					}

				if (m_CurrentPicker == pickNone)
					{
					SetProgramState(psPaintingMessageDisplay);
					m_MessageDisplay.Paint(TheScreen);
					}

				SetProgramState(psAnimating);

				if (m_CurrentMenu != menuNone)
					m_MenuDisplay.Paint(TheScreen);
				if (m_CurrentPicker != pickNone)
					m_PickerDisplay.Paint(TheScreen);
				if (m_bDebugConsole)
					m_DebugConsole.Paint(TheScreen);

#ifdef DEBUG_LINE_OF_FIRE
				if (GetPlayer())
					{
					if (!GetPlayer()->GetShip()->IsLineOfFireClear(GetPlayer()->GetShip()->GetPos(),
							NULL,
							GetPlayer()->GetShip()->GetRotation()))
						g_pUniverse->DebugOutput("line of fire blocked");
					}
#endif
#ifdef DEBUG
				PaintDebugLines();
#endif

				//	Figure out how long it took to paint

				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					{
					DWORD dwNow = ::GetTickCount();
					m_iPaintTime[m_iFrameCount % FRAME_RATE_COUNT] = dwNow - dwStartTimer;
					dwStartTimer = dwNow;
					}

				//	Some debug information

				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					PaintFrameRate();

				//	Update the screen

				if (bTopMost)
					g_pHI->GetScreenMgr().Blt();

				//	Figure out how long it took to blt

				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					{
					DWORD dwNow = ::GetTickCount();
					m_iBltTime[m_iFrameCount % FRAME_RATE_COUNT] = dwNow - dwStartTimer;
					dwStartTimer = dwNow;
					}

				//	Update the universe

				if (!m_bPaused || m_bPausedStep)
					{
					SetProgramState(psUpdating);
					g_pUniverse->Update(g_SecondsPerUpdate);
					if (m_bAutopilot)
						{
						g_pUniverse->Update(g_SecondsPerUpdate);
						g_pUniverse->Update(g_SecondsPerUpdate);
						g_pUniverse->Update(g_SecondsPerUpdate);
						g_pUniverse->Update(g_SecondsPerUpdate);
						}
					SetProgramState(psAnimating);

					if (GetPlayer())
						GetPlayer()->Update(m_iTick);
					if (GetPlayer() && GetPlayer()->GetSelectedTarget())
						m_TargetDisplay.Invalidate();
					m_iTick++;

					m_bPausedStep = false;
					}

				m_MessageDisplay.Update();

				//	Figure out how long it took to update

				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					{
					DWORD dwNow = ::GetTickCount();
					m_iUpdateTime[m_iFrameCount % FRAME_RATE_COUNT] = dwNow - dwStartTimer;
					dwStartTimer = dwNow;
					}

				//	Destroyed?

				if (m_State == gsDestroyed)
					{
					if (!m_bPaused || m_bPausedStep)
						{
						if (--m_iCountdown == 0)
							g_pHI->HICommand(CONSTLIT("gameEndDestroyed"));
						m_bPausedStep = false;
						}
					}

				break;
				}

			case gsDocked:
				{
				//	Paint the screen

				m_pCurrentScreen->Paint(TheScreen);
				m_pCurrentScreen->Update();
				PaintMainScreenBorder();
				m_ArmorDisplay.Paint(TheScreen);
				m_TargetDisplay.Paint(TheScreen);

				//	Debug console

				if (m_bDebugConsole)
					m_DebugConsole.Paint(TheScreen);

				//	We don't paint the LRS because the player doesn't need it and
				//	because it overwrites the credits/cargo space display
				//PaintLRS();

				//	Update the screen

				if (bTopMost)
					g_pHI->GetScreenMgr().Blt();

				//	Update the universe (at 1/4 rate)

				if ((m_iTick % 4) == 0)
					g_pUniverse->Update(g_SecondsPerUpdate);
				m_MessageDisplay.Update();
				m_CurrentDock.Update(m_iTick);
				m_iTick++;

				//	Invalidate areas of the screen that are overlapped by
				//	the displays. Note that we need to convert to main screen
				//	coordinates.

				if (m_pCurrentScreen)
					{
					RECT rcRect = m_ArmorDisplay.GetRect();
					::OffsetRect(&rcRect, -m_rcMainScreen.left, -m_rcMainScreen.top);
					m_pCurrentScreen->Invalidate(rcRect);

					rcRect = m_TargetDisplay.GetRect();
					::OffsetRect(&rcRect, -m_rcMainScreen.left, -m_rcMainScreen.top);
					m_pCurrentScreen->Invalidate(rcRect);

					rcRect = m_rcLRS;
					::OffsetRect(&rcRect, -m_rcMainScreen.left, -m_rcMainScreen.top);
					m_pCurrentScreen->Invalidate(rcRect);

					if (m_bDebugConsole)
						{
						rcRect = m_DebugConsole.GetRect();
						::OffsetRect(&rcRect, -m_rcMainScreen.left, -m_rcMainScreen.top);
						m_pCurrentScreen->Invalidate(rcRect);
						}
					}

				break;
				}

			case gsEnteringStargate:
				{
				//	Update some displays

				if ((m_iTick % 10) == 0)
					m_ReactorDisplay.Update();

				//	Tell the universe to paint

				g_pUniverse->PaintPOV(TheScreen, m_rcMainScreen, false);
				PaintMainScreenBorder();
				PaintLRS();
				m_ArmorDisplay.Paint(TheScreen);
				m_MessageDisplay.Paint(TheScreen);
				m_ReactorDisplay.Paint(TheScreen);
				m_TargetDisplay.Paint(TheScreen);
				m_DeviceDisplay.Paint(TheScreen);

				//	Debug information

				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					PaintFrameRate();

#ifdef DEBUG
				PaintDebugLines();
#endif

				//	Update the screen

				if (bTopMost)
					g_pHI->GetScreenMgr().Blt();

				//	Update the universe

				g_pUniverse->Update(g_SecondsPerUpdate);
				m_MessageDisplay.Update();
				m_iTick++;

				if (--m_iCountdown == 0)
					EnterStargate();
				break;
				}

			case gsLeavingStargate:
				{
				//	Update some displays

				if ((m_iTick % 10) == 0)
					m_ReactorDisplay.Update();

				//	Tell the universe to paint

				g_pUniverse->PaintPOV(TheScreen, m_rcMainScreen, false);
				PaintMainScreenBorder();
				PaintLRS();
				m_ArmorDisplay.Paint(TheScreen);
				m_MessageDisplay.Paint(TheScreen);
				m_ReactorDisplay.Paint(TheScreen);
				m_TargetDisplay.Paint(TheScreen);
				m_DeviceDisplay.Paint(TheScreen);

				//	Debug information

				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					PaintFrameRate();

#ifdef DEBUG
				PaintDebugLines();
#endif

				//	Update the screen

				if (bTopMost)
					g_pHI->GetScreenMgr().Blt();

				//	Update the universe

				g_pUniverse->Update(g_SecondsPerUpdate);
				m_MessageDisplay.Update();
				m_iTick++;

				if (--m_iCountdown == 0)
					LeaveStargate();
				break;
				}
			}

		//	Flip

		if (bTopMost)
			g_pHI->GetScreenMgr().Flip();

		SetProgramState(psUnknown);
		}
	catch (...)
		{
		bFailed = true;
		}

	//	Deal with errors/crashes

	if (bFailed)
		{
		g_pHI->GetScreenMgr().StopDX();
		ReportCrash();
		}
	}
コード例 #3
0
void CDockingPorts::UpdateAll (CSpaceObject *pOwner)

//	UpdateAll
//
//	UpdateAll 

	{
	int i, j;

	for (i = 0; i < m_iPortCount; i++)
		{
		if (m_pPort[i].iStatus == psDocking)
			{
			CShip *pShip = m_pPort[i].pObj->AsShip();

			ASSERT(pShip);
			if (pShip == NULL)
				continue;

			CVector vDest = pOwner->GetPos() + m_pPort[i].vPos;
			CVector vDestVel = pOwner->GetVel();

			//	Figure out how far we are from where we want to be

			CVector vDelta = vDest - pShip->GetPos();

			//	Figure out if we're aligned

			int iFinalRotation = pShip->AlignToRotationAngle(m_pPort[i].iRotation);

			//	If the docking object is within the appropriate threshold 
			//	of the port, then complete the docking sequence.

			Metric rDelta2 = vDelta.Length2();
			if (rDelta2 < DOCKING_THRESHOLD2 
					&& (pShip == g_pUniverse->GetPlayer() || iFinalRotation == pShip->GetRotation()))
				{
				pShip->Place(vDest);
				pShip->UnfreezeControls();
				IShipController *pController = pShip->GetController();
				pController->SetManeuver(IShipController::NoRotation);

				m_pPort[i].iStatus = psInUse;

				//	Tell the owner that somone has docked with it first
				//	(We do this because sometimes we want to handle stuff
				//	in OnObjDocked before we show the player a dock screen)

				if (pOwner && pOwner->HasOnObjDockedEvent() && pOwner != pShip)
					pOwner->OnObjDocked(pShip, pOwner);

				//	Dock

				pShip->OnDocked(pOwner);

				//	Tell all objects in the system that a ship has docked

				CSystem *pSystem = pShip->GetSystem();
				for (j = 0; j < pSystem->GetObjectCount(); j++)
					{
					CSpaceObject *pObj = pSystem->GetObject(j);

					if (pObj && pObj->HasOnObjDockedEvent() && pObj != pShip && pObj != pOwner)
						pObj->OnObjDocked(pShip, pOwner);
					}
				}

			//	Otherwise accelerate the ship towards the docking port

			else
				{
				Metric rMaxSpeed = pShip->GetMaxSpeed();
				Metric rMinSpeed = rMaxSpeed / 10.0;

				//	We slow down as we get closer

				Metric rSpeed;
				if (rDelta2 < FINAL_DOCKING2)
					rSpeed = rMinSpeed;
				else if (rDelta2 < FINAL_APPROACH2)
					{
					Metric rSpeedRange = rMaxSpeed - rMinSpeed;
					Metric rDelta = sqrt(rDelta2);
					rSpeed = rMinSpeed + (rSpeedRange * (rDelta - FINAL_DOCKING) / (FINAL_APPROACH - FINAL_DOCKING));
					}
				else
					rSpeed = rMaxSpeed;

				//	Figure out the ideal velocity vector that we want to
				//	be following.

				CVector vIdealVel = vDelta.Normal() * rSpeed;

				//	Calculate the delta v that we need

				CVector vDeltaV = vIdealVel - pShip->GetVel();

				//	Rotate

				if (pShip != g_pUniverse->GetPlayer())
					{
					IShipController *pController = pShip->GetController();

					//	If we're close enough, align to rotation angle

					if (rDelta2 < FINAL_APPROACH2)
						pController->SetManeuver(CalcTurnManeuver(iFinalRotation, pShip->GetRotation(), pShip->GetRotationAngle()));

					//	Otherwise, align along delta v

					else
						pController->SetManeuver(CalcTurnManeuver(VectorToPolar(vDeltaV), pShip->GetRotation(), pShip->GetRotationAngle()));
					}

				//	Accelerate

				pShip->Accelerate(vDeltaV * pShip->GetMass() / 10000.0, g_SecondsPerUpdate);

				pShip->ClipSpeed(rSpeed);
				}
			}
		}
	}