예제 #1
0
void CUIHelper::CreateClassInfoCargo (CShipClass *pClass, const CDeviceDescList &Devices, int x, int y, int cxWidth, DWORD dwOptions, int *retcyHeight, IAnimatron **retpInfo) const

//	CreateClassInfoCargo
//
//	Creates info about the ship class' cargo

	{
	const CVisualPalette &VI = m_HI.GetVisuals();

	CDeviceClass *pCargoExtension = Devices.GetNamedDevice(devCargo);
	int iCargoSpace = pClass->GetCargoSpace();
	if (pCargoExtension)
		iCargoSpace += pCargoExtension->GetCargoSpace();

	//	Icon

	CItemType *pItemIcon = (pCargoExtension ? pCargoExtension->GetItemType() : g_pUniverse->FindItemType(CARGO_HOLD_EXPANSION_UNID));

	//	Text

	CString sText = strPatternSubst(CONSTLIT("{/rtf {/f:LargeBold;/c:%d; %s} {/f:MediumBold;/c:%d; %s}\n{/f:Medium;/c:%d; %s}}"),
			CG16bitImage::RGBFromPixel(VI.GetColor(colorTextDialogLabel)),
			strFromInt(iCargoSpace, TRUE),
			CG16bitImage::RGBFromPixel(VI.GetColor(colorTextDialogInput)),
			(pCargoExtension ? strPatternSubst(CONSTLIT("ton %s"), CTextBlock::Escape(pCargoExtension->GetItemType()->GetNounPhrase(nounActual))) : CONSTLIT("ton cargo hold")),
			CG16bitImage::RGBFromPixel(VI.GetColor(colorTextDialogLabel)),
			(iCargoSpace < pClass->GetMaxCargoSpace() ? strPatternSubst(CONSTLIT("optional expansion up to %d tons"), pClass->GetMaxCargoSpace()) : CONSTLIT("cargo space cannot be expanded")));

	CreateClassInfoSpecialItem(pItemIcon, sText, x, y, cxWidth, dwOptions, retcyHeight, retpInfo);
	}
예제 #2
0
void CUIHelper::CreateClassInfoReactor (CShipClass *pClass, const CDeviceDescList &Devices, int x, int y, int cxWidth, DWORD dwOptions, int *retcyHeight, IAnimatron **retpInfo) const

//	CreateClassInfoReactor
//
//	Creates info about the ship class' reactor

	{
	const CVisualPalette &VI = m_HI.GetVisuals();

	//	Get reactor info from the ship class

	const ReactorDesc *pReactorDesc = pClass->GetReactorDesc();
	if (pReactorDesc == NULL)
		{
		if (retcyHeight)
			*retcyHeight = 0;

		CAniSequencer::Create(CVector(x, y), (CAniSequencer **)retpInfo);
		return;
		}

	CDeviceClass *pReactor = Devices.GetNamedDevice(devReactor);
	if (pReactor)
		pReactorDesc = pReactor->GetReactorDesc();

	//	Get the icon (OK if this is NULL)

	CItemType *pItemIcon = (pReactor ? pReactor->GetItemType() : g_pUniverse->FindItemType(NOVA25_REACTOR_UNID));

	//	Create the info

	CString sText = strPatternSubst(CONSTLIT("{/rtf {/f:LargeBold;/c:%d; %s} {/f:MediumBold;/c:%d; %s}}"),
			CG16bitImage::RGBFromPixel(VI.GetColor(colorTextDialogLabel)),
			CTextBlock::Escape(ReactorPower2String(pReactorDesc->iMaxPower)),
			CG16bitImage::RGBFromPixel(VI.GetColor(colorTextDialogInput)),
			(pReactor ? CTextBlock::Escape(pReactor->GetItemType()->GetNounPhrase()) : strPatternSubst(CONSTLIT("%s reactor"), CTextBlock::Escape(pClass->GetShortName()))));

	CreateClassInfoSpecialItem(pItemIcon, sText, x, y, cxWidth, dwOptions, retcyHeight, retpInfo);
	}
예제 #3
0
void PaintWeaponFrames (CG32bitImage &Image, CItemType *pType, CShip *pPlatform, int iFrames, int x, int y, int cxCell, int cyCell)
	{
	int i, j;

	Metric rFireDist = 18.0 * LIGHT_SECOND;

	//	Make sure we're refueled and in position

	pPlatform->Place(CVector(-rFireDist, 0.0));
	pPlatform->Refuel(pPlatform->GetMaxFuel());
	CItemListManipulator ItemList(pPlatform->GetItemList());

	//	Get the device and weapon fire desc for this item. The call will do the
	//	right thing if this is a missile.

	CDeviceClass *pWeapon;
	int iVariant;
	CWeaponFireDesc *pDesc;
	if (!CDeviceClass::FindWeaponFor(pType, &pWeapon, &iVariant, &pDesc))
		{
		printf("ERROR: Unable to find weapon for ammo.\n");
		return;
		}

	//	Compute the number of ticks that we need to cover the distance

	Metric rDist = rFireDist - (60 * g_KlicksPerPixel);
	Metric rSpeed = pDesc->GetRatedSpeed();
	Metric rTime = (rSpeed > 0.0 ? (rDist / pDesc->GetRatedSpeed()) : 0.0);
	int iFrameToSkip = iFrames / 4;
	int iTicksToHit = (int)(rTime / STD_SECONDS_PER_UPDATE) - iFrameToSkip - 4;

	//	If the item is a missile, create one to fire

	CItemType *pAmmoType = pDesc->GetAmmoType();
	if (pAmmoType)
		{
		CItem MissileItem(pAmmoType, 1);
		ItemList.AddItem(MissileItem);

		pPlatform->OnComponentChanged(comCargo);
		pPlatform->ItemsModified();
		pPlatform->InvalidateItemListAddRemove();
		}

	//	Install the appropriate weapon on the platform

	CItem WeaponItem(pWeapon->GetItemType(), 1);
	ItemList.AddItem(WeaponItem);

	pPlatform->OnComponentChanged(comCargo);
	pPlatform->ItemsModified();
	pPlatform->InvalidateItemListAddRemove();

	pPlatform->InstallItemAsDevice(ItemList);

	//	Select the weapon (we rely on the fact that this is the current
	//	item in the list).

	DeviceNames iDev = pPlatform->SelectWeapon(ItemList.GetItemAtCursor().GetInstalled(), iVariant);
	CInstalledDevice *pInstalledDevice = pPlatform->GetNamedDevice(iDev);
	if (pInstalledDevice == NULL
			|| pInstalledDevice->GetClass()->GetUNID() != pWeapon->GetUNID())
		{
		printf("ERROR: Failed to install %s.\n", pWeapon->GetItemType()->GetNounPhrase(0).GetASCIIZPointer());
		return;
		}

	//	Fire the weapon

	pInstalledDevice->SetTimeUntilReady(0);
	pPlatform->SetWeaponTriggered(iDev);

	//	Update context

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

	//	Now loop over the appropriate number of frames

	int xDest = x;
	int yDest = y;
	for (i = 0; i < iFrames; i++)
		{
		//	Update the universe

		g_pUniverse->Update(Ctx);
		if (pPlatform->IsDestroyed())
			printf("Platform destroyed.\n");

		//	Paint

		RECT rcView;
		rcView.left = xDest;
		rcView.top = yDest;
		rcView.right = xDest + (iFrames * cxCell * 2);
		rcView.bottom = yDest + cyCell;

		g_pUniverse->PaintPOV(Image, rcView, CSystem::VWP_NO_STAR_FIELD);

		//	Next

		pPlatform->ClearAllTriggered();

		//	At the half-way mark, update until the missile hits

		if (i == iFrameToSkip)
			{
			for (j = 0; j < iTicksToHit; j++)
				g_pUniverse->Update(Ctx);
			}

		yDest += cyCell;
		}

	//	Skip for a while

	for (j = 0; j < 100; j++)
		{
		g_pUniverse->Update(Ctx);
		if (pPlatform->IsDestroyed())
			printf("Platform destroyed.\n");
		}

	//	Uninstall weapon

	ItemList.Refresh(CItem::NullItem());
	while (ItemList.MoveCursorForward() 
			&& ItemList.GetItemAtCursor().GetType() != pWeapon->GetItemType())
		;

	pPlatform->RemoveItemAsDevice(ItemList);
	}
예제 #4
0
void CUIHelper::CreateClassInfoDrive (CShipClass *pClass, const CDeviceDescList &Devices, int x, int y, int cxWidth, DWORD dwOptions, int *retcyHeight, IAnimatron **retpInfo) const

//	CreateClassInfoDrive
//
//	Creates info about the ship class' drive

	{
	const CVisualPalette &VI = m_HI.GetVisuals();

	const DriveDesc *pDriveDesc = pClass->GetHullDriveDesc();
	if (pDriveDesc == NULL)
		{
		if (retcyHeight)
			*retcyHeight = 0;

		CAniSequencer::Create(CVector(x, y), (CAniSequencer **)retpInfo);
		return;
		}

	//	Base speed and thrust

	Metric rMaxSpeed = pDriveDesc->rMaxSpeed;
	int iThrust = pDriveDesc->iThrust;

	//	If we have a drive upgrade, we account for it here

	CDeviceClass *pDrive = Devices.GetNamedDevice(devDrive);
	if (pDrive)
		{
		pDriveDesc = pDrive->GetDriveDesc();
		rMaxSpeed = Max(rMaxSpeed, pDriveDesc->rMaxSpeed);
		iThrust += pDriveDesc->iThrust;
		}

	//	Icon

	CItemType *pItemIcon = (pDrive ? pDrive->GetItemType() : g_pUniverse->FindItemType(TRITIUM_PROPULSION_UPGRADE_UNID));

	//	Add speed box

	CString sSpeedNumber = strPatternSubst(CONSTLIT(".%02dc"), (int)((100.0 * rMaxSpeed / LIGHT_SECOND) + 0.5));
	CString sSpeedHeader = (pDrive ? pDrive->GetItemType()->GetNounPhrase(nounActual) : CONSTLIT("main drive"));

	//	Add thrust/mass ratio

	Metric rMass = pClass->CalcMass(Devices);
	int iRatio = (int)((200.0 * (rMass > 0.0 ? iThrust / rMass : 0.0)) + 0.5);

	CString sThrustNumber = strPatternSubst(CONSTLIT("%d.%d"), iRatio / 100, ((iRatio % 100) + 5) / 10);

	//	Add maneuver speed

	int iManeuver = pClass->GetManeuverability() * pClass->GetRotationRange() / STD_ROTATION_COUNT;
	if (iManeuver <= 0)
		iManeuver = 1;

	CString sManeuverNumber = strPatternSubst(CONSTLIT("%d.%d"), 30 / iManeuver, (10 * (30 % iManeuver) + (iManeuver / 2)) / iManeuver);

	//	Compose the text

	CString sText = strPatternSubst(CONSTLIT(
			"{/rtf/f:Medium;/c:%d; {/f:LargeBold;/c:%d; %s} {/f:MediumBold;/c:%d; %s}\n"
			"(max speed as fraction of light-speed)\n"
			"{/f:LargeBold;/c:%d; %s} thrust//mass ratio\n"
			"(thrust as proportion of total mass)\n"
			"{/f:LargeBold;/c:%d; %s} maneuverability\n"
			"(turning speed)}"),

			CG16bitImage::RGBFromPixel(VI.GetColor(colorTextDialogLabel)),
			CG16bitImage::RGBFromPixel(VI.GetColor(colorTextDialogLabel)),
			sSpeedNumber,
			CG16bitImage::RGBFromPixel(VI.GetColor(colorTextDialogInput)),
			sSpeedHeader,

			CG16bitImage::RGBFromPixel(VI.GetColor(colorTextDialogLabel)),
			sThrustNumber,

			CG16bitImage::RGBFromPixel(VI.GetColor(colorTextDialogLabel)),
			sManeuverNumber);

	CreateClassInfoSpecialItem(pItemIcon, sText, x, y, cxWidth, dwOptions, retcyHeight, retpInfo);
	}
예제 #5
0
void CNewGameSession::SetShipClass (CShipClass *pClass, int x, int y, int cxWidth)

//	SetShipClass
//
//	Sets the ship class

	{
	int i;

	const CPlayerSettings *pPlayerSettings = pClass->GetPlayerSettings();

	const CVisualPalette &VI = m_HI.GetVisuals();
	const CG16bitFont &MediumBoldFont = VI.GetFont(fontMediumBold);
	const CG16bitFont &SubTitleFont = VI.GetFont(fontSubTitle);

	//	Ship class name

	SetShipClassName(pClass->GetName(), x, y, cxWidth);
	SetShipClassDesc(pPlayerSettings->GetDesc(), x, y, cxWidth);

	//	Offset

	int yOffset = SMALL_BUTTON_HEIGHT + SMALL_SPACING_VERT + MediumBoldFont.GetHeight() + 2 * SubTitleFont.GetHeight();

	//	Ship class image

	SetShipClassImage(pClass, x, y + yOffset, cxWidth);

	//	Delete previous info

	DeleteElement(ID_SHIP_CLASS_INFO);

	//	Create a sequencer for all class info components

	CAniSequencer *pClassInfo;
	CAniSequencer::Create(CVector(x, y + yOffset + SubTitleFont.GetHeight()), &pClassInfo);
	pClassInfo->SetID(ID_SHIP_CLASS_INFO);

	//	Generate default devices for the ship class

	CDeviceDescList Devices;
	pClass->GenerateDevices(1, Devices);

	//	Generate list of all weapons, sorted by level and name

	TSortMap<CString, CItem> RightSide;
	for (i = 0; i < Devices.GetCount(); i++)
		{
		CDeviceClass *pDevice = Devices.GetDeviceClass(i);
		if (pDevice->GetCategory() == itemcatWeapon ||
				pDevice->GetCategory() == itemcatLauncher)
			RightSide.Insert(strPatternSubst(CONSTLIT("%02d_%02d_%s"), 1, pDevice->GetLevel(), pDevice->GetName()), CItem(pDevice->GetItemType(), 1));
		}

	//	Add shields

	TSortMap<CString, CItem> LeftSide;
	CDeviceClass *pShields = Devices.GetNamedDevice(devShields);
	if (pShields)
		RightSide.Insert(strPatternSubst(CONSTLIT("%02d_%02d_%s"), 2, pShields->GetLevel(), pShields->GetName()), CItem(pShields->GetItemType(), 1));

	//	Add armor

	RightSide.Insert(CONSTLIT("03"), CItem(g_pUniverse->GetItemType(0), SPECIAL_ARMOR));

	//	Add reactor

	LeftSide.Insert(CONSTLIT("01"), CItem(g_pUniverse->GetItemType(0), SPECIAL_REACTOR));

	//	Add engines

	LeftSide.Insert(CONSTLIT("02"), CItem(g_pUniverse->GetItemType(0), SPECIAL_DRIVE));

	//	Add cargo

	LeftSide.Insert(CONSTLIT("03"), CItem(g_pUniverse->GetItemType(0), SPECIAL_CARGO));

	//	Add misc devices

	for (i = 0; i < Devices.GetCount(); i++)
		{
		CDeviceClass *pDevice = Devices.GetDeviceClass(i);
		if (pDevice->GetCategory() == itemcatMiscDevice)
			LeftSide.Insert(strPatternSubst(CONSTLIT("%02d_%02d_%s"), 4, pDevice->GetLevel(), pDevice->GetName()), CItem(pDevice->GetItemType(), 1));
		}

	//	Add device slots

	LeftSide.Insert(CONSTLIT("05"), CItem(g_pUniverse->GetItemType(0), SPECIAL_DEVICE_SLOTS));

	//	Set the ship class info. All weapons go to the right of the ship image

	int xPos = (cxWidth / 2) + (SHIP_IMAGE_RECT_WIDTH / 2);
	int yPos = 0;
	int cxInfo = (cxWidth - xPos);

	for (i = 0; i < RightSide.GetCount(); i++)
		{
		int cyInfo;
		IAnimatron *pInfo;
		AddClassInfo(pClass, Devices, RightSide[i], xPos, yPos, cxInfo, 0, &cyInfo, &pInfo);

		pClassInfo->AddTrack(pInfo, 0);
		yPos += cyInfo + ITEM_INFO_PADDING_VERT;
		}

	//	Misc devices go on the left

	xPos = (cxWidth / 2) - (SHIP_IMAGE_RECT_WIDTH / 2);
	yPos = 0;
	cxInfo = xPos;

	for (i = 0; i < LeftSide.GetCount(); i++)
		{
		int cyInfo;
		IAnimatron *pInfo;
		AddClassInfo(pClass, Devices, LeftSide[i], xPos, yPos, cxInfo, CUIHelper::OPTION_ITEM_RIGHT_ALIGN, &cyInfo, &pInfo);

		pClassInfo->AddTrack(pInfo, 0);
		yPos += cyInfo + ITEM_INFO_PADDING_VERT;
		}

	m_pRoot->AddLine(pClassInfo);
	}