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; }
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; }
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); }
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); } } } } }
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; }
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; }
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); }
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; }
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); }
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; }
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); }
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; }
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; }
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); }
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"); } }
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); } } } }
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); }