ALERROR CAdventureDesc::GetStartingShipClasses (TSortMap<CString, CShipClass *> *retClasses, CString *retsError)

//	GetStartingShipClasses
//
//	Returns a sorted list of ship classes for this adventure

{
    int i;

    bool bShowDebugShips = g_pUniverse->InDebugMode();

    //	Make a list

    retClasses->DeleteAll();
    for (i = 0; i < g_pUniverse->GetShipClassCount(); i++)
    {
        CShipClass *pClass = g_pUniverse->GetShipClass(i);
        if (pClass->IsShownAtNewGame()
                && IsValidStartingClass(pClass)
                && (!pClass->IsDebugOnly() || bShowDebugShips))
        {
            CString sKey = strPatternSubst(CONSTLIT("%d %s !%x"),
                                           (pClass->IsDebugOnly() ? 2 : 1),
                                           pClass->GetName(),
                                           pClass->GetUNID());
            retClasses->Insert(sKey, pClass);
        }
    }

    return NOERROR;
}
Esempio n. 2
0
void RunEncounterSim (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	int iRuns = pCmdLine->GetAttributeIntegerBounded(COUNT_ATTRIB, 1, -1, DEFAULT_RUN_COUNT);
	int iTimeOut = DEFAULT_TIME_OUT;

	//	Get the station criteria

	CString sCriteria = strPatternSubst(CONSTLIT("%s t"), pCmdLine->GetAttribute(DEFENDERS_ATTRIB));

	CDesignTypeCriteria DefenderCriteria;
	if (CDesignTypeCriteria::ParseCriteria(sCriteria, &DefenderCriteria) != NOERROR)
		{
		printf("ERROR: Unable to parse defenders criteria.\n");
		return;
		}

	bool bAll = pCmdLine->GetAttributeBool(CONSTLIT("all"));

	//	Get the criteria from the command line. Always append 's' because we
	//	want ship classes.

	sCriteria = strPatternSubst(CONSTLIT("%s s"), pCmdLine->GetAttribute(ATTACKERS_ATTRIB));

	CDesignTypeCriteria AttackerCriteria;
	if (CDesignTypeCriteria::ParseCriteria(sCriteria, &AttackerCriteria) != NOERROR)
		{
		printf("ERROR: Unable to parse attackers criteria.\n");
		return;
		}

	//	Create a viewer, if desired

	CSimViewer Viewer;
	if (pCmdLine->GetAttributeBool(VIEWER_ATTRIB))
		Viewer.Create();

	//	Print headers

	printf("Encounter\tLevel");

	int iAttacker;
	for (iAttacker = 0; iAttacker < Universe.GetShipClassCount(); iAttacker++)
		{
		CShipClass *pAttackerClass = Universe.GetShipClass(iAttacker);
		if (!pAttackerClass->MatchesCriteria(AttackerCriteria))
			continue;

		printf("\t%s", pAttackerClass->GetName().GetASCIIZPointer());
		}

	printf("\n");

	//	Loop over all defenders

	int iDefender;
	for (iDefender = 0; iDefender < Universe.GetStationTypeCount(); iDefender++)
		{
		CStationType *pDefenderType = Universe.GetStationType(iDefender);
		if (!bAll && pDefenderType->GetLevel() == 0)
			continue;

		if (!pDefenderType->MatchesCriteria(DefenderCriteria))
			continue;

		//	Compute an enemy of the station

		CSovereign *pAttackerSovereign = GetAttackerSovereign(Universe, pDefenderType);
		if (pAttackerSovereign == NULL)
			{
			printf("ERROR: Unable to find enemy sovereign of encounter: %s [%x].\n", pDefenderType->GetNounPhrase().GetASCIIZPointer(), pDefenderType->GetUNID());
			return;
			}

		printf("%s [%x]\t%d", pDefenderType->GetNounPhrase().GetASCIIZPointer(), pDefenderType->GetUNID(), pDefenderType->GetLevel());

		//	Loop over all attackers

		for (iAttacker = 0; iAttacker < Universe.GetShipClassCount(); iAttacker++)
			{
			CShipClass *pAttackerClass = Universe.GetShipClass(iAttacker);
			if (!pAttackerClass->MatchesCriteria(AttackerCriteria))
				continue;

			//	Do several runs so we can get some statistical data

			int iAttackerSurvived = 0;
			int iRun;
			for (iRun = 0; iRun < iRuns; iRun++)
				{
				EResults iResult = RunEncounter(Universe, Viewer, pDefenderType, pAttackerClass, pAttackerSovereign);
				if (iResult == resultError)
					return;

				//	Did the attacker survive?

				if (iResult != resultAttackerDestroyed)
					iAttackerSurvived++;
				}

			//	Output results for this attacker

			int iSurvivability = 100 * iAttackerSurvived / iRuns;
			printf("\t%d%%", iSurvivability);
			}

		printf("\n");
		}

	Viewer.Destroy();
	}
Esempio n. 3
0
void CListSaveFilesTask::CreateFileEntry (CGameFile &GameFile, const CTimeDate &ModifiedTime, int yStart, IAnimatron **retpEntry, int *retcyHeight)

//	CreateFileEntry
//
//	Creates a display entry for the save file

	{
	const CVisualPalette &VI = m_HI.GetVisuals();
	const CG16bitFont &MediumFont = VI.GetFont(fontMedium);
	const CG16bitFont &SubTitleFont = VI.GetFont(fontSubTitle);

	int x = 0;
	int y = 0;
	int xText = x + ADVENTURE_ICON_WIDTH + ICON_SPACING_HORZ;
	int cxText = m_cxWidth - (ADVENTURE_ICON_WIDTH + 2 * ICON_SPACING_HORZ + SHIP_IMAGE_WIDTH);

	//	Start with a sequencer

	CAniSequencer *pRoot = new CAniSequencer;
	pRoot->SetPropertyVector(PROP_POSITION, CVector(0, yStart));

	//	Add the character name and current star system

	CString sHeading = strPatternSubst(CONSTLIT("%s — %s"), GameFile.GetPlayerName(), GameFile.GetSystemName());

	IAnimatron *pName = new CAniText;
	pName->SetPropertyVector(PROP_POSITION, CVector(xText, y));
	pName->SetPropertyVector(PROP_SCALE, CVector(10000, 1000));
	pName->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogInput));
	pName->SetPropertyFont(PROP_FONT, &SubTitleFont);
	pName->SetPropertyString(PROP_TEXT, sHeading);

	pRoot->AddTrack(pName, 0);
	y += SubTitleFont.GetHeight();

	//	Now add some additional information

	CShipClass *pClass = g_pUniverse->FindShipClass(GameFile.GetPlayerShip());
	CString sShipClass = (pClass ? pClass->GetName() : NULL_STR);
	CString sGenome = strCapitalize(GetGenomeName(GameFile.GetPlayerGenome()));

	CString sState;
	if (GameFile.IsGameResurrect())
		sState = strPatternSubst(CONSTLIT("Resurrect in the %s System"), GameFile.GetSystemName());
	else
		sState = strPatternSubst(CONSTLIT("Continue in the %s System"), GameFile.GetSystemName());

	CString sDesc;
	if (!sGenome.IsBlank() && !sShipClass.IsBlank())
		sDesc = strPatternSubst(CONSTLIT("%s — %s — %s"), sGenome, sShipClass, sState);
	else
		sDesc = sState;

	IAnimatron *pDesc = new CAniText;
	pDesc->SetPropertyVector(PROP_POSITION, CVector(xText, y));
	pDesc->SetPropertyVector(PROP_SCALE, CVector(cxText, 1000));
	pDesc->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogInput));
	pDesc->SetPropertyFont(PROP_FONT, &MediumFont);
	pDesc->SetPropertyString(PROP_TEXT, sDesc);

	RECT rcLine;
	pDesc->GetSpacingRect(&rcLine);

	pRoot->AddTrack(pDesc, 0);
	y += RectHeight(rcLine);

	//	Adventure info

	CExtension *pAdventure = NULL;
	bool bHasAdventureIcon = false;

	if (g_pUniverse->FindExtension(GameFile.GetAdventure(), 0, &pAdventure))
		{
		//	Adventure icon

		CG16bitImage *pIcon;
		pAdventure->CreateIcon(ADVENTURE_ICON_WIDTH, ADVENTURE_ICON_HEIGHT, &pIcon);

		if (pIcon)
			{
			int xOffset = (ADVENTURE_ICON_WIDTH - pIcon->GetWidth()) / 2;
			IAnimatron *pIconAni = new CAniRect;
			pIconAni->SetPropertyVector(PROP_POSITION, CVector(x + xOffset, 0));
			pIconAni->SetPropertyVector(PROP_SCALE, CVector(pIcon->GetWidth(), pIcon->GetHeight()));
			pIconAni->SetFillMethod(new CAniImageFill(pIcon, true));

			pRoot->AddTrack(pIconAni, 0);

			bHasAdventureIcon = true;
			}

		//	Adventure name

		pName = new CAniText;
		pName->SetPropertyVector(PROP_POSITION, CVector(xText, y));
		pName->SetPropertyVector(PROP_SCALE, CVector(10000, 1000));
		pName->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogLabel));
		pName->SetPropertyFont(PROP_FONT, &MediumFont);
		pName->SetPropertyString(PROP_TEXT, pAdventure->GetName());

		pRoot->AddTrack(pName, 0);
		y += MediumFont.GetHeight();
		}

	//	Create an image of the ship class

	if (pClass)
		{
		const CObjectImageArray &ObjImage = pClass->GetImage();
		if (ObjImage.IsLoaded())
			{
			RECT rcRect = ObjImage.GetImageRect();
			CG16bitImage &Image = ObjImage.GetImage(NULL_STR);
			int cxImage = RectWidth(rcRect);
			int cyImage = RectHeight(rcRect);

			int cxNewWidth = Min(SHIP_IMAGE_WIDTH, cxImage);
			int cyNewHeight = cxNewWidth;

			CG16bitImage *pNewImage = new CG16bitImage;
			pNewImage->CreateFromImageTransformed(Image, 
					rcRect.left, 
					rcRect.top, 
					cxImage,
					cyImage,
					(Metric)cxNewWidth / cxImage,
					(Metric)cyNewHeight / cyImage,
					0.0);

			//	Position

			int xImage = x + m_cxWidth - SHIP_IMAGE_WIDTH + (SHIP_IMAGE_WIDTH - cxNewWidth) / 2;
			int yImage = (SHIP_IMAGE_HEIGHT - cyNewHeight) / 2;

			//	New image frame

			IAnimatron *pImageFrame = new CAniRect;
			pImageFrame->SetPropertyVector(PROP_POSITION, CVector(xImage, yImage));
			pImageFrame->SetPropertyVector(PROP_SCALE, CVector(cxNewWidth, cyNewHeight));
			pImageFrame->SetFillMethod(new CAniImageFill(pNewImage, true));

			pRoot->AddTrack(pImageFrame, 0);
			}
		}

	//	Extra information

	CString sEpitaph = GameFile.GetEpitaph();
	int iScore = GameFile.GetScore();
	CTimeDate LocalTime = ModifiedTime.ToLocalTime();
	CString sModifiedTime = LocalTime.Format("%d %B %Y %I:%M %p");
	CString sFilename = pathGetFilename(GameFile.GetFilespec());

	CString sGameType;
	if (GameFile.IsRegistered())
		sGameType = CONSTLIT("Registered");
	else if (GameFile.IsDebug())
		sGameType = CONSTLIT("Debug");
	else
		sGameType = CONSTLIT("Unregistered");

	CString sExtra;
	if (!sEpitaph.IsBlank())
		sExtra = strPatternSubst(CONSTLIT("Score %d — %s\n%s — %s — %s"), iScore, sEpitaph, sGameType, sModifiedTime, sFilename);
	else if (iScore > 0)
		sExtra = strPatternSubst(CONSTLIT("Score %d\n%s — %s — %s"), iScore, sGameType, sModifiedTime, sFilename);
	else
		sExtra = strPatternSubst(CONSTLIT("%s — %s — %s"), sGameType, sModifiedTime, sFilename);

	pDesc = new CAniText;
	pDesc->SetPropertyVector(PROP_POSITION, CVector(xText, y));
	pDesc->SetPropertyVector(PROP_SCALE, CVector(cxText, 1000));
	pDesc->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogLabel));
	pDesc->SetPropertyFont(PROP_FONT, &MediumFont);
	pDesc->SetPropertyString(PROP_TEXT, sExtra);

	pDesc->GetSpacingRect(&rcLine);

	pRoot->AddTrack(pDesc, 0);
	y += RectHeight(rcLine);

	//	Done

	*retpEntry = pRoot;

	if (retcyHeight)
		*retcyHeight = (bHasAdventureIcon ? Max(ADVENTURE_ICON_HEIGHT, y) : y);
	}
Esempio n. 4
0
void GenerateShipImageChart (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	int i;

	enum OrderTypes
		{
		orderSmallest = 1,
		orderLargest = 2,
		orderName = 3,
		};

	//	Options

	bool bTextBoxesOnly = pCmdLine->GetAttributeBool(CONSTLIT("textBoxesOnly"));

	//	Figure out what order we want

	CString sOrder = pCmdLine->GetAttribute(CONSTLIT("sort"));
	int iOrder;
	if (strEquals(sOrder, CONSTLIT("smallest")))
		iOrder = orderSmallest;
	else if (strEquals(sOrder, CONSTLIT("largest")))
		iOrder = orderLargest;
	else
		iOrder = orderName;

	//	Image size

	int cxDesiredWidth;
	if (pCmdLine->FindAttributeInteger(CONSTLIT("width"), &cxDesiredWidth))
		cxDesiredWidth = Max(512, cxDesiredWidth);
	else
		cxDesiredWidth = 1280;

	//	Spacing

	int cxSpacing = pCmdLine->GetAttributeInteger(CONSTLIT("xSpacing"));
	int cxExtraMargin = pCmdLine->GetAttributeInteger(CONSTLIT("xMargin"));

	//	Rotation

	int iRotation = pCmdLine->GetAttributeInteger(CONSTLIT("rotation"));

	//	Font for text

	CString sTypeface;
	int iSize;
	bool bBold;
	bool bItalic;

	if (!CG16bitFont::ParseFontDesc(pCmdLine->GetAttribute(CONSTLIT("font")),
			&sTypeface,
			&iSize,
			&bBold,
			&bItalic))
		{
		sTypeface = CONSTLIT("Arial");
		iSize = 10;
		bBold = false;
		bItalic = false;
		}

	CG16bitFont NameFont;
	NameFont.Create(sTypeface, -PointsToPixels(iSize), bBold, bItalic);
	WORD wNameColor = CG16bitImage::RGBValue(255, 255, 255);

	//	Output file

	CString sFilespec = pCmdLine->GetAttribute(CONSTLIT("output"));
	if (!sFilespec.IsBlank())
		sFilespec = pathAddExtensionIfNecessary(sFilespec, CONSTLIT(".bmp"));

	//	Generate a table of ships

	CSymbolTable Table(FALSE, TRUE);
	for (i = 0; i < Universe.GetShipClassCount(); i++)
		{
		CShipClass *pClass = Universe.GetShipClass(i);

		//	Skip player ship classes

		if (pClass->GetPlayerSettings())
			continue;

		//	Skip non-generic classes

		if (!pClass->HasAttribute(CONSTLIT("genericClass")))
			continue;

		//	Compute the sort key

		char szBuffer[1024];
		switch (iOrder)
			{
			case orderLargest:
				wsprintf(szBuffer, "%04d%s%x",
						2048 - RectWidth(pClass->GetImage().GetImageRect()),
						pClass->GetName().GetASCIIZPointer(),
						pClass);
				break;

			case orderSmallest:
				wsprintf(szBuffer, "%04d%s%x",
						RectWidth(pClass->GetImage().GetImageRect()),
						pClass->GetName().GetASCIIZPointer(),
						pClass);
				break;

			default:
				wsprintf(szBuffer, "%s%x", pClass->GetName().GetASCIIZPointer(), pClass);
				break;
			}

		//	Add to list

		Table.AddEntry(CString(szBuffer), (CObject *)pClass);
		}

	//	Allocate a map that tracks where to paint each ship

	CPaintMap Map(Table.GetCount());

	//	Arrange the ships

	SArrangeDesc Desc;
	Desc.cxDesiredWidth = Max(512, cxDesiredWidth - (2 * (cxSpacing + cxExtraMargin)));
	Desc.cxSpacing = cxSpacing;
	Desc.cxExtraMargin = cxExtraMargin;
	Desc.pHeader = &NameFont;

	ArrangeByRow(Table, Desc, Map);
	//ArrangeByCell(Table, cxDesiredWidth, Map);

	//	Create a large image

	CG16bitImage Output;
	int cxWidth = Max(cxDesiredWidth, Map.GetWidth());
	int cyHeight = Map.GetHeight();
	Output.CreateBlank(cxWidth, cyHeight, false);
	printf("Creating %dx%d image.\n", cxWidth, cyHeight);

	//	Paint the images

	for (i = 0; i < Table.GetCount(); i++)
		{
		CShipClass *pClass = (CShipClass *)Table.GetValue(i);

		int x = Map.GetX(i);
		int y = Map.GetY(i);
		if (x != -1)
			{
			if (!bTextBoxesOnly)
				pClass->GetImage().PaintImageUL(Output,
						x,
						y,
						0,
						Angle2Direction(iRotation));

			//	Paint name

			int xText = Map.GetTextX(i);
			int yText = Map.GetTextY(i);
			if (xText != -1)
				{
				if (bTextBoxesOnly)
					Output.Fill(xText, yText, Map.GetTextWidth(i), Map.GetTextHeight(i), 0xffff);

				if (!bTextBoxesOnly)
					{
					Output.FillColumn(x + (Map.GetWidth(i) / 2),
							y + Map.GetHeight(i),
							yText - (y + Map.GetHeight(i)),
							wNameColor);

					NameFont.DrawText(Output,
							xText,
							yText,
							wNameColor,
							255,
							pClass->GetNounPhrase(0));
					}
				}
			}
		}

	//	Write to file or clipboard

	OutputImage(Output, sFilespec);
	}