コード例 #1
0
ファイル: CEconomyType.cpp プロジェクト: bmer/Mammoth
CurrencyValue CEconomyType::RinHackInc (CSpaceObject *pObj, CurrencyValue iInc)

//	RinHackInc
//
//	Increment rin

	{
	CShip *pPlayerShip = pObj->AsShip();
	IShipController *pController = (pPlayerShip ? pPlayerShip->GetController() : NULL);
	CCurrencyBlock *pMoney = (pController ? pController->GetCurrencyBlock() : NULL);
	return (pMoney ? pMoney->IncCredits(CONSTLIT("rin"), iInc) : 0);
	}
コード例 #2
0
ファイル: CEconomyType.cpp プロジェクト: bmer/Mammoth
void CEconomyType::RinHackSet (CSpaceObject *pObj, const CString &sData)

//	RinHackSet
//
//	Sets rin

	{
	CShip *pPlayerShip = pObj->AsShip();
	IShipController *pController = (pPlayerShip ? pPlayerShip->GetController() : NULL);
	CCurrencyBlock *pMoney = (pController ? pController->GetCurrencyBlock() : NULL);
	if (pMoney)
		pMoney->SetCredits(CONSTLIT("rin"), strToInt(sData, 0));
	}
コード例 #3
0
ファイル: CEconomyType.cpp プロジェクト: bmer/Mammoth
CString CEconomyType::RinHackGet (CSpaceObject *pObj)

//	RinHackGet
//
//	In previous version we used to store rin as object data on the player ship
//	This hack returns it from the proper place

	{
	CShip *pPlayerShip = pObj->AsShip();
	IShipController *pController = (pPlayerShip ? pPlayerShip->GetController() : NULL);
	CCurrencyBlock *pMoney = (pController ? pController->GetCurrencyBlock() : NULL);
	return (pMoney ? strFromInt((int)pMoney->GetCredits(CONSTLIT("rin"))) : NULL_STR);
	}
コード例 #4
0
EResults RunEncounter (CUniverse &Universe, CSimViewer &Viewer, CStationType *pDefenderType, CShipClass *pAttackerClass, CSovereign *pAttackerSovereign)
	{
	int iTimeOut = DEFAULT_TIME_OUT;

	//	Make sure the universe is clean

	CString sError;
	if (Universe.InitGame(0, &sError) != NOERROR)
		{
		printf("ERROR: %s", sError.GetASCIIZPointer());
		return resultError;
		}

	//	Create an empty system

	CSystem *pSystem;
	if (Universe.CreateEmptyStarSystem(&pSystem) != NOERROR)
		{
		printf("ERROR: Unable to create empty star system.\n");
		return resultError;
		}

	//	Create a station in the center of the system

	CSpaceObject *pStation;
	if (pSystem->CreateStation(pDefenderType, NULL, CVector(), &pStation) != NOERROR)
		{
		printf("ERROR: Unable to create station.\n");
		return resultError;
		}

	//	Set the POV

	Universe.SetPOV(pStation);
	pSystem->SetPOVLRS(pStation);

	//	Prepare system

	Universe.UpdateExtended();
	Universe.GarbageCollectLibraryBitmaps();
	Universe.StartGame(true);

	//	Now create an attacker some distance away

	CVector vPos = PolarToVector(mathRandom(0, 359), INITIAL_DISTANCE);

	CShip *pAttacker;
	if (pSystem->CreateShip(pAttackerClass->GetUNID(), NULL, NULL, pAttackerSovereign, vPos, CVector(), 0, NULL, NULL, &pAttacker) != NOERROR)
		{
		printf("ERROR: Unable to create attacking ship.\n");
		return resultError;
		}

	//	Set the attacker to attack the station

	IShipController *pController = pAttacker->GetController();
	if (pController == NULL)
		{
		printf("ERROR: No controller for ship.\n");
		return resultError;
		}

	pController->AddOrder(IShipController::orderAttackStation, pStation, IShipController::SData());

	//	Watch the attacker

	Universe.SetPOV(pAttacker);
	pSystem->SetPOVLRS(pAttacker);

	//	Update context

	SSystemUpdateCtx Ctx;
	Ctx.bForceEventFiring = true;
	Ctx.bForcePainted = true;

	//	Now keep updating until either the station is destroyed, the ship is destroyed, or we time-out

	int iTime = 0;
	int iDestroyedTime = (Viewer.IsEmpty() ? 0 : DESTROY_TIME);
	bool bDestroyed = false;
	EResults iResult = resultTimeout;
	while (iTime < iTimeOut && (!bDestroyed || iDestroyedTime > 0))
		{
		iTime++;
		Universe.Update(Ctx);

		if (!Viewer.IsEmpty())
			Viewer.PaintViewport(Universe);

		if (bDestroyed)
			iDestroyedTime--;
		else if (pStation->IsDestroyed() || pStation->IsAbandoned())
			{
			bDestroyed = true;
			iResult = resultDefenderDestroyed;
			}
		else if (pAttacker->IsDestroyed())
			{
			bDestroyed = true;
			iResult = resultAttackerDestroyed;
			}
		}

	//	Done

	return iResult;
	}
コード例 #5
0
void GenerateWeaponEffectChart (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	int i;

	//	Compute the list of weapons to show, making sure we filter to weapons
	//	and missiles only.

	CItemTypeTable Selection;
	if (!Selection.Filter(pCmdLine->GetAttribute(CRITERIA_ATTRIB))
			|| (Selection.IsAll() && !Selection.Filter(CONSTLIT("wm"))))
		{
		printf("No entries match criteria.\n");
		return;
		}

	Selection.Sort();

	//	Ship to use

	DWORD dwPlatformUNID;
	if (!pCmdLine->FindAttributeInteger(SHIP_UNID_ATTRIB, (int *)&dwPlatformUNID))
		dwPlatformUNID = WEAPON_PLATFORM_UNID;

	//	Compute some metrics

	int iFramesPerItem = 10;
	int cxFrameHorzMargin = 10;
	int cxMaxDistPerTick = (int)(STD_SECONDS_PER_UPDATE * (LIGHT_SECOND / g_KlicksPerPixel));
	int cyFrame = 64;
	int cxFrame = (2 * cxFrameHorzMargin) + (iFramesPerItem * cxMaxDistPerTick);

	int iHitEffectFramesPerItem = 5;
	int cxHitEffect = 128;
	int cyHitEffect = 128;
	
	int cyRowTitle = 20;
	int cyRow = cyRowTitle + Max(ITEM_ICON_HEIGHT, cyFrame * iFramesPerItem);
	int cxRow = ITEM_ICON_WIDTH + cxFrame;

	int iColumns = Max(1, mathSqrt(Selection.GetCount()));
	int iRows = (Selection.GetCount() + (iColumns - 1)) / iColumns;

	int cxImage = cxRow * iColumns;
	int cyImage = cyRow * iRows;

	//	Initialize the output

	COutputChart Output;
	Output.SetContentSize(cxImage, cyImage);
	Output.SetOutputFilespec(pCmdLine->GetAttribute(CONSTLIT("output")));

	//	Initialize fonts

	Output.SetStyleFont(STYLE_TITLE, pCmdLine->GetAttribute(CONSTLIT("font")));
	Output.SetStyleColor(STYLE_TITLE, CG32bitPixel(0xFF, 0xFF, 0xFF));

	//	Prepare the universe

	CSystem *pSystem;
	if (Universe.CreateEmptyStarSystem(&pSystem) != NOERROR)
		{
		printf("ERROR: Unable to create empty star system.\n");
		return;
		}

	//	Create a target in the center of the system

	CSpaceObject *pStation;
	CStationType *pTargetType = Universe.FindStationType(TARGET_UNID);
	if (pTargetType == NULL 
			|| pSystem->CreateStation(pTargetType, NULL, CVector(), &pStation) != NOERROR)
		{
		printf("ERROR: Unable to create station.\n");
		return;
		}

	//	Create the weapon platform some distance away

	CSovereign *pPlatformSovereign = Universe.FindSovereign(PLAYER_SOVEREIGN_UNID);
	CShip *pPlatform;
	if (pPlatformSovereign == NULL
				|| pSystem->CreateShip(dwPlatformUNID,
					NULL,
					NULL,
					pPlatformSovereign,
					CVector(-5.0 * LIGHT_SECOND, 0.),
					CVector(),
					0,
					NULL,
					NULL,
					&pPlatform) != NOERROR)
		{
		printf("ERROR: Unable to create weapons platform.\n");
		return;
		}

	//	Set the attacker to hold

	IShipController *pController = pPlatform->GetController();
	if (pController == NULL)
		{
		printf("ERROR: No controller for ship.\n");
		return;
		}

	pController->AddOrder(IShipController::orderHold, NULL, IShipController::SData());
	pPlatform->SetControllerEnabled(false);

	//	Install the largest possible reactor on the ship

	CItemType *pReactorType = Universe.FindItemType(REACTOR_UNID);
	if (pReactorType)
		{
		CItem ReactorItem(pReactorType, 1);

		CItemListManipulator ItemList(pPlatform->GetItemList());
		ItemList.AddItem(ReactorItem);
		pPlatform->OnComponentChanged(comCargo);
		pPlatform->ItemsModified();
		pPlatform->InvalidateItemListAddRemove();

		pPlatform->InstallItemAsDevice(ItemList);
		}

	//	Set the POV

	Universe.SetPOV(pStation);
	pSystem->SetPOVLRS(pStation);

	//	Prepare system

	Universe.UpdateExtended();
	Universe.GarbageCollectLibraryBitmaps();
	Universe.StartGame(true);

	//	Output each weapon

	int xOrigin;
	int yOrigin;
	CG32bitImage &Image = Output.GetOutputImage(&xOrigin, &yOrigin);
	const CG16bitFont &TitleFont = Output.GetStyleFont(STYLE_TITLE);
	CG32bitPixel rgbTitleColor = Output.GetStyleColor(STYLE_TITLE);

	for (i = 0; i < Selection.GetCount(); i++)
		{
		CItemType *pType = Selection.GetItemType(i);

		//	Compute the metrics of this row

		int xRow = xOrigin + (i % iColumns) * cxRow;
		int yRow = yOrigin + (i / iColumns) * cyRow;

		//	Paint the weapon title

		Image.Fill(xRow, yRow, cxRow, cyRow, CG32bitPixel(0x40, 0x40, 0x40));
		TitleFont.DrawText(Image, xRow + 8, yRow, rgbTitleColor, pType->GetNounPhrase());

		//	Paint the frames

		PaintWeaponFrames(Image, pType, pPlatform, iFramesPerItem, 
				xRow + ITEM_ICON_WIDTH + cxFrameHorzMargin,
				yRow + cyRowTitle, 
				cxMaxDistPerTick,
				cyFrame);
		}

	//	Done

	Output.Output();
	}
コード例 #6
0
void CFleetShipAI::OnObjDestroyedNotify (const SDestroyCtx &Ctx)

//	OnObjDestroyedNotify
//
//	Deal with an object that has been destroyed

	{
	switch (GetCurrentOrder())
		{
		case IShipController::orderEscort:
			if (Ctx.pObj == GetCurrentOrderTarget())
				{
				CancelCurrentOrder();

				//	Get the orders of the leader

				IShipController::OrderTypes iLeaderOrders = IShipController::orderNone;
				CSpaceObject *pLeaderTarget = NULL;
				if (Ctx.pObj && Ctx.pObj->GetCategory() == CSpaceObject::catShip)
					{
					CShip *pLeader = Ctx.pObj->AsShip();
					if (pLeader)
						iLeaderOrders = pLeader->GetController()->GetCurrentOrderEx(&pLeaderTarget);
					}

				//	Avenge the leader

				int iAvengeChance = (pLeaderTarget ? 40 : 100);
				if (Ctx.pDestroyer 
						&& Ctx.pDestroyer != pLeaderTarget
						&& Ctx.pDestroyer->CanAttack() 
						&& !m_pShip->IsFriend(Ctx.pDestroyer)
						&& mathRandom(1, 100) <= iAvengeChance)
					AddOrder(IShipController::orderDestroyTarget, Ctx.pDestroyer, 0);

				//	Take on leader's orders

				switch (iLeaderOrders)
					{
					case IShipController::orderDestroyTarget:
					case IShipController::orderGuard:
						if (pLeaderTarget)
							AddOrder(iLeaderOrders, pLeaderTarget, 0);
						break;
					default:
						break;
					}

				//	Attack other enemies

				AddOrder(IShipController::orderAttackNearestEnemy, NULL, 0);
				}
			break;

		case IShipController::orderDock:
		case IShipController::orderDestroyTarget:
		case IShipController::orderPatrol:
		case IShipController::orderGuard:
			if (Ctx.pObj == GetCurrentOrderTarget())
				CancelCurrentOrder();
			break;
		default:
			break;
		}

	//	If our target gets destroyed...

	switch (m_State)
		{
		case stateAttackTarget:
		case stateAttackOnPatrol:
			if (Ctx.pObj == m_pTarget)
				SetState(stateNone);
			break;
		default:
			break;
		}

	//	Reset

	if (m_pDest == Ctx.pObj)
		m_pDest = NULL;
	if (m_pTarget == Ctx.pObj)
		m_pTarget = NULL;
	}
コード例 #7
0
ファイル: IntroScreen.cpp プロジェクト: alanhorizon/Transport
ALERROR CTranscendenceWnd::StartIntro (void)

//	StartIntro
//
//	Start introduction

	{
	ALERROR error;
	int i;

	ClearDebugLines();

	//	Use widescreen topology

	int cyBarHeight = (g_cyScreen - INTRO_DISPLAY_HEIGHT) / 2;
	m_rcIntroTop.top = 0;
	m_rcIntroTop.left = 0;
	m_rcIntroTop.bottom = cyBarHeight;
	m_rcIntroTop.right = g_cxScreen;

	m_rcIntroMain.top = cyBarHeight;
	m_rcIntroMain.left = 0;
	m_rcIntroMain.bottom = g_cyScreen - cyBarHeight;
	m_rcIntroMain.right = g_cxScreen;

	m_rcIntroBottom.top = g_cyScreen - cyBarHeight;
	m_rcIntroBottom.left = 0;
	m_rcIntroBottom.bottom = g_cyScreen;
	m_rcIntroBottom.right = g_cxScreen;

	m_Screen.DrawRectFilled(m_rcIntroTop.left, m_rcIntroTop.top,m_rcIntroTop.right, m_rcIntroTop.bottom, CGImage::RGBColor(0, 0, 0));
	m_Screen.DrawRectFilled(m_rcIntroBottom.left, m_rcIntroBottom.top,m_rcIntroBottom.right, m_rcIntroBottom.bottom, CGImage::RGBColor(0, 0, 0));
	//	Create the High-Score display

	RECT rcRect;
	rcRect.left = m_rcMainScreen.left + HIGHSCORE_DISPLAY_X;
	rcRect.top = m_rcMainScreen.top + HIGHSCORE_DISPLAY_Y;
	rcRect.right = rcRect.left + HIGHSCORE_DISPLAY_WIDTH;
	rcRect.bottom = rcRect.top + HIGHSCORE_DISPLAY_HEIGHT;
	m_HighScoreDisplay.Init(rcRect, m_pHighScoreList, m_iLastHighScore);
	m_HighScoreDisplay.SetFontTable(&m_Fonts);
	m_HighScoreDisplay.Update();

	//	Create the player display

	m_PlayerDisplay.Init(this, m_rcIntroTop, m_Options.bDebugMode);

	//	Create the buttons

	m_ButtonBar.Init();

	CString sContinueLabel = ComputeLoadGameLabel(&m_bSavedGame);
	m_ButtonBar.AddButton(CMD_CONTINUE_OLD_GAME,
			CONSTLIT("Continue Game"),
			sContinueLabel,
			CONSTLIT("C"),
			0,
			CButtonBarData::alignLeft);
	if (sContinueLabel.IsBlank())
		m_ButtonBar.SetVisible(0, false);

	m_ButtonBar.AddButton(CMD_START_NEW_GAME,
			CONSTLIT("New Game"),
			CONSTLIT("Begin a New Game"),
			CONSTLIT("N"),
			1,
			CButtonBarData::alignCenter);

	m_ButtonBar.AddButton(CMD_QUIT_GAME,
			CONSTLIT("Quit"),
			CONSTLIT("Exit Transcendence"),
			CONSTLIT("Q"),
			2,
			CButtonBarData::alignRight);

	m_ButtonBarDisplay.SetFontTable(&m_Fonts);
	m_ButtonBarDisplay.Init(this, &m_ButtonBar, m_rcIntroBottom);

	//	Create an empty system

	if (error = m_Universe.CreateEmptyStarSystem(&m_pIntroSystem))
		{
		ASSERT(false);
		return error;
		}

	m_Universe.SetCurrentSystem(m_pIntroSystem);

	CSovereign *pSovereign1 = m_Universe.FindSovereign(g_PlayerSovereignUNID);
	CSovereign *pSovereign2 = m_Universe.FindSovereign(g_PirateSovereignUNID);

	//	Create a couple of random enemy ships

	CShip *pShip1;
	CShip *pShip2;
	if ((error = CreateRandomShip(m_pIntroSystem, pSovereign1, &pShip1)))
		{
		ASSERT(false);
		return error;
		}

	if ((error = CreateRandomShip(m_pIntroSystem, pSovereign2, &pShip2)))
		{
		ASSERT(false);
		return error;
		}

	//	Make the ships attack each other

	for (i = 0; i < m_pIntroSystem->GetObjectCount(); i++)
		{
		CSpaceObject *pObj = m_pIntroSystem->GetObject(i);

		if (pObj
				&& pObj->GetCategory() == CSpaceObject::catShip
				&& !pObj->GetData(CONSTLIT("IntroController")).IsBlank())
			{
			CShip *pShip = pObj->AsShip();
			if (pShip)
				{
				IShipController *pController = pShip->GetController();
				if (pShip->GetSovereign() == pSovereign1)
					pController->AddOrder(IShipController::orderDestroyTarget, pShip2, 0);
				else
					pController->AddOrder(IShipController::orderDestroyTarget, pShip1, 0);
				}
			}
		}

	//	Other initialization

	m_bOverwriteGameDlg = false;
	m_rcOverwriteGameDlg.left = m_rcIntroMain.left + (RectWidth(m_rcIntroMain) - DIALOG_WIDTH) / 2;
	m_rcOverwriteGameDlg.top = m_rcIntroMain.top + (RectHeight(m_rcIntroMain) - DIALOG_HEIGHT) / 2;
	m_rcOverwriteGameDlg.right = m_rcOverwriteGameDlg.left + DIALOG_WIDTH;
	m_rcOverwriteGameDlg.bottom = m_rcOverwriteGameDlg.top + DIALOG_HEIGHT;

	int cxMid = m_rcOverwriteGameDlg.left + (DIALOG_WIDTH / 2);
	m_rcOverwriteGameOK.left = cxMid - DIALOG_SPACING_X - DIALOG_BUTTON_WIDTH;
	m_rcOverwriteGameOK.top = m_rcOverwriteGameDlg.bottom - DIALOG_SPACING_Y - DIALOG_BUTTON_HEIGHT;
	m_rcOverwriteGameOK.right = m_rcOverwriteGameOK.left + DIALOG_BUTTON_WIDTH;
	m_rcOverwriteGameOK.bottom = m_rcOverwriteGameOK.top + DIALOG_BUTTON_HEIGHT;

	m_rcOverwriteGameCancel = m_rcOverwriteGameOK;
	m_rcOverwriteGameCancel.left = cxMid + DIALOG_SPACING_X;
	m_rcOverwriteGameCancel.right = m_rcOverwriteGameCancel.left + DIALOG_BUTTON_WIDTH;

	//	No sound

	m_Universe.SetSound(false);

	//	Set the POV to one of them

	m_Universe.SetPOV(pShip1);
	m_iTick = 0;
	m_iLastShipCreated = m_iTick;

	m_State = gsIntro;

	//	Show the cursor

	SDL_ShowCursor(true);

	return NOERROR;
	}
コード例 #8
0
ファイル: IntroScreen.cpp プロジェクト: alanhorizon/Transport
ALERROR CTranscendenceWnd::CreateRandomShip (CSystem *pSystem, CSovereign *pSovereign, CShip **retpShip)

//	CreateRandomShip
//
//	Creates a random ship

	{
	ALERROR error;
	int i;

	//	Figure out the class

	CShipClass *pShipClass;
	if (m_dwIntroShipClass == 0)
		{
		do
			pShipClass = m_Universe.GetShipClass(mathRandom(0, m_Universe.GetShipClassCount()-1));
		while (pShipClass->GetScore() > 1000 || pShipClass->IsPlayerShip());
		}
	else
		{
		int i;
		int iIndex = -1;
		for (i = 0; i < m_Universe.GetShipClassCount(); i++)
			if (m_Universe.GetShipClass(i)->GetUNID() == m_dwIntroShipClass)
				{
				iIndex = i;
				break;
				}

		if (iIndex == -1 || (iIndex + 1) == m_Universe.GetShipClassCount())
			pShipClass = m_Universe.GetShipClass(0);
		else
			pShipClass = m_Universe.GetShipClass(iIndex + 1);

		m_dwIntroShipClass = 0;
		}

	//	Normally we create a single ship, but sometimes we create lots

	int iCount;
	int iRoll = mathRandom(1, 100);

	//	Adjust the roll for capital ships

	if (pShipClass->GetHullMass() >= 10000)
		iRoll -= 9;
	else if (pShipClass->GetHullMass() >= 1000)
		iRoll -= 6;

	if (iRoll == 100)
		iCount = mathRandom(30, 60);
	else if (iRoll >= 98)
		iCount = mathRandom(10, 20);
	else if (iRoll >= 95)
		iCount = mathRandom(5, 10);
	else if (iRoll >= 90)
		iCount = mathRandom(2, 5);
	else
		iCount = 1;

	//	Create the ships

	for (i = 0; i < iCount; i++)
		{
		CShip *pShip;
		if ((error = pSystem->CreateShip(pShipClass->GetUNID(),
				NULL,
				pSovereign,
				PolarToVector(mathRandom(0, 359), mathRandom(250, 2500) * g_KlicksPerPixel),
				NullVector,
				mathRandom(0, 359),
				NULL,
				&pShip)))
			return error;

		//	Override the controller

		CIntroShipController *pNewController = new CIntroShipController(this, pShip->GetController());
		pShip->SetController(pNewController, false);
		pNewController->SetShip(pShip);
		pShip->SetData(CONSTLIT("IntroController"), CONSTLIT("True"));

		*retpShip = pShip;
		}

	return NOERROR;
	}
コード例 #9
0
void CDockingPorts::UpdateDockingManeuvers (CSpaceObject *pOwner, DockingPort &Port)

//	UpdateDockingManeuvers
//
//	Updates the motion of a ship docking with a port

	{
	CShip *pShip = Port.pObj->AsShip();

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

	CVector vDest = pOwner->GetPos() + Port.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(Port.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);

		Port.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->IsDestroyed()
				&& pShip->IsSubscribedToEvents(pOwner))
			pOwner->FireOnObjDocked(pShip, pOwner);

		//	Set the owner as "explored" (if the ship is the player)

		if (pShip->IsPlayer())
			pOwner->SetExplored();

		//	Dock

		pShip->OnDocked(pOwner);

		//	Notify other subscribers

		pShip->NotifyOnObjDocked(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->IsPlayer())
			{
			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()));

			//	Don't let the AI thrust

			pController->SetThrust(false);
			}

		//	Accelerate

		pShip->Accelerate(vDeltaV * pShip->GetMass() / 10000.0, g_SecondsPerUpdate);
		pShip->ClipSpeed(rSpeed);
		}
	}
コード例 #10
0
void CPlayerGameStats::GenerateGameStats (CGameStats &Stats, CSpaceObject *pPlayerShip, bool bGameOver) const

//	GenerateGameStats
//
//	Generates a stats for everything we track

	{
	int j;

	CShip *pShip = (pPlayerShip ? pPlayerShip->AsShip() : NULL);
	if (pShip == NULL)
		return;

	CPlayerShipController *pPlayer = (CPlayerShipController *)pShip->GetController();
	if (pPlayer == NULL)
		return;

	CSovereign *pPlayerSovereign = g_pUniverse->FindSovereign(g_PlayerSovereignUNID);
	if (pPlayerSovereign == NULL)
		return;

	//	Base stats

	Stats.Insert(CONSTLIT("Genome"), strCapitalize(GetGenomeName(pPlayer->GetPlayerGenome())));
	Stats.Insert(CONSTLIT("Score"), strFormatInteger(CalcEndGameScore(), -1, FORMAT_THOUSAND_SEPARATOR | FORMAT_UNSIGNED));
	Stats.Insert(CONSTLIT("Ship class"), pShip->GetNounPhrase(0));

	CTimeSpan Time = GetPlayTime();
	if (!Time.IsBlank())
		Stats.Insert(CONSTLIT("Time played"), Time.Format(NULL_STR));

#ifdef REAL_TIME
	Time = GetGameTime();
	if (!Time.IsBlank())
		Stats.Insert(CONSTLIT("Time elapsed in game"), Time.Format(NULL_STR));
#endif

	//	Some combat stats

	CString sDestroyed = GetStat(ENEMY_SHIPS_DESTROYED_STAT);
	if (!sDestroyed.IsBlank())
		Stats.Insert(CONSTLIT("Enemy ships destroyed"), sDestroyed, CONSTLIT("combat"));

	sDestroyed = GetStat(FRIENDLY_SHIPS_DESTROYED_STAT);
	if (!sDestroyed.IsBlank())
		Stats.Insert(CONSTLIT("Friendly ships destroyed"), sDestroyed, CONSTLIT("combat"));

	sDestroyed = GetStat(ENEMY_STATIONS_DESTROYED_STAT);
	if (!sDestroyed.IsBlank())
		Stats.Insert(CONSTLIT("Enemy stations destroyed"), sDestroyed, CONSTLIT("combat"));

	sDestroyed = GetStat(FRIENDLY_STATIONS_DESTROYED_STAT);
	if (!sDestroyed.IsBlank())
		Stats.Insert(CONSTLIT("Friendly stations destroyed"), sDestroyed, CONSTLIT("combat"));

	//	Add stat for every station destroyed

	CStatCounterArray CounterArray;

	CMapIterator i;
	m_StationStats.Reset(i);
	while (m_StationStats.HasMore(i))
		{
		SStationTypeStats *pStats;
		DWORD dwUNID = m_StationStats.GetNext(i, &pStats);
		CStationType *pType = g_pUniverse->FindStationType(dwUNID);
		if (pType == NULL)
			continue;

		CString sName = pType->GetNounPhrase(0);
		CString sSort = strPatternSubst(CONSTLIT("%03d%s"), 100 - pType->GetLevel(), sName);

		if (pType->GetSovereign()->IsEnemy(pPlayerSovereign))
			CounterArray.Insert(sName, pStats->iDestroyed, CONSTLIT("Enemy stations destroyed"), sSort);
		else
			CounterArray.Insert(sName, pStats->iDestroyed, CONSTLIT("Friendly stations destroyed"), sSort);
		}

	CounterArray.GenerateGameStats(Stats);
		
	//	Add stat for every ship class destroyed

	CounterArray.DeleteAll();
	m_ShipStats.Reset(i);
	while (m_ShipStats.HasMore(i))
		{
		SShipClassStats *pStats;
		DWORD dwUNID = m_ShipStats.GetNext(i, &pStats);
		CShipClass *pClass = g_pUniverse->FindShipClass(dwUNID);
		if (pClass == NULL)
			continue;

		CString sName = pClass->GetNounPhrase(0);
		CString sSort = strPatternSubst(CONSTLIT("%09d%s"), 100000000 - pClass->GetScore(), sName);

		if (pStats->iEnemyDestroyed > 0)
			CounterArray.Insert(sName, pStats->iEnemyDestroyed, CONSTLIT("Enemy ships destroyed"), sSort);

		if (pStats->iFriendDestroyed > 0)
			CounterArray.Insert(sName, pStats->iFriendDestroyed, CONSTLIT("Friendly ships destroyed"), sSort);
		}

	CounterArray.GenerateGameStats(Stats);

	//	Add stat for every weapon fired

	m_ItemStats.Reset(i);
	while (m_ItemStats.HasMore(i))
		{
		SItemTypeStats *pStats;
		DWORD dwUNID = m_ItemStats.GetNext(i, &pStats);
		CItemType *pItemType = g_pUniverse->FindItemType(dwUNID);
		if (pItemType == NULL)
			continue;

		CString sName = pItemType->GetNounPhrase(nounShort);
		CString sSort = strPatternSubst(CONSTLIT("%03d%s"), 100 - pItemType->GetLevel(), sName);

		//	Installed items

		if (pStats->dwFirstInstalled != INVALID_TIME)
			Stats.Insert(sName, NULL_STR, CONSTLIT("Items installed"), sSort);

		if (pStats->iCountFired > 0)
			Stats.Insert(sName, 
					strFormatInteger(pStats->iCountFired, -1, FORMAT_THOUSAND_SEPARATOR | FORMAT_UNSIGNED), 
					CONSTLIT("Weapons fired"), 
					sSort);
		}

	//	Stats for player equipment (but only if the game is done)

	if (bGameOver)
		{
		TSortMap<CString, CItem> InstalledItems;

		//	First we generate a sorted list of installed items
		//	(We do this in case there are multiple of the same device/armor so that
		//	we can coalesce them together into a single line).

		CItemListManipulator ItemList(pShip->GetItemList());
		ItemList.ResetCursor();
		while (ItemList.MoveCursorForward())
			{
			const CItem &Item(ItemList.GetItemAtCursor());

			if (Item.IsInstalled())
				{
				CString sEnhancement = Item.GetEnhancedDesc(pShip);
				CString sItemName = Item.GetNounPhrase(nounActual | nounCountOnly | nounShort);
				CString sLine = (sEnhancement.IsBlank() ? sItemName : strPatternSubst(CONSTLIT("%s [%s]"), sItemName, sEnhancement));

				bool bInserted;
				CItem *pEntry = InstalledItems.SetAt(sLine, &bInserted);
				if (bInserted)
					{
					*pEntry = Item;
					pEntry->SetCount(1);
					}
				else
					pEntry->SetCount(pEntry->GetCount() + 1);
				}
			}

		//	Now add all the installed items to the stats

		for (j = 0; j < InstalledItems.GetCount(); j++)
			{
			//	Redo the line now that we know the proper count

			CString sEnhancement = InstalledItems[j].GetEnhancedDesc(pShip);
			CString sItemName = InstalledItems[j].GetNounPhrase(nounActual | nounCountOnly);
			CString sLine = (sEnhancement.IsBlank() ? sItemName : strPatternSubst(CONSTLIT("%s [%s]"), sItemName, sEnhancement));

			//	Compute the sort order

			int iOrder;
			switch (InstalledItems[j].GetType()->GetCategory())
				{
				case itemcatWeapon:
					iOrder = 0;
					break;

				case itemcatLauncher:
					iOrder = 1;
					break;

				case itemcatShields:
					iOrder = 2;
					break;

				case itemcatArmor:
					iOrder = 3;
					break;

				case itemcatReactor:
					iOrder = 4;
					break;

				case itemcatDrive:
					iOrder = 5;
					break;

				default:
					iOrder = 6;
					break;
				}

			CString sSort = strPatternSubst(CONSTLIT("%d%03d%s"), iOrder, 100 - InstalledItems[j].GetType()->GetLevel(), sLine);
			Stats.Insert(sLine, NULL_STR, CONSTLIT("Final equipment"), sSort);
			}

		//	Add the remaining items

		ItemList.ResetCursor();
		while (ItemList.MoveCursorForward())
			{
			const CItem &Item(ItemList.GetItemAtCursor());

			if (!Item.IsInstalled())
				{
				CString sEnhancement = Item.GetEnhancedDesc(pShip);
				CString sItemName = Item.GetNounPhrase(nounActual | nounCountOnly);
				CString sLine = (sEnhancement.IsBlank() ? sItemName : strPatternSubst(CONSTLIT("%s [%s]"), sItemName, sEnhancement));
				CString sSort = strPatternSubst(CONSTLIT("%03d%s"), 100 - Item.GetType()->GetLevel(), sLine);

				Stats.Insert(sLine, NULL_STR, CONSTLIT("Final items"), sSort);
				}
			}
		}
	}
コード例 #11
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);
				}
			}
		}
	}