void CNewGameSession::SetPlayerGenome (GenomeTypes iGenome, int x, int y, int cxWidth) // SetPlayerGenome // // Sets the current player genome { const CVisualPalette &VI = m_HI.GetVisuals(); const CG16bitFont &MediumBoldFont = VI.GetFont(fontMediumBold); const CG16bitFont &SubTitleFont = VI.GetFont(fontSubTitle); // Delete the previous one DeleteElement(ID_PLAYER_GENOME); // Player genome IAnimatron *pGenome = new CAniText; pGenome->SetID(ID_PLAYER_GENOME); pGenome->SetPropertyVector(PROP_POSITION, CVector(x, y + MediumBoldFont.GetHeight())); pGenome->SetPropertyVector(PROP_SCALE, CVector(cxWidth - SMALL_BUTTON_WIDTH - MAJOR_PADDING_HORZ, 100.0)); pGenome->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogLabel)); pGenome->SetPropertyFont(PROP_FONT, &SubTitleFont); pGenome->SetPropertyString(PROP_TEXT, strTitleCapitalize(GetGenomeName(iGenome))); pGenome->SetPropertyString(PROP_TEXT_ALIGN_HORZ, ALIGN_RIGHT); m_pRoot->AddLine(pGenome); // Change the button image IAnimatron *pButton; if (m_pRoot->FindElement(CMD_CHANGE_GENOME, &pButton)) { const CG16bitImage *pImage; if (iGenome == genomeHumanMale) pImage = &VI.GetImage(imageSmallHumanMale); else pImage = &VI.GetImage(imageSmallHumanFemale); IAnimatron *pStyle = pButton->GetStyle(STYLE_IMAGE); pStyle->SetFillMethod(new CAniImageFill(pImage, false)); } }
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); }
void CPlayerGameStats::GenerateGameStats (CGameStats &Stats, CSpaceObject *pPlayerShip, bool bGameOver) const // GenerateGameStats // // Generates a stats for everything we track { int j; CShip *pShip = (pPlayerShip ? pPlayerShip->AsShip() : NULL); if (pShip == NULL) return; CPlayerShipController *pPlayer = (CPlayerShipController *)pShip->GetController(); if (pPlayer == NULL) return; CSovereign *pPlayerSovereign = g_pUniverse->FindSovereign(g_PlayerSovereignUNID); if (pPlayerSovereign == NULL) return; // Base stats Stats.Insert(CONSTLIT("Genome"), strCapitalize(GetGenomeName(pPlayer->GetPlayerGenome()))); Stats.Insert(CONSTLIT("Score"), strFormatInteger(CalcEndGameScore(), -1, FORMAT_THOUSAND_SEPARATOR | FORMAT_UNSIGNED)); Stats.Insert(CONSTLIT("Ship class"), pShip->GetNounPhrase(0)); CTimeSpan Time = GetPlayTime(); if (!Time.IsBlank()) Stats.Insert(CONSTLIT("Time played"), Time.Format(NULL_STR)); #ifdef REAL_TIME Time = GetGameTime(); if (!Time.IsBlank()) Stats.Insert(CONSTLIT("Time elapsed in game"), Time.Format(NULL_STR)); #endif // Some combat stats CString sDestroyed = GetStat(ENEMY_SHIPS_DESTROYED_STAT); if (!sDestroyed.IsBlank()) Stats.Insert(CONSTLIT("Enemy ships destroyed"), sDestroyed, CONSTLIT("combat")); sDestroyed = GetStat(FRIENDLY_SHIPS_DESTROYED_STAT); if (!sDestroyed.IsBlank()) Stats.Insert(CONSTLIT("Friendly ships destroyed"), sDestroyed, CONSTLIT("combat")); sDestroyed = GetStat(ENEMY_STATIONS_DESTROYED_STAT); if (!sDestroyed.IsBlank()) Stats.Insert(CONSTLIT("Enemy stations destroyed"), sDestroyed, CONSTLIT("combat")); sDestroyed = GetStat(FRIENDLY_STATIONS_DESTROYED_STAT); if (!sDestroyed.IsBlank()) Stats.Insert(CONSTLIT("Friendly stations destroyed"), sDestroyed, CONSTLIT("combat")); // Add stat for every station destroyed CStatCounterArray CounterArray; CMapIterator i; m_StationStats.Reset(i); while (m_StationStats.HasMore(i)) { SStationTypeStats *pStats; DWORD dwUNID = m_StationStats.GetNext(i, &pStats); CStationType *pType = g_pUniverse->FindStationType(dwUNID); if (pType == NULL) continue; CString sName = pType->GetNounPhrase(0); CString sSort = strPatternSubst(CONSTLIT("%03d%s"), 100 - pType->GetLevel(), sName); if (pType->GetSovereign()->IsEnemy(pPlayerSovereign)) CounterArray.Insert(sName, pStats->iDestroyed, CONSTLIT("Enemy stations destroyed"), sSort); else CounterArray.Insert(sName, pStats->iDestroyed, CONSTLIT("Friendly stations destroyed"), sSort); } CounterArray.GenerateGameStats(Stats); // Add stat for every ship class destroyed CounterArray.DeleteAll(); m_ShipStats.Reset(i); while (m_ShipStats.HasMore(i)) { SShipClassStats *pStats; DWORD dwUNID = m_ShipStats.GetNext(i, &pStats); CShipClass *pClass = g_pUniverse->FindShipClass(dwUNID); if (pClass == NULL) continue; CString sName = pClass->GetNounPhrase(0); CString sSort = strPatternSubst(CONSTLIT("%09d%s"), 100000000 - pClass->GetScore(), sName); if (pStats->iEnemyDestroyed > 0) CounterArray.Insert(sName, pStats->iEnemyDestroyed, CONSTLIT("Enemy ships destroyed"), sSort); if (pStats->iFriendDestroyed > 0) CounterArray.Insert(sName, pStats->iFriendDestroyed, CONSTLIT("Friendly ships destroyed"), sSort); } CounterArray.GenerateGameStats(Stats); // Add stat for every weapon fired m_ItemStats.Reset(i); while (m_ItemStats.HasMore(i)) { SItemTypeStats *pStats; DWORD dwUNID = m_ItemStats.GetNext(i, &pStats); CItemType *pItemType = g_pUniverse->FindItemType(dwUNID); if (pItemType == NULL) continue; CString sName = pItemType->GetNounPhrase(nounShort); CString sSort = strPatternSubst(CONSTLIT("%03d%s"), 100 - pItemType->GetLevel(), sName); // Installed items if (pStats->dwFirstInstalled != INVALID_TIME) Stats.Insert(sName, NULL_STR, CONSTLIT("Items installed"), sSort); if (pStats->iCountFired > 0) Stats.Insert(sName, strFormatInteger(pStats->iCountFired, -1, FORMAT_THOUSAND_SEPARATOR | FORMAT_UNSIGNED), CONSTLIT("Weapons fired"), sSort); } // Stats for player equipment (but only if the game is done) if (bGameOver) { TSortMap<CString, CItem> InstalledItems; // First we generate a sorted list of installed items // (We do this in case there are multiple of the same device/armor so that // we can coalesce them together into a single line). CItemListManipulator ItemList(pShip->GetItemList()); ItemList.ResetCursor(); while (ItemList.MoveCursorForward()) { const CItem &Item(ItemList.GetItemAtCursor()); if (Item.IsInstalled()) { CString sEnhancement = Item.GetEnhancedDesc(pShip); CString sItemName = Item.GetNounPhrase(nounActual | nounCountOnly | nounShort); CString sLine = (sEnhancement.IsBlank() ? sItemName : strPatternSubst(CONSTLIT("%s [%s]"), sItemName, sEnhancement)); bool bInserted; CItem *pEntry = InstalledItems.SetAt(sLine, &bInserted); if (bInserted) { *pEntry = Item; pEntry->SetCount(1); } else pEntry->SetCount(pEntry->GetCount() + 1); } } // Now add all the installed items to the stats for (j = 0; j < InstalledItems.GetCount(); j++) { // Redo the line now that we know the proper count CString sEnhancement = InstalledItems[j].GetEnhancedDesc(pShip); CString sItemName = InstalledItems[j].GetNounPhrase(nounActual | nounCountOnly); CString sLine = (sEnhancement.IsBlank() ? sItemName : strPatternSubst(CONSTLIT("%s [%s]"), sItemName, sEnhancement)); // Compute the sort order int iOrder; switch (InstalledItems[j].GetType()->GetCategory()) { case itemcatWeapon: iOrder = 0; break; case itemcatLauncher: iOrder = 1; break; case itemcatShields: iOrder = 2; break; case itemcatArmor: iOrder = 3; break; case itemcatReactor: iOrder = 4; break; case itemcatDrive: iOrder = 5; break; default: iOrder = 6; break; } CString sSort = strPatternSubst(CONSTLIT("%d%03d%s"), iOrder, 100 - InstalledItems[j].GetType()->GetLevel(), sLine); Stats.Insert(sLine, NULL_STR, CONSTLIT("Final equipment"), sSort); } // Add the remaining items ItemList.ResetCursor(); while (ItemList.MoveCursorForward()) { const CItem &Item(ItemList.GetItemAtCursor()); if (!Item.IsInstalled()) { CString sEnhancement = Item.GetEnhancedDesc(pShip); CString sItemName = Item.GetNounPhrase(nounActual | nounCountOnly); CString sLine = (sEnhancement.IsBlank() ? sItemName : strPatternSubst(CONSTLIT("%s [%s]"), sItemName, sEnhancement)); CString sSort = strPatternSubst(CONSTLIT("%03d%s"), 100 - Item.GetType()->GetLevel(), sLine); Stats.Insert(sLine, NULL_STR, CONSTLIT("Final items"), sSort); } } } }