예제 #1
0
파일: Devices.cpp 프로젝트: bmer/Mammoth
bool CDeviceClass::FindAmmoDataField (CItemType *pItem, const CString &sField, CString *retsValue)

//	FindAmmoDataField
//
//	Finds the device that fires this item and returns the given field

	{
	int i;

	for (i = 0; i < g_pUniverse->GetItemTypeCount(); i++)
		{
		CItemType *pType = g_pUniverse->GetItemType(i);
		CDeviceClass *pWeapon;

		if (pType->IsDevice() 
				&& (pWeapon = pType->GetDeviceClass()))
			{
			int iVariant = pWeapon->GetAmmoVariant(pItem);
			if (iVariant != -1)
				return pWeapon->FindDataField(iVariant, sField, retsValue);
			}
		}

	return false;
	}
예제 #2
0
파일: Devices.cpp 프로젝트: bmer/Mammoth
bool CDeviceClass::FindWeaponFor (CItemType *pItem, CDeviceClass **retpWeapon, int *retiVariant, CWeaponFireDesc **retpDesc)

//	FindWeaponFor
//
//	Returns weapon data for the given item (which may be a weapon or a missile).

	{
	int i;
	CDeviceClass *pDevice;
	int iVariant;

	//	Get the device and variant

	if (pItem->IsMissile())
		{
		iVariant = -1;

		for (i = 0; i < g_pUniverse->GetItemTypeCount(); i++)
			{
			CItemType *pType = g_pUniverse->GetItemType(i);

			if (pDevice = pType->GetDeviceClass())
				{
				iVariant = pDevice->GetAmmoVariant(pItem);
				if (iVariant != -1)
					break;
				}
			}

		if (iVariant == -1)
			return false;
		}
	else
		{
		pDevice = pItem->GetDeviceClass();
		if (pDevice == NULL)
			return false;

		iVariant = 0;
		}

	CWeaponClass *pWeapon = pDevice->AsWeaponClass();
	if (pWeapon == NULL)
		return false;

	CWeaponFireDesc *pDesc = pWeapon->GetVariant(iVariant);

	//	Done

	if (retpWeapon)
		*retpWeapon = pDevice;

	if (retiVariant)
		*retiVariant = iVariant;

	if (retpDesc)
		*retpDesc = pDesc;

	return true;
	}
예제 #3
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);
	}
예제 #4
0
void CAutoDefenseClass::Update (CInstalledDevice *pDevice, 
								CSpaceObject *pSource, 
								int iTick,
								bool *retbSourceDestroyed,
								bool *retbConsumedItems)

//	Update
//
//	Update device

	{
	if (pDevice->IsReady() && pDevice->IsEnabled())
		{
		int i;

		//	Look for a target

		CSpaceObject *pBestTarget = NULL;
		Metric rBestDist2 = MAX_INTERCEPT_DISTANCE * MAX_INTERCEPT_DISTANCE;

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

			if (pObj
					&& pObj->GetCategory() == CSpaceObject::catMissile
					&& pObj->GetSource() != pSource
					&& (pObj->GetSource() == NULL || pSource->IsEnemy(pObj->GetSource())))
				{
				CVector vRange = pObj->GetPos() - pSource->GetPos();
				Metric rDistance2 = vRange.Dot(vRange);

				if (rDistance2 < rBestDist2)
					{
					pBestTarget = pObj;
					rBestDist2 = rDistance2;
					}
				}
			}

		//	If we found a target, try to shoot at it

		if (pBestTarget)
			{
			CDeviceClass *pWeapon = GetWeapon();

			if (pWeapon)
				{
				int iFireAngle;
				if (pWeapon->IsWeaponAligned(pSource, pDevice, pBestTarget, &iFireAngle))
					{
					pDevice->SetFireAngle(iFireAngle);
					pWeapon->Activate(pDevice, pSource, pBestTarget, iFireAngle, retbSourceDestroyed, retbConsumedItems);
					pDevice->SetActivationDelay(m_iRechargeTicks);
					}
				}
			}
		}
	}
예제 #5
0
int CAutoDefenseClass::GetPowerRating (const CItem *pItem)

//	GetPowerRating
//
//	Returns the minimum reactor power needed for this device

	{
	CDeviceClass *pWeapon = GetWeapon();

	if (pWeapon)
		return pWeapon->GetPowerRating(pItem);
	else
		return 0;
	}
예제 #6
0
int CAutoDefenseClass::GetDamageType (CInstalledDevice *pDevice)

//	GetDamageType
//
//	Returns the type of damage done by this device

	{
	CDeviceClass *pWeapon = GetWeapon();

	if (pWeapon)
		return pWeapon->GetDamageType(pDevice);
	else
		return -1;
	}
예제 #7
0
int CAutoDefenseClass::CalcPowerUsed (CInstalledDevice *pDevice, CSpaceObject *pSource)

//	CalcPowerUsed
//
//	Return power used by device

	{
	CDeviceClass *pWeapon = GetWeapon();

	if (pWeapon == NULL || !pDevice->IsEnabled())
		return 0;

	return pWeapon->CalcPowerUsed(pDevice, pSource);
	}
예제 #8
0
CDeviceClass *CDeviceDescList::GetNamedDevice (DeviceNames iDev) const

//	GetNamedDevice
//
//	Returns the named device (or NULL if not found)

	{
	int i;
	ItemCategories iCatToFind = CDeviceClass::GetItemCategory(iDev);

	for (i = 0; i < m_iCount; i++)
		{
		CDeviceClass *pDevice = GetDeviceClass(i);

		//	See if this is the category that we want to find

		if (pDevice->GetCategory() == iCatToFind)
			return pDevice;
		}

	return NULL;
	}
예제 #9
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);
	}
예제 #10
0
CWeaponFireDesc *CWeaponFireDesc::FindWeaponFireDescFromFullUNID (const CString &sUNID)

//	FindWeaponFireDesc
//
//	Finds the descriptor by name

	{
	char *pPos = sUNID.GetPointer();

	//	Get the UNID of the type

	DWORD dwUNID = (DWORD)strParseInt(pPos, 0, &pPos);
	if (dwUNID == 0)
		return NULL;

	//	Get the type

	CDesignType *pType = g_pUniverse->FindDesignType(dwUNID);
	if (pType == NULL)
		return NULL;

	//	If this is an item, then it must be a weapon

	if (pType->GetType() == designItemType)
		{
		CItemType *pItemType = CItemType::AsType(pType);
		ASSERT(pItemType);

		CDeviceClass *pDevice = pItemType->GetDeviceClass();
		if (pDevice == NULL)
			return NULL;

		CWeaponClass *pClass = pDevice->AsWeaponClass();
		if (pClass == NULL)
			return NULL;

		//	Get the ordinal

		ASSERT(*pPos == '/');
		pPos++;
		int iOrdinal = strParseInt(pPos, 0, &pPos);

		//	Get the weapon fire desc of the ordinal

		CWeaponFireDesc *pDesc = pClass->GetVariant(iOrdinal);
		if (pDesc == NULL)
			return NULL;

		//	Continue parsing

		return pDesc->FindWeaponFireDesc(CString(pPos));
		}

	//	If this is an effect, then get it from that

	else if (pType->GetType() == designEffectType)
		{
		CEffectCreator *pEffectType = CEffectCreator::AsType(pType);
		ASSERT(pEffectType);

		//	Expect /d

		ASSERT(*pPos == '/');
		pPos++;
		ASSERT(*pPos == 'd');
		pPos++;

		CWeaponFireDesc *pDesc = pEffectType->GetDamageDesc();
		if (pDesc == NULL)
			return NULL;

		//	Continue parsing

		return pDesc->FindWeaponFireDesc(CString(pPos));
		}

	//	Otherwise, we don't know

	else
		return NULL;
	}
예제 #11
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);
	}
예제 #12
0
CWeaponFireDesc *GetWeaponFireDescArg (ICCItem *pArg)

//	GetWeaponFireDescArg
//
//	If arg is a weapon UNID, then we return the first weapon desc
//	If arg is a missile, then we return the first weapon desc we find for the missile
//	If arg is a list, then the first is a weapon UNID and the second is a missile UNID
//	Returns NULL on error

	{
	int i;
	DWORD dwWeaponUNID;
	DWORD dwVariantUNID;

	//	If the argument is a list, then we get the weapon UNID and the variant
	//	from the list.

	if (pArg->IsList() && pArg->GetCount() >= 2)
		{
		dwWeaponUNID = (DWORD)pArg->GetElement(0)->GetIntegerValue();
		dwVariantUNID = (DWORD)pArg->GetElement(1)->GetIntegerValue();
		}

	//	Otherwise, get the first variant of the weapon

	else
		{
		dwWeaponUNID = (DWORD)pArg->GetIntegerValue();
		dwVariantUNID = 0;
		}

	//	Get the item associated with the UNID

	CItemType *pType = g_pUniverse->FindItemType(dwWeaponUNID);
	if (pType == NULL)
		return NULL;

	//	If this is a weapon, then return the weapon fire desc

	if (pType->GetCategory() == itemcatWeapon || pType->GetCategory() == itemcatLauncher)
		{
		CDeviceClass *pClass = pType->GetDeviceClass();
		if (pClass == NULL)
			return NULL;

		CWeaponClass *pWeapon = pClass->AsWeaponClass();
		if (pWeapon == NULL)
			return NULL;

		//	If variant UNID is 0, then we just want the weapon

		if (dwVariantUNID == 0)
			return pWeapon->GetVariant(0);

		//	Otherwise, we need to find the variant index for the given UNID

		int i;
		for (i = 0; i < pWeapon->GetVariantCount(); i++)
			{
			CWeaponFireDesc *pDesc = pWeapon->GetVariant(i);
			if (pDesc->GetAmmoType()->GetUNID() == dwVariantUNID)
				return pDesc;
			}

		//	If we get this far, then we couldn't find the missile

		return NULL;
		}

	//	Otherwise, if this is a missile, then find the appropriate weapon

	else if (pType->GetCategory() == itemcatMissile)
		{
		for (i = 0; i < g_pUniverse->GetItemTypeCount(); i++)
			{
			CItemType *pWeaponType = g_pUniverse->GetItemType(i);
			CDeviceClass *pClass;
			if (pClass = pWeaponType->GetDeviceClass())
				{
				int iWeaponVariant;
				if ((iWeaponVariant = pClass->GetAmmoVariant(pType)) != -1)
					{
					CWeaponClass *pWeapon = dynamic_cast<CWeaponClass *>(pClass);
					if (pWeapon)
						return pWeapon->GetVariant(iWeaponVariant);
					}
				}
			}

		return NULL;
		}

	//	Otherwise, nothing

	else
		return NULL;
	}
예제 #13
0
void CUIHelper::CreateClassInfoDeviceSlots (CShipClass *pClass, const CDeviceDescList &Devices, int x, int y, int cxWidth, DWORD dwOptions, int *retcyHeight, IAnimatron **retpInfo) const

//	CreateClassInfoDeviceSlots
//
//	Creates info about the number of open device slots

	{
	int i;

	const CVisualPalette &VI = m_HI.GetVisuals();

	//	Count the number of slots being used

	int iAll = 0;
	int iWeapons = 0;
	int iNonWeapons = 0;
	for (i = 0; i < Devices.GetCount(); i++)
		{
		CDeviceClass *pDevice = Devices.GetDeviceClass(i);
		int iSlots = pDevice->GetSlotsRequired();
		iAll += iSlots;

		if (pDevice->GetCategory() == itemcatWeapon || pDevice->GetCategory() == itemcatLauncher)
			iWeapons += iSlots;
		else
			iNonWeapons += iSlots;
		}

	int iAllLeft = Max(0, pClass->GetMaxDevices() - iAll);
	int iWeaponsLeft = Max(0, Min(iAllLeft, pClass->GetMaxWeapons() - iWeapons));
	int iNonWeaponsLeft = Max(0, Min(iAllLeft, pClass->GetMaxNonWeapons() - iNonWeapons));

	//	Add the device slot statistic

	CString sNumber = strPatternSubst(CONSTLIT("%d"), iAllLeft);
	CString sHeader = (iAllLeft == 1 ? CONSTLIT("device slot for expansion") : CONSTLIT("device slots for expansion"));
	CString sDesc;
	if (iWeaponsLeft != iAllLeft && iNonWeaponsLeft != iAllLeft)
		sDesc = strPatternSubst(CONSTLIT("only %d for weapons; only %d for non-weapons"), iWeaponsLeft, iNonWeaponsLeft);
	else if (iWeaponsLeft != iAllLeft)
		sDesc = strPatternSubst(CONSTLIT("only %d device slot%p available for weapons"), iWeaponsLeft);
	else if (iNonWeaponsLeft != iAllLeft)
		sDesc = strPatternSubst(CONSTLIT("only %d device slot%p available for non-weapons"), iNonWeaponsLeft);

	//	Figure out some dimensions and metrics. Everything is relative to x, y.

	bool bRightAlign = ((dwOptions & OPTION_ITEM_RIGHT_ALIGN) ? true : false);
	int cxIcon = SMALL_ICON_WIDTH;
	int cyIcon = SMALL_ICON_HEIGHT;
	int xIcon = (bRightAlign ? -cxIcon : 0);
	int yIcon = 0;

	int cxText = cxWidth - (cxIcon + ITEM_INFO_SPACING_HORZ);
	int xText = (bRightAlign ? -cxWidth : cxIcon + ITEM_INFO_SPACING_HORZ);
	int yText = 0;

	//	Create a sequencer to hold all the controls

	CAniSequencer *pRoot;
	CAniSequencer::Create(CVector(x, y), &pRoot);

	//	Create a small item icon

	IAnimatron *pImageFrame = new CAniRect;
	pImageFrame->SetPropertyVector(PROP_POSITION, CVector(xIcon, yIcon));
	pImageFrame->SetPropertyVector(PROP_SCALE, CVector(SMALL_ICON_WIDTH, SMALL_ICON_HEIGHT));
	pImageFrame->SetFillMethod(new CAniImageFill(&VI.GetImage(imageSlotIcon), false));

	pRoot->AddTrack(pImageFrame, 0);

	//	Create some text

	int cyText = 0;

	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)),
			sNumber,
			CG16bitImage::RGBFromPixel(VI.GetColor(colorTextDialogInput)),
			sHeader,
			CG16bitImage::RGBFromPixel(VI.GetColor(colorTextDialogLabel)),
			sDesc);

	//	Add the text item

	IAnimatron *pRef = new CAniRichText(VI);
	pRef->SetPropertyVector(PROP_POSITION, CVector(xText, yText + cyText));
	pRef->SetPropertyVector(PROP_SCALE, CVector(cxText, 1000));
	pRef->SetPropertyString(PROP_TEXT, sText);
	if (bRightAlign)
		pRef->SetPropertyString(PROP_TEXT_ALIGN_HORZ, ALIGN_RIGHT);

	pRoot->AddTrack(pRef, 0);

	RECT rcRef;
	pRef->GetSpacingRect(&rcRef);
	cyText += RectHeight(rcRef);

	//	Done

	if (retcyHeight)
		*retcyHeight = Max(cyText, SMALL_ICON_HEIGHT);

	*retpInfo = pRoot;
	}
예제 #14
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);
	}
예제 #15
0
void OutputTable (SItemTableCtx &Ctx, const SItemTypeList &ItemList)
	{
	int i, j;

	if (ItemList.GetCount() == 0)
		return;

	//	Output each row

	for (i = 0; i < ItemList.GetCount(); i++)
		{
		CItemType *pType = ItemList[i];
		CItem Item(pType, 1);
		CItemCtx ItemCtx(Item);

		for (j = 0; j < Ctx.Cols.GetCount(); j++)
			{
			if (j != 0)
				printf("\t");

			const CString &sField = Ctx.Cols[j];

            //  Handle some special fields

            if (strEquals(sField, FIELD_BENCHMARK))
                {
                CWeaponBenchmarkCtx::SStats Stats;
                if (!Ctx.WeaponBenchmarks.GetStats(pType, Stats))
                    {
                    printf("\t\t\t\t");
                    }
                else
                    {
                    CString sBestArmor;
                    if (Stats.pBestArmor)
                        {
                        CItem BestArmor(Stats.pBestArmor, 1);
                        sBestArmor = BestArmor.GetNounPhrase(nounShort);
                        }

                    CString sWorstArmor;
                    if (Stats.pWorstArmor)
                        {
                        CItem WorstArmor(Stats.pWorstArmor, 1);
                        sWorstArmor = WorstArmor.GetNounPhrase(nounShort);
                        }

                    printf("%d\t%s\t%d\t%s\t%d",
                            Stats.iAverageTime,
                            (LPSTR)sBestArmor,
                            Stats.iBestTime,
                            (LPSTR)sWorstArmor,
                            Stats.iWorstTime);
                    }
                }

            else if (strEquals(sField, FIELD_BALANCE_STATS))
                {
                CDeviceClass *pDevice = pType->GetDeviceClass();
                CWeaponClass *pWeapon = NULL;

                if (pDevice)
                    pWeapon = pDevice->AsWeaponClass();
                else if (pType->IsMissile() && ItemCtx.ResolveVariant())
                    {
                    pDevice = ItemCtx.GetVariantDevice();
                    pWeapon = pDevice->AsWeaponClass();
                    }

                if (pWeapon)
                    {
                    CWeaponClass::SBalance Balance;
                    pWeapon->CalcBalance(ItemCtx, Balance);
                    printf("%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f",
                            Balance.rBalance,
                            Balance.rBalance - Balance.rCost,
                            Balance.rDamage,
                            Balance.rDamageType,
                            Balance.rAmmo,
                            Balance.rOmni,
                            Balance.rTracking,
                            Balance.rRange,
                            Balance.rSpeed,
                            Balance.rWMD,
                            Balance.rRadiation,
                            Balance.rMining,
                            Balance.rShatter,
                            Balance.rDeviceDisrupt,
                            Balance.rDeviceDamage,
                            Balance.rDisintegration,
                            Balance.rShieldPenetrate,
                            Balance.rArmor,
                            Balance.rShield,
                            Balance.rProjectileHP,
                            Balance.rPower,
                            Balance.rCost,
                            Balance.rSlots,
                            Balance.rExternal,
                            Balance.rLinkedFire,
                            Balance.rRecoil
                            );
                    }
                else
                    printf("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t");
                }

			//	Get the field value

            else
                {
			    CString sValue;
			    CCodeChainCtx CCCtx;

			    ICCItem *pResult = Item.GetProperty(&CCCtx, ItemCtx, sField);

			    if (pResult->IsNil())
				    sValue = NULL_STR;
			    else
				    sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);

			    pResult->Discard(&g_pUniverse->GetCC());

			    //	Format the value

			    if (strEquals(sField, FIELD_POWER_PER_SHOT))
				    printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0);
			    else if (strEquals(sField, FIELD_POWER))
				    printf("%.1f", strToInt(sValue, 0, NULL) / 1000.0);
			    else if (strEquals(sField, FIELD_TOTAL_COUNT))
				    {
				    SDesignTypeInfo *pInfo = Ctx.TotalCount.GetAt(pType->GetUNID());
				    double rCount = (pInfo ? pInfo->rPerGameMeanCount : 0.0);
				    printf("%.2f", rCount);
				    }
			    else
				    printf(sValue.GetASCIIZPointer());
                }
			}

		printf("\n");
		}
	}
예제 #16
0
void CGSelectorArea::PaintInstalledItem (CG32bitImage &Dest, const RECT &rcRect, const SEntry &Entry)

//	PaintInstalledItem
//
//	Paints the installed item.

	{
	const CItem &Item = Entry.pItemCtx->GetItem();
	if (Item.GetType() == NULL)
		return;

	CSpaceObject *pSource = Entry.pItemCtx->GetSource();
	CInstalledArmor *pArmor = Entry.pItemCtx->GetArmor();
	CInstalledDevice *pDevice = Entry.pItemCtx->GetDevice();
	CDeviceClass *pDeviceClass;

	//	Paint the item icon

	bool bGrayed = (pDevice && !pDevice->IsEnabled());
	int xIcon = rcRect.left + (RectWidth(rcRect) - ITEM_ICON_WIDTH) / 2;
	int yIcon = rcRect.top + ITEM_ENTRY_PADDING_TOP;
	DrawItemTypeIcon(Dest, xIcon, yIcon, Item.GetType(), ITEM_ICON_WIDTH, ITEM_ICON_HEIGHT, bGrayed);

	//	Paint the name of the item below.

	RECT rcText;
	rcText.left = rcRect.left + ITEM_ENTRY_PADDING_LEFT;
	rcText.right = rcRect.right - ITEM_ENTRY_PADDING_RIGHT;
	rcText.top = yIcon + ITEM_ICON_HEIGHT;
	rcText.bottom = rcRect.bottom;

	m_VI.GetFont(fontMedium).DrawText(Dest, 
			rcText,
			m_rgbTextColor,
			Item.GetNounPhrase(nounShort | nounNoModifiers),
			0,
			CG16bitFont::AlignCenter);


	//	If this is an armor segment, then paint HP, etc.

	if (pArmor)
		{
		int x = rcRect.right - ITEM_ENTRY_PADDING_RIGHT;
		int y = rcRect.top + ITEM_ENTRY_PADDING_TOP;

		//	HP

		CString sHP = strFromInt(pArmor->GetHitPoints());
		m_VI.GetFont(fontLarge).DrawText(Dest,
				x,
				y,
				m_rgbTextColor,
				sHP,
				CG16bitFont::AlignRight);
		y += m_VI.GetFont(fontLarge).GetHeight();

		//	Damage

		int iMaxHP = pArmor->GetMaxHP(pSource);
		if (iMaxHP != pArmor->GetHitPoints() && iMaxHP > 0)
			{
			int iPercent = ((1000 * pArmor->GetHitPoints() / iMaxHP) + 5) / 10;
			CString sPercent = strPatternSubst(CONSTLIT("%d%%"), iPercent);

			m_VI.GetFont(fontMedium).DrawText(Dest,
					x,
					y,
					m_VI.GetColor(colorTextDockWarning),
					sPercent,
					CG16bitFont::AlignRight);
			y += m_VI.GetFont(fontMedium).GetHeight();
			}

		//	Modifiers

		if (pArmor->GetMods().IsNotEmpty())
			{
			CString sMods = Item.GetEnhancedDesc(pSource);
			if (!sMods.IsBlank())
				{
				bool bIsDisadvantage = *sMods.GetASCIIZPointer() == '-';
				CG32bitPixel rgbBackColor = (bIsDisadvantage ? m_VI.GetColor(colorAreaDisadvantage) : m_VI.GetColor(colorAreaAdvantage));
				CG32bitPixel rgbTextColor = (bIsDisadvantage ? m_VI.GetColor(colorTextDisadvantage) : m_VI.GetColor(colorTextAdvantage));

				PaintModifier(Dest, x, y, sMods, rgbTextColor, rgbBackColor, &y);
				}
			}
		}

	//	If this is a device, then paint device-specific stuff

	else if (pDevice
				&& (pDeviceClass = pDevice->GetClass()))
		{
		int x = rcRect.right - ITEM_ENTRY_PADDING_RIGHT;
		int y = rcRect.top + ITEM_ENTRY_PADDING_TOP;

		//	HP

		if (pDevice->IsEnabled())
			{
			if (pDevice->GetCategory() == itemcatShields)
				{
				int iHP;
				int iMaxHP;
				pDevice->GetStatus(pSource, &iHP, &iMaxHP);

				CString sHP = strFromInt(iHP);
				m_VI.GetFont(fontLarge).DrawText(Dest,
						x,
						y,
						m_rgbTextColor,
						sHP,
						CG16bitFont::AlignRight);
				y += m_VI.GetFont(fontLarge).GetHeight();

				//	Shield level

				if (iMaxHP != iHP && iMaxHP > 0)
					{
					int iPercent = ((1000 * iHP / iMaxHP) + 5) / 10;
					CString sPercent = strPatternSubst(CONSTLIT("%d%%"), iPercent);

					m_VI.GetFont(fontMedium).DrawText(Dest,
							x,
							y,
							m_VI.GetColor(colorTextShields),
							sPercent,
							CG16bitFont::AlignRight);
					y += m_VI.GetFont(fontMedium).GetHeight();
					}
				}
			}
		else
			PaintModifier(Dest, x, y, CONSTLIT("disabled"), m_VI.GetColor(colorTextNormal), CG32bitPixel::Null(), &y);

		//	External

		if (pDevice->IsExternal() || pDeviceClass->IsExternal())
			PaintModifier(Dest, x, y, CONSTLIT("external"), m_VI.GetColor(colorTextNormal), CG32bitPixel::Null(), &y);

		//	Damaged

		if (pDevice->IsDamaged())
			PaintModifier(Dest, x, y, CONSTLIT("damaged"), m_VI.GetColor(colorTextDisadvantage), m_VI.GetColor(colorAreaDisadvantage), &y);

		if (pDevice->IsDisrupted())
			PaintModifier(Dest, x, y, CONSTLIT("ionized"), m_VI.GetColor(colorTextDisadvantage), m_VI.GetColor(colorAreaDisadvantage), &y);

		//	Modifiers

		if (pDevice->GetEnhancements() != NULL)
			{
			CString sMods = pDevice->GetEnhancedDesc(pSource, &Item);
			if (!sMods.IsBlank())
				{
				bool bIsDisadvantage = *sMods.GetASCIIZPointer() == '-';
				CG32bitPixel rgbBackColor = (bIsDisadvantage ? m_VI.GetColor(colorAreaDisadvantage) : m_VI.GetColor(colorAreaAdvantage));
				CG32bitPixel rgbTextColor = (bIsDisadvantage ? m_VI.GetColor(colorTextDisadvantage) : m_VI.GetColor(colorTextAdvantage));

				PaintModifier(Dest, x, y, sMods, rgbTextColor, rgbBackColor, &y);
				}
			}
		}
	}
예제 #17
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);
	}