コード例 #1
0
ファイル: CItemCtx.cpp プロジェクト: bmer/Mammoth
CInstalledArmor *CItemCtx::GetArmor(void)

//	GetArmor
//
//	Returns the installed armor struct

	{
	//	If we've got it, done

	if (m_pArmor)
		return m_pArmor;

	//	Otherwise, try to get it from the item and source

	CShip *pShip;
	if (m_pSource 
			&& m_pItem 
			&& m_pItem->IsInstalled() 
			&& m_pItem->GetType()
			&& m_pItem->GetType()->GetCategory() == itemcatArmor
			&& (pShip = m_pSource->AsShip()))
		{
		//	Cache it in case someone asks later
		m_pArmor = pShip->GetArmorSection(m_pItem->GetInstalled());
		return m_pArmor;
		}

	//	Couldn't get it

	return NULL;
	}
コード例 #2
0
int CShieldClass::GetMaxHP (CInstalledDevice *pDevice, CSpaceObject *pSource)

//	GetMaxHP
//
//	Max HP of shields
	
	{
	int iMax = m_iHitPoints;

	//	Adjust based on charges

	if (m_iExtraHPPerCharge)
		iMax = Max(0, iMax + m_iExtraHPPerCharge * pDevice->GetCharges(pSource));

	//	Adjust if shield is based on armor strength

	CShip *pShip;
	if (m_iArmorShield && (pShip = pSource->AsShip()))
		{
		//	Compute the average HP of all the armor

		int iArmorHP = 0;
		int iArmorCount = pShip->GetArmorSectionCount();
		for (int i = 0; i < iArmorCount; i++)
			iArmorHP += pShip->GetArmorSection(i)->GetHitPoints();

		if (iArmorCount > 0)
			iArmorHP = ((m_iArmorShield * iArmorHP / iArmorCount) + 5) / 10;

		//	Return HP left

		iMax = Min(iMax, iArmorHP);
		}

	//	Fire event

	iMax = FireGetMaxHP(pDevice, pSource, iMax);

	//	Adjust based on enhancements

	CItemEnhancementStack *pEnhancements = pDevice->GetEnhancements();
	if (pEnhancements)
		iMax = iMax + ((iMax * pEnhancements->GetBonus()) / 100);

	//	Done

	return iMax;
	}
コード例 #3
0
void CRepairerClass::Update (CInstalledDevice *pDevice, CSpaceObject *pSource, int iTick, bool *retbSourceDestroyed, bool *retbConsumedItems)

//	Update
//
//	Updates the device

	{
	int i;

	CShip *pShip = pSource->AsShip();
	if (pShip)
		{
		if ((iTick % REPAIR_CYCLE_TIME) == 0
				&& pDevice->IsEnabled() && !pDevice->IsDamaged())
			{
			int iCycle = iTick / REPAIR_CYCLE_TIME;

			for (i = 0; i < pShip->GetArmorSectionCount(); i++)
				{
				if (pShip->IsArmorDamaged(i))
					{
					//	Figure out the tech of this armor

					CArmorClass *pArmorClass = pShip->GetArmorSection(i)->pArmorClass;
					int iArmorTech = pArmorClass->GetRepairTech();

					//	Figure out the cycle time for repairing this tech

					int iRepairCycle = 0;
					if (iArmorTech <= m_RepairCycle.GetCount())
						iRepairCycle = m_RepairCycle.GetElement(iArmorTech-1);

					//	Time to repair?

					if (iRepairCycle > 0 && (iCycle % iRepairCycle) == 0)
						{
						//	Repair one point of armor

						pShip->RepairArmor(i, 1);
						}
					}
				}
			}
		}

	if (retbConsumedItems)
		*retbConsumedItems = false;
	}
コード例 #4
0
int CRepairerClass::CalcPowerUsed (CInstalledDevice *pDevice, CSpaceObject *pSource)

//	CalcPowerUsed
//
//	Computes the amount of power used by this device each tick

	{
	int i;

	//	Doesn't work if not enabled

	if (!pDevice->IsEnabled())
		return 0;

	int iPower = 0;

	//	Get a ship object and calculate based on armor

	CShip *pShip = pSource->AsShip();
	if (pShip)
		{
		for (i = 0; i < pShip->GetArmorSectionCount(); i++)
			{
			if (pShip->IsArmorDamaged(i))
				{
				//	Figure out the tech of this armor

				CArmorClass *pArmorClass = pShip->GetArmorSection(i)->pArmorClass;
				int iArmorTech = pArmorClass->GetRepairTech();

				//	Figure out the cycle time for repairing this tech

				int iRepairCycle = 0;
				if (iArmorTech <= m_RepairCycle.GetCount())
					iRepairCycle = m_RepairCycle.GetElement(iArmorTech-1);

				//	Repair?

				if (iRepairCycle > 0)
					iPower += m_iPowerUse;
				}
			}
		}

	return iPower;
	}
コード例 #5
0
ファイル: CCUtil.cpp プロジェクト: alanhorizon/Transcendence
CInstalledArmor *GetArmorSectionArg (CCodeChain &CC, ICCItem *pArg, CSpaceObject *pObj)

//	GetArmorSectionArg
//
//	Returns an armor section from a section number or an item struct
//	Returns NULL if invalid.

	{
	//	Get the ship 

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

	//	Set the armor segment

	int iArmorSeg;
	if (pArg->IsList())
		{
		CItem Item = CreateItemFromList(CC, pArg);
		if (Item.GetType() && Item.GetType()->GetArmorClass() && Item.IsInstalled())
			iArmorSeg = Item.GetInstalled();
		else
			return NULL;
		}
	else
		iArmorSeg = pArg->GetIntegerValue();

	//	Some error checking

	if (iArmorSeg < 0 || iArmorSeg >= pShip->GetArmorSectionCount())
		return NULL;

	//	Done

	return pShip->GetArmorSection(iArmorSeg);
	}
コード例 #6
0
void CGSelectorArea::SetRegionsFromArmor (CSpaceObject *pSource)

//	SetRegionsFromArmor
//
//	Generates regions showing armor and shields for the given ship.

	{
	int i;
	ASSERT(pSource);
	if (pSource == NULL)
		return;

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

	CShipClass *pClass = pShip->GetClass();

	//	Compute some metrics.
	//
	//	We place the shield generator in the center and the armor segments in a
	//	circle around it.

	const RECT &rcRect = GetRect();
	int cxArea = RectWidth(rcRect);
	int cyArea = RectHeight(rcRect);

	const int iRadius = WIDE_COLUMN_SPACING;

	//	Now add all the armor segments

	for (i = 0; i < pShip->GetArmorSectionCount(); i++)
		{
		SEntry *pEntry = m_Regions.Insert();
		CInstalledArmor *pArmor = pShip->GetArmorSection(i);

		pEntry->iType = typeInstalledItem;
		pEntry->pItemCtx = new CItemCtx(pShip, pArmor);

		//	Position the armor segment in a circle (add 90 degrees because the
		//	ship image points up).

        const CShipArmorSegmentDesc &Section = pClass->GetHullSection(i);
        int iCenterAngle = 90 + Section.GetCenterAngle();

		int xCenter;
		int yCenter;
		IntPolarToVector(iCenterAngle, iRadius, &xCenter, &yCenter);

		pEntry->rcRect.left = xCenter - (ITEM_ENTRY_WIDTH / 2);
		pEntry->rcRect.top = -yCenter - (ITEM_ENTRY_HEIGHT / 2);
		pEntry->rcRect.right = pEntry->rcRect.left + ITEM_ENTRY_WIDTH;
		pEntry->rcRect.bottom = pEntry->rcRect.top + ITEM_ENTRY_HEIGHT;
		}

	//	Add the shield generator last

	SEntry *pEntry = m_Regions.Insert();
	CInstalledDevice *pShields = pShip->GetNamedDevice(devShields);
	if (pShields)
		{
		pEntry->iType = typeInstalledItem;
		pEntry->pItemCtx = new CItemCtx(pShip, pShields);
		}
	else
		{
		pEntry->iType = typeEmptySlot;
		pEntry->iSlotType = devShields;
		}

	pEntry->rcRect.left = -ITEM_ENTRY_WIDTH / 2;
	pEntry->rcRect.top = -ITEM_ENTRY_HEIGHT / 2;
	pEntry->rcRect.right = pEntry->rcRect.left + ITEM_ENTRY_WIDTH;
	pEntry->rcRect.bottom = pEntry->rcRect.top + ITEM_ENTRY_HEIGHT;
	}
コード例 #7
0
void CArmorDisplay::Update (void)

//	Update
//
//	Updates buffer from data

	{
	int i;

	if (m_pPlayer == NULL)
		return;

	CShip *pShip = m_pPlayer->GetShip();
	const CPlayerSettings *pSettings = pShip->GetClass()->GetPlayerSettings();
	CItemListManipulator ItemList(pShip->GetItemList());
	const CG16bitFont &SmallFont = m_pPlayer->GetTrans()->GetFonts().Small;
	m_Text.DeleteAll();

	//	If we've changed ships then we need to delete the painters

	if (m_dwCachedShipID != pShip->GetID())
		{
		if (m_pShieldPainter)
			{
			m_pShieldPainter->Delete();
			m_pShieldPainter = NULL;
			}

		m_dwCachedShipID = pShip->GetID();
		}

	//	Erase everything

	m_Buffer.Fill(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, DEFAULT_TRANSPARENT_COLOR);

	//	Figure out the status of the shields

	int iHP = 0;
	int iMaxHP = 10;
	CInstalledDevice *pShield = pShip->GetNamedDevice(devShields);
	if (pShield)
		pShield->GetStatus(pShip, &iHP, &iMaxHP);

	//	Draw the base ship image, if we have it

	const SArmorImageDesc &ArmorDesc = pSettings->GetArmorDesc();
	if (!ArmorDesc.ShipImage.IsEmpty())
		{
		const RECT &rcShip = ArmorDesc.ShipImage.GetImageRect();

		m_Buffer.ColorTransBlt(rcShip.left, 
				rcShip.top, 
				RectWidth(rcShip), 
				RectHeight(rcShip), 
				255,
				ArmorDesc.ShipImage.GetImage(NULL_STR), 
				DESCRIPTION_WIDTH + ((SHIELD_IMAGE_WIDTH - RectWidth(rcShip)) / 2),
				(SHIELD_IMAGE_HEIGHT - RectHeight(rcShip)) / 2);
		}

	//	Draw the old-style shields

	const SShieldImageDesc &ShieldDesc = pSettings->GetShieldDesc();
	if (!ShieldDesc.pShieldEffect)
		{
		int iWhole = (iMaxHP > 0 ? (iHP * 100) / iMaxHP : 100);
		int iIndex = (100 - iWhole) / 20;

		const RECT &rcShield = ShieldDesc.Image.GetImageRect();
		m_Buffer.ColorTransBlt(rcShield.left, 
				rcShield.top + (RectHeight(rcShield) * iIndex), 
				RectWidth(rcShield), 
				RectHeight(rcShield), 
				255,
				ShieldDesc.Image.GetImage(NULL_STR), 
				DESCRIPTION_WIDTH + ((SHIELD_IMAGE_WIDTH - RectWidth(rcShield)) / 2),
				(SHIELD_IMAGE_HEIGHT - RectHeight(rcShield)) / 2);
		}

	if (pShield)
		{
		m_Buffer.Fill(SHIELD_HP_DISPLAY_X,
				SHIELD_HP_DISPLAY_Y, 
				SHIELD_HP_DISPLAY_WIDTH, 
				SHIELD_HP_DISPLAY_HEIGHT,
				SHIELD_HP_DISPLAY_BACK_COLOR);
		
		CString sHP = strFromInt(iHP);
		int cxWidth = m_pFonts->Medium.MeasureText(sHP, NULL);
		m_pFonts->Medium.DrawText(m_Buffer,
				SHIELD_HP_DISPLAY_X + (SHIELD_HP_DISPLAY_WIDTH - cxWidth) / 2,
				SHIELD_HP_DISPLAY_Y - 1,
				CG16bitImage::LightenPixel(m_pFonts->wAltGreenColor, 60),
				sHP);

		DrawBrokenLine(m_Buffer,
				0,
				SHIELD_HP_DISPLAY_Y,
				SHIELD_HP_DISPLAY_X,
				SHIELD_HP_DISPLAY_Y,
				0,
				SHIELD_HP_DISPLAY_LINE_COLOR);

		WORD wColor;
		if (pShield->IsEnabled() && !pShield->IsDamaged() && !pShield->IsDisrupted())
			wColor = m_pFonts->wAltGreenColor;
		else
			wColor = DISABLED_TEXT_COLOR;

		CString sShieldName = pShield->GetClass()->GetName();
		int cyHeight;
		cxWidth = m_pFonts->Medium.MeasureText(sShieldName, &cyHeight);

		//	Add the shield name to list of text to paint

		STextPaint *pPaint = m_Text.Insert();
		pPaint->sText = sShieldName;
		pPaint->x = 0;
		pPaint->y = SHIELD_HP_DISPLAY_Y;
		pPaint->pFont = &m_pFonts->Medium;
		pPaint->wColor = wColor;

		//	Paint the modifiers

		if (pShield->GetMods().IsNotEmpty() || pShield->GetBonus() != 0)
			{
			pShip->SetCursorAtNamedDevice(ItemList, devShields);
			CString sMods = pShield->GetEnhancedDesc(pShip, &ItemList.GetItemAtCursor());
			if (!sMods.IsBlank())
				{
				bool bDisadvantage = (*(sMods.GetASCIIZPointer()) == '-');

				int cx = SmallFont.MeasureText(sMods);
				m_Buffer.Fill(SHIELD_HP_DISPLAY_X - cx - 8,
						SHIELD_HP_DISPLAY_Y,
						cx + 8,
						SHIELD_HP_DISPLAY_HEIGHT,
						(bDisadvantage ? ARMOR_DAMAGED_BACK_COLOR : ARMOR_ENHANCE_BACK_COLOR));

				SmallFont.DrawText(m_Buffer,
						SHIELD_HP_DISPLAY_X - cx - 4,
						SHIELD_HP_DISPLAY_Y + (SHIELD_HP_DISPLAY_HEIGHT - SmallFont.GetHeight()) / 2,
						(bDisadvantage ? ARMOR_DAMAGED_TEXT_COLOR : ARMOR_ENHANCE_TEXT_COLOR),
						sMods);
				}
			}
		}

	//	Draw armor

	int iArmorCount = Min(pShip->GetArmorSectionCount(), pSettings->GetArmorDescCount());
	for (i = 0; i < iArmorCount; i++)
		{
		const SArmorSegmentImageDesc *pImage = &pSettings->GetArmorDesc(i);

		CInstalledArmor *pArmor = pShip->GetArmorSection(i);
		int iMaxHP = pArmor->GetMaxHP(pShip);
		int iWhole = (iMaxHP == 0 ? 100 : (pArmor->GetHitPoints() * 100) / iMaxHP);
		int iIndex = (100 - iWhole) / 20;
		
		if (iIndex < 5)
			{
			const RECT &rcImage = pImage->Image.GetImageRect();
			m_Buffer.ColorTransBlt(rcImage.left,
					rcImage.top + iIndex * RectHeight(rcImage),
					RectWidth(rcImage),
					RectHeight(rcImage),
					255,
					pImage->Image.GetImage(NULL_STR),
					DESCRIPTION_WIDTH + pImage->xDest,
					pImage->yDest);
			}
		}

	//	Draw the new style shields on top

	if (ShieldDesc.pShieldEffect)
		{
		int x = DESCRIPTION_WIDTH + SHIELD_IMAGE_WIDTH / 2;
		int y = SHIELD_IMAGE_HEIGHT / 2;

		SViewportPaintCtx Ctx;
		Ctx.iTick = g_pUniverse->GetTicks();
		Ctx.iVariant = (iMaxHP > 0 ? (iHP * 100) / iMaxHP : 0);
		Ctx.iDestiny = pShip->GetDestiny();
		Ctx.iRotation = 90;

		if (m_pShieldPainter == NULL)
			m_pShieldPainter = ShieldDesc.pShieldEffect->CreatePainter();

		m_pShieldPainter->Paint(m_Buffer, x, y, Ctx);
		}

	//	Draw armor names

	for (i = 0; i < iArmorCount; i++)
		{
		const SArmorSegmentImageDesc *pImage = &pSettings->GetArmorDesc(i);
		CInstalledArmor *pArmor = pShip->GetArmorSection(i);

		//	Paint the HPs

		if (i == m_iSelection)
			{
			m_Buffer.Fill(DESCRIPTION_WIDTH + pImage->xHP - 1, 
					pImage->yHP - 1, 
					HP_DISPLAY_WIDTH + 2, 
					HP_DISPLAY_HEIGHT + 2,
					CG16bitImage::DarkenPixel(m_pFonts->wSelectBackground, 128));
			}
		else
			{
			m_Buffer.Fill(DESCRIPTION_WIDTH + pImage->xHP, 
					pImage->yHP, 
					HP_DISPLAY_WIDTH, 
					HP_DISPLAY_HEIGHT,
					HP_DISPLAY_BACK_COLOR);
			}

		CString sHP = strFromInt(pArmor->GetHitPoints());
		int cxWidth = m_pFonts->Medium.MeasureText(sHP, NULL);
		m_pFonts->Medium.DrawText(m_Buffer,
				DESCRIPTION_WIDTH + pImage->xHP + (HP_DISPLAY_WIDTH - cxWidth) / 2,
				pImage->yHP - 1,
				m_pFonts->wTitleColor,
				sHP);

		//	Paint the armor name line

		DrawBrokenLine(m_Buffer,
				0,
				pImage->yName + m_pFonts->Medium.GetHeight(),
				DESCRIPTION_WIDTH + pImage->xHP + pImage->xNameDestOffset,
				pImage->yHP + pImage->yNameDestOffset,
				pImage->cxNameBreak,
				(i == m_iSelection ? CG16bitImage::DarkenPixel(m_pFonts->wSelectBackground, 128) : ARMOR_LINE_COLOR));

		//	Paint the armor names

		CString sName = pArmor->GetClass()->GetShortName();
		int cy;
		int cx = m_pFonts->Medium.MeasureText(sName, &cy) + 4;
		if (i == m_iSelection)
			{
			m_Buffer.Fill(0, 
					pImage->yName, 
					cx, 
					cy,
					CG16bitImage::DarkenPixel(m_pFonts->wSelectBackground, 128));
			}

		STextPaint *pPaint = m_Text.Insert();
		pPaint->sText = sName;
		pPaint->x = 2;
		pPaint->y = pImage->yName;
		pPaint->pFont = &m_pFonts->Medium;
		pPaint->wColor = m_pFonts->wTitleColor;

		//	Paint the modifiers

		if (pArmor->GetMods().IsNotEmpty())
			{
			pShip->SetCursorAtArmor(ItemList, i);
			CString sMods = ItemList.GetItemAtCursor().GetEnhancedDesc(pShip);
			if (!sMods.IsBlank())
				{
				int cx = SmallFont.MeasureText(sMods);
				m_Buffer.Fill(ARMOR_ENHANCE_X - cx - 4,
						pImage->yName + m_pFonts->Medium.GetHeight() - HP_DISPLAY_HEIGHT,
						cx + 8,
						HP_DISPLAY_HEIGHT,
						ARMOR_ENHANCE_BACK_COLOR);

				SmallFont.DrawText(m_Buffer,
						ARMOR_ENHANCE_X - cx,
						pImage->yName + 3,
						ARMOR_ENHANCE_TEXT_COLOR,
						sMods);
				}
			}
		}
	}