diff --git a/GameSettings.cpp b/GameSettings.cpp index 32441e55..a259fe61 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1795,6 +1795,9 @@ void LoadGameExternalOptions() gGameExternalOptions.fFastWWWSitesLoading = iniReader.ReadBoolean("Laptop Settings", "FAST_WWW_SITES_LOADING", FALSE); gGameExternalOptions.fLaptopMouseCaptured = iniReader.ReadBoolean("Laptop Settings", "LAPTOP_MOUSE_CAPTURED", FALSE); + gGameExternalOptions.fCampaignHistoryWebSite = iniReader.ReadBoolean("Laptop Settings", "CAMPAIGN_HISTORY", TRUE); + gGameExternalOptions.usReportsToLoad = iniReader.ReadInteger("Laptop Settings", "CAMPAIGN_HISTORY_MAX_REPORTS", -1, -1, 100); + //################# Bobby Ray Settings ################## diff --git a/GameSettings.h b/GameSettings.h index 5986a853..848c816e 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -828,6 +828,10 @@ typedef struct BOOLEAN fFastWWWSitesLoading; BOOLEAN fDisableStrategicTransition; + // Flugente: campaign history + BOOLEAN fCampaignHistoryWebSite; // if set to FALSE, the website won't be displayed, and thus the data cannot be seen + INT16 usReportsToLoad; // number of reports to read when loading a game, older reports will be lost. This is irreversible. -1: read all (default) + // CPT: Cover System Settings UINT8 ubStealthTraitCoverValue; UINT8 ubStealthEffectiveness; diff --git a/GameVersion.h b/GameVersion.h index 64edc72b..3032c294 100644 --- a/GameVersion.h +++ b/GameVersion.h @@ -21,6 +21,7 @@ extern CHAR16 zTrackingNumber[16]; // Keeps track of the saved game version. Increment the saved game version whenever // you will invalidate the saved game file +#define CAMPAIGNSTATS 150 // Flugente: store campaign statistics #define WALDO_CAN_REPAIR_HELICOPTER 149 // anv: have to refresh Waldo records #define ENCYCLOPEDIA_ITEM_VISIBILITY 148 // Moa: Items discovered during compain have to be saved. #define TRAIT_RADIO_OPERATOR 147 // Flugente: new trait radio operator @@ -29,7 +30,7 @@ extern CHAR16 zTrackingNumber[16]; #define NO_VEHICLE_SAVE 144 // Flugente: vehicle data isn't saved anymore, as it has long been externalised #define SOLDIER_PROFILES 143 // Flugente: profiles for enemy and militia (possibly any non-NPC/RPC character) #define DYNAMIC_FLASHLIGHTS 142 // Flugente: had to add variables to LIGHTEFFECT-struct -#define ENLARGED_OPINIONS 141 // Flugente: increased numberof merc opinions to 255, thus need to change savegame reading +#define ENLARGED_OPINIONS 141 // Flugente: increased number of merc opinions to 255, thus need to change savegame reading #define MODULARIZED_AI 140 // Flugente: new savegame version due to modularized AI #define MILITIA_EQUIPMENT 139 // Flugente: militia can equip from sector inventory #define MULTITURN_ACTIONS 138 // Flugente: multiturn actions @@ -68,7 +69,7 @@ extern CHAR16 zTrackingNumber[16]; #define AP100_SAVEGAME_DATATYPE_CHANGE 105 // Before this, we didn't have the 100AP structure changes #define NIV_SAVEGAME_DATATYPE_CHANGE 102 // Before this, we used the old structure system -#define SAVE_GAME_VERSION WALDO_CAN_REPAIR_HELICOPTER +#define SAVE_GAME_VERSION CAMPAIGNSTATS //#define RUSSIANGOLD #ifdef __cplusplus diff --git a/Init.cpp b/Init.cpp index d62a81a3..14bf2716 100644 --- a/Init.cpp +++ b/Init.cpp @@ -1020,6 +1020,21 @@ BOOLEAN LoadExternalGameplayData(STR directoryName) } #endif + // Flugente: campaign stats + strcpy(fileName, directoryName); + strcat(fileName, CAMPAIGNSTATSEVENTSFILENAME); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName)); + SGP_THROW_IFFALSE(ReadInCampaignStatsEvents(fileName,FALSE), CAMPAIGNSTATSEVENTSFILENAME); + +#ifndef ENGLISH + AddLanguagePrefix(fileName); + if ( FileExists(fileName) ) + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName)); + SGP_THROW_IFFALSE(ReadInCampaignStatsEvents(fileName,TRUE), CAMPAIGNSTATSEVENTSFILENAME); + } +#endif + // WANNE: Only in a singleplayer game... // Externalised taunts if (!is_networked) diff --git a/Laptop/CampaignHistoryData.h b/Laptop/CampaignHistoryData.h new file mode 100644 index 00000000..278dac6f --- /dev/null +++ b/Laptop/CampaignHistoryData.h @@ -0,0 +1,6 @@ +#ifndef __CAMPAIGNHISTORY_DATA_H +#define __CAMPAIGNHISTORY_DATA_H + + + +#endif // __CAMPAIGNHISTORY_DATA_H \ No newline at end of file diff --git a/Laptop/CampaignHistoryMain.cpp b/Laptop/CampaignHistoryMain.cpp new file mode 100644 index 00000000..f82743fa --- /dev/null +++ b/Laptop/CampaignHistoryMain.cpp @@ -0,0 +1,268 @@ +/** + * @file + * @author Flugente (bears-pit.com) + */ + +#ifdef PRECOMPILEDHEADERS + #include "Laptop All.h" +#else + #include "laptop.h" + #include "insurance.h" + #include "insurance Contract.h" + #include "WCheck.h" + #include "Utilities.h" + #include "WordWrap.h" + #include "Cursors.h" + #include "Line.h" + #include "Insurance Text.h" + #include "Encrypted File.h" + #include "Text.h" + #include "Multi Language Graphic Utils.h" + #include "CampaignHistoryMain.h" +#endif + + +#define CAMPAIGN_HISTORY_BACKGROUND_WIDTH 125 +#define CAMPAIGN_HISTORY_BACKGROUND_HEIGHT 100 + +#define CAMPAIGN_HISTORY_BIG_TITLE_X 115 + LAPTOP_SCREEN_UL_X +#define CAMPAIGN_HISTORY_BIG_TITLE_Y 10 + LAPTOP_SCREEN_WEB_UL_Y + +#define CAMPAIGN_HISTORY_RED_BAR_X LAPTOP_SCREEN_UL_X +#define CAMPAIGN_HISTORY_RED_BAR_Y LAPTOP_SCREEN_WEB_UL_Y + +#define CAMPAIGN_HISTORY_TOP_RED_BAR_X LAPTOP_SCREEN_UL_X + 66 +#define CAMPAIGN_HISTORY_TOP_RED_BAR_Y 109 + LAPTOP_SCREEN_WEB_UL_Y +#define CAMPAIGN_HISTORY_TOP_RED_BAR_Y1 31 + LAPTOP_SCREEN_WEB_UL_Y + +#define CAMPAIGN_HISTORY_BOTTOM_RED_BAR_Y 345 + LAPTOP_SCREEN_WEB_UL_Y + +#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X 77 + LAPTOP_SCREEN_UL_X +#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_Y 392 + LAPTOP_SCREEN_WEB_UL_Y +#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_WIDTH 107 +#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_OFFSET 148 +#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X_2 CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X + CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_OFFSET +#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X_3 CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X_2 + CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_OFFSET + +#define CAMPAIGN_HISTORY_SUBTITLE_X CAMPAIGN_HISTORY_BIG_TITLE_X +#define CAMPAIGN_HISTORY_SUBTITLE_Y CAMPAIGN_HISTORY_BIG_TITLE_Y + 20 + +#define CAMPAIGN_HISTORY_BULLET_TEXT_1_Y 188 + LAPTOP_SCREEN_WEB_UL_Y +#define CAMPAIGN_HISTORY_BULLET_TEXT_2_Y 215 + LAPTOP_SCREEN_WEB_UL_Y +#define CAMPAIGN_HISTORY_BULLET_TEXT_3_Y 242 + LAPTOP_SCREEN_WEB_UL_Y + +#define CAMPAIGN_HISTORY_BOTTOM_SLOGAN_X CAMPAIGN_HISTORY_SUBTITLE_X +#define CAMPAIGN_HISTORY_BOTTOM_SLOGAN_Y 285 + LAPTOP_SCREEN_WEB_UL_Y +#define CAMPAIGN_HISTORY_BOTTOM_SLOGAN_WIDTH 370 + +#define CAMPAIGN_HISTORY_SMALL_TITLE_X 64 + LAPTOP_SCREEN_UL_X +#define CAMPAIGN_HISTORY_SMALL_TITLE_Y 5 + LAPTOP_SCREEN_WEB_UL_Y + +#define CAMPAIGN_HISTORY_SMALL_TITLE_WIDTH 434 - 170 +#define CAMPAIGN_HISTORY_SMALL_TITLE_HEIGHT 40 - 10 + + +extern UINT32 guiInsuranceBackGround; +extern UINT32 guiInsuranceSmallTitleImage; +extern UINT32 guiInsuranceBigRedLineImage; +UINT32 guiCampaignBulletImage; +UINT32 guiCampaignLogoImage; + + +//link to the various pages +MOUSE_REGION gCampaignHistoryLinkRegion[4]; +void SelectCampaignHistoryRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ); + + +void GameInitCampaignHistory() +{ + +} + +BOOLEAN EnterCampaignHistory() +{ + VOBJECT_DESC VObjectDesc; + + InitCampaignHistoryDefaults(); + + // load the Insurance bullet graphic and add it + VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; + FilenameForBPP("LAPTOP\\bullet.sti", VObjectDesc.ImageFile); + CHECKF(AddVideoObject(&VObjectDesc, &guiCampaignBulletImage)); + + RenderCampaignHistory(); + + return(TRUE); +} + +void ExitCampaignHistory() +{ + RemoveCampaignHistoryDefaults(); + + DeleteVideoObjectFromIndex( guiCampaignBulletImage ); + DeleteVideoObjectFromIndex( guiCampaignLogoImage ); +} + +void HandleCampaignHistory() +{ + +} + +void RenderCampaignHistory() +{ + CHAR16 sText[800]; + swprintf( sText, L"" ); + UINT16 usPosX, usPosY; + HVOBJECT hPixHandle; + + //Get the bullet + GetVideoObject(&hPixHandle, guiCampaignBulletImage ); + + DisplayCampaignHistoryDefaults(); + + SetFontShadow( CAMPHIS_FONT_SHADOW ); + + usPosX = LAPTOP_SCREEN_UL_X; + usPosY = LAPTOP_SCREEN_WEB_UL_Y + 80; + + swprintf(sText, szCampaignHistoryWebSite[TEXT_CAMPAIGNHISTORY_DESCRIPTION_1] ); + usPosY += DisplayWrappedString( usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, 2, CAMPHIS_FONT_MED, CAMPHIS_FONT_COLOR, sText, FONT_MCOLOR_BLACK, FALSE, 0); + + for(int i = TEXT_CAMPAIGNHISTORY_NAME_MINISTRY; i < TEXT_CAMPAIGNHISTORY_NAME_PRESSORGANISATION_SUBTITLE; ++i) + { + // display bullet + BltVideoObject(FRAME_BUFFER, hPixHandle, 0, usPosX, usPosY, VO_BLT_SRCTRANSPARENCY,NULL); + + swprintf(sText, szCampaignHistoryWebSite[i] ); + DrawTextToScreen( sText, usPosX + 25, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, CAMPHIS_FONT_MED, CAMPHIS_FONT_COLOR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosY += 15; + } + + SetFontShadow( DEFAULT_SHADOW ); + + MarkButtonsDirty( ); + RenderWWWProgramTitleBar( ); + InvalidateRegion(LAPTOP_SCREEN_UL_X,LAPTOP_SCREEN_WEB_UL_Y,LAPTOP_SCREEN_LR_X,LAPTOP_SCREEN_WEB_LR_Y); +} + + +BOOLEAN InitCampaignHistoryDefaults() +{ + VOBJECT_DESC VObjectDesc; + + // load the Flower Account Box graphic and add it + VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; + FilenameForBPP("LAPTOP\\BackGroundTile.sti", VObjectDesc.ImageFile); + CHECKF(AddVideoObject(&VObjectDesc, &guiInsuranceBackGround)); + + // load the red bar on the side of the page and add it + VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; + FilenameForBPP("LAPTOP\\LargeBar.sti", VObjectDesc.ImageFile); + CHECKF(AddVideoObject(&VObjectDesc, &guiInsuranceBigRedLineImage)); + + VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; + FilenameForBPP("LAPTOP\\PressLogos.sti", VObjectDesc.ImageFile); + CHECKF(AddVideoObject(&VObjectDesc, &guiCampaignLogoImage)); + + UINT16 usPosX = CAMPAIGN_HISTORY_LINK_START_X; + UINT16 usPosY = CAMPAIGN_HISTORY_LINK_START_Y; + for(int i=0; i<4; ++i) + { + MSYS_DefineRegion( &gCampaignHistoryLinkRegion[i], usPosX, usPosY, (UINT16)(usPosX + CAMPAIGN_HISTORY_LINK_TEXT_WIDTH), usPosY+CAMPAIGN_HISTORY_LINK_STEP_Y, MSYS_PRIORITY_HIGH, + CURSOR_WWW, MSYS_NO_CALLBACK, SelectCampaignHistoryRegionCallBack); + MSYS_AddRegion(&gCampaignHistoryLinkRegion[i]); + MSYS_SetRegionUserData( &gCampaignHistoryLinkRegion[i], 0, i ); + + usPosY += CAMPAIGN_HISTORY_LINK_STEP_Y; + } + + return( TRUE ); +} + +void DisplayCampaignHistoryDefaults() +{ + HVOBJECT hPixHandle; + GetVideoObject(&hPixHandle, guiCampaignLogoImage ); + + SetFontShadow( CAMPHIS_FONT_SHADOW ); + + CHAR16 sText[800]; + UINT16 usPosX = CAMPAIGN_HISTORY_LINK_START_X; + UINT16 usPosY = CAMPAIGN_HISTORY_LINK_START_Y; + + WebPageTileBackground(4, 4, CAMPAIGN_HISTORY_BACKGROUND_WIDTH, CAMPAIGN_HISTORY_BACKGROUND_HEIGHT, guiInsuranceBackGround); + + //Display the title slogan + GetCampaignHistoryText( TEXT_CAMPAIGNHISTORY_NAME_PRESSORGANISATION, sText ); + DrawTextToScreen( sText, CAMPAIGN_HISTORY_BIG_TITLE_X, CAMPAIGN_HISTORY_BIG_TITLE_Y, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, CAMPHIS_FONT_BIG, CAMPHIS_FONT_COLOR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + //Display the subtitle slogan + GetCampaignHistoryText( TEXT_CAMPAIGNHISTORY_NAME_PRESSORGANISATION_SUBTITLE, sText ); + DrawTextToScreen( sText, CAMPAIGN_HISTORY_SUBTITLE_X, CAMPAIGN_HISTORY_SUBTITLE_Y, 0, CAMPHIS_FONT_BIG, CAMPHIS_FONT_COLOR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX = CAMPAIGN_HISTORY_LINK_START_X; + usPosY = CAMPAIGN_HISTORY_LINK_START_Y; + for(int i=0; i<4; ++i) + { + GetCampaignHistoryText( TEXT_CAMPAIGNHISTORY_LINK_CONFLICTSUMMARY + i, sText ); + DisplayWrappedString( usPosX, usPosY, CAMPAIGN_HISTORY_LINK_TEXT_WIDTH, 2, CAMPHIS_FONT_MED, CAMPHIS_FONT_COLOR, sText, FONT_MCOLOR_BLACK, FALSE, 0); + + usPosY += CAMPAIGN_HISTORY_LINK_STEP_Y; + + //Display the red bar under the link at the bottom. and the text + DisplaySmallRedLineWithShadow( usPosX, usPosY-2, LAPTOP_SCREEN_UL_X+CAMPAIGN_HISTORY_LINK_TEXT_WIDTH, usPosY-2); + } + + // closing line that separates header from individual page + DisplaySmallRedLineWithShadow( usPosX, usPosY-2, LAPTOP_SCREEN_LR_X, usPosY-2); + + usPosX = LAPTOP_SCREEN_LR_X - 50; + usPosY = CAMPAIGN_HISTORY_LINK_START_Y; + BltVideoObject(FRAME_BUFFER, hPixHandle, 0, usPosX, usPosY, VO_BLT_SRCTRANSPARENCY,NULL); + + SetFontShadow( DEFAULT_SHADOW ); +} + +void RemoveCampaignHistoryDefaults() +{ + DeleteVideoObjectFromIndex( guiInsuranceBackGround ); + DeleteVideoObjectFromIndex( guiInsuranceBigRedLineImage ); + + for(int i=0; i<4; ++i) + MSYS_RemoveRegion( &gCampaignHistoryLinkRegion[i]); +} + +void GetCampaignHistoryText( UINT8 ubNumber, STR16 pString ) +{ + UINT32 uiStartLoc=0; + + if ( ubNumber >= TEXT_CAMPAIGNHISTORY_MAX ) + wcscpy( pString, L"bla" ); + + wcscpy( pString, szCampaignHistoryWebSite[ubNumber] ); +} + + +void SelectCampaignHistoryRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ) +{ + if (iReason & MSYS_CALLBACK_REASON_INIT) + { + } + else if(iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) + { + UINT32 uiLink = MSYS_GetRegionUserData( pRegion, 0 ); + + if( uiLink == 0 ) + guiCurrentLaptopMode = LAPTOP_MODE_CAMPAIGNHISTORY_SUMMARY; + else if( uiLink == 1 ) + guiCurrentLaptopMode = LAPTOP_MODE_CAMPAIGNHISTORY_MOSTIMPORTANT; + else if( uiLink == 2 ) + guiCurrentLaptopMode = LAPTOP_MODE_CAMPAIGNHISTORY_LATESTNEWS; + else if( uiLink == 3 ) + guiCurrentLaptopMode = LAPTOP_MODE_CAMPAIGNHISTORY_ABOUTTUS; + } + else if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) + { + } +} diff --git a/Laptop/CampaignHistoryMain.h b/Laptop/CampaignHistoryMain.h new file mode 100644 index 00000000..ee9f7737 --- /dev/null +++ b/Laptop/CampaignHistoryMain.h @@ -0,0 +1,46 @@ +#ifndef __CAMPAIGNHISTORY_MAIN_H +#define __CAMPAIGNHISTORY_MAIN_H + +/** + * @file + * @author Flugente (bears-pit.com) + */ + +//#include "insurance.h" + +#define CAMPHIS_FONT_COLOR 2 +#define CAMPHIS_FONT_COLOR_RED FONT_MCOLOR_RED +#define CAMPHIS_FONT_BIG FONT14ARIAL +#define CAMPHIS_FONT_MED FONT12ARIAL +#define CAMPHIS_FONT_SMALL FONT10ARIAL + +#define CAMPHIS_FONT_BTN_COLOR FONT_MCOLOR_WHITE +#define CAMPHIS_FONT_BTN_SHADOW_COLOR 2 + +#define CAMPHIS_FONT_SHADOW FONT_MCOLOR_WHITE + +#define CAMPAIGN_HISTORY_BULLET_TEXT_OFFSET_X 21 + +#define CAMPHIS_INFO_LEFT_ARROW_BUTTON_X 71 + LAPTOP_SCREEN_UL_X +#define CAMPHIS_INFO_LEFT_ARROW_BUTTON_Y 354 + LAPTOP_SCREEN_WEB_UL_Y + +#define CAMPHIS_INFO_RIGHT_ARROW_BUTTON_X 409 + LAPTOP_SCREEN_UL_X +#define CAMPHIS_INFO_RIGHT_ARROW_BUTTON_Y CAMPHIS_INFO_LEFT_ARROW_BUTTON_Y + +#define CAMPAIGN_HISTORY_LINK_START_X LAPTOP_SCREEN_UL_X +#define CAMPAIGN_HISTORY_LINK_START_Y LAPTOP_SCREEN_WEB_UL_Y + 5 +#define CAMPAIGN_HISTORY_LINK_TEXT_WIDTH 107 +#define CAMPAIGN_HISTORY_LINK_STEP_Y 14 + +void GameInitCampaignHistory(); +BOOLEAN EnterCampaignHistory(); +void ExitCampaignHistory(); +void HandleCampaignHistory(); +void RenderCampaignHistory(); + +BOOLEAN InitCampaignHistoryDefaults(); +void DisplayCampaignHistoryDefaults(); +void RemoveCampaignHistoryDefaults(); +void GetCampaignHistoryText( UINT8 ubNumber, STR16 pString ); + +#endif //__CAMPAIGNHISTORY_MAIN_H diff --git a/Laptop/CampaignHistory_Summary.cpp b/Laptop/CampaignHistory_Summary.cpp new file mode 100644 index 00000000..18f50781 --- /dev/null +++ b/Laptop/CampaignHistory_Summary.cpp @@ -0,0 +1,1057 @@ +/** + * @file + * @author Flugente (bears-pit.com) + */ + +#ifdef PRECOMPILEDHEADERS + #include "Laptop All.h" +#else + #include "laptop.h" + #include "Insurance Text.h" + #include "insurance.h" + #include "insurance Comments.h" + #include "WCheck.h" + #include "Utilities.h" + #include "WordWrap.h" + #include "Cursors.h" + #include "Text.h" + #include "CampaignHistory_Summary.h" + #include "CampaignHistoryMain.h" + #include "CampaignStats.h" + #include "Campaign Types.h" + #include "Game Clock.h" + #include "random.h" + #include "strategicmap.h" +#endif + +#define CAMPHIS_SUM_TITLE_Y 52 + LAPTOP_SCREEN_WEB_UL_Y + +#define CAMPHIS_SUM_FIRST_BULLET_X 82 + LAPTOP_SCREEN_UL_X +#define CAMPHIS_SUM_FIRST_BULLET_Y 75 + LAPTOP_SCREEN_WEB_UL_Y + +#define CAMPHIS_SUM_REDLINE_WIDTH 384 + +#define CAMPHIS_SUM_COMMENT_OFFSET_Y 20 + +#define CAMPHIS_SUM_NEXT_COMMENT_OFFSET_Y 65 + +#define CAMPHIS_SUM_COMMENT_TEXT_WIDTH 364 + +#define CAMPHIS_SUM_LINK_Y 357 + LAPTOP_SCREEN_WEB_UL_Y +#define CAMPHIS_SUM_LINK_WIDTH 90 +#define CAMPHIS_SUM_LINK_HEIGHT 35 +#define CAMPHIS_SUM_LINK_OFFSET_X 166 + +#define CAMPAIGN_HISTORY_PAGEBTN_X LAPTOP_SCREEN_UL_X + 150 +#define CAMPAIGN_HISTORY_PAGEBTN_Y LAPTOP_SCREEN_LR_Y - 4 +#define CAMPAIGN_HISTORY_PAGEBTN_STEP_X 50 + +#define CAMPAIGN_HISTORY_TABLE_STEP_X 60 + +#define CAMPAIGN_HISTORY_FONT_COLOR_REGULAR 2 +#define CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE FONT_MCOLOR_DKGRAY + +#define CAMPAIGN_HISTORY_DETAIL_STEP_Y 15 + +extern UINT32 guiInsCmntBulletImage; + +extern BOOLEAN DisplayComment( UINT8 ubCommentorsName, UINT8 ubComment, UINT16 usPosY ); + +////////////////////////// SUMMARY PAGE ////////////////////////////////// +MOUSE_REGION gCampaignHistorySummaryRegion[1]; +void SelectCampaignHistorySummaryRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ); + +UINT8 gusSummaryMode = 0; // 0: Kills etc., 1: Consumption etc. + +void GameInitCampaignHistorySummary() +{ + +} + +BOOLEAN EnterCampaignHistorySummary() +{ + InitCampaignHistoryDefaults(); + + // previous/next buttons + UINT16 usPosX = CAMPAIGN_HISTORY_PAGEBTN_X; + UINT16 usPosY = CAMPAIGN_HISTORY_PAGEBTN_Y; + for(int i=0; i<1; ++i) + { + MSYS_DefineRegion( &gCampaignHistorySummaryRegion[i], usPosX, usPosY, (UINT16)(usPosX + CAMPAIGN_HISTORY_LINK_TEXT_WIDTH), usPosY+CAMPAIGN_HISTORY_LINK_STEP_Y, MSYS_PRIORITY_HIGH, + CURSOR_WWW, MSYS_NO_CALLBACK, SelectCampaignHistorySummaryRegionCallBack); + MSYS_AddRegion(&gCampaignHistorySummaryRegion[i]); + MSYS_SetRegionUserData( &gCampaignHistorySummaryRegion[i], 0, i ); + + usPosX += CAMPAIGN_HISTORY_PAGEBTN_STEP_X; + } + + RenderCampaignHistorySummary(); + + return(TRUE); +} + +void ExitCampaignHistorySummary() +{ + // previous/next buttons + for(int i=0; i<1; ++i) + MSYS_RemoveRegion( &gCampaignHistorySummaryRegion[i]); + + RemoveCampaignHistoryDefaults(); +} + +void HandleCampaignHistorySummary() +{ + +} + +void RenderCampaignHistorySummary() +{ +// HVOBJECT hPixHandle; + CHAR16 sText[800]; + swprintf( sText, L"" ); + UINT16 usPosX, usPosY; + + DisplayCampaignHistoryDefaults(); + + SetFontShadow( CAMPHIS_FONT_SHADOW ); + + usPosX = LAPTOP_SCREEN_UL_X; + usPosY = LAPTOP_SCREEN_WEB_UL_Y + 80; + + if ( gusSummaryMode == 0 ) + { + swprintf(sText, L""); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += 2 * CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_KILLED]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_WOUNDED]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_PRISONERS]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_SHOTSFIRED]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX = LAPTOP_SCREEN_UL_X; + // closing line that separates header from individual page + DisplaySmallRedLineWithShadow( usPosX, usPosY+15, LAPTOP_SCREEN_LR_X - LAPTOP_SCREEN_UL_X, usPosY+15); + + usPosY += 20; + + for(int i = CAMPAIGNHISTORY_SD_MERC; i < CAMPAIGNHISTORY_SD_MAX; ++i) + { + // if faction was not involved at all, ignore + if ( !gCampaignStats.usKills[i] && !gCampaignStats.usWounds[i] && !gCampaignStats.usPrisoners[i] && !gCampaignStats.usShots[i] ) + continue; + + usPosX = LAPTOP_SCREEN_UL_X; + swprintf(sText, L"%s", szSoldierClassName[i]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += 2 * CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, L"%d", gCampaignStats.usKills[i]); + if ( gCampaignStats.usKills[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, L"%d", gCampaignStats.usWounds[i]); + if ( gCampaignStats.usWounds[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, L"%d", gCampaignStats.usPrisoners[i]); + if ( gCampaignStats.usPrisoners[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, L"%d", gCampaignStats.usShots[i]); + if ( gCampaignStats.usShots[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosY += 20; + } + } + else if ( gusSummaryMode == 1 ) + { + usPosX = LAPTOP_SCREEN_UL_X; + usPosX += 2 * CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_MONEYEARNED]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosY += 20; + + for(int i = 0; i < CAMPAIGN_MONEY_MAX; ++i) + { + usPosX = LAPTOP_SCREEN_UL_X; + swprintf(sText, L"%s", szCampaignHistoryMoneyTypeString[i]); + if ( gCampaignStats.sMoneyEarned[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += 2 * CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, L"%d $", gCampaignStats.sMoneyEarned[i]); + if ( gCampaignStats.sMoneyEarned[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosY += 20; + } + + usPosX = LAPTOP_SCREEN_UL_X; + usPosX += 2 * CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_CONSUMPTION]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosY += 20; + + for(int i = 0; i < CAMPAIGN_CONSUMED_MAX; ++i) + { + usPosX = LAPTOP_SCREEN_UL_X; + swprintf(sText, L"%s", szCampaignHistoryConsumptionTypeString[i]); + if ( gCampaignStats.usConsumed[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += 2 * CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, L"%3.3f kg", gCampaignStats.usConsumed[i] / 10.0 ); + if ( gCampaignStats.usConsumed[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosY += 20; + } + } + + // previous/next buttons + usPosX = CAMPAIGN_HISTORY_PAGEBTN_X; + usPosY = CAMPAIGN_HISTORY_PAGEBTN_Y; + if ( gusSummaryMode ) + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_LOSSES]); + else + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_CONSUMPTION]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + SetFontShadow( DEFAULT_SHADOW ); + MarkButtonsDirty( ); + RenderWWWProgramTitleBar( ); + InvalidateRegion(LAPTOP_SCREEN_UL_X,LAPTOP_SCREEN_WEB_UL_Y,LAPTOP_SCREEN_LR_X,LAPTOP_SCREEN_WEB_LR_Y); + + SetFontShadow( DEFAULT_SHADOW ); + MarkButtonsDirty( ); + RenderWWWProgramTitleBar( ); + InvalidateRegion(LAPTOP_SCREEN_UL_X,LAPTOP_SCREEN_WEB_UL_Y,LAPTOP_SCREEN_LR_X,LAPTOP_SCREEN_WEB_LR_Y); +} + +void SelectCampaignHistorySummaryRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ) +{ + if (iReason & MSYS_CALLBACK_REASON_INIT) + { + } + else if(iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) + { + UINT32 uiLink = MSYS_GetRegionUserData( pRegion, 0 ); + + //if( uiLink == 0 ) + { + ++gusSummaryMode; + + if ( gusSummaryMode >= 2) + gusSummaryMode = 0; + } + + RenderCampaignHistorySummary(); + } + else if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) + { + } +} +////////////////////////// SUMMARY PAGE ////////////////////////////////// + +////////////////////////// MOST IMPORTANT PAGE ////////////////////////////////// +//link to the various pages +MOUSE_REGION gCampaignHistoryMostImportantLinkRegion[3]; +void SelectCampaignHistoryMostImportantRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ); + +UINT8 gusMostImportantPage = 0; +UINT8 gusMostImportantMode = 0; // 0: Summary, 1: Detail + +// special pics for one-time-events +UINT32 guiCampaignEventImage; + +// in order to display a fitting picture, we need a lot of libraries. +// There are several folders according to the terrain. Each has subfolders for +// - player wins battle +// - player loses battle +// - tank battle +// - military installation (SAM site, barracks etc.) +// - airdrop +// The image number displayed is then determined as 'id of incident % number of pics in library'. That way each incident keeps its picture, while pictures don't repeat that often +// Each library needs at least one picture + + +UINT32 guiCampaignHistoryPicture[CAMPAINGHISTORY_PICLIBRARY_TERRAIN_MAX][CAMPAINGHISTORY_PICLIBRARY_TYPE_MAX]; + + +void GameInitCampaignHistory_MostImportant() +{ + gusMostImportantPage = 0; +} + +BOOLEAN EnterCampaignHistory_MostImportant() +{ + InitCampaignHistoryDefaults(); + + // previous/next buttons + UINT16 usPosX = CAMPAIGN_HISTORY_PAGEBTN_X; + UINT16 usPosY = CAMPAIGN_HISTORY_PAGEBTN_Y; + for(int i=0; i<3; ++i) + { + MSYS_DefineRegion( &gCampaignHistoryMostImportantLinkRegion[i], usPosX, usPosY, (UINT16)(usPosX + CAMPAIGN_HISTORY_LINK_TEXT_WIDTH), usPosY+CAMPAIGN_HISTORY_LINK_STEP_Y, MSYS_PRIORITY_HIGH, + CURSOR_WWW, MSYS_NO_CALLBACK, SelectCampaignHistoryMostImportantRegionCallBack); + MSYS_AddRegion(&gCampaignHistoryMostImportantLinkRegion[i]); + MSYS_SetRegionUserData( &gCampaignHistoryMostImportantLinkRegion[i], 0, i ); + + usPosX += CAMPAIGN_HISTORY_PAGEBTN_STEP_X; + } + + VOBJECT_DESC VObjectDesc; + + // picture libraries. Do NOT translate this! + STR terrainfolders[] = + { + "Coastal", + "Desert", + "Forest", + "Mountain", + "Polar", + "River", + "Sparse", + "Swamp", + "Tropical", + "Underground", + "Urban", + }; + + STR typenames[] = + { + "win", + "loss", + "installation", + "airdrop", + "tanks", + }; + + VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; + FilenameForBPP("LAPTOP\\CampaignStats\\events.sti", VObjectDesc.ImageFile); + CHECKF(AddVideoObject(&VObjectDesc, &guiCampaignEventImage)); + + UINT8 i, j; + for(i = 0; i < CAMPAINGHISTORY_PICLIBRARY_TERRAIN_MAX; ++i) + { + for(j = 0; j < CAMPAINGHISTORY_PICLIBRARY_TYPE_MAX; ++j) + { + CHAR8 sString[100]; + sprintf(sString, "LAPTOP\\CampaignStats\\%s\\%s.sti", terrainfolders[i], typenames[j]); + + VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; + FilenameForBPP((sString), VObjectDesc.ImageFile); + + // if a picture library dos not exist, use the default library instead + if ( !AddVideoObject(&VObjectDesc, &guiCampaignHistoryPicture[i][j]) ) + { + guiCampaignHistoryPicture[i][j] = guiCampaignEventImage; + } + } + } + + + RenderCampaignHistorySummary(); + + return(TRUE); +} + +void ExitCampaignHistory_MostImportant() +{ + RemoveCampaignHistoryDefaults(); + + // previous/next buttons + for(int i=0; i<3; ++i) + MSYS_RemoveRegion( &gCampaignHistoryMostImportantLinkRegion[i]); + + DeleteVideoObjectFromIndex( guiCampaignEventImage ); + + for(int i = 0; i < CAMPAINGHISTORY_PICLIBRARY_TERRAIN_MAX; ++i) + { + for(int j = 0; j < CAMPAINGHISTORY_PICLIBRARY_TYPE_MAX; ++j) + { + DeleteVideoObjectFromIndex( guiCampaignHistoryPicture[i][j] ); + } + } +} + +void HandleCampaignHistory_MostImportant() +{ + +} + +void RenderCampaignHistory_MostImportant() +{ + HVOBJECT hPixHandle; + CHAR16 sText[800]; + swprintf( sText, L"" ); + UINT16 usPosX, usPosY; + + DisplayCampaignHistoryDefaults(); + + SetFontShadow( CAMPHIS_FONT_SHADOW ); + + usPosX = LAPTOP_SCREEN_UL_X; + usPosY = LAPTOP_SCREEN_WEB_UL_Y + 80; + + // return if there are no incidents yet + if ( !gCampaignStats.usNumIncidents ) + return; + + Incident_Stats incident = gCampaignStats.mIncidentVector[ gusMostImportantPage ]; + + CHAR16 wSectorName_Target[ 100 ]; + GetSectorIDString( SECTORX(incident.usSector), SECTORY(incident.usSector), incident.usLevel, wSectorName_Target, TRUE ); + + INT8 bTownId = GetTownIdForSector( SECTORX(incident.usSector), SECTORY(incident.usSector) ); + + //Calculate the day, hour, and minutes. + UINT32 day = ( incident.usTime / NUM_SEC_IN_DAY ); + UINT32 hour = ( incident.usTime - ( day * NUM_SEC_IN_DAY ) ) / NUM_SEC_IN_HOUR; + UINT32 minute = ( incident.usTime - ( ( day * NUM_SEC_IN_DAY ) + ( hour * NUM_SEC_IN_HOUR ) ) ) / NUM_SEC_IN_MIN; + + UINT8 importancenr = TEXT_CAMPAIGNHISTORY_IMPORTANCE_MOMENTOUS; + if ( incident.usInterestRating < 500 ) + importancenr = TEXT_CAMPAIGNHISTORY_IMPORTANCE_IRRELEVANT; + else if ( incident.usInterestRating < 1000 ) + importancenr = TEXT_CAMPAIGNHISTORY_IMPORTANCE_INSIGNIFICANT; + else if ( incident.usInterestRating < 2000 ) + importancenr = TEXT_CAMPAIGNHISTORY_IMPORTANCE_NOTABLE; + else if ( incident.usInterestRating < 3000 ) + importancenr = TEXT_CAMPAIGNHISTORY_IMPORTANCE_NOTEWORTHY; + else if ( incident.usInterestRating < 4000 ) + importancenr = TEXT_CAMPAIGNHISTORY_IMPORTANCE_SIGNIFICANT; + else if ( incident.usInterestRating < 5000 ) + importancenr = TEXT_CAMPAIGNHISTORY_IMPORTANCE_INTERESTING; + else if ( incident.usInterestRating < 6000 ) + importancenr = TEXT_CAMPAIGNHISTORY_IMPORTANCE_IMPORTANT; + else if ( incident.usInterestRating < 7000 ) + importancenr = TEXT_CAMPAIGNHISTORY_IMPORTANCE_VERYIMPORTANT; + else if ( incident.usInterestRating < 8000 ) + importancenr = TEXT_CAMPAIGNHISTORY_IMPORTANCE_GRAVE; + else if ( incident.usInterestRating < 10000 ) + importancenr = TEXT_CAMPAIGNHISTORY_IMPORTANCE_MAJOR; + + swprintf(sText, L"%s %s #%d - %s, %s %d, %02d:%02d", szCampaignHistoryImportanceString[importancenr], szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_INCIDENT], incident.usID, wSectorName_Target, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_DAY], day, hour, minute); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, CAMPHIS_FONT_BIG, CAMPHIS_FONT_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); + + usPosY = LAPTOP_SCREEN_WEB_UL_Y + 110; + + if ( gusMostImportantMode == 0 ) + { + usPosX += 2 * CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_KILLED]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_WOUNDED]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_PRISONERS]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_SHOTSFIRED]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_PARTICIPANTS]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_PROMOTIONS]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX = LAPTOP_SCREEN_UL_X; + // closing line that separates header from individual page + DisplaySmallRedLineWithShadow( usPosX, usPosY+15, LAPTOP_SCREEN_LR_X - LAPTOP_SCREEN_UL_X, usPosY+15); + + usPosY += 20; + + for(int i = CAMPAIGNHISTORY_SD_MERC; i < CAMPAIGNHISTORY_SD_MAX; ++i) + { + // if faction was not involved at all, ignore + if ( !incident.usKills[i] && !incident.usWounds[i] && !incident.usPrisoners[i] && !incident.usShots[i] && !incident.usParticipants[i] && !incident.usPromotions[i] ) + continue; + + usPosX = LAPTOP_SCREEN_UL_X; + swprintf(sText, L"%s", szSoldierClassName[i]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += 2 * CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, L"%d", incident.usKills[i]); + if ( incident.usKills[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, L"%d", incident.usWounds[i]); + if ( incident.usWounds[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, L"%d", incident.usPrisoners[i]); + if ( incident.usPrisoners[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, L"%d", incident.usShots[i]); + if ( incident.usShots[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, L"%d", incident.usParticipants[i]); + if ( incident.usParticipants[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_TABLE_STEP_X; + + swprintf(sText, L"%d", incident.usPromotions[i]); + if ( incident.usPromotions[i] ) + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + else + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_PASSIVE, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosY += 20; + } + } + else + { + UINT8 terrain, type; + incident.GetTerrainandType(terrain, type); + + // draw text + // if this is a one-time event, display a special text + if ( incident.usOneTimeEventFlags & 0xFFFFFFFF ) + { + UINT8 eventnr = 0; + if ( incident.usOneTimeEventFlags & INCIDENT_ONETIMEEVENT_OMERTA ) + eventnr = 0; + else if ( incident.usOneTimeEventFlags & INCIDENT_ONETIMEEVENT_DEATH_KINGPIN ) + eventnr = 1; + else if ( incident.usOneTimeEventFlags & INCIDENT_ONETIMEEVENT_MASSACRE_HICKS ) + eventnr = 2; + else if ( incident.usOneTimeEventFlags & INCIDENT_ONETIMEEVENT_MASSACRE_BLOODCATS ) + eventnr = 3; + else if ( incident.usOneTimeEventFlags & INCIDENT_ONETIMEEVENT_CITY_RETAKEN ) + eventnr = 4; + else + { + for(int i = 0; i < NUM_CAMPAIGNSTATSEVENTS; ++i) + { + if ( bTownId == zCampaignStatsEvent[i].usCityTaken ) + { + eventnr = i; + break; + } + } + } + + // special picture - use eventnr + GetVideoObject(&hPixHandle, guiCampaignEventImage ); + + BltVideoObject(FRAME_BUFFER, hPixHandle, eventnr, usPosX, usPosY, VO_BLT_SRCTRANSPARENCY, NULL); + + UINT16 picend = usPosY + hPixHandle->pETRLEObject[ eventnr ].usHeight + 3; + usPosX += hPixHandle->pETRLEObject[ eventnr ].usWidth + 3; + + for (int i = 0; i < MAX_CAMPAIGNSTATSEVENTS_TEXTS; ++i) + { + swprintf(sText, zCampaignStatsEvent[eventnr].szText[i] ); + usPosY += DisplayWrappedString( usPosX, usPosY, LAPTOP_SCREEN_LR_X - usPosX, 2, CAMPHIS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, sText, FONT_MCOLOR_BLACK, FALSE, 0); + if ( picend < usPosY ) usPosX = LAPTOP_SCREEN_UL_X; + } + } + else + { + GetVideoObject(&hPixHandle, guiCampaignHistoryPicture[terrain][type] ); + + UINT16 picnum = incident.usID % hPixHandle->usNumberOfObjects; + + BltVideoObject(FRAME_BUFFER, hPixHandle, picnum, usPosX, usPosY, VO_BLT_SRCTRANSPARENCY,NULL); + + UINT16 picend = usPosY + hPixHandle->pETRLEObject[ picnum ].usHeight + 3; + usPosX += hPixHandle->pETRLEObject[ picnum ].usWidth + 3; + + // time string + CHAR16 timestring[ 50 ]; + if ( hour < 3 || hour > 23 ) + swprintf(timestring, szCampaignHistoryTimeString[TEXT_CAMPAIGNHISTORY_TIME_DEEPNIGHT]); + else if ( hour < 6 ) + swprintf(timestring, szCampaignHistoryTimeString[TEXT_CAMPAIGNHISTORY_TIME_DAWN]); + else if ( hour < 8 ) + swprintf(timestring, szCampaignHistoryTimeString[TEXT_CAMPAIGNHISTORY_TIME_EARLYMORNING]); + else if ( hour < 11 ) + swprintf(timestring, szCampaignHistoryTimeString[TEXT_CAMPAIGNHISTORY_TIME_MORNING]); + else if ( hour < 14 ) + swprintf(timestring, szCampaignHistoryTimeString[TEXT_CAMPAIGNHISTORY_TIME_NOON]); + else if ( hour < 18 ) + swprintf(timestring, szCampaignHistoryTimeString[TEXT_CAMPAIGNHISTORY_TIME_AFTERNOON]); + else if ( hour < 21 ) + swprintf(timestring, szCampaignHistoryTimeString[TEXT_CAMPAIGNHISTORY_TIME_EVENING]); + else + swprintf(timestring, szCampaignHistoryTimeString[TEXT_CAMPAIGNHISTORY_TIME_NIGHT]); + + CHAR16 aggressor[ 50 ]; + CHAR16 defender[ 50 ]; + if ( incident.usIncidentFlags & INCIDENT_ATTACK_ENEMY ) + { + swprintf(aggressor, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_ARMY]); + swprintf(defender, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_REBELFORCES]); + } + else + { + swprintf(aggressor, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_REBELFORCES]); + swprintf(defender, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_ARMY]); + } + + CHAR16 rebel[ 50 ]; + CHAR16 enemy[ 50 ]; + swprintf(enemy, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_ARMY]); + swprintf(rebel, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_REBELFORCES]); + + CHAR16 attacktype[ 50 ]; + if ( incident.usIncidentFlags & INCIDENT_AIRDROP ) + swprintf(attacktype, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_AIRDROPPED]); + else if ( incident.usIncidentFlags & INCIDENT_AMBUSH ) + swprintf(attacktype, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_AMBUSHED]); + else + swprintf(attacktype, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_ATTACKED]); + + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_SETTING], timestring, aggressor, attacktype, defender, wSectorName_Target); + + usPosY += DisplayWrappedString( usPosX, usPosY, LAPTOP_SCREEN_LR_X - usPosX, 2, CAMPHIS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR,sText, FONT_MCOLOR_BLACK, FALSE, 0); + if ( picend < usPosY ) usPosX = LAPTOP_SCREEN_UL_X; + + if ( incident.usIncidentFlags & (INCIDENT_PLAYER_ALLDIRS|INCIDENT_ENEMY_ALLDIRS) ) + { + if ( incident.usIncidentFlags & INCIDENT_PLAYER_ALLDIRS && incident.usIncidentFlags & INCIDENT_ENEMY_ALLDIRS ) + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_ATTACKERANDDEFENDERDIR], incident.GetAttackerDirString(TRUE), defender, incident.GetAttackerDirString(FALSE) ); + else if ( ( incident.usIncidentFlags & INCIDENT_PLAYER_ALLDIRS && incident.usIncidentFlags & INCIDENT_ATTACK_PLAYERSIDE ) || ( incident.usIncidentFlags & INCIDENT_ENEMY_ALLDIRS && incident.usIncidentFlags & INCIDENT_ATTACK_ENEMY ) ) + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_ATTACKERDIR], incident.GetAttackerDirString(TRUE) ); + else + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_DEFENDERDIR], defender, incident.GetAttackerDirString(FALSE) ); + + usPosY += DisplayWrappedString( usPosX, usPosY, LAPTOP_SCREEN_LR_X - usPosX, 2, CAMPHIS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR,sText, FONT_MCOLOR_BLACK, FALSE, 0); + if ( picend < usPosY ) usPosX = LAPTOP_SCREEN_UL_X; + } + + if ( incident.usIncidentFlags & INCIDENT_BUILDINGS_DAMAGED ) + { + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_BUILDINGDAMAGE], incident.usKills[CAMPAIGNHISTORY_SD_CIV], incident.usWounds[CAMPAIGNHISTORY_SD_CIV] ); + usPosY += DisplayWrappedString( usPosX, usPosY, LAPTOP_SCREEN_LR_X - usPosX, 2, CAMPHIS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR,sText, FONT_MCOLOR_BLACK, FALSE, 0); + if ( picend < usPosY ) usPosX = LAPTOP_SCREEN_UL_X; + } + + if ( incident.usIncidentFlags & (INCIDENT_REINFORCEMENTS_ENEMY|INCIDENT_REINFORCEMENTS_PLAYERSIDE) ) + { + if ( incident.usIncidentFlags & INCIDENT_REINFORCEMENTS_ENEMY && incident.usIncidentFlags & INCIDENT_REINFORCEMENTS_PLAYERSIDE ) + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_REINFORCE_BOTH], aggressor, defender ); + else if ( incident.usIncidentFlags & INCIDENT_REINFORCEMENTS_ENEMY ) + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_REINFORCE], enemy ); + else + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_REINFORCE], rebel ); + + usPosY += DisplayWrappedString( usPosX, usPosY, LAPTOP_SCREEN_LR_X - usPosX, 2, CAMPHIS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR,sText, FONT_MCOLOR_BLACK, FALSE, 0); + if ( picend < usPosY ) usPosX = LAPTOP_SCREEN_UL_X; + } + + if ( incident.usIncidentFlags & (INCIDENT_MUSTARDGAS_ENEMY|INCIDENT_MUSTARDGAS_PLAYERSIDE) ) + { + if ( incident.usIncidentFlags & INCIDENT_MUSTARDGAS_ENEMY && incident.usIncidentFlags & INCIDENT_MUSTARDGAS_PLAYERSIDE ) + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_CHEMICAL_BOTH] ); + else if ( incident.usIncidentFlags & INCIDENT_MUSTARDGAS_ENEMY ) + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_CHEMICAL], enemy ); + else + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_CHEMICAL], rebel ); + + usPosY += DisplayWrappedString( usPosX, usPosY, LAPTOP_SCREEN_LR_X - usPosX, 2, CAMPHIS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR,sText, FONT_MCOLOR_BLACK, FALSE, 0); + if ( picend < usPosY ) usPosX = LAPTOP_SCREEN_UL_X; + } + + if ( incident.usIncidentFlags & (INCIDENT_TANKS_ENEMY|INCIDENT_TANKS_PLAYERSIDE) ) + { + if ( incident.usIncidentFlags & INCIDENT_TANKS_ENEMY && incident.usIncidentFlags & INCIDENT_TANKS_PLAYERSIDE ) + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_TANKS_BOTH] ); + else if ( incident.usIncidentFlags & INCIDENT_TANKS_ENEMY ) + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_TANKS], incident.usParticipants[CAMPAIGNHISTORY_SD_ENEMY_TANK], enemy, incident.usKills[CAMPAIGNHISTORY_SD_ENEMY_TANK] ); + else + // TODO + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_TANKS], incident.usParticipants[CAMPAIGNHISTORY_SD_ENEMY_TANK], rebel, incident.usKills[CAMPAIGNHISTORY_SD_ENEMY_TANK] ); + + usPosY += DisplayWrappedString( usPosX, usPosY, LAPTOP_SCREEN_LR_X - usPosX, 2, CAMPHIS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR,sText, FONT_MCOLOR_BLACK, FALSE, 0); + if ( picend < usPosY ) usPosX = LAPTOP_SCREEN_UL_X; + } + + if ( incident.usIncidentFlags & (INCIDENT_SNIPERS_ENEMY|INCIDENT_SNIPERS_PLAYERSIDE) ) + { + if ( incident.usIncidentFlags & INCIDENT_SNIPERS_ENEMY && incident.usIncidentFlags & INCIDENT_SNIPERS_PLAYERSIDE ) + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_SNIPERS_BOTH] ); + else if ( incident.usIncidentFlags & INCIDENT_SNIPERS_ENEMY ) + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_SNIPERS], enemy ); + else + swprintf(sText, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_SNIPERS], rebel ); + + usPosY += DisplayWrappedString( usPosX, usPosY, LAPTOP_SCREEN_LR_X - usPosX, 2, CAMPHIS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR,sText, FONT_MCOLOR_BLACK, FALSE, 0); + if ( picend < usPosY ) usPosX = LAPTOP_SCREEN_UL_X; + } + + { + // team losses + UINT16 rebellosses = incident.usKills[CAMPAIGNHISTORY_SD_MERC] + incident.usKills[CAMPAIGNHISTORY_SD_MILITIA_GREEN] + incident.usKills[CAMPAIGNHISTORY_SD_MILITIA_REGULAR] + incident.usKills[CAMPAIGNHISTORY_SD_MILITIA_ELITE]; + UINT16 armylosses = incident.usKills[CAMPAIGNHISTORY_SD_ENEMY_ADMIN] + incident.usKills[CAMPAIGNHISTORY_SD_ENEMY_ARMY] + incident.usKills[CAMPAIGNHISTORY_SD_ENEMY_ELITE] + incident.usKills[CAMPAIGNHISTORY_SD_ENEMY_TANK]; + UINT16 armypows = incident.usPrisoners[CAMPAIGNHISTORY_SD_ENEMY_ADMIN] + incident.usPrisoners[CAMPAIGNHISTORY_SD_ENEMY_ARMY] + incident.usPrisoners[CAMPAIGNHISTORY_SD_ENEMY_ELITE] + incident.usPrisoners[CAMPAIGNHISTORY_SD_ENEMY_TANK]; + + // team sizes + UINT16 rebelsize = max(1, incident.usParticipants[CAMPAIGNHISTORY_SD_MERC] + incident.usParticipants[CAMPAIGNHISTORY_SD_MILITIA_GREEN] + incident.usParticipants[CAMPAIGNHISTORY_SD_MILITIA_REGULAR] + incident.usParticipants[CAMPAIGNHISTORY_SD_MILITIA_ELITE]); + UINT16 armysize = max(1, incident.usParticipants[CAMPAIGNHISTORY_SD_ENEMY_ADMIN] + incident.usParticipants[CAMPAIGNHISTORY_SD_ENEMY_ARMY] + incident.usParticipants[CAMPAIGNHISTORY_SD_ENEMY_ELITE] + incident.usParticipants[CAMPAIGNHISTORY_SD_ENEMY_TANK]); + + // if rebels won... + if ( incident.usIncidentFlags & INCIDENT_WIN ) + { + FLOAT ratio = (FLOAT)(rebellosses / rebelsize); + if ( ratio < 0.1 ) + swprintf(sText, szCampaignHistoryResultString[TEXT_CAMPAIGNHISTORY_RESULT_ONESIDED_REBEL] ); + else if ( ratio < 0.3 ) + { + if ( armypows ) + swprintf(sText, szCampaignHistoryResultString[TEXT_CAMPAIGNHISTORY_RESULT_EASY_REBEL_PRISONER] ); + else + swprintf(sText, szCampaignHistoryResultString[TEXT_CAMPAIGNHISTORY_RESULT_EASY_REBEL] ); + } + else if ( ratio < 0.6 ) + { + if ( armypows ) + swprintf(sText, szCampaignHistoryResultString[TEXT_CAMPAIGNHISTORY_RESULT_MEDIUM_REBEL] ); + else + swprintf(sText, szCampaignHistoryResultString[TEXT_CAMPAIGNHISTORY_RESULT_MEDIUM_REBEL_PRISONER] ); + } + else + swprintf(sText, szCampaignHistoryResultString[TEXT_CAMPAIGNHISTORY_RESULT_HARD_REBEL] ); + } + else // army won... + { + FLOAT ratio = (FLOAT)(armylosses / armysize); + BOOLEAN armyhadmore = (armysize > rebelsize); + + if ( ratio < 0.1 ) + { + if ( armyhadmore ) + swprintf(sText, szCampaignHistoryResultString[TEXT_CAMPAIGNHISTORY_RESULT_ONESIDED_ARMY_NUMBERS] ); + else + swprintf(sText, szCampaignHistoryResultString[TEXT_CAMPAIGNHISTORY_RESULT_ONESIDED_ARMY_TRAINING] ); + } + else if ( ratio < 0.3 ) + { + if ( armyhadmore ) + swprintf(sText, szCampaignHistoryResultString[TEXT_CAMPAIGNHISTORY_RESULT_EASY_ARMY_NUMBERS] ); + else + swprintf(sText, szCampaignHistoryResultString[TEXT_CAMPAIGNHISTORY_RESULT_EASY_ARMY_TRAINING] ); + } + else if ( ratio < 0.6 ) + { + if ( armyhadmore ) + swprintf(sText, szCampaignHistoryResultString[TEXT_CAMPAIGNHISTORY_RESULT_MEDIUM_ARMY_NUMBERS] ); + else + swprintf(sText, szCampaignHistoryResultString[TEXT_CAMPAIGNHISTORY_RESULT_MEDIUM_ARMY_TRAINING] ); + } + else + swprintf(sText, szCampaignHistoryResultString[TEXT_CAMPAIGNHISTORY_RESULT_HARD_ARMY] ); + } + + usPosY += DisplayWrappedString( usPosX, usPosY, LAPTOP_SCREEN_LR_X - usPosX, 2, CAMPHIS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR,sText, FONT_MCOLOR_BLACK, FALSE, 0); + if ( picend < usPosY ) usPosX = LAPTOP_SCREEN_UL_X; + } + } + } + + // previous/next buttons + usPosX = CAMPAIGN_HISTORY_PAGEBTN_X; + usPosY = CAMPAIGN_HISTORY_PAGEBTN_Y; + if ( gusMostImportantMode ) + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_SUMMARY]); + else + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_DETAIL]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_PAGEBTN_STEP_X; + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_PREVIOUS]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_PAGEBTN_STEP_X; + swprintf(sText, szCampaignHistoryWebpageString[WEBPAGE_CAMPAIGNHISTORY_NEXT]); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + SetFontShadow( DEFAULT_SHADOW ); + MarkButtonsDirty( ); + RenderWWWProgramTitleBar( ); + InvalidateRegion(LAPTOP_SCREEN_UL_X,LAPTOP_SCREEN_WEB_UL_Y,LAPTOP_SCREEN_LR_X,LAPTOP_SCREEN_WEB_LR_Y); +} + +void SelectCampaignHistoryMostImportantRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ) +{ + if (iReason & MSYS_CALLBACK_REASON_INIT) + { + } + else if(iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) + { + UINT32 uiLink = MSYS_GetRegionUserData( pRegion, 0 ); + + // only display existing incidents + UINT8 numpages = gCampaignStats.usNumIncidents; + /*for(int i = 0; i < CAMPAIGNSTATS_NUM_MOST_IMPORTANT; ++i) + { + if ( gCampaignStats.importantIncidents[i].usID ) + ++numpages; + }*/ + + if( uiLink == 0 ) + { + ++gusMostImportantMode; + + if ( gusMostImportantMode >= 2) + gusMostImportantMode = 0; + } + else if( uiLink == 1 ) + { + if ( gusMostImportantPage == 0 ) + gusMostImportantPage = numpages; + + --gusMostImportantPage; + } + else if( uiLink == 2 ) + { + ++gusMostImportantPage; + + if ( gusMostImportantPage >= numpages ) + gusMostImportantPage = 0; + } + + RenderCampaignHistory_MostImportant(); + } + else if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) + { + } +} +////////////////////////// MOST IMPORTANT PAGE ////////////////////////////////// + +////////////////////////// NEWS PAGE ////////////////////////////////// +//link to the various pages +MOUSE_REGION gCampaignHistoryNewsLinkRegion[4]; +void SelectCampaignHistoryNewsRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ); + +UINT8 gusNewsPage = 0; + +void GameInitCampaignHistory_News() +{ + gusNewsPage = 0; +} + +BOOLEAN EnterCampaignHistory_News() +{ + InitCampaignHistoryDefaults(); + + // previous/next buttons + UINT16 usPosX = CAMPAIGN_HISTORY_PAGEBTN_X; + UINT16 usPosY = CAMPAIGN_HISTORY_PAGEBTN_Y; + for(int i=0; i<4; ++i) + { + MSYS_DefineRegion( &gCampaignHistoryNewsLinkRegion[i], usPosX, usPosY, (UINT16)(usPosX + CAMPAIGN_HISTORY_LINK_TEXT_WIDTH), usPosY+CAMPAIGN_HISTORY_LINK_STEP_Y, MSYS_PRIORITY_HIGH, + CURSOR_WWW, MSYS_NO_CALLBACK, SelectCampaignHistoryNewsRegionCallBack); + MSYS_AddRegion(&gCampaignHistoryNewsLinkRegion[i]); + MSYS_SetRegionUserData( &gCampaignHistoryNewsLinkRegion[i], 0, i ); + + usPosX += CAMPAIGN_HISTORY_PAGEBTN_STEP_X; + } + + RenderCampaignHistorySummary(); + + return(TRUE); +} + +void ExitCampaignHistory_News() +{ + RemoveCampaignHistoryDefaults(); + + // previous/next buttons + for(int i=0; i<4; ++i) + MSYS_RemoveRegion( &gCampaignHistoryNewsLinkRegion[i]); +} + +void HandleCampaignHistory_News() +{ + +} + +void RenderCampaignHistory_News() +{ +// HVOBJECT hPixHandle; + CHAR16 sText[800]; + swprintf( sText, L"" ); + UINT16 usPosX, usPosY; + + DisplayCampaignHistoryDefaults(); + + SetFontShadow( CAMPHIS_FONT_SHADOW ); + + usPosX = LAPTOP_SCREEN_UL_X; + usPosY = LAPTOP_SCREEN_WEB_UL_Y + 80; + + // return if there are no incidents yet + /*if ( !gCampaignStats.usNumIncidents ) + return; + + Incident_Stats incident = gCampaignStats.mIncidentVector[ gusNewsPage ]; + + CHAR16 wSectorName_Target[ 100 ]; + GetSectorIDString( SECTORX(incident.usSector), SECTORY(incident.usSector), incident.usLevel, wSectorName_Target, TRUE ); + + //Calculate the day, hour, and minutes. + UINT32 day = ( incident.usTime / NUM_SEC_IN_DAY ); + UINT32 hour = ( incident.usTime - ( day * NUM_SEC_IN_DAY ) ) / NUM_SEC_IN_HOUR; + UINT32 minute = ( incident.usTime - ( ( day * NUM_SEC_IN_DAY ) + ( hour * NUM_SEC_IN_HOUR ) ) ) / NUM_SEC_IN_MIN;*/ + + //swprintf(sText, L"Incident #%d - %s, Day %d, %02d:%02d", incident.usID, wSectorName_Target, day, hour, minute); + swprintf(sText, L"--- currently under construction ---"); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, CAMPHIS_FONT_BIG, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); + + + + // previous/next buttons + /*usPosX = CAMPAIGN_HISTORY_PAGEBTN_X; + usPosY = CAMPAIGN_HISTORY_PAGEBTN_Y; + swprintf(sText, L"Summary"); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_PAGEBTN_STEP_X; + swprintf(sText, L"Detail"); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_PAGEBTN_STEP_X; + swprintf(sText, L"Previous"); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 ); + + usPosX += CAMPAIGN_HISTORY_PAGEBTN_STEP_X; + swprintf(sText, L"Next"); + DrawTextToScreen( sText, usPosX, usPosY, LAPTOP_SCREEN_LR_X-LAPTOP_SCREEN_UL_X, INS_FONT_SMALL, CAMPAIGN_HISTORY_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 );*/ + + + SetFontShadow( DEFAULT_SHADOW ); + MarkButtonsDirty( ); + RenderWWWProgramTitleBar( ); + InvalidateRegion(LAPTOP_SCREEN_UL_X,LAPTOP_SCREEN_WEB_UL_Y,LAPTOP_SCREEN_LR_X,LAPTOP_SCREEN_WEB_LR_Y); +} + +void SelectCampaignHistoryNewsRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ) +{ + if (iReason & MSYS_CALLBACK_REASON_INIT) + { + } + else if(iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) + { + UINT32 uiLink = MSYS_GetRegionUserData( pRegion, 0 ); + + // only display existing incidents + UINT8 numpages = gCampaignStats.usNumIncidents; + /*for(int i = 0; i < CAMPAIGNSTATS_NUM_LAST_INCIDENTS; ++i) + { + if ( gCampaignStats.lastIncidents[i].usID ) + ++numpages; + }*/ + + if( uiLink == 0 ) + { + + } + else if( uiLink == 1 ) + { + + } + else if( uiLink == 2 ) + { + if ( gusNewsPage == 0 ) + gusNewsPage = numpages; + + --gusNewsPage; + } + else if( uiLink == 3 ) + { + ++gusNewsPage; + + if ( gusNewsPage >= numpages ) + gusNewsPage = 0; + } + + RenderCampaignHistory_News(); + } + else if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) + { + } +} +////////////////////////// NEWS PAGE ////////////////////////////////// diff --git a/Laptop/CampaignHistory_Summary.h b/Laptop/CampaignHistory_Summary.h new file mode 100644 index 00000000..75f80692 --- /dev/null +++ b/Laptop/CampaignHistory_Summary.h @@ -0,0 +1,30 @@ +#ifndef __CAMPAIGNHISTORY_SUMMARY_H +#define __CAMPAIGNHISTORY_SUMMARY_H + +/** + * @file + * @author Flugente (bears-pit.com) + */ + +// webpage displaying a summary of events +void GameInitCampaignHistorySummary(); +BOOLEAN EnterCampaignHistorySummary(); +void ExitCampaignHistorySummary(); +void HandleCampaignHistorySummary(); +void RenderCampaignHistorySummary(); + +// webpage displaying most important incidents +void GameInitCampaignHistory_MostImportant(); +BOOLEAN EnterCampaignHistory_MostImportant(); +void ExitCampaignHistory_MostImportant(); +void HandleCampaignHistory_MostImportant(); +void RenderCampaignHistory_MostImportant(); + +// webpage displaying most recent incidents (not useable for the time being) +void GameInitCampaignHistory_News(); +BOOLEAN EnterCampaignHistory_News(); +void ExitCampaignHistory_News(); +void HandleCampaignHistory_News(); +void RenderCampaignHistory_News(); + +#endif // __CAMPAIGNHISTORY_SUMMARY_H \ No newline at end of file diff --git a/Laptop/CampaignStats.cpp b/Laptop/CampaignStats.cpp new file mode 100644 index 00000000..52cdbafe --- /dev/null +++ b/Laptop/CampaignStats.cpp @@ -0,0 +1,715 @@ +/** + * @file + * @author Flugente (bears-pit.com) + */ + +#include "CampaignStats.h" +#include "message.h" +#include "SaveLoadGame.h" +#include "GameVersion.h" +#include "Campaign Types.h" +#include "Game Clock.h" +#include "Soldier macros.h" +#include "Text.h" +#include "Laptop.h" +#include "LaptopSave.h" +#include "email.h" + +Campaign_Stats gCampaignStats; +Incident_Stats gCurrentIncident; // we might save during an incident, thus we have to store the ongoing incident + +CAMPAIGNSTATSEVENT zCampaignStatsEvent[NUM_CAMPAIGNSTATSEVENTS]; + +extern INT32 ReadFieldByField(HWFILE hFile, PTR pDest, UINT32 uiFieldSize, UINT32 uiElementSize, UINT32 uiCurByteCount); + +void +Incident_Stats::clear() +{ + usID = 0; + usTime = 0; + usSector = 0; + usLevel = 0; + usInterestRating = 0; + usNPCDied = 0; + usCivFactionFought = 0; + usIncidentFlags = 0; + usOneTimeEventFlags = 0; + + for (UINT8 i = 0; i < CAMPAIGNHISTORY_SD_MAX; ++i) + { + usKills[i] = 0; + usWounds[i] = 0; + usPrisoners[i] = 0; + usShots[i] = 0; + usParticipants[i] = 0; + usPromotions[i] = 0; + } +} + +// determine how 'interesting' an incident is - the more happens, the more interesting it is +void +Incident_Stats::CalcInterestRating() +{ + usInterestRating = 0; + + for (UINT8 i = 0; i < CAMPAIGNHISTORY_SD_MAX; ++i) + { + usInterestRating += 100 * usKills[i]; + usInterestRating += 50 * usWounds[i]; + usInterestRating += 75 * usPrisoners[i]; + usInterestRating += usShots[i] / 30; + usInterestRating += 20 * usParticipants[i]; + usInterestRating += 5 * usPromotions[i]; + } + + if ( usNPCDied ) + usInterestRating += 500; + + if ( usCivFactionFought ) + usInterestRating += 1000; + + // evaluate flags + if ( usIncidentFlags & INCIDENT_ARTILLERY_ENEMY ) usInterestRating += 500; + if ( usIncidentFlags & INCIDENT_ARTILLERY_PLAYERSIDE ) usInterestRating += 500; + if ( usIncidentFlags & INCIDENT_TANKS_ENEMY ) usInterestRating += 1000; + if ( usIncidentFlags & INCIDENT_TANKS_PLAYERSIDE ) usInterestRating += 2000; + if ( usIncidentFlags & INCIDENT_MUSTARDGAS_ENEMY ) usInterestRating += 500; + if ( usIncidentFlags & INCIDENT_MUSTARDGAS_PLAYERSIDE ) usInterestRating += 500; + if ( usIncidentFlags & INCIDENT_ATTACK_ENEMY ) usInterestRating += 200; + if ( usIncidentFlags & INCIDENT_ATTACK_PLAYERSIDE ) usInterestRating += 100; + if ( usIncidentFlags & INCIDENT_REINFORCEMENTS_ENEMY ) usInterestRating += 500; + if ( usIncidentFlags & INCIDENT_REINFORCEMENTS_PLAYERSIDE ) usInterestRating += 500; + if ( usIncidentFlags & INCIDENT_SNIPERS_ENEMY ) usInterestRating += 200; + if ( usIncidentFlags & INCIDENT_SNIPERS_PLAYERSIDE ) usInterestRating += 100; + if ( usIncidentFlags & INCIDENT_AMBUSH ) usInterestRating += 100; + if ( usIncidentFlags & INCIDENT_AIRDROP ) usInterestRating += 100; + if ( usIncidentFlags & INCIDENT_SURGERY ) usInterestRating += 50; + if ( usIncidentFlags & INCIDENT_BUILDINGS_DAMAGED ) usInterestRating += 100; + if ( usIncidentFlags & INCIDENT_WIN ) usInterestRating += 100; + else usInterestRating += 200; + + if ( usOneTimeEventFlags & INCIDENT_ONETIMEEVENT_OMERTA ) usInterestRating += 1000; + if ( usOneTimeEventFlags & INCIDENT_ONETIMEEVENT_DEATH_KINGPIN ) usInterestRating += 500; + if ( usOneTimeEventFlags & (INCIDENT_ONETIMEEVENT_MASSACRE_HICKS|INCIDENT_ONETIMEEVENT_MASSACRE_BLOODCATS) ) usInterestRating += 800; + if ( usOneTimeEventFlags & INCIDENT_ONETIMEEVENT_CITY_RETAKEN ) usInterestRating += 2000; + if ( usOneTimeEventFlags & INCIDENT_ONETIMEEVENT_CITY_LIBERATED ) usInterestRating += 1000; +} + +BOOLEAN +Incident_Stats::Save( HWFILE hFile ) +{ + UINT32 uiNumBytesWritten = 0; + + if ( !FileWrite( hFile, this, SIZEOF_INCIDENT_STATS_POD, &uiNumBytesWritten ) ) + { + return(FALSE); + } + + return( TRUE ); +} + +BOOLEAN +Incident_Stats::Load( HWFILE hwFile ) +{ + if(guiCurrentSaveGameVersion >= CAMPAIGNSTATS) + { + UINT32 numBytesRead = 0; + + numBytesRead = ReadFieldByField(hwFile, &usID, sizeof(usID), sizeof(UINT32), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usTime, sizeof(usTime), sizeof(UINT32), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usSector, sizeof(usSector), sizeof(UINT8), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usLevel, sizeof(usLevel), sizeof(UINT8), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usInterestRating, sizeof(usInterestRating), sizeof(UINT32), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usNPCDied, sizeof(usNPCDied), sizeof(UINT8), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usCivFactionFought, sizeof(usCivFactionFought), sizeof(UINT8), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usIncidentFlags, sizeof(usIncidentFlags), sizeof(UINT64), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usOneTimeEventFlags, sizeof(usOneTimeEventFlags),sizeof(UINT64), numBytesRead); + + numBytesRead = ReadFieldByField(hwFile, &usKills, sizeof(usKills), sizeof(UINT16), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usWounds, sizeof(usWounds), sizeof(UINT16), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usPrisoners, sizeof(usPrisoners), sizeof(UINT16), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usShots, sizeof(usShots), sizeof(UINT16), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usParticipants, sizeof(usParticipants), sizeof(UINT16), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usPromotions, sizeof(usPromotions), sizeof(UINT16), numBytesRead); + + numBytesRead = ReadFieldByField(hwFile, &usFiller, sizeof(usFiller), sizeof(UINT8), numBytesRead); + + if( numBytesRead != SIZEOF_INCIDENT_STATS_POD ) + return(FALSE); + } + + return( TRUE ); +} + +void +Incident_Stats::AddStat( SOLDIERTYPE* pSoldier, UINT8 aType ) +{ + UINT8 group = CAMPAIGNHISTORY_SD_MERC; + + switch ( pSoldier->bTeam ) + { + case OUR_TEAM: + group = CAMPAIGNHISTORY_SD_MERC; + break; + + case ENEMY_TEAM: + { + if ( TANK(pSoldier) ) + group = CAMPAIGNHISTORY_SD_ENEMY_TANK; + else if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR ) + group = CAMPAIGNHISTORY_SD_ENEMY_ADMIN; + else if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE ) + group = CAMPAIGNHISTORY_SD_ENEMY_ELITE; + else if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ARMY ) + group = CAMPAIGNHISTORY_SD_ENEMY_ARMY; + } + break; + + case CREATURE_TEAM: +#ifdef ENABLE_ZOMBIES + if ( pSoldier->IsZombie() ) + group = CAMPAIGNHISTORY_SD_ZOMBIE; + else +#endif + group = CAMPAIGNHISTORY_SD_CREATURE; + break; + + case MILITIA_TEAM: + { + if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA ) + group = CAMPAIGNHISTORY_SD_MILITIA_GREEN; + else if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA ) + group = CAMPAIGNHISTORY_SD_MILITIA_REGULAR; + else if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA ) + group = CAMPAIGNHISTORY_SD_MILITIA_ELITE; + } + break; + + case CIV_TEAM: + default: + group = CAMPAIGNHISTORY_SD_CIV; + break; + } + + switch ( aType ) + { + case CAMPAIGNHISTORY_TYPE_KILL: + { + usKills[group]++; + + if ( pSoldier->ubProfile == KINGPIN ) + usOneTimeEventFlags |= INCIDENT_ONETIMEEVENT_DEATH_KINGPIN; + else if ( pSoldier->ubProfile == DARREL ) + usOneTimeEventFlags |= INCIDENT_ONETIMEEVENT_MASSACRE_HICKS; + } + break; + + case CAMPAIGNHISTORY_TYPE_WOUND: + usWounds[group]++; + break; + + case CAMPAIGNHISTORY_TYPE_PRISONER: + usPrisoners[group]++; + break; + + case CAMPAIGNHISTORY_TYPE_SHOT: + usShots[group]++; + break; + + case CAMPAIGNHISTORY_TYPE_PARTICIPANT: + usParticipants[group]++; + break; + + case CAMPAIGNHISTORY_TYPE_PROMOTION: + default: + usPromotions[group]++; + break; + } + + if ( TANK(pSoldier) ) + { + if ( pSoldier->bSide == 0 ) + usIncidentFlags |= INCIDENT_TANKS_PLAYERSIDE; + else + usIncidentFlags |= INCIDENT_TANKS_ENEMY; + } +} + +UINT8 tmpnr = 0; +static CHAR16 tmpdirstring[2][ 50 ]; // we need 2 arrays, in case we need 2 name pointers in one string +STR16 +Incident_Stats::GetAttackerDirString( BOOLEAN fAttacker ) +{ + CHAR16 helperstr[ 50 ]; + swprintf(helperstr, L"" ); + + ++tmpnr; + if ( tmpnr > 1 ) + tmpnr = 0; + + tmpdirstring[tmpnr][0] = '\0' ; + + UINT8 dirs = 0; + CHAR16 dir1[ 10 ], dir2[ 10 ], dir3[ 10 ], dir4[ 10 ]; + swprintf(dir1, L"" ); + swprintf(dir2, L"" ); + swprintf(dir3, L"" ); + swprintf(dir4, L"" ); + + if ( (fAttacker && usIncidentFlags & INCIDENT_ATTACK_ENEMY) || (!fAttacker && usIncidentFlags & INCIDENT_ATTACK_PLAYERSIDE) ) + { + if ( usIncidentFlags & INCIDENT_ATTACKDIR_NORTH_ENEMY ) + { + swprintf(dir1, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_NORTH] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_WEST_ENEMY ) + { + swprintf(dir2, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_WEST] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_SOUTH_ENEMY ) + { + swprintf(dir3, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_SOUTH] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST_ENEMY ) + { + swprintf(dir4, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST_ENEMY ) + { + swprintf(dir3, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_SOUTH_ENEMY ) + { + swprintf(dir2, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_SOUTH] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST_ENEMY ) + { + swprintf(dir3, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST_ENEMY ) + { + swprintf(dir2, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_WEST_ENEMY ) + { + swprintf(dir1, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_WEST] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_SOUTH_ENEMY ) + { + swprintf(dir2, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_SOUTH] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST_ENEMY ) + { + swprintf(dir3, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST_ENEMY ) + { + swprintf(dir2, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_SOUTH_ENEMY ) + { + swprintf(dir1, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_SOUTH] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST_ENEMY ) + { + swprintf(dir2, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST_ENEMY ) + { + swprintf(dir1, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else + { + if ( usIncidentFlags & INCIDENT_ATTACKDIR_NORTH ) + { + swprintf(dir1, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_NORTH] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_WEST ) + { + swprintf(dir2, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_WEST] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_SOUTH ) + { + swprintf(dir3, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_SOUTH] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST ) + { + swprintf(dir4, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST ) + { + swprintf(dir3, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_SOUTH ) + { + swprintf(dir2, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_SOUTH] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST ) + { + swprintf(dir3, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST ) + { + swprintf(dir2, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_WEST ) + { + swprintf(dir1, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_WEST] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_SOUTH ) + { + swprintf(dir2, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_SOUTH] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST ) + { + swprintf(dir3, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST ) + { + swprintf(dir2, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_SOUTH ) + { + swprintf(dir1, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_SOUTH] ); + ++dirs; + + if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST ) + { + swprintf(dir2, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + else if ( usIncidentFlags & INCIDENT_ATTACKDIR_EAST ) + { + swprintf(dir1, szCampaignHistoryDetail[TEXT_CAMPAIGNHISTORY_DETAIL_EAST] ); + ++dirs; + } + } + + switch ( dirs ) + { + case 4: + swprintf(helperstr, L"%s, %s, %s and %s", dir1, dir2, dir3, dir4 ); + break; + + case 3: + swprintf(helperstr, L"%s, %s and %s", dir1, dir2, dir3 ); + break; + + case 2: + swprintf(helperstr, L"%s and %s", dir1, dir2 ); + break; + + case 1: + swprintf(helperstr, L"%s", dir1 ); + break; + + default: + break; + } + + wcscat( tmpdirstring[tmpnr], helperstr ); + + return tmpdirstring[tmpnr]; +} + +void +Incident_Stats::GetTerrainandType(UINT8& arTerrain, UINT8& arType) +{ + if ( usLevel > 0 ) + arTerrain = CAMPAINGHISTORY_PICLIBRARY_TERRAIN_UNDERGROUND; + else + { + SECTORINFO *pSector = &SectorInfo[ usSector ]; + + switch( pSector->ubTraversability[ THROUGH_STRATEGIC_MOVE ] ) + { + case COASTAL: + case COASTAL_ROAD: + case WATER: + arTerrain = CAMPAINGHISTORY_PICLIBRARY_TERRAIN_COASTAL; + break; + + case SAND: + case SAND_ROAD: + case SAND_SAM_SITE: + arTerrain = CAMPAINGHISTORY_PICLIBRARY_TERRAIN_DESERT; + break; + + case DENSE: + case DENSE_ROAD: + arTerrain = CAMPAINGHISTORY_PICLIBRARY_TERRAIN_FOREST; + break; + + case GROUNDBARRIER: + case EDGEOFWORLD: + case HILLS: + case HILLS_ROAD: + arTerrain = CAMPAINGHISTORY_PICLIBRARY_TERRAIN_MOUNTAIN; + break; + + case NS_RIVER: + case EW_RIVER: + arTerrain = CAMPAINGHISTORY_PICLIBRARY_TERRAIN_RIVER; + break; + + case SWAMP: + case SWAMP_ROAD: + arTerrain = CAMPAINGHISTORY_PICLIBRARY_TERRAIN_SWAMP; + break; + + case TROPICS: + case TROPICS_ROAD: + case TROPICS_SAM_SITE: + arTerrain = CAMPAINGHISTORY_PICLIBRARY_TERRAIN_TROPICAL; + break; + + case TOWN: + case MEDUNA_SAM_SITE: + case CAMBRIA_HOSPITAL_SITE: + case DRASSEN_AIRPORT_SITE: + case MEDUNA_AIRPORT_SITE: + case SAM_SITE: + case REBEL_HIDEOUT: + case TIXA_DUNGEON: + case CREATURE_LAIR: + case ORTA_BASEMENT: + case TUNNEL: + case SHELTER: + case ABANDONED_MINE: + arTerrain = CAMPAINGHISTORY_PICLIBRARY_TERRAIN_URBAN; + break; + + case ROAD: + case PLAINS: + case SPARSE: + case FARMLAND: + case PLAINS_ROAD: + case SPARSE_ROAD: + case FARMLAND_ROAD: + case SPARSE_SAM_SITE: + default: + arTerrain = CAMPAINGHISTORY_PICLIBRARY_TERRAIN_SPARSE; + break; + } + } + + if ( usIncidentFlags & INCIDENT_AIRDROP ) + arType = CAMPAINGHISTORY_PICLIBRARY_TYPE_AIRDROP; + else if ( usIncidentFlags & (INCIDENT_TANKS_ENEMY|INCIDENT_TANKS_PLAYERSIDE) ) + arType = CAMPAINGHISTORY_PICLIBRARY_TYPE_TANKS; + else if ( usIncidentFlags & INCIDENT_WIN ) + arType = CAMPAINGHISTORY_PICLIBRARY_TYPE_WIN; + else + arType = CAMPAINGHISTORY_PICLIBRARY_TYPE_LOSS; +} + +Campaign_Stats::Campaign_Stats() +{ + //*mspSelf = *this; +} + +Campaign_Stats::~Campaign_Stats() +{ + //if ( mspSelf ) + //delete mspSelf; +} + +/*Campaign_Stats* +Campaign_Stats::GetObject() +{ + if ( !mspSelf ) + mspSelf = new Campaign_Stats; + + return mspSelf; +}*/ + +void +Campaign_Stats::clear() +{ + memset(this, 0, SIZEOF_CAMPAIGN_STATS_POD); + + mIncidentVector.clear(); +} + +BOOLEAN +Campaign_Stats::Save( HWFILE hFile ) +{ + if(guiCurrentSaveGameVersion >= CAMPAIGNSTATS) + { + UINT32 uiNumBytesWritten = 0; + + if ( !FileWrite( hFile, this, SIZEOF_CAMPAIGN_STATS_POD, &uiNumBytesWritten ) ) + return(FALSE); + + std::vector::iterator itend = mIncidentVector.end(); + for (std::vector::iterator it = mIncidentVector.begin(); it != itend; ++it) + { + if ( !(*it).Save ( hFile ) ) + return(FALSE); + } + } + + return( TRUE ); +} + +BOOLEAN +Campaign_Stats::Load( HWFILE hwFile ) +{ + if(guiCurrentSaveGameVersion >= CAMPAIGNSTATS) + { + UINT32 numBytesRead = 0; + + numBytesRead = ReadFieldByField(hwFile, &usKills, sizeof(usKills), sizeof(UINT32), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usWounds, sizeof(usWounds), sizeof(UINT32), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usPrisoners, sizeof(usPrisoners), sizeof(UINT32), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usShots, sizeof(usShots), sizeof(UINT32), numBytesRead); + + numBytesRead = ReadFieldByField(hwFile, &sMoneyEarned, sizeof(sMoneyEarned), sizeof(INT32), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usConsumed, sizeof(usConsumed), sizeof(FLOAT), numBytesRead); + + numBytesRead = ReadFieldByField(hwFile, &usNumIncidents, sizeof(usNumIncidents), sizeof(UINT32), numBytesRead); + numBytesRead = ReadFieldByField(hwFile, &usHighestID, sizeof(usHighestID), sizeof(UINT32), numBytesRead); + + numBytesRead = ReadFieldByField(hwFile, &usFiller, sizeof(usFiller), sizeof(UINT8), numBytesRead); + + if( numBytesRead != SIZEOF_CAMPAIGN_STATS_POD ) + return(FALSE); + + for (UINT8 i = 0; i < usNumIncidents; ++i) + { + Incident_Stats incident; + if ( !incident.Load ( hwFile ) ) + return(FALSE); + + // if option is active, only read the last reports and forget the rest + if ( gGameExternalOptions.usReportsToLoad < 0 || i >= usNumIncidents - gGameExternalOptions.usReportsToLoad ) + mIncidentVector.push_back(incident); + } + + // re-evaluate the vector size - we may have been ordered to forget some + usNumIncidents = mIncidentVector.size(); + } + + return( TRUE ); +} + +// Warning! As this also updates the overall kill counters, don't use this function when loading incidents +void +Campaign_Stats::AddNewIncident(Incident_Stats arIncident) +{ + // make sure interest rating is up to date + arIncident.CalcInterestRating(); + + mIncidentVector.push_back(arIncident); + ++usNumIncidents; + + // update kills/wounds/prisoner numbers + for (UINT i = 0; i < CAMPAIGNHISTORY_SD_MAX; ++i) + { + usKills[i] += arIncident.usKills[i]; + usWounds[i] += arIncident.usWounds[i]; + usPrisoners[i] += arIncident.usPrisoners[i]; + usShots[i] += arIncident.usShots[i]; + } +} + +void +Campaign_Stats::AddMoneyEarned(UINT8 aType, INT32 aVal) +{ + if ( aType >= CAMPAIGN_MONEY_MAX ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Error: Unknown money type!" ); + return; + } + + sMoneyEarned[aType] += aVal; +} + +void +Campaign_Stats::AddConsumption(UINT8 aType, FLOAT aVal) +{ + if ( aType >= CAMPAIGN_MONEY_MAX ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Error: Unknown consumption type!" ); + return; + } + + usConsumed[aType] += aVal; +} + +// add this incident to the campaign stats and then clear it +void FinishIncident(INT16 sX, INT16 sY, INT8 sZ) +{ + // due to odd coding, we do not know when an incident starts + // (checking for entering combat isn't enough, as we do that multiple times per battle) + // we thus set the relevant data when finishing an incident + gCampaignStats.usHighestID++; + + gCurrentIncident.usID = gCampaignStats.usHighestID; + gCurrentIncident.usTime = GetWorldTotalSeconds(); + gCurrentIncident.usSector = SECTOR(sX, sY); + gCurrentIncident.usLevel = sZ; + + // add flags depending on quests etc. + // if this is incident 1, we just landed - special text then + if ( gCampaignStats.usHighestID == 1 ) + gCurrentIncident.usOneTimeEventFlags |= INCIDENT_ONETIMEEVENT_OMERTA; + + gCampaignStats.AddNewIncident(gCurrentIncident); + + // reset incident after adding it + gCurrentIncident.clear(); +} + +// start a new incident +void StartIncident(INT16 sX, INT16 sY, INT8 sZ) +{ + gCampaignStats.usHighestID++; + + gCurrentIncident.usID = gCampaignStats.usHighestID; + gCurrentIncident.usTime = GetWorldTotalSeconds(); + gCurrentIncident.usSector = SECTOR(sX, sY); + gCurrentIncident.usLevel = sZ; +} diff --git a/Laptop/CampaignStats.h b/Laptop/CampaignStats.h new file mode 100644 index 00000000..b429adae --- /dev/null +++ b/Laptop/CampaignStats.h @@ -0,0 +1,328 @@ +#ifndef __CAMPAIGNSTATS_H +#define __CAMPAIGNSTATS_H + +/** + * @file + * @author Flugente (bears-pit.com) + * @brief Define data structures for campaign statistics. These statistics are updated throughout the campaign and can be viewed in the laptop websites. + */ + +#include "types.h" +#include "Soldier Control.h" + +// -------- added by Flugente: various flags for incidents -------- +// easier than adding 32 differently named variables. DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!! +#define INCIDENT_ARTILLERY_ENEMY 0x00000001 //1 // side used artillery +#define INCIDENT_ARTILLERY_PLAYERSIDE 0x00000002 //2 // +#define INCIDENT_TANKS_ENEMY 0x00000004 //4 // side used tanks +#define INCIDENT_TANKS_PLAYERSIDE 0x00000008 //8 // + +#define INCIDENT_MUSTARDGAS_ENEMY 0x00000010 //16 // side used mustard gas +#define INCIDENT_MUSTARDGAS_PLAYERSIDE 0x00000020 //32 // +#define INCIDENT_ATTACK_ENEMY 0x00000040 //64 // side began the attack +#define INCIDENT_ATTACK_PLAYERSIDE 0x00000080 //128 // + +#define INCIDENT_REINFORCEMENTS_ENEMY 0x00000100 //256 // side was reinforced +#define INCIDENT_REINFORCEMENTS_PLAYERSIDE 0x00000200 //512 // +#define INCIDENT_SNIPERS_ENEMY 0x00000400 //1024 // side used snipers +#define INCIDENT_SNIPERS_PLAYERSIDE 0x00000800 //2048 // + +#define INCIDENT_AMBUSH 0x00001000 //4096 // player was ambushed +#define INCIDENT_AIRDROP 0x00002000 //8192 // player airdropped +#define INCIDENT_SURGERY 0x00004000 //16384 // player performed surgery +#define INCIDENT_BUILDINGS_DAMAGED 0x00008000 //32768 // buildings were damaged in the fighting + +#define INCIDENT_ATTACKDIR_NORTH 0x00010000 //65536 // direction attackers came from +#define INCIDENT_ATTACKDIR_WEST 0x00020000 //131072 // +#define INCIDENT_ATTACKDIR_SOUTH 0x00040000 //262144 // +#define INCIDENT_ATTACKDIR_EAST 0x00080000 //524288 // + +#define INCIDENT_ATTACKDIR_NORTH_ENEMY 0x00100000 //1048576 // +#define INCIDENT_ATTACKDIR_WEST_ENEMY 0x00200000 //2097152 // +#define INCIDENT_ATTACKDIR_SOUTH_ENEMY 0x00400000 //4194304 // +#define INCIDENT_ATTACKDIR_EAST_ENEMY 0x00800000 //8388608 // + +#define INCIDENT_WIN 0x01000000 //16777216 // player won battle (otherwise he lost) +#define INCIDENT_OMERTA_LANDING 0x02000000 //33554432 // omerta landing +#define INCIDENT_FIRST_LIBERATION 0x04000000 //67108864 // first time we free a sector +/*#define PLAYER_NET_4_LVL_3 0x08000000 //134217728 + +#define PLAYER_NET_1_LVL_4 0x10000000 //268435456 +#define PLAYER_NET_2_LVL_4 0x20000000 //536870912 +#define WH40K_SOLDIER_ILLUSION 0x40000000 //1073741824 // Soldier is an Illusion +#define WH40K_SOLDIER_KILLTHISTURN 0x80000000 //2147483648 // Soldier is on a kill streak*/ + +#define INCIDENT_PLAYER_ALLDIRS (INCIDENT_ATTACKDIR_NORTH|INCIDENT_ATTACKDIR_WEST|INCIDENT_ATTACKDIR_SOUTH|INCIDENT_ATTACKDIR_EAST) +#define INCIDENT_ENEMY_ALLDIRS (INCIDENT_ATTACKDIR_NORTH_ENEMY|INCIDENT_ATTACKDIR_WEST_ENEMY|INCIDENT_ATTACKDIR_SOUTH_ENEMY|INCIDENT_ATTACKDIR_EAST_ENEMY) +// ---------------------------------------------------------------- + +// -------- added by Flugente: flags for one time events that commence an individual report -------- +// the numbering of these flags is important. DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!! +#define INCIDENT_ONETIMEEVENT_OMERTA 0x00000001 // mercenary forces land in Omerta, the campaign begins +#define INCIDENT_ONETIMEEVENT_DEATH_KINGPIN 0x00000002 // kingpin was killed in battle +#define INCIDENT_ONETIMEEVENT_MASSACRE_HICKS 0x00000004 // hicks clan has been massacred +#define INCIDENT_ONETIMEEVENT_MASSACRE_BLOODCATS 0x00000008 // bloodcat lair was raided + +#define INCIDENT_ONETIMEEVENT_CITY_RETAKEN 0x00000010 // the army has retaken a city +#define INCIDENT_ONETIMEEVENT_CITY_LIBERATED 0x00000020 // we liberated a city for the first time +/*#define CORPSE_HAIR_WHITE 0x00000040 //64 +#define CORPSE_HAIR_BLOND 0x00000080 //128 + +#define CORPSE_NO_ZOMBIE_RISE 0x00000100 //256 // no zombie can rise from this corpse +#define CORPSE_SKIN_PINK 0x00000200 //512 +#define CORPSE_SKIN_TAN 0x00000400 //1024 +#define CORPSE_SKIN_DARK 0x00000800 //2048 + +#define CORPSE_SKIN_BLACK 0x00001000 //4096 +#define CORPSE_VEST_BROWN 0x00002000 //8192 +#define CORPSE_VEST_grey 0x00004000 //16384 +#define CORPSE_VEST_GREEN 0x00008000 //32768 + +#define CORPSE_VEST_JEAN 0x00010000 //65536 +#define CORPSE_VEST_RED 0x00020000 //131072 +#define CORPSE_VEST_BLUE 0x00040000 //262144 +#define CORPSE_VEST_YELLOW 0x00080000 //524288 + +#define CORPSE_VEST_WHITE 0x00100000 //1048576 +#define CORPSE_VEST_BLACK 0x00200000 //2097152 +#define CORPSE_VEST_GYELLOW 0x00400000 //4194304 +#define CORPSE_VEST_PURPLE 0x00800000 //8388608 + +#define CORPSE_PANTS_GREEN 0x01000000 //16777216 +#define CORPSE_PANTS_JEAN 0x02000000 //33554432 +#define CORPSE_PANTS_TAN 0x04000000 //67108864 +#define CORPSE_PANTS_BLACK 0x08000000 //134217728 + +#define CORPSE_PANTS_BLUE 0x10000000 //268435456 +#define CORPSE_PANTS_BEIGE 0x20000000 //536870912 +#define CORPSE_NO_VEST 0x40000000 //1073741824 // corpse has no vest item (it has been either taken or been destroyed) +#define CORPSE_NO_PANTS 0x80000000 //2147483648 // corpse has no pants item/for tripwire activation (gets set and unset when activating tripwire)*/ +// ---------------------------------------------------------------- + +#define MAX_CAMPAIGNSTATSEVENTS_TEXTS 10 +#define NUM_CAMPAIGNSTATSEVENTS 20 + +typedef struct +{ + UINT16 uiIndex; + CHAR16 szText[MAX_CAMPAIGNSTATSEVENTS_TEXTS][300]; // Up to 10 sentences can be defined + + UINT8 usCityTaken; // if > 0, this is a text for the liberation of a city (defined in Cities.xml) +} CAMPAIGNSTATSEVENT; + +extern CAMPAIGNSTATSEVENT zCampaignStatsEvent[NUM_CAMPAIGNSTATSEVENTS]; + +enum +{ + CAMPAIGNHISTORY_SD_MERC, + CAMPAIGNHISTORY_SD_MILITIA_GREEN, + CAMPAIGNHISTORY_SD_MILITIA_REGULAR, + CAMPAIGNHISTORY_SD_MILITIA_ELITE, + + CAMPAIGNHISTORY_SD_CIV, + + CAMPAIGNHISTORY_SD_ENEMY_ADMIN, + CAMPAIGNHISTORY_SD_ENEMY_ARMY, + CAMPAIGNHISTORY_SD_ENEMY_ELITE, + CAMPAIGNHISTORY_SD_ENEMY_TANK, + + CAMPAIGNHISTORY_SD_CREATURE, + CAMPAIGNHISTORY_SD_ZOMBIE, + + CAMPAIGNHISTORY_SD_MAX, +}; + +enum +{ + CAMPAIGNHISTORY_TYPE_KILL, + CAMPAIGNHISTORY_TYPE_WOUND, + CAMPAIGNHISTORY_TYPE_PRISONER, + CAMPAIGNHISTORY_TYPE_SHOT, + CAMPAIGNHISTORY_TYPE_PARTICIPANT, + CAMPAIGNHISTORY_TYPE_PROMOTION, + + CAMPAIGNHISTORY_TYPE_MAX, +}; + +enum { + CAMPAINGHISTORY_PICLIBRARY_TERRAIN_COASTAL, + CAMPAINGHISTORY_PICLIBRARY_TERRAIN_DESERT, + CAMPAINGHISTORY_PICLIBRARY_TERRAIN_FOREST, + CAMPAINGHISTORY_PICLIBRARY_TERRAIN_MOUNTAIN, + CAMPAINGHISTORY_PICLIBRARY_TERRAIN_POLAR, + CAMPAINGHISTORY_PICLIBRARY_TERRAIN_RIVER, + CAMPAINGHISTORY_PICLIBRARY_TERRAIN_SPARSE, + CAMPAINGHISTORY_PICLIBRARY_TERRAIN_SWAMP, + CAMPAINGHISTORY_PICLIBRARY_TERRAIN_TROPICAL, + CAMPAINGHISTORY_PICLIBRARY_TERRAIN_UNDERGROUND, + CAMPAINGHISTORY_PICLIBRARY_TERRAIN_URBAN, + + CAMPAINGHISTORY_PICLIBRARY_TERRAIN_MAX, +}; + +enum { + CAMPAINGHISTORY_PICLIBRARY_TYPE_WIN, + CAMPAINGHISTORY_PICLIBRARY_TYPE_LOSS, + CAMPAINGHISTORY_PICLIBRARY_TYPE_INSTALLATION, + CAMPAINGHISTORY_PICLIBRARY_TYPE_AIRDROP, + CAMPAINGHISTORY_PICLIBRARY_TYPE_TANKS, + + CAMPAINGHISTORY_PICLIBRARY_TYPE_MAX, +}; + +class Incident_Stats +{ +public: + Incident_Stats() {} + ~Incident_Stats() {} + + void clear(); + + // determine how 'interesting' an incident is - the more happens, the more interesting it is + void CalcInterestRating(); + + BOOLEAN Save( HWFILE hFile ); + BOOLEAN Load( HWFILE hwFile ); + + void AddStat( SOLDIERTYPE* pSoldier, UINT8 aType ); + + STR16 GetAttackerDirString( BOOLEAN fAttacker ); + + void GetTerrainandType(UINT8& arTerrain, UINT8& arType); + +public: + // unique data of incident + UINT32 usID; + UINT32 usTime; + UINT8 usSector; + UINT8 usLevel; + + // every incident has a rating, which signifies how 'interesting' it is. We use this to show + // the most interesting incidents of the entire campaign on the website - 'milestones' of the war + UINT32 usInterestRating; + + // NPC involvement + UINT8 usNPCDied; + UINT8 usCivFactionFought; + + // various notable properties of this incident + UINT64 usIncidentFlags; + + // some events happen only once and get special coverage (like the initial Omerta landing, the Drassenn lieration, Kingpin#s death etc.). + // In those cases, we use special text and picture defined in an xml. + UINT64 usOneTimeEventFlags; + + // total number of fallen + UINT16 usKills[CAMPAIGNHISTORY_SD_MAX]; + + // total number of wounded + UINT16 usWounds[CAMPAIGNHISTORY_SD_MAX]; + + // total number of prisoners + UINT16 usPrisoners[CAMPAIGNHISTORY_SD_MAX]; + + // shots fired + UINT16 usShots[CAMPAIGNHISTORY_SD_MAX]; + + // total number of participants + UINT16 usParticipants[CAMPAIGNHISTORY_SD_MAX]; + + // total number of promotions + UINT16 usPromotions[CAMPAIGNHISTORY_SD_MAX]; + + // reserve + UINT8 usFiller[40]; + + char endOfPOD; // marker for end of POD (plain old data) +}; + +#define SIZEOF_INCIDENT_STATS_POD offsetof( Incident_Stats, endOfPOD ) + +enum { + CAMPAIGN_MONEY_START, + CAMPAIGN_MONEY_MINES, + CAMPAIGN_MONEY_TRADE, + CAMPAIGN_MONEY_ETC, + + CAMPAIGN_MONEY_MAX, +}; + +enum { + CAMPAIGN_CONSUMED_AMMO, + CAMPAIGN_CONSUMED_EXPLOSIVES, + CAMPAIGN_CONSUMED_FOOD, + CAMPAIGN_CONSUMED_MEDICAL, + CAMPAIGN_CONSUMED_REPAIR, + + CAMPAIGN_CONSUMED_MAX, +}; + +#define CAMPAIGNSTATS_NUM_LAST_INCIDENTS 20 +#define CAMPAIGNSTATS_NUM_MOST_IMPORTANT 20 + +class Campaign_Stats +{ +public: + Campaign_Stats(); + ~Campaign_Stats(); + + void clear(); + + //Campaign_Stats* GetObject(); // TODO: ist das berhaupt ntig? + + BOOLEAN Save( HWFILE hFile ); + BOOLEAN Load( HWFILE hwFile ); + + void AddNewIncident(Incident_Stats arIncident); + void AddMoneyEarned(UINT8 aType, INT32 aVal); + void AddConsumption(UINT8 aType, FLOAT aVal); + +public: + // total number of fallen + UINT32 usKills[CAMPAIGNHISTORY_SD_MAX]; + + // total number of wounded + UINT32 usWounds[CAMPAIGNHISTORY_SD_MAX]; + + // total number of prisoners + UINT32 usPrisoners[CAMPAIGNHISTORY_SD_MAX]; + + // shots fired + UINT32 usShots[CAMPAIGNHISTORY_SD_MAX]; + + // money earned + INT32 sMoneyEarned[CAMPAIGN_MONEY_MAX]; + + // amount of items consumed (e.g. how many kilos of ammo did we fire?) + FLOAT usConsumed[CAMPAIGN_CONSUMED_MAX]; + + // number of incidents + UINT32 usNumIncidents; + + // highest ID + UINT32 usHighestID; + + // reserve + UINT8 usFiller[40]; + + char endOfPOD; // marker for end of POD (plain old data) + + // vector of all incidents + std::vector mIncidentVector; + +private: + //Campaign_Stats* mspSelf; +}; + +#define SIZEOF_CAMPAIGN_STATS_POD offsetof( Campaign_Stats, endOfPOD ) + +extern Campaign_Stats gCampaignStats; +extern Incident_Stats gCurrentIncident; // we might save during an incident, thus we have to store the ongoing incident + +// add this incident to the campaign stats and then clear it +void FinishIncident(INT16 sX, INT16 sY, INT8 sZ); + +// start a new incident +void StartIncident(INT16 sX, INT16 sY, INT8 sZ); + +#endif // __CAMPAIGNSTATS_H \ No newline at end of file diff --git a/Laptop/Laptop_VS2005.vcproj b/Laptop/Laptop_VS2005.vcproj index 62963b6b..51d3cebd 100644 --- a/Laptop/Laptop_VS2005.vcproj +++ b/Laptop/Laptop_VS2005.vcproj @@ -417,7 +417,23 @@ + + + + + + + + @@ -728,6 +744,18 @@ RelativePath=".\BrokenLink.cpp" > + + + + + + @@ -940,6 +968,10 @@ RelativePath=".\XML_BriefingRoom.cpp" > + + diff --git a/Laptop/Laptop_VS2008.vcproj b/Laptop/Laptop_VS2008.vcproj index d91b53e2..a847e09e 100644 --- a/Laptop/Laptop_VS2008.vcproj +++ b/Laptop/Laptop_VS2008.vcproj @@ -418,6 +418,22 @@ RelativePath="BrokenLink.h" > + + + + + + + + @@ -718,6 +734,18 @@ RelativePath="BrokenLink.cpp" > + + + + + + @@ -926,6 +954,10 @@ RelativePath=".\XML_BriefingRoom.cpp" > + + diff --git a/Laptop/Laptop_VS2010.vcxproj b/Laptop/Laptop_VS2010.vcxproj index 4efbfb1c..f2d71418 100644 --- a/Laptop/Laptop_VS2010.vcxproj +++ b/Laptop/Laptop_VS2010.vcxproj @@ -43,6 +43,10 @@ + + + + @@ -121,6 +125,9 @@ + + + @@ -175,6 +182,7 @@ + diff --git a/Laptop/Laptop_VS2010.vcxproj.filters b/Laptop/Laptop_VS2010.vcxproj.filters index 62230fad..5bff6ba2 100644 --- a/Laptop/Laptop_VS2010.vcxproj.filters +++ b/Laptop/Laptop_VS2010.vcxproj.filters @@ -237,6 +237,18 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + @@ -485,5 +497,17 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + \ No newline at end of file diff --git a/Laptop/XML_CampaignStatsEvents.cpp b/Laptop/XML_CampaignStatsEvents.cpp new file mode 100644 index 00000000..99aebf41 --- /dev/null +++ b/Laptop/XML_CampaignStatsEvents.cpp @@ -0,0 +1,243 @@ +#ifdef PRECOMPILEDHEADERS + #include "Tactical All.h" +#else + #include "sgp.h" + #include "Debug Control.h" + #include "expat.h" + #include "XML.h" + #include "CampaignStats.h" +#endif + +struct +{ + PARSE_STAGE curElement; + + CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1]; + CAMPAIGNSTATSEVENT curItem; + CAMPAIGNSTATSEVENT* curArray; + + UINT32 maxArraySize; + UINT32 curIndex; + UINT32 currentDepth; + UINT32 maxReadDepth; + CHAR16 gzBackground[MAX_ENEMY_NAMES_CHARS]; +} +typedef CSEParseData; + +BOOLEAN localizedTextOnly_CSE; + +static void XMLCALL +CSEStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts) +{ + CSEParseData * pData = (CSEParseData *)userData; + + if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element? + { + if(strcmp(name, "CAMPAIGNSTATSEVENTS") == 0 && pData->curElement == ELEMENT_NONE) + { + pData->curElement = ELEMENT_LIST; + + if ( !localizedTextOnly_CSE ) + memset(pData->curArray,0,sizeof(CAMPAIGNSTATSEVENT)*pData->maxArraySize); + + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "EVENT") == 0 && pData->curElement == ELEMENT_LIST) + { + pData->curElement = ELEMENT; + + if ( !localizedTextOnly_CSE ) + memset(&pData->curItem,0,sizeof(CAMPAIGNSTATSEVENT)); + + pData->maxReadDepth++; //we are not skipping this element + } + else if(pData->curElement == ELEMENT && + (strcmp(name, "uiIndex") == 0 || + strcmp(name, "szText0") == 0 || + strcmp(name, "szText1") == 0 || + strcmp(name, "szText2") == 0 || + strcmp(name, "szText3") == 0 || + strcmp(name, "szText4") == 0 || + strcmp(name, "szText5") == 0 || + strcmp(name, "szText6") == 0 || + strcmp(name, "szText7") == 0 || + strcmp(name, "szText8") == 0 || + strcmp(name, "szText9") == 0 || + strcmp(name, "usCityTaken") == 0 )) + { + pData->curElement = ELEMENT_PROPERTY; + + pData->maxReadDepth++; //we are not skipping this element + } + + pData->szCharData[0] = '\0'; + } + + pData->currentDepth++; +} + +static void XMLCALL +CSECharacterDataHandle(void *userData, const XML_Char *str, int len) +{ + CSEParseData * pData = (CSEParseData *)userData; + + if( (pData->currentDepth <= pData->maxReadDepth) && + (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH) + ){ + strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData))); + } +} + +static void XMLCALL +CSEEndElementHandle(void *userData, const XML_Char *name) +{ + CSEParseData * pData = (CSEParseData *)userData; + + if(pData->currentDepth <= pData->maxReadDepth) + { + if(strcmp(name, "CAMPAIGNSTATSEVENTS") == 0) + { + pData->curElement = ELEMENT_NONE; + } + else if(strcmp(name, "EVENT") == 0) + { + pData->curElement = ELEMENT_LIST; + + if(pData->curItem.uiIndex < pData->maxArraySize) + { + if ( localizedTextOnly_CSE ) + { + wcscpy(pData->curArray[pData->curItem.uiIndex].szText[0],pData->curItem.szText[0]); + } + else + pData->curArray[pData->curItem.uiIndex] = pData->curItem; + } + + num_found_background = pData->curItem.uiIndex; + } + else if(strcmp(name, "uiIndex") == 0) + { + pData->curElement = ELEMENT; + pData->curItem.uiIndex = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "usCityTaken") == 0) + { + pData->curElement = ELEMENT; + pData->curItem.usCityTaken = (UINT8) atol(pData->szCharData); + } + else + { + for(int i = 0; i < MAX_CAMPAIGNSTATSEVENTS_TEXTS; ++i) + { + char txt[10]; + sprintf(txt, "szText%d", i); + + if(strcmp(name, txt) == 0 ) + { + pData->curElement = ELEMENT; + + MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curItem.szText[i], sizeof(pData->curItem.szText[i])/sizeof(pData->curItem.szText[i][0]) ); + pData->curItem.szText[i][sizeof(pData->curItem.szText[i])/sizeof(pData->curItem.szText[i][0]) - 1] = '\0'; + + break; + } + } + } + + pData->maxReadDepth--; + } + pData->currentDepth--; +} + +BOOLEAN ReadInCampaignStatsEvents(STR fileName, BOOLEAN localizedVersion) +{ + HWFILE hFile; + UINT32 uiBytesRead; + UINT32 uiFSize; + CHAR8 * lpcBuffer; + XML_Parser parser = XML_ParserCreate(NULL); + + CSEParseData pData; + + DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading CampaignStatsEvents.xml" ); + + localizedTextOnly_CSE = localizedVersion; + + // Open file + hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE ); + if ( !hFile ) + return( FALSE ); + + uiFSize = FileGetSize(hFile); + lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1); + + //Read in block + if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) ) + { + MemFree(lpcBuffer); + return( FALSE ); + } + + lpcBuffer[uiFSize] = 0; //add a null terminator + + FileClose( hFile ); + + + XML_SetElementHandler(parser, CSEStartElementHandle, CSEEndElementHandle); + XML_SetCharacterDataHandler(parser, CSECharacterDataHandle); + + + memset(&pData,0,sizeof(pData)); + pData.curArray = zCampaignStatsEvent; + pData.maxArraySize = NUM_CAMPAIGNSTATSEVENTS; + + XML_SetUserData(parser, &pData); + + if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE)) + { + CHAR8 errorBuf[511]; + + sprintf(errorBuf, "XML Parser Error in CampaignStatsEvents.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); + LiveMessage(errorBuf); + + MemFree(lpcBuffer); + return FALSE; + } + + MemFree(lpcBuffer); + + + XML_ParserFree(parser); + + + return( TRUE ); +} + + +BOOLEAN WriteCampaignStatsEvents( STR fileName) +{ + HWFILE hFile; + + //Debug code; make sure that what we got from the file is the same as what's there + // Open a new file + hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE ); + if ( !hFile ) + return( FALSE ); + + { + UINT32 cnt; + + FilePrintf(hFile,"\r\n"); + for(cnt = 0; cnt < NUM_CAMPAIGNSTATSEVENTS; ++cnt) + { + FilePrintf(hFile,"\t\r\n"); + FilePrintf(hFile,"\t\t%d\r\n", cnt); + + FilePrintf(hFile,"\t\r\n"); + } + FilePrintf(hFile,"\r\n"); + } + FileClose( hFile ); + + return( TRUE ); +} diff --git a/Laptop/email.cpp b/Laptop/email.cpp index 3a771ca9..fb3c8129 100644 --- a/Laptop/email.cpp +++ b/Laptop/email.cpp @@ -1824,17 +1824,17 @@ void DisplayEmailList() else if(pEmail->fRead) { // message has been read, reset color to black - SetFontForeground(FONT_BLACK); + SetFontForeground(FONT_BLACK); //SetFontBackground(FONT_BLACK); } else { - // defualt, message is not read, set font red - SetFontForeground(FONT_RED); + // defualt, message is not read, set font red + SetFontForeground(FONT_RED); //SetFontBackground(FONT_BLACK); } - SetFontBackground(FONT_BLACK); + SetFontBackground(FONT_BLACK); //draw the icon, sender, date, subject DrawLetterIcon(iCounter,pEmail->fRead ); @@ -1845,15 +1845,15 @@ void DisplayEmailList() else if ( pEmail->EmailVersion == TYPE_EMAIL_EMAIL_EDT || pEmail->EmailVersion == TYPE_EMAIL_EMAIL_EDT_NAME_MERC || pEmail->EmailVersion == TYPE_EMAIL_BOBBY_R || pEmail->EmailVersion == TYPE_EMAIL_BOBBY_R_EMAIL_JA2_EDT || pEmail->EmailVersion == TYPE_EMAIL_INSURANCE_COMPANY_EMAIL_JA2_EDT || pEmail->EmailVersion == TYPE_EMAIL_DEAD_MERC_AIM_SITE_EMAIL_JA2_EDT) //|| pEmail->EmailVersion == TYPE_EMAIL_OTHER ) DrawSender(iCounter, pEmail->ubSender, pEmail->fRead, pEmail->EmailVersion); - DrawDate(iCounter, pEmail->iDate, pEmail->fRead ); + DrawDate(iCounter, pEmail->iDate, pEmail->fRead ); iCounter++; // too many messages onthis page, reset pEmail, so no more are drawn - if(iCounter >=MAX_MESSAGES_PAGE) - pEmail=NULL; + if(iCounter >= MAX_MESSAGES_PAGE) + pEmail=NULL; else - pEmail=GetEmailMessage(pPage->iIds[iCounter]); + pEmail=GetEmailMessage(pPage->iIds[iCounter]); } @@ -3670,7 +3670,7 @@ BOOLEAN HandleMailSpecialMessages( UINT16 usMessageId, INT32 *iResults, EmailPtr //Set the book mark so the player can access the site SetBookMark( MERC_BOOKMARK ); break; - + case MERC_DIED_ON_OTHER_ASSIGNMENT: ModifyInsuranceEmails( usMessageId, iResults, pMail, MERC_DIED_ON_OTHER_ASSIGNMENT_LENGTH ); break; @@ -3728,7 +3728,7 @@ BOOLEAN HandleMailSpecialMessages( UINT16 usMessageId, INT32 *iResults, EmailPtr } } giPrevMessageId = giMessageId; - break; + break; #endif } diff --git a/Laptop/email.h b/Laptop/email.h index ca9ec3cf..3478f204 100644 --- a/Laptop/email.h +++ b/Laptop/email.h @@ -361,7 +361,7 @@ #define JOHN_KULBA_MISSED_FLIGHT_2_LENGTH 3 #define JOHN_KULBA_MISSED_FLIGHT_3 ( JOHN_KULBA_MISSED_FLIGHT_2 + JOHN_KULBA_MISSED_FLIGHT_2_LENGTH ) - #define JOHN_KULBA_MISSED_FLIGHT_3_LENGTH 3 + #define JOHN_KULBA_MISSED_FLIGHT_3_LENGTH 3 #endif @@ -644,7 +644,7 @@ enum { TYPE_EMAIL_INSURANCE_COMPANY, TYPE_EMAIL_KING_PIN, TYPE_EMAIL_JOHN_KULBA, - TYPE_EMAIL_AIM_SITE, + TYPE_EMAIL_AIM_SITE, TYPE_EMAIL_OTHER, }; diff --git a/Laptop/finances.cpp b/Laptop/finances.cpp index 4dc0a50b..838f77f7 100644 --- a/Laptop/finances.cpp +++ b/Laptop/finances.cpp @@ -20,6 +20,7 @@ #include "Facilities.h" // HEADROCK HAM 3.6: Militia upkeep #include "Town Militia.h" + #include "CampaignStats.h" // added by Flugente #endif // the global defines @@ -231,16 +232,26 @@ UINT32 AddTransactionToPlayersBook (UINT8 ubCode, UINT8 ubSecondCode, UINT32 uiD if( !fInFinancialMode ) { - ClearFinanceList( ); + ClearFinanceList( ); } else { SetFinanceButtonStates( ); // force update - fPausedReDrawScreenFlag = TRUE; + fPausedReDrawScreenFlag = TRUE; } + // Flugente: campaign stats + if ( ubCode == ANONYMOUS_DEPOSIT ) + gCampaignStats.AddMoneyEarned(CAMPAIGN_MONEY_START, iAmount ); + else if ( ubCode == DEPOSIT_FROM_GOLD_MINE || ubCode == DEPOSIT_FROM_SILVER_MINE ) + gCampaignStats.AddMoneyEarned(CAMPAIGN_MONEY_MINES, iAmount ); + else if ( ubCode == SOLD_ITEMS ) + gCampaignStats.AddMoneyEarned(CAMPAIGN_MONEY_TRADE, iAmount ); + else + gCampaignStats.AddMoneyEarned(CAMPAIGN_MONEY_ETC, iAmount ); + fMapScreenBottomDirty = TRUE; // return unique id of this transaction diff --git a/Laptop/laptop.cpp b/Laptop/laptop.cpp index 9dd906d8..ed0cbbbb 100644 --- a/Laptop/laptop.cpp +++ b/Laptop/laptop.cpp @@ -85,6 +85,8 @@ #include "GameSettings.h" #include "Encyclopedia_new.h" #include "Encyclopedia_Data_new.h" + #include "CampaignHistoryMain.h" // added by Flugente + #include "CampaignHistory_Summary.h" // added by Flugente #endif #include "connect.h" @@ -798,6 +800,9 @@ UINT32 LaptopScreenInit() GameInitBriefingRoom(); GameInitBriefingRoomEnter(); + // Flugente: campaign history + GameInitCampaignHistory(); + // init program states memset( &gLaptopProgramStates, LAPTOP_PROGRAM_MINIMIZED, sizeof( gLaptopProgramStates ) ); @@ -1047,7 +1052,10 @@ INT32 EnterLaptop() SetBookMark(ENCYCLOPEDIA_BOOKMARK); if ( gGameExternalOptions.gBriefingRoom == TRUE && !is_networked ) - SetBookMark(BRIEFING_ROOM_BOOKMARK); + SetBookMark(BRIEFING_ROOM_BOOKMARK); + + if ( gGameExternalOptions.fCampaignHistoryWebSite && !is_networked ) + SetBookMark(CAMPAIGNHISTORY_BOOKMARK); LoadLoadPending( ); @@ -1420,7 +1428,21 @@ void RenderLaptop() RenderBobbyRShipments(); break; + case LAPTOP_MODE_CAMPAIGNHISTORY_SUMMARY: + RenderCampaignHistorySummary(); + break; + case LAPTOP_MODE_CAMPAIGNHISTORY_MOSTIMPORTANT: + RenderCampaignHistory_MostImportant(); + break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_LATESTNEWS: + RenderCampaignHistory_News(); + break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_ABOUTTUS: + RenderCampaignHistory(); + break; } @@ -1820,7 +1842,24 @@ void EnterNewLaptopMode() break; case LAPTOP_MODE_BROKEN_LINK: EnterBrokenLink(); - break; + break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_SUMMARY: + EnterCampaignHistorySummary(); + break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_MOSTIMPORTANT: + EnterCampaignHistory_MostImportant(); + break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_LATESTNEWS: + EnterCampaignHistory_News(); + break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_ABOUTTUS: + EnterCampaignHistory(); + break; + case LAPTOP_MODE_BOBBYR_SHIPMENTS: EnterBobbyRShipments(); break; @@ -1839,7 +1878,7 @@ void EnterNewLaptopMode() if( ( !fLoadPendingFlag) ) { - CreateDestroyMinimizeButtonForCurrentMode( ); + CreateDestroyMinimizeButtonForCurrentMode( ); guiPreviousLaptopMode = guiCurrentLaptopMode; SetSubSiteAsVisted( ); } @@ -2042,6 +2081,22 @@ void HandleLapTopHandles() case LAPTOP_MODE_BOBBYR_SHIPMENTS: HandleBobbyRShipments(); break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_SUMMARY: + HandleCampaignHistorySummary(); + break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_MOSTIMPORTANT: + HandleCampaignHistory_MostImportant(); + break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_LATESTNEWS: + HandleCampaignHistory_News(); + break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_ABOUTTUS: + HandleCampaignHistory(); + break; } } @@ -2581,6 +2636,22 @@ UINT32 ExitLaptopMode(UINT32 uiMode) case LAPTOP_MODE_BOBBYR_SHIPMENTS: ExitBobbyRShipments(); break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_SUMMARY: + ExitCampaignHistorySummary(); + break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_MOSTIMPORTANT: + ExitCampaignHistory_MostImportant(); + break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_LATESTNEWS: + ExitCampaignHistory_News(); + break; + + case LAPTOP_MODE_CAMPAIGNHISTORY_ABOUTTUS: + ExitCampaignHistory(); + break; } if( ( uiMode != LAPTOP_MODE_NONE )&&( uiMode < LAPTOP_MODE_WWW ) ) @@ -4149,6 +4220,36 @@ if( (gubQuest[ QUEST_FIX_LAPTOP ] != QUESTINPROGRESS) || (gGameUBOptions.LaptopQ } break; + case CAMPAIGNHISTORY_BOOKMARK: + { + // if the option is off, we instead link to a 'broken' website + if ( !gGameExternalOptions.fCampaignHistoryWebSite ) + { + guiCurrentWWWMode=LAPTOP_MODE_BROKEN_LINK; + guiCurrentLaptopMode=LAPTOP_MODE_BROKEN_LINK; + + return GoToWebPage(LAPTOP_MODE_BROKEN_LINK); + } + + guiCurrentWWWMode=LAPTOP_MODE_CAMPAIGNHISTORY_ABOUTTUS; + guiCurrentLaptopMode=LAPTOP_MODE_CAMPAIGNHISTORY_ABOUTTUS; + + // do we have to have a World Wide Wait + if( LaptopSaveInfo.fVisitedBookmarkAlready[ CAMPAIGNHISTORY_BOOKMARK ] == FALSE ) + { + // reset flag and set load pending flag + LaptopSaveInfo.fVisitedBookmarkAlready[ CAMPAIGNHISTORY_BOOKMARK ] = TRUE; + fLoadPendingFlag = TRUE; + } + else + { + // fast reload + fLoadPendingFlag = TRUE; + fFastLoadFlag = TRUE; + } + } + break; + } #ifdef JA2UB diff --git a/Laptop/laptop.h b/Laptop/laptop.h index 3ebfe1d9..dde25a41 100644 --- a/Laptop/laptop.h +++ b/Laptop/laptop.h @@ -138,6 +138,13 @@ enum LAPTOP_MODE_FUNERAL, LAPTOP_MODE_SIRTECH, LAPTOP_MODE_BROKEN_LINK, + + // Flugente: Campaign History + LAPTOP_MODE_CAMPAIGNHISTORY_SUMMARY, + LAPTOP_MODE_CAMPAIGNHISTORY_MOSTIMPORTANT, + LAPTOP_MODE_CAMPAIGNHISTORY_LATESTNEWS, + LAPTOP_MODE_CAMPAIGNHISTORY_ABOUTTUS, + LAPTOP_MODE_BOBBYR_SHIPMENTS, //ENCYCLOPEDIA @@ -150,8 +157,6 @@ enum LAPTOP_MODE_BRIEFING_ROOM_ENTER, LAPTOP_MODE_AIM_MEMBERS_ARCHIVES_NEW, - - }; // bookamrks for WWW bookmark list @@ -213,6 +218,7 @@ enum{ CANCEL_STRING, ENCYCLOPEDIA_BOOKMARK, //Encyclopedia BRIEFING_ROOM_BOOKMARK, + CAMPAIGNHISTORY_BOOKMARK, // added by Flugente TEXT_NUM_LAPTOP_BOOKMARKS }; diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp index c631d715..b48b71f0 100644 --- a/SaveLoadGame.cpp +++ b/SaveLoadGame.cpp @@ -113,6 +113,7 @@ #include "Town Militia.h" #include "Items.h" #include "Encyclopedia_new.h" + #include "CampaignStats.h" // added by Flugente #endif #include "BobbyR.h" @@ -1513,13 +1514,13 @@ BOOLEAN MERCPROFILESTRUCT::Load(HWFILE hFile, bool forceLoadOldVersion, bool for } else { - if ( !FileRead( hFile, &this->usBackground, sizeof(UINT8), &uiNumBytesRead ) ) - { - return(FALSE); - } + if ( !FileRead( hFile, &this->usBackground, sizeof(UINT8), &uiNumBytesRead ) ) + { + return(FALSE); } } } + } if ( this->uiProfileChecksum != this->GetChecksum() ) { return( FALSE ); @@ -2061,7 +2062,7 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile) numBytesRead = ReadFieldByField(hFile, &this->bExtraWisdom, sizeof(bExtraWisdom), sizeof(INT16), numBytesRead); numBytesRead = ReadFieldByField(hFile, &this->bExtraExpLevel, sizeof(bExtraExpLevel), sizeof(INT8), numBytesRead); numBytesRead = ReadFieldByField(hFile, &this->bSoldierFlagMask, sizeof(bSoldierFlagMask), sizeof(INT32), numBytesRead); - + if ( guiCurrentSaveGameVersion >= FOOD_CHANGES ) { numBytesRead = ReadFieldByField(hFile, &this->bFoodLevel, sizeof(bFoodLevel), sizeof(INT32), numBytesRead); @@ -2220,16 +2221,16 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile) { numBytesRead = ReadFieldByField(hFile, &this->usSoldierProfile, sizeof(usSoldierProfile), sizeof(UINT16), numBytesRead); numBytesRead = ReadFieldByField(hFile, &this->usItemMoveSectorID, sizeof(usItemMoveSectorID), sizeof(UINT8), numBytesRead); - + if ( guiCurrentSaveGameVersion >= SOLDIER_PROFILES ) { numBytesRead = ReadFieldByField(hFile, &this->usSkillCounter, sizeof(usSkillCounter), sizeof(UINT16), numBytesRead); numBytesRead = ReadFieldByField(hFile, &this->usSkillCooldown, sizeof(usSkillCooldown), sizeof(UINT32), numBytesRead); numBytesRead = ReadFieldByField(hFile, &this->usAISkillUse, sizeof(usAISkillUse), sizeof(UINT8), numBytesRead); - numBytesRead = ReadFieldByField(hFile, &this->ubFiller, sizeof(ubFiller), sizeof(UINT8), numBytesRead); - } - else - { + numBytesRead = ReadFieldByField(hFile, &this->ubFiller, sizeof(ubFiller), sizeof(UINT8), numBytesRead); + } + else + { for(UINT8 i = 0; i < SOLDIER_COUNTER_MAX; ++i) this->usSkillCounter[i] = 0; @@ -4168,7 +4169,19 @@ if( !SaveNewEmailDataToSaveGameFile( hFile ) ) SaveGameFilePosition( FileGetPos( hFile), "Encyclopedia item visibility" ); #endif } -//Close the saved game file + + // Flugente: campaign stats + if( !gCampaignStats.Save( hFile ) || !gCurrentIncident.Save( hFile ) ) + { + ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing Campaign Stats"); + goto FAILED_TO_SAVE; + } + +#ifdef JA2BETAVERSION + SaveGameFilePosition( FileGetPos( hFile ), "Campaign Stats" ); +#endif + + //Close the saved game file FileClose( hFile ); // This defines, which savegame is highlighted in the load screen @@ -4713,7 +4726,7 @@ BOOLEAN LoadSavedGame( int ubSavedGameID ) #endif - + uiRelEndPerc += 1; SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"The Laptop FILES file..." ); @@ -5793,6 +5806,29 @@ BOOLEAN LoadSavedGame( int ubSavedGameID ) } else EncyclopediaInitItemsVisibility(); + if( guiCurrentSaveGameVersion >= CAMPAIGNSTATS ) + { + uiRelEndPerc += 1; + SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Load Campaign Stats..." ); + RenderProgressBar( 0, 100 ); + uiRelStartPerc = uiRelEndPerc; + + if( !gCampaignStats.Load( hFile ) ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("gCampaignStats.Load failed" ) ); + FileClose( hFile ); + return( FALSE ); + } + + // we also have to load the currently active incident + if( !gCurrentIncident.Load( hFile ) ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("gCurrentIncident.Load failed" ) ); + FileClose( hFile ); + return( FALSE ); + } + } + // //Close the saved game file // diff --git a/Strategic/Assignments.cpp b/Strategic/Assignments.cpp index e01d5759..5d8afed3 100644 --- a/Strategic/Assignments.cpp +++ b/Strategic/Assignments.cpp @@ -2678,7 +2678,7 @@ UINT32 CalculateInterrogationValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts ) SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ] ); UINT8 prisonersspecial = 0, prisonerselite = 0, prisonersregular = 0, prisonersadmin = 0; - *pusMaxPts = GetNumberOrPrisoners( pSectorInfo, &prisonersspecial, &prisonerselite, &prisonersregular, &prisonersadmin ); + *pusMaxPts = GetNumberOfPrisoners( pSectorInfo, &prisonersspecial, &prisonerselite, &prisonersregular, &prisonersadmin ); // no prisoners -> no interrogation (this should not happen) if ( !*pusMaxPts ) @@ -5734,7 +5734,7 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ ) SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] ); UINT8 prisoners[PRISONER_MAX] = {0}; - UINT16 numprisoners = GetNumberOrPrisoners( pSectorInfo, &prisoners[PRISONER_SPECIAL], &prisoners[PRISONER_ELITE], &prisoners[PRISONER_REGULAR], &prisoners[PRISONER_ADMIN] ); + UINT16 numprisoners = GetNumberOfPrisoners( pSectorInfo, &prisoners[PRISONER_SPECIAL], &prisoners[PRISONER_ELITE], &prisoners[PRISONER_REGULAR], &prisoners[PRISONER_ADMIN] ); // add interrogation progress from last hour and erase it in data UINT32 interrogationpoints = pSectorInfo->uiInterrogationHundredsLeft; @@ -5963,7 +5963,7 @@ void HandlePrison( INT16 sMapX, INT16 sMapY, INT8 bZ ) SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] ); UINT8 prisonersspecial = 0, prisonerselite = 0, prisonersregular = 0, prisonersadmin = 0; - UINT16 numprisoners = GetNumberOrPrisoners( pSectorInfo, &prisonersspecial, &prisonerselite, &prisonersregular, &prisonersadmin ); + UINT16 numprisoners = GetNumberOfPrisoners( pSectorInfo, &prisonersspecial, &prisonerselite, &prisonersregular, &prisonersadmin ); // for now, simply count specials as elites ChangeNumberOfPrisoners( pSectorInfo, -prisonersspecial, prisonersspecial, 0, 0 ); diff --git a/Strategic/Auto Resolve.cpp b/Strategic/Auto Resolve.cpp index ce5898b2..c2784900 100644 --- a/Strategic/Auto Resolve.cpp +++ b/Strategic/Auto Resolve.cpp @@ -69,6 +69,7 @@ #include "interface Dialogue.h" #include "AIInternals.h" // added by SANDRO #include "Bullets.h" // HEADROCK HAM 5, for use with Bullet Impact. + #include "CampaignStats.h" // added by Flugente #endif #include "Reinforcement.h" @@ -1693,6 +1694,9 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB pVictim->iHealableInjury = ((pVictim->stats.bLifeMax - pVictim->stats.bLife)*100); else if (pVictim->iHealableInjury < 0) pVictim->iHealableInjury = 0; + + // Flugente: campaign stats + gCurrentIncident.usIncidentFlags |= INCIDENT_SURGERY; } // if any healing points remain, apply that to any remaining bleeding (1/1) @@ -4603,6 +4607,10 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget ) } if( iNewLife <= 0 ) { //soldier has been killed + + // Flugente: campaign stats + gCurrentIncident.AddStat( pTarget->pSoldier, CAMPAIGNHISTORY_TYPE_KILL ); + if( pAttacker->uiFlags & CELL_MERC ) { //Player killed the enemy soldier -- update his stats as well as any assisters. ///////////////////////////////////////////////////////////////////////////////////// @@ -4798,6 +4806,9 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index ) { if( pKiller->uiFlags & CELL_MERC ) { + // Flugente: campaign stats + gCurrentIncident.AddStat( pTarget->pSoldier, CAMPAIGNHISTORY_TYPE_KILL ); + ///////////////////////////////////////////////////////////////////////////////////// // SANDRO - new mercs' records switch(pTarget->pSoldier->ubSoldierClass) diff --git a/Strategic/Game Init.cpp b/Strategic/Game Init.cpp index 33777744..efbdc8b0 100644 --- a/Strategic/Game Init.cpp +++ b/Strategic/Game Init.cpp @@ -59,6 +59,7 @@ // HEADROCK HAM 4: Include for initializing Manual Restrictions #include "MilitiaSquads.h" #include "Map Screen Interface Map Inventory.h"//dnl ch51 081009 + #include "CampaignStats.h" // added by Flugente #endif #include "Vehicles.h" @@ -695,6 +696,9 @@ fFirstTimeInMapScreen = TRUE; //Init the laptop here InitLaptopAndLaptopScreens(); + // Flugente campaign stats + gCampaignStats.clear(); + InitStrategicLayer(); // Set new game flag diff --git a/Strategic/Player Command.cpp b/Strategic/Player Command.cpp index 099dac40..35ad9e44 100644 --- a/Strategic/Player Command.cpp +++ b/Strategic/Player Command.cpp @@ -27,6 +27,7 @@ #include "Random.h" // HEADROCK HAM 3.6: Added for facility string printing... #include "PopUpBox.h" + #include "CampaignStats.h" // added by Flugente #endif #include "postalservice.h" @@ -382,6 +383,21 @@ BOOLEAN SetThisSectorAsPlayerControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, B // also set fact the player knows they own it SectorInfo[ SECTOR( sMapX, sMapY ) ].fPlayer[ bMapZ ] = TRUE; + // Flugente: campaign stats + if ( !SectorInfo[ SECTOR( sMapX, sMapY ) ].fSurfaceWasEverPlayerControlled ) + { + //UINT8 ubSector = (UINT8)SECTOR( sMapX, sMapY ); + //UINT8 ubTraverseType = SectorInfo[ ubSector ].ubTraversability[ 4 ]; + + //if ( ubTraverseType == ) + + if ( GetTownIdForSector( sMapX, sMapY ) != BLANK_SECTOR ) + { + // first liberation of a town sector -> special texts + gCurrentIncident.usIncidentFlags |= INCIDENT_FIRST_LIBERATION; + } + } + if ( bMapZ == 0 ) { SectorInfo[ SECTOR( sMapX, sMapY ) ].fSurfaceWasEverPlayerControlled = TRUE; diff --git a/Strategic/PreBattle Interface.cpp b/Strategic/PreBattle Interface.cpp index e0a817c5..831c82e8 100644 --- a/Strategic/PreBattle Interface.cpp +++ b/Strategic/PreBattle Interface.cpp @@ -47,6 +47,7 @@ // added by SANDRO #include "Tactical Save.h" #include "message.h" + #include "CampaignStats.h" // added by Flugente #endif #ifdef JA2UB @@ -2157,6 +2158,9 @@ void LogBattleResults( UINT8 ubVictoryCode) AddHistoryToPlayersLog( HISTORY_SLAUGHTEREDBLOODCATS, 0, GetWorldTotalMin(), sSectorX, sSectorY ); break; } + + // Flugente: campaign stats + gCurrentIncident.usIncidentFlags |= INCIDENT_WIN; } else { @@ -2183,6 +2187,29 @@ void LogBattleResults( UINT8 ubVictoryCode) break; } } + + switch( gubEnemyEncounterCode ) + { + case ENEMY_INVASION_CODE: + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACK_ENEMY; + break; + case ENEMY_ENCOUNTER_CODE: + case ENTERING_ENEMY_SECTOR_CODE: + case CREATURE_ATTACK_CODE: + case ENTERING_BLOODCAT_LAIR_CODE: + case FIGHTING_CREATURES_CODE: + case HOSTILE_CIVILIANS_CODE: + case HOSTILE_BLOODCATS_CODE: + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACK_PLAYERSIDE; + break; + case ENEMY_AMBUSH_CODE: + case BLOODCAT_AMBUSH_CODE: + gCurrentIncident.usIncidentFlags |= (INCIDENT_ATTACK_ENEMY|INCIDENT_AMBUSH); + break; + } + + // Flugente: if battle has ended, close this incident, add it to the global incidents, and clear it + FinishIncident(gWorldSectorX, gWorldSectorY, gbWorldSectorZ); } void HandlePreBattleInterfaceStates() diff --git a/Strategic/Queen Command.cpp b/Strategic/Queen Command.cpp index 9f937cc7..842077e6 100644 --- a/Strategic/Queen Command.cpp +++ b/Strategic/Queen Command.cpp @@ -43,6 +43,7 @@ #include "meanwhile.h" #include "Soldier macros.h" #include "Morale.h" + #include "CampaignStats.h" // added by Flugente #endif #ifdef JA2BETAVERSION @@ -1899,6 +1900,12 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub // Flugente: due to a fix, also note here that the reinforcements get no APs. pSoldier->bSoldierFlagMask |= SOLDIER_NO_AP; + + // Flugente: campaign stats + if ( IsOurSoldier(pSoldier) ) + gCurrentIncident.usIncidentFlags |= INCIDENT_REINFORCEMENTS_PLAYERSIDE; + else + gCurrentIncident.usIncidentFlags |= INCIDENT_REINFORCEMENTS_ENEMY; } } diff --git a/Strategic/Strategic Town Loyalty.cpp b/Strategic/Strategic Town Loyalty.cpp index 4019f910..64149681 100644 --- a/Strategic/Strategic Town Loyalty.cpp +++ b/Strategic/Strategic Town Loyalty.cpp @@ -36,6 +36,7 @@ #include "MilitiaSquads.h" // HEADROCK HAM 3.6: Include for Facility Debt #include "Facilities.h" + #include "CampaignStats.h" // added by Flugente #endif #include "Luaglobal.h" @@ -1869,6 +1870,9 @@ void CheckIfEntireTownHasBeenLiberated( INT8 bTownId, INT16 sSectorX, INT16 sSec #else HandleMeanWhileEventPostingForTownLiberation( bTownId ); #endif + + // Flugente: campaign stats: if we captured an entire city for the first time, take note of that. We don't have to note the city here, as that is obvious from the sector anyway + gCurrentIncident.usOneTimeEventFlags |= INCIDENT_ONETIMEEVENT_CITY_LIBERATED; } // even taking over non-trainable "towns" like Orta/Tixa for the first time should count as "player activity" diff --git a/Strategic/strategic.cpp b/Strategic/strategic.cpp index 30ed50b4..9a683226 100644 --- a/Strategic/strategic.cpp +++ b/Strategic/strategic.cpp @@ -15,6 +15,7 @@ #include "Isometric Utils.h" #include "Vehicles.h" #include "Game Clock.h" + #include "CampaignStats.h" // added by Flugente #endif #ifdef JA2UB @@ -90,7 +91,7 @@ BOOLEAN HandleStrategicDeath( SOLDIERTYPE *pSoldier ) StopTimeCompression(); } - + return( TRUE ); } diff --git a/Tactical/Drugs And Alcohol.cpp b/Tactical/Drugs And Alcohol.cpp index ec752aad..63b5c799 100644 --- a/Tactical/Drugs And Alcohol.cpp +++ b/Tactical/Drugs And Alcohol.cpp @@ -15,6 +15,7 @@ #include "Interface.h" #include "Food.h" // added by Flugente #include "Animation data.h" // added by Flugente for SoldierBodyTypes + #include "CampaignStats.h" // added by Flugente #endif //forward declarations of common classes to eliminate includes @@ -224,9 +225,13 @@ BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject ) UseKitPoints( pObject, 100, pSoldier ); else { + UINT16 ptsused = (*pObject)[0]->data.objectStatus; + + gCampaignStats.AddConsumption(CAMPAIGN_CONSUMED_MEDICAL, (FLOAT)(ptsused * Item[usItem].ubWeight / 100.0) ); + // remove object pObject->RemoveObjectsFromStack(1); - } + } } if ( (ubDrugType & DRUG_ALCOHOL) != 0 ) diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index 194695d9..31178d0d 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -57,6 +57,7 @@ #include "Food.h" #include "opplist.h" #include "Sys Globals.h"//dnl ch74 201013 + #include "CampaignStats.h" // added by Flugente #endif #ifdef JA2UB @@ -7322,6 +7323,15 @@ UINT16 UseKitPoints( OBJECTTYPE * pObj, UINT16 usPoints, SOLDIERTYPE *pSoldier ) if( (usPoints * (max( 0, (100 - Item[pObj->usItem].percentstatusdrainreduction)))/100) < (*pObj)[bLoop]->data.objectStatus ) { (*pObj)[bLoop]->data.objectStatus -= (INT8)(usPoints * (max( 0, (100 - Item[pObj->usItem].percentstatusdrainreduction) ) )/100); + + // Flugente: campaign stats + if ( Item[pObj->usItem].foodtype || Item[pObj->usItem].canteen) + gCampaignStats.AddConsumption(CAMPAIGN_CONSUMED_FOOD, (FLOAT)(usOriginalPoints * Item[pObj->usItem].ubWeight / 100.0) ); + else if ( Item[pObj->usItem].medical || Item[pObj->usItem].drugtype) + gCampaignStats.AddConsumption(CAMPAIGN_CONSUMED_MEDICAL, (FLOAT)(usOriginalPoints * Item[pObj->usItem].ubWeight / 100.0) ); + else if ( Item[pObj->usItem].toolkit || HasItemFlag(pObj->usItem, CLEANING_KIT) ) + gCampaignStats.AddConsumption(CAMPAIGN_CONSUMED_REPAIR, (FLOAT)(usOriginalPoints * Item[pObj->usItem].ubWeight / 100.0) ); + return( usOriginalPoints ); } // Flugente: we no longer destroy canteens upon emtptying them - as we can now refill them @@ -7361,6 +7371,14 @@ UINT16 UseKitPoints( OBJECTTYPE * pObj, UINT16 usPoints, SOLDIERTYPE *pSoldier ) }*/ } + // Flugente: campaign stats + if ( Item[pObj->usItem].foodtype || Item[pObj->usItem].canteen) + gCampaignStats.AddConsumption(CAMPAIGN_CONSUMED_FOOD, (FLOAT)((usOriginalPoints - usPoints) * Item[pObj->usItem].ubWeight / 100.0) ); + else if ( Item[pObj->usItem].medical || Item[pObj->usItem].drugtype) + gCampaignStats.AddConsumption(CAMPAIGN_CONSUMED_MEDICAL, (FLOAT)((usOriginalPoints - usPoints) * Item[pObj->usItem].ubWeight / 100.0) ); + else if ( Item[pObj->usItem].toolkit || HasItemFlag(pObj->usItem, CLEANING_KIT) ) + gCampaignStats.AddConsumption(CAMPAIGN_CONSUMED_REPAIR, (FLOAT)((usOriginalPoints - usPoints) * Item[pObj->usItem].ubWeight / 100.0) ); + // check if pocket/hand emptied..update inventory, then update panel if( pObj->exists() == false ) { diff --git a/Tactical/LOS.cpp b/Tactical/LOS.cpp index 19f329ed..c39d956b 100644 --- a/Tactical/LOS.cpp +++ b/Tactical/LOS.cpp @@ -51,6 +51,7 @@ #include "soldier tile.h" // added by Flugente #include "Sound Control.h" // added by Flugente #include "Soldier Functions.h" // added by Flugente for DoesSoldierWearGasMask(...) +#include "CampaignStats.h" // added by Flugente #include "AIInternals.h"//dnl ch61 180813 //forward declarations of common classes to eliminate includes @@ -5820,6 +5821,9 @@ INT8 FireBulletGivenTargetTrapOnly( SOLDIERTYPE* pThrower, OBJECTTYPE* pObj, INT GunIncreaseHeat( pObj, pThrower ); + // Flugente: campaign stats + gCurrentIncident.AddStat( pThrower, CAMPAIGNHISTORY_TYPE_SHOT ); + // Flugente : Added a malus to reliability for overheated guns // HEADROCK HAM 5: Variable NCTH base change UINT32 uiDepreciateTest = 0; diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index 07d92f96..371ed30a 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -110,6 +110,7 @@ #include "Lua Interpreter.h" #include "bullets.h" #include "Inventory Choosing.h" // added by Flugente for TakeMilitiaEquipmentfromSector() +#include "CampaignStats.h" // added by Flugente #endif #include "connect.h" @@ -6627,8 +6628,8 @@ void PrisonerMessageBoxCallBack( UINT8 ubExitValue ) { SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ] ); - prisonerstobemoved = GetNumberOrPrisoners( pSectorInfo, &prisonersspecial, &prisonerselite, &prisonersregular, &prisonersadmin ); - + prisonerstobemoved = GetNumberOfPrisoners( pSectorInfo, &prisonersspecial, &prisonerselite, &prisonersregular, &prisonersadmin ); + DeleteAllPrisoners( pSectorInfo ); if ( usSectorID > 0) @@ -6651,8 +6652,8 @@ void PrisonerMessageBoxCallBack( UINT8 ubExitValue ) { UNDERGROUND_SECTORINFO *pSectorInfo = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); - prisonerstobemoved = GetNumberOrPrisoners( pSectorInfo, &prisonersspecial, &prisonerselite, &prisonersregular, &prisonersadmin ); - + prisonerstobemoved = GetNumberOfPrisoners( pSectorInfo, &prisonersspecial, &prisonerselite, &prisonersregular, &prisonersadmin ); + DeleteAllPrisoners( pSectorInfo ); if ( usSectorID > 0) @@ -6711,6 +6712,9 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) break; } + // Flugente: campaign stats + gCurrentIncident.AddStat( pTeamSoldier, CAMPAIGNHISTORY_TYPE_PRISONER ); + ++ubNumPrisoners; // place items on the floor @@ -6832,6 +6836,38 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) } } +// Flugente: for campaign stats, we want to know how many people were wounded. +// Each time we are wounded, we set a 'wounded'-flag +// Once combat ends, we count all these flags and remove them +void UpdateWoundedFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) +{ + SOLDIERTYPE *pSoldier; + INT32 cnt = 0; + UINT8 ubNumPrisoners = 0; + UINT8 ubNumPrisonerAdmin = 0; + UINT8 ubNumPrisonerTroop = 0; + UINT8 ubNumPrisonerElite = 0; + + // Check if the battle is won! + // Loop through all mercs and make go + for ( pSoldier = Menptr, cnt = 0; cnt < TOTAL_SOLDIERS; ++pSoldier, ++cnt ) + { + // Kill those not already dead.,... + if ( pSoldier->bActive && pSoldier->bInSector && pSoldier->bSoldierFlagMask & SOLDIER_FRESHWOUND ) + { + // remove flag, so we are not counted again + pSoldier->bSoldierFlagMask &= ~SOLDIER_FRESHWOUND; + + // the dead count as dead, not as wounded + if ( pSoldier->stats.bLife <= 0 ) + continue; + + // Flugente: campaign stats + gCurrentIncident.AddStat( pSoldier, CAMPAIGNHISTORY_TYPE_WOUND ); + } + } +} + void RemoveStaticEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) { if (!bMapZ) // Battle ended Above-ground @@ -6933,12 +6969,15 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) } } - if( ( fBattleLost ) || ( fBattleWon ) ) + if ( fBattleLost || fBattleWon ) { if( !gbWorldSectorZ ) { SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY) ].bLastKnownEnemies = NumEnemiesInSector( gWorldSectorX, gWorldSectorY ); } + + // Flugente: note number of wounded for campaign stats + UpdateWoundedFromSectorInfo( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); } // We should NEVER have a battle lost and won at the same time... @@ -7012,7 +7051,7 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) //Whenever returning TRUE, make sure you clear gfBlitBattleSectorLocator; LogBattleResults( LOG_DEFEAT ); gfBlitBattleSectorLocator = FALSE; - // If we are the server, we escape this function at the top if we think the game should still be running + // If we are the server, we escape this function at the top if we think the game should still be running // hence if we get here the game is over for all clients and we should report it if (is_networked && is_server) game_over(); @@ -7259,10 +7298,11 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) if ( gTacticalStatus.bBoxingState == NOT_BOXING ) // if boxing don't do any of this stuff { - LogBattleResults( LOG_VICTORY ); - SetThisSectorAsPlayerControlled( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, TRUE ); HandleVictoryInNPCSector( gWorldSectorX, gWorldSectorY,( INT16 ) gbWorldSectorZ ); + + LogBattleResults( LOG_VICTORY ); + if ( CheckFact( FACT_FIRST_BATTLE_BEING_FOUGHT, 0 ) ) { // ATE: Need to trigger record for this event .... for NPC scripting @@ -7298,7 +7338,7 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) //But only if the option is turned ON. if(gGameExternalOptions.gfRevealItems) RevealAllDroppedEnemyItems(); - + // If we are the server, we escape this function at the top if we think the game should still be running // hence if we get here the game is over for all clients and we should report it if (is_networked && is_server) @@ -10497,7 +10537,7 @@ BOOLEAN IsProfileInUse(UINT8 usTeam, INT8 aType, UINT16 aNr) return FALSE; } -UINT16 GetNumberOrPrisoners( SECTORINFO *pSectorInfo, UINT8* apSpecial, UINT8* apElite, UINT8* apRegular, UINT8* apAdmin ) +UINT16 GetNumberOfPrisoners( SECTORINFO *pSectorInfo, UINT8* apSpecial, UINT8* apElite, UINT8* apRegular, UINT8* apAdmin ) { if ( !pSectorInfo ) return 0; @@ -10510,7 +10550,7 @@ UINT16 GetNumberOrPrisoners( SECTORINFO *pSectorInfo, UINT8* apSpecial, UINT8* a return (UINT16)(pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_SPECIAL] + pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ELITE] + pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_REGULAR] + pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ADMIN]); } -UINT16 GetNumberOrPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, UINT8* apSpecial, UINT8* apElite, UINT8* apRegular, UINT8* apAdmin ) +UINT16 GetNumberOfPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, UINT8* apSpecial, UINT8* apElite, UINT8* apRegular, UINT8* apAdmin ) { if ( !pSectorInfo ) return 0; diff --git a/Tactical/Overhead.h b/Tactical/Overhead.h index 6a73873e..d51ea67c 100644 --- a/Tactical/Overhead.h +++ b/Tactical/Overhead.h @@ -373,8 +373,8 @@ BOOLEAN AllowedToStealFromTeamMate( UINT8 aAccessorID, UINT8 aTargetID ); BOOLEAN IsProfileInUse(UINT8 usTeam, INT8 aType, UINT16 aNr); // Flugente: functions altering a sector's prisoners -UINT16 GetNumberOrPrisoners( SECTORINFO *pSectorInfo, UINT8* apSpecial, UINT8* apElite, UINT8* apRegular, UINT8* apAdmin ); -UINT16 GetNumberOrPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, UINT8* apSpecial, UINT8* apElite, UINT8* apRegular, UINT8* apAdmin ); +UINT16 GetNumberOfPrisoners( SECTORINFO *pSectorInfo, UINT8* apSpecial, UINT8* apElite, UINT8* apRegular, UINT8* apAdmin ); +UINT16 GetNumberOfPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, UINT8* apSpecial, UINT8* apElite, UINT8* apRegular, UINT8* apAdmin ); void ChangeNumberOfPrisoners( SECTORINFO *pSectorInfo, INT16 aSpecial, INT16 aElite, INT16 aRegular, INT16 aAdmin ); void ChangeNumberOfPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, INT16 aSpecial, INT16 aElite, INT16 aRegular, INT16 aAdmin ); diff --git a/Tactical/Points.cpp b/Tactical/Points.cpp index 87f23194..36db9816 100644 --- a/Tactical/Points.cpp +++ b/Tactical/Points.cpp @@ -34,10 +34,11 @@ #include "Map Information.h" #include "Interface Items.h" #include "Soldier Control.h" // added by SANDRO - #include "opplist.h" // added by SANDRO - #include "lighting.h" // added by SANDRO - #include "Food.h" // added by Flugente - #include "AIInternals.h"//dnl ch69 150913 + #include "opplist.h" // added by SANDRO + #include "lighting.h" // added by SANDRO + #include "Food.h" // added by Flugente + #include "AIInternals.h" //dnl ch69 150913 + #include "CampaignStats.h" // added by Flugente #endif #include "connect.h" //rain @@ -2841,6 +2842,12 @@ void DeductAmmo( SOLDIERTYPE *pSoldier, INT8 bInvPos ) (*pObjUsed)[0]->data.gun.ubGunShotsLeft--; } } + + // Flugente: campaign stats - ammo. explosive consumption is handled elsewhere + if ( pSoldier->bTeam == OUR_TEAM ) + { + gCampaignStats.AddConsumption(CAMPAIGN_CONSUMED_AMMO, (FLOAT)(Item[(*pObjUsed)[0]->data.gun.usGunAmmoItem].ubWeight) / (FLOAT)(Magazine[ Item[ (*pObjUsed)[0]->data.gun.usGunAmmoItem ].ubClassIndex ].ubMagSize ) ); + } } else if ( Item[ pObj->usItem ].usItemClass == IC_LAUNCHER || Item[pObj->usItem].cannon || pSoldier->bWeaponMode == WM_ATTACHED_GL || pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST || pSoldier->bWeaponMode == WM_ATTACHED_GL_AUTO ) { diff --git a/Tactical/Soldier Add.cpp b/Tactical/Soldier Add.cpp index a6169098..33a7b07b 100644 --- a/Tactical/Soldier Add.cpp +++ b/Tactical/Soldier Add.cpp @@ -23,6 +23,8 @@ #include "Exit Grids.h" #include "Interface.h" // added by Flugente for zBackground #include "renderworld.h" // added by Flugente + #include "Vehicles.h" // added by Flugente + #include "CampaignStats.h" // added by Flugente #endif #ifdef JA2UB @@ -1195,7 +1197,42 @@ BOOLEAN InternalAddSoldierToSector( UINT8 ubID, BOOLEAN fCalculateDirection, BOO sGridNo = pSoldier->sInsertionGridNo; } } - + + // Flugente: campaign stats + if ( pSoldier->bSoldierFlagMask & SOLDIER_AIRDROP ) + gCurrentIncident.usIncidentFlags |= INCIDENT_AIRDROP; + + // problem: soldiers already present in a sector have ubStrategicInsertionCode = 0, which is INSERTION_CODE_NORTH - but they don't actually coem from north, as they are already present + // we thus count them as coming from north if they either already have a gridno, or usStrategicInsertionData + if ( pSoldier->ubStrategicInsertionCode == INSERTION_CODE_NORTH && pSoldier->usStrategicInsertionData || pSoldier->sGridNo != NOWHERE ) + { + if ( pSoldier->bSide == gbPlayerNum ) + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_NORTH; + else if ( !pSoldier->aiData.bNeutral ) + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_NORTH_ENEMY; + } + else if ( pSoldier->ubStrategicInsertionCode == INSERTION_CODE_SOUTH ) + { + if ( pSoldier->bSide == gbPlayerNum ) + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_SOUTH; + else if ( !pSoldier->aiData.bNeutral ) + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_SOUTH_ENEMY; + } + else if ( pSoldier->ubStrategicInsertionCode == INSERTION_CODE_EAST ) + { + if ( pSoldier->bSide == gbPlayerNum ) + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_EAST; + else if ( !pSoldier->aiData.bNeutral ) + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_EAST_ENEMY; + } + else if ( pSoldier->ubStrategicInsertionCode == INSERTION_CODE_WEST ) + { + if ( pSoldier->bSide == gbPlayerNum ) + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_WEST; + else if ( !pSoldier->aiData.bNeutral ) + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_WEST_ENEMY; + } + // add this flag whenever we enter strategically enter a sector (= we attack a sector) pSoldier->bSoldierFlagMask |= SOLDIER_ASSAULT_BONUS; @@ -1496,7 +1533,7 @@ void AddSoldierToSectorGridNo( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDir if ( pSoldier->bSoldierFlagMask & SOLDIER_AIRDROP ) { pSoldier->bSoldierFlagMask &= ~SOLDIER_AIRDROP; - + if ( gGameExternalOptions.ubSkyriderHotLZ == 3 ) { gfIgnoreScrolling = FALSE; @@ -1536,7 +1573,7 @@ void AddSoldierToSectorGridNo( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDir pSoldier->EVENT_SetSoldierDesiredDirection( ubDirection ); } } - + if( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) ) { if ( !( pSoldier->flags.uiStatusFlags & SOLDIER_DEAD ) ) diff --git a/Tactical/Soldier Ani.cpp b/Tactical/Soldier Ani.cpp index 9844cc47..45f48687 100644 --- a/Tactical/Soldier Ani.cpp +++ b/Tactical/Soldier Ani.cpp @@ -61,6 +61,7 @@ #include "interface dialogue.h" #include "Strategic Status.h" #include "Food.h" +#include "CampaignStats.h" // added by Flugente #endif // anv: for enemy taunts @@ -3974,6 +3975,9 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse ) } } + // Flugente: campaign stats + gCurrentIncident.AddStat( pSoldier, CAMPAIGNHISTORY_TYPE_KILL ); + if ( TurnSoldierIntoCorpse( pSoldier, TRUE, TRUE ) ) { *pfMadeCorpse = TRUE; diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 38964bfa..11cc8355 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -91,6 +91,7 @@ #include "Strategic Pathing.h" #include "Debug Control.h" #include "LOS.h" // added by SANDRO +#include "CampaignStats.h" // added by Flugente #endif #include "ub_config.h" @@ -9529,7 +9530,7 @@ void HandleTakeDamageDeath( SOLDIERTYPE *pSoldier, UINT8 bOldLife, UINT8 ubReaso } break; } - + // 0verhaul: This is also already handled by the animation transitions // if ( ubReason == TAKE_DAMAGE_ELECTRICITY ) // { @@ -9851,6 +9852,9 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPo this->bPoisonBleeding = 0; } + // Flugente: note we received a fresh wound + if ( sLifeDeduct > 0 ) + this->bSoldierFlagMask |= SOLDIER_FRESHWOUND; // Calculate damage to our items if from an explosion! if ( ubReason == TAKE_DAMAGE_EXPLOSION || ubReason == TAKE_DAMAGE_STRUCTURE_EXPLOSION) @@ -12929,6 +12933,9 @@ UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT1 pVictim->iHealableInjury = ((pVictim->stats.bLifeMax - pVictim->stats.bLife)*100); else if (pVictim->iHealableInjury < 0) pVictim->iHealableInjury = 0; + + // Flugente: campaign stats + gCurrentIncident.usIncidentFlags |= INCIDENT_SURGERY; } // if any healing points remain, apply that to any remaining bleeding (1/1) @@ -15803,7 +15810,7 @@ BOOLEAN SOLDIERTYPE::CanProcessPrisoners() SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( this->sSectorX, this->sSectorY ) ] ); UINT8 tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0; - if ( GetNumberOrPrisoners(pSectorInfo, &tmp1, &tmp2, &tmp3, &tmp4) > 0 ) + if ( GetNumberOfPrisoners(pSectorInfo, &tmp1, &tmp2, &tmp3, &tmp4) > 0 ) return TRUE; } @@ -17044,6 +17051,22 @@ void SOLDIERTYPE::SoldierPropertyUpkeep() else usSkillCounter[counter] = max(0, usSkillCounter[counter] - 1 ); } + + // if there is a combat going and we are in sector, note that in the battle report + if ( this->bInSector && (gTacticalStatus.uiFlags & INCOMBAT || gTacticalStatus.fEnemyInSector) ) + { + if ( !(this->bSoldierFlagMask & SOLDIER_BATTLE_PARTICIPATION) ) + { + this->bSoldierFlagMask |= SOLDIER_BATTLE_PARTICIPATION; + + // Flugente: campaign stats + gCurrentIncident.AddStat( this, CAMPAIGNHISTORY_TYPE_PARTICIPANT ); + } + } + else + { + this->bSoldierFlagMask &= ~SOLDIER_BATTLE_PARTICIPATION; + } } // check if Soldier can use the spell skillwise, with fAPCheck = TRUE also check current APs @@ -17859,6 +17882,11 @@ BOOLEAN SOLDIERTYPE::OrderArtilleryStrike( UINT32 usSectorNr, INT32 sTargetGridN else // how did this even happen? return FALSE; + + if ( bTeam == ENEMY_TEAM ) + gCurrentIncident.usIncidentFlags |= INCIDENT_ARTILLERY_ENEMY; + else + gCurrentIncident.usIncidentFlags |= INCIDENT_ARTILLERY_PLAYERSIDE; return TRUE; } diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 450d51bf..d2af71fc 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -328,9 +328,8 @@ enum SOLDIER_CLASS_ELITE_MILITIA, SOLDIER_CLASS_CREATURE, SOLDIER_CLASS_MINER, -#ifdef ENABLE_ZOMBIES SOLDIER_CLASS_ZOMBIE, -#endif + SOLDIER_CLASS_MAX, }; // Flugente: there are now separate gun choices, depending on a soldier's class @@ -381,10 +380,10 @@ enum #define SOLDIER_RADIO_OPERATOR_JAMMING 0x00100000 //1048576 // radio operator is jamming frequencies #define SOLDIER_RADIO_OPERATOR_SCANNING 0x00200000 //2097152 // radio operator is scanning for jammers #define SOLDIER_AIRDROP 0x00400000 //4194304 // soldier is entering the sector via airdrop from a helicopter. Sligthly different from SOLDIER_AIRDROP_TURN -/*#define PLAYER_NET_4_LVL_2 0x00800000 //8388608 +#define SOLDIER_FRESHWOUND 0x00800000 //8388608 // campaign stats: soldier was wounded in this battle -#define PLAYER_NET_1_LVL_3 0x01000000 //16777216 -#define PLAYER_NET_2_LVL_3 0x02000000 //33554432 +#define SOLDIER_BATTLE_PARTICIPATION 0x01000000 //16777216 // campaign stats: soldier took part in this battle +/*#define PLAYER_NET_2_LVL_3 0x02000000 //33554432 #define PLAYER_NET_3_LVL_3 0x04000000 //67108864 #define PLAYER_NET_4_LVL_3 0x08000000 //134217728 diff --git a/Tactical/Soldier Init List.cpp b/Tactical/Soldier Init List.cpp index 29ab0c6f..ccd8e80e 100644 --- a/Tactical/Soldier Init List.cpp +++ b/Tactical/Soldier Init List.cpp @@ -53,7 +53,8 @@ #include "Queen Command.h" #include "Map Edgepoints.h" -#include "Campaign.h" // added by Flugente for HighestPlayerProgressPercentage() +#include "Campaign.h" // added by Flugente for HighestPlayerProgressPercentage() +#include "CampaignStats.h" // added by Flugente BOOLEAN gfOriginalList = TRUE; @@ -2717,6 +2718,12 @@ void AddSoldierInitListMilitiaOnEdge( UINT8 ubStrategicInsertionCode, UINT8 ubNu // Flugente: due to a fix, also note here that the reinforcements get no APs. pSoldier->bSoldierFlagMask |= SOLDIER_NO_AP; + + // Flugente: campaign stats + if ( IsOurSoldier(pSoldier) ) + gCurrentIncident.usIncidentFlags |= INCIDENT_REINFORCEMENTS_PLAYERSIDE; + else + gCurrentIncident.usIncidentFlags |= INCIDENT_REINFORCEMENTS_ENEMY; } } } @@ -2818,7 +2825,7 @@ void SectorAddPrisonersofWar( INT16 sMapX, INT16 sMapY, INT16 sMapZ ) // only continue if there are prisoners in this sector that need to be placed UINT8 tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0; - UINT16 numprisoners = GetNumberOrPrisoners(pSector, &tmp1, &tmp2, &tmp3, &tmp4); + UINT16 numprisoners = GetNumberOfPrisoners(pSector, &tmp1, &tmp2, &tmp3, &tmp4); if ( !numprisoners ) return; diff --git a/Tactical/Vehicles.cpp b/Tactical/Vehicles.cpp index a18061b4..8320be28 100644 --- a/Tactical/Vehicles.cpp +++ b/Tactical/Vehicles.cpp @@ -2686,6 +2686,12 @@ BOOLEAN DoesVehicleGroupHaveAnyPassengers( GROUP *pGroup ) return DoesVehicleHaveAnyPassengers( iVehicleID ); } +BOOLEAN IsHelicopterInSector(INT16 sX, INT16 sY) +{ + if ( pVehicleList[ iHelicopterVehicleId ].sSectorX == sX && pVehicleList[ iHelicopterVehicleId ].sSectorY == sY ) + { + return TRUE; + } - - + return FALSE; +} diff --git a/Tactical/Vehicles.h b/Tactical/Vehicles.h index 66e81c5f..d82c56eb 100644 --- a/Tactical/Vehicles.h +++ b/Tactical/Vehicles.h @@ -449,5 +449,6 @@ void InitAVehicle(int index, int x, int y); void InitAllVehicles( ); +BOOLEAN IsHelicopterInSector(INT16 sX, INT16 sY); #endif diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index 68969aec..926d2169 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -49,6 +49,7 @@ #include "Drugs And Alcohol.h" // HEADROCK HAM 4: Get drunk level #include "LOS.h" // HEADROCK HAM 4: Required for new shooting mechanism. Alternately, maybe move the functions to LOS.h. #include "Campaign Types.h" // added by Flugente + #include "CampaignStats.h" // added by Flugente #endif //forward declarations of common classes to eliminate includes @@ -2293,6 +2294,17 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo ) GunIncreaseHeat( pObjAttHand, pSoldier ); + // Flugente: campaign stats + gCurrentIncident.AddStat( pSoldier, CAMPAIGNHISTORY_TYPE_SHOT ); + + if ( Weapon[Item[(pObjAttHand)->usItem].ubClassIndex].ubWeaponType == GUN_SN_RIFLE ) + { + if ( pSoldier->bTeam == OUR_TEAM || pSoldier->bTeam == MILITIA_TEAM ) + gCurrentIncident.usIncidentFlags |= INCIDENT_SNIPERS_PLAYERSIDE; + else + gCurrentIncident.usIncidentFlags |= INCIDENT_SNIPERS_ENEMY; + } + // CJC: since jamming is no longer affected by reliability, increase chance of status going down for really unreliabile guns //INT16 ammoReliability = 0; // Madd: ammo reliability affects gun @@ -2919,6 +2931,17 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo ) GunIncreaseHeat( pObjUsed, pSoldier ); + // Flugente: campaign stats + gCurrentIncident.AddStat( pSoldier, CAMPAIGNHISTORY_TYPE_SHOT ); + + if ( Weapon[Item[(pObjUsed)->usItem].ubClassIndex].ubWeaponType == GUN_SN_RIFLE ) + { + if ( pSoldier->bTeam == OUR_TEAM || pSoldier->bTeam == MILITIA_TEAM ) + gCurrentIncident.usIncidentFlags |= INCIDENT_SNIPERS_PLAYERSIDE; + else + gCurrentIncident.usIncidentFlags |= INCIDENT_SNIPERS_ENEMY; + } + /* //WarmSteel - Replaced with GetReliability( pObj ) // CJC: since jamming is no longer affected by reliability, increase chance of status going down for really unreliabile guns INT16 ammoReliability = 0; // Madd: ammo reliability affects gun @@ -4068,25 +4091,37 @@ BOOLEAN UseLauncher( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo ) } } - // ATE: Check here if the launcher should fail 'cause of bad status..... - if ( WillExplosiveWeaponFail( pSoldier, pgunobj ) ) - { - GunIncreaseHeat( pgunobj, pSoldier ); - // Explode dude! + // Flugente: campaign stats + gCurrentIncident.AddStat( pSoldier, CAMPAIGNHISTORY_TYPE_SHOT ); - // So we still should have ABC > 0 - // Begin explosion due to failure... + if ( Weapon[Item[(pgunobj)->usItem].ubClassIndex].ubWeaponType == GUN_SN_RIFLE ) + { + if ( pSoldier->bTeam == OUR_TEAM || pSoldier->bTeam == MILITIA_TEAM ) + gCurrentIncident.usIncidentFlags |= INCIDENT_SNIPERS_PLAYERSIDE; + else + gCurrentIncident.usIncidentFlags |= INCIDENT_SNIPERS_ENEMY; + } + + // ATE: Check here if the launcher should fail 'cause of bad status..... + if ( WillExplosiveWeaponFail( pSoldier, pgunobj ) ) + { + GunIncreaseHeat( pgunobj, pSoldier ); + + // Explode dude! + + // So we still should have ABC > 0 + // Begin explosion due to failure... IgniteExplosion( pSoldier->ubID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, Launchable.usItem, pSoldier->pathing.bLevel ); - // Reduce again for attack end 'cause it has been incremented for a normal attack - // Nope, not anymore. + // Reduce again for attack end 'cause it has been incremented for a normal attack + // Nope, not anymore. DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - ATTACK ANIMATION %s ENDED BY BAD EXPLOSIVE CHECK, Now %d", gAnimControl[ pSoldier->usAnimState ].zAnimStr, gTacticalStatus.ubAttackBusyCount ) ); DebugAttackBusy( String("@@@@@@@ Freeing up attacker - ATTACK ANIMATION %s ENDED BY BAD EXPLOSIVE CHECK\n", gAnimControl[ pSoldier->usAnimState ].zAnimStr ) ); // ReduceAttackBusyCount( pSoldier->ubID, FALSE ); - // So all's well, should be good from here.... - return( FALSE ); - } + // So all's well, should be good from here.... + return( FALSE ); + } GunIncreaseHeat( pgunobj, pSoldier ); diff --git a/Tactical/XML.h b/Tactical/XML.h index a1e7ae2d..cdbf7aaf 100644 --- a/Tactical/XML.h +++ b/Tactical/XML.h @@ -237,6 +237,7 @@ typedef PARSE_STAGE; #define VEHICLESFILENAME "Vehicles.xml" #define SQUADNAMEFILENAME "SquadNames.xml" #define BACKGROUNDSFILENAME "Backgrounds.xml" +#define CAMPAIGNSTATSEVENTSFILENAME "CampaignStatsEvents.xml" #define TAUNTSFOLDERNAME "EnemyTaunts\\" #define TAUNTSFILENAME "EnemyTaunts.xml" @@ -478,6 +479,10 @@ extern void LoadIMPPortraitsTEMP(); extern BOOLEAN ReadInBackgrounds(STR fileName, BOOLEAN localizedVersion ); extern BOOLEAN WriteBackgrounds( STR fileName); +// Flugente: campaign stats events +extern BOOLEAN ReadInCampaignStatsEvents(STR fileName, BOOLEAN localizedVersion ); +extern BOOLEAN WriteCampaignStatsEvents( STR fileName); + // anv: externalised taunts extern BOOLEAN ReadInTaunts(STR fileName, BOOLEAN localizedVersion ); extern BOOLEAN WriteTaunts( STR fileName ); diff --git a/TileEngine/Explosion Control.cpp b/TileEngine/Explosion Control.cpp index 43aff546..1aae29f3 100644 --- a/TileEngine/Explosion Control.cpp +++ b/TileEngine/Explosion Control.cpp @@ -66,6 +66,7 @@ #include "Soldier Functions.h"//dnl ch40 200909 #include "Text.h" // added by SANDRO #include "campaign.h" // yet another one added +#include "CampaignStats.h" // added by Flugente #endif #include "Soldier Macros.h" @@ -309,6 +310,13 @@ void InternalIgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 { return; // no explosive and attackers gun is not fireing HE } + + // Flugente: campaign stats + if ( MercPtrs[ ubOwner ]->bTeam == OUR_TEAM ) + { + if ( Item[ usItem ].usItemClass & IC_EXPLOSV ) + gCampaignStats.AddConsumption(CAMPAIGN_CONSUMED_EXPLOSIVES, (FLOAT)(Item[usItem].ubWeight) ); + } } // Increment attack counter... @@ -366,6 +374,9 @@ void InternalIgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT32 if ( Item[ usItem ].usItemClass & IC_EXPLOSV && ubOwner != NOBODY && ubOwner < NUM_PROFILES && InARoom( sGridNo, &tmp ) ) { HandleLoyaltyForDemolitionOfBuilding( MercPtrs[ubOwner], Explosive[ Item[ usItem ].ubClassIndex ].ubDamage ); + + // Flugente: campaign stats + gCurrentIncident.usIncidentFlags |= INCIDENT_BUILDINGS_DAMAGED; } // HEADROCK HAM 5.1: Launch fragments from the explosion. @@ -2870,6 +2881,15 @@ void SpreadEffect( INT32 sGridNo, UINT8 ubRadius, UINT16 usItem, UINT8 ubOwner, // with the client that spawns set off the explosion/grenade/whatever return; } + + // Flugente: campaign stats + if ( Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_MUSTGAS ) + { + if ( IsOurSoldier(pAttacker) ) + gCurrentIncident.usIncidentFlags |= INCIDENT_MUSTARDGAS_PLAYERSIDE; + else + gCurrentIncident.usIncidentFlags |= INCIDENT_MUSTARDGAS_ENEMY; + } } #ifdef JA2BETAVERSION CHAR tmpMPDbgString[512]; diff --git a/TileEngine/Tactical Placement GUI.cpp b/TileEngine/Tactical Placement GUI.cpp index 188f3f97..c60f4da2 100644 --- a/TileEngine/Tactical Placement GUI.cpp +++ b/TileEngine/Tactical Placement GUI.cpp @@ -50,6 +50,7 @@ #include "Map Edgepoints.h" #include "renderworld.h"//dnl ch45 051009 #include "merc entering.h" +#include "CampaignStats.h" // added by Flugente typedef struct MERCPLACEMENT { @@ -395,13 +396,30 @@ void InitTacticalPlacementGUI() // WANNE: We always want to have edgepoints CheckForValidMapEdge( &MercPtrs[ i ]->ubStrategicInsertionCode ); + + // Flugente: campaign stats + switch( MercPtrs[ i ]->ubStrategicInsertionCode ) + { + case INSERTION_CODE_NORTH: + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_NORTH; + break; + case INSERTION_CODE_EAST: + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_EAST; + break; + case INSERTION_CODE_SOUTH: + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_SOUTH; + break; + case INSERTION_CODE_WEST: + gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACKDIR_WEST; + break; + } // WANNE - MP: Center if (is_networked && MercPtrs[ i ]->ubStrategicInsertionCode == INSERTION_CODE_CENTER) { gfCenter = TRUE; - } - + } + giPlacements++; } } @@ -411,25 +429,25 @@ void InitTacticalPlacementGUI() VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; //Load the faces - { + { ubFaceIndex = gMercProfiles[ gMercPlacement[ i ].pSoldier->ubProfile ].ubFaceIndex; - - if ( ( ubFaceIndex < 100 ) && ( gProfilesIMP[ gMercPlacement[ i ].pSoldier->ubProfile ].ProfilId == gMercPlacement[ i ].pSoldier->ubProfile ) ) - { - sprintf( VObjectDesc.ImageFile, "IMPFaces\\65Face\\%02d.sti", ubFaceIndex ); - } - else if ( ( ubFaceIndex > 99 ) && ( gProfilesIMP[ gMercPlacement[ i ].pSoldier->ubProfile ].ProfilId == gMercPlacement[ i ].pSoldier->ubProfile ) ) - { - sprintf( VObjectDesc.ImageFile, "IMPFaces\\65Face\\%03d.sti", ubFaceIndex ); - } - else if( ubFaceIndex < 100 ) - { - sprintf( VObjectDesc.ImageFile, "Faces\\65Face\\%02d.sti", ubFaceIndex ); - } - else if( ubFaceIndex > 99 ) - { - sprintf( VObjectDesc.ImageFile, "Faces\\65Face\\%03d.sti", ubFaceIndex ); - } + + if ( ( ubFaceIndex < 100 ) && ( gProfilesIMP[ gMercPlacement[ i ].pSoldier->ubProfile ].ProfilId == gMercPlacement[ i ].pSoldier->ubProfile ) ) + { + sprintf( VObjectDesc.ImageFile, "IMPFaces\\65Face\\%02d.sti", ubFaceIndex ); + } + else if ( ( ubFaceIndex > 99 ) && ( gProfilesIMP[ gMercPlacement[ i ].pSoldier->ubProfile ].ProfilId == gMercPlacement[ i ].pSoldier->ubProfile ) ) + { + sprintf( VObjectDesc.ImageFile, "IMPFaces\\65Face\\%03d.sti", ubFaceIndex ); + } + else if( ubFaceIndex < 100 ) + { + sprintf( VObjectDesc.ImageFile, "Faces\\65Face\\%02d.sti", ubFaceIndex ); + } + else if( ubFaceIndex > 99 ) + { + sprintf( VObjectDesc.ImageFile, "Faces\\65Face\\%03d.sti", ubFaceIndex ); + } } if( !AddVideoObject( &VObjectDesc, &gMercPlacement[ i ].uiVObjectID ) ) @@ -744,19 +762,19 @@ void RenderTacticalPlacementGUI() gTPClipRect.iLeft = iOffsetHorizontal + 1; gTPClipRect.iTop = iOffsetVertical + 1; gTPClipRect.iBottom = iOffsetVertical + 716;// 318; - gTPClipRect.iRight = iOffsetHorizontal + 1434; //634; + gTPClipRect.iRight = iOffsetHorizontal + 1434; //634; } else { - BlitBufferToBuffer( guiSAVEBUFFER, FRAME_BUFFER, iOffsetHorizontal, iOffsetVertical, 640, 320 ); - InvalidateRegion( iOffsetHorizontal, iOffsetVertical, iOffsetHorizontal + 640, iOffsetVertical + 320 ); - //dnl ch45 051009 - gTPClipRect.iLeft = iOffsetHorizontal + 1; - gTPClipRect.iTop = iOffsetVertical + 1; - gTPClipRect.iBottom = iOffsetVertical + 318; - gTPClipRect.iRight = iOffsetHorizontal + 634; + BlitBufferToBuffer( guiSAVEBUFFER, FRAME_BUFFER, iOffsetHorizontal, iOffsetVertical, 640, 320 ); + InvalidateRegion( iOffsetHorizontal, iOffsetVertical, iOffsetHorizontal + 640, iOffsetVertical + 320 ); + //dnl ch45 051009 + gTPClipRect.iLeft = iOffsetHorizontal + 1; + gTPClipRect.iTop = iOffsetVertical + 1; + gTPClipRect.iBottom = iOffsetVertical + 318; + gTPClipRect.iRight = iOffsetHorizontal + 634; } - + if( gbCursorMercID == -1 ) { // WANNE - MP: Center @@ -812,7 +830,7 @@ void RenderTacticalPlacementGUI() gTPClipRectCenterBottom.iTop = iOffsetVertical + AIRDROPENTRYPTS_BOTTOM_Y; gTPClipRectCenterBottom.iBottom = iOffsetVertical + 320; gTPClipRectCenterBottom.iRight = iOffsetHorizontal + 634; - } + } } else { @@ -869,34 +887,34 @@ void RenderTacticalPlacementGUI() case INSERTION_CODE_NORTH: if(sWorldScreenY <= PLACEMENT_OFFSET) { - sY = (PLACEMENT_OFFSET - sWorldScreenY) / 5; - gTPClipRect.iTop += sY; - } - break; - case INSERTION_CODE_EAST: + sY = (PLACEMENT_OFFSET - sWorldScreenY) / 5; + gTPClipRect.iTop += sY; + } + break; + case INSERTION_CODE_EAST: if((sWorldScreenX + NORMAL_MAP_SCREEN_WIDTH) >= (MAPWIDTH - PLACEMENT_OFFSET)) { - sX = ((sWorldScreenX + NORMAL_MAP_SCREEN_WIDTH) - (MAPWIDTH - PLACEMENT_OFFSET)) / 5; - gTPClipRect.iRight -= sX; - } - break; - case INSERTION_CODE_SOUTH: + sX = ((sWorldScreenX + NORMAL_MAP_SCREEN_WIDTH) - (MAPWIDTH - PLACEMENT_OFFSET)) / 5; + gTPClipRect.iRight -= sX; + } + break; + case INSERTION_CODE_SOUTH: if((sWorldScreenY + NORMAL_MAP_SCREEN_HEIGHT) >= (MAPHEIGHT - PLACEMENT_OFFSET)) { - sY = ((sWorldScreenY + NORMAL_MAP_SCREEN_HEIGHT) - (MAPHEIGHT - PLACEMENT_OFFSET)) / 5; - gTPClipRect.iBottom -= sY; - } - break; - case INSERTION_CODE_WEST: + sY = ((sWorldScreenY + NORMAL_MAP_SCREEN_HEIGHT) - (MAPHEIGHT - PLACEMENT_OFFSET)) / 5; + gTPClipRect.iBottom -= sY; + } + break; + case INSERTION_CODE_WEST: if(sWorldScreenX <= PLACEMENT_OFFSET) { - sX = (PLACEMENT_OFFSET - sWorldScreenX) / 5; - gTPClipRect.iLeft += sX; - } - break; + sX = (PLACEMENT_OFFSET - sWorldScreenX) / 5; + gTPClipRect.iLeft += sX; } + break; } - + } + // WANNE - MP: Center if (is_networked && gfCenter) { @@ -950,7 +968,7 @@ void RenderTacticalPlacementGUI() gTPClipRectCenterBottom.iTop = iOffsetVertical + AIRDROPENTRYPTS_BOTTOM_Y; gTPClipRectCenterBottom.iBottom = iOffsetVertical + 320; gTPClipRectCenterBottom.iRight = iOffsetHorizontal + 634; - } + } } pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); @@ -1060,34 +1078,34 @@ void EnsureDoneButtonStatus() void lockui (bool unlock) //lock onluck ui for lan //hayden { - if(unlock==0 && islocked==0 && is_client) - { - islocked=1; - DisableButton( iTPButtons[ DONE_BUTTON ] ); - DisableButton( iTPButtons[ SPREAD_BUTTON ] ); - DisableButton( iTPButtons[ GROUP_BUTTON ] ); - DisableButton( iTPButtons[ CLEAR_BUTTON ] ); + if(unlock==0 && islocked==0 && is_client) + { + islocked=1; + DisableButton( iTPButtons[ DONE_BUTTON ] ); + DisableButton( iTPButtons[ SPREAD_BUTTON ] ); + DisableButton( iTPButtons[ GROUP_BUTTON ] ); + DisableButton( iTPButtons[ CLEAR_BUTTON ] ); - SGPRect CenterRect = { 100 + xResOffset, 100, SCREEN_WIDTH - 100 - xResOffset, 300 }; - DoMessageBox( MSG_BOX_BASIC_STYLE, MPServerMessage[8], guiCurrentScreen, MSG_BOX_FLAG_OK | MSG_BOX_FLAG_USE_CENTERING_RECT, DialogRemoved, &CenterRect ); + SGPRect CenterRect = { 100 + xResOffset, 100, SCREEN_WIDTH - 100 - xResOffset, 300 }; + DoMessageBox( MSG_BOX_BASIC_STYLE, MPServerMessage[8], guiCurrentScreen, MSG_BOX_FLAG_OK | MSG_BOX_FLAG_USE_CENTERING_RECT, DialogRemoved, &CenterRect ); - //send loaded - send_loaded(); - } + //send loaded + send_loaded(); + } - if(unlock) //oh yeah ! :) - { - islocked=3; - EnableButton( iTPButtons[ SPREAD_BUTTON ] ); - EnableButton( iTPButtons[ GROUP_BUTTON ] ); - EnableButton( iTPButtons[ CLEAR_BUTTON ] ); + if(unlock) //oh yeah ! :) + { + islocked=3; + EnableButton( iTPButtons[ SPREAD_BUTTON ] ); + EnableButton( iTPButtons[ GROUP_BUTTON ] ); + EnableButton( iTPButtons[ CLEAR_BUTTON ] ); - ButtonList[ iTPButtons[ GROUP_BUTTON ] ]->uiFlags &= ~BUTTON_CLICKED_ON; - ButtonList[ iTPButtons[ GROUP_BUTTON ] ]->uiFlags |= BUTTON_DIRTY; - gubDefaultButton = CLEAR_BUTTON; - PlaceMercs(); - gMsgBox.bHandled = MSG_BOX_RETURN_OK; //close if still open - } + ButtonList[ iTPButtons[ GROUP_BUTTON ] ]->uiFlags &= ~BUTTON_CLICKED_ON; + ButtonList[ iTPButtons[ GROUP_BUTTON ] ]->uiFlags |= BUTTON_DIRTY; + gubDefaultButton = CLEAR_BUTTON; + PlaceMercs(); + gMsgBox.bHandled = MSG_BOX_RETURN_OK; //close if still open + } } void TacticalPlacementHandle() @@ -1114,34 +1132,34 @@ void TacticalPlacementHandle() { switch( InputEvent.usParam ) { - #ifdef JA2TESTVERSION - case ESC: - //if (!is_networked) - KillTacticalPlacementGUI(); - break; - #endif - case ENTER: - if( ButtonList[ iTPButtons[ DONE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) - { - if(!is_client)KillTacticalPlacementGUI(); - if(is_client)send_donegui(0); - } - break; - case 'c': - if(islocked!=1)ClearPlacementsCallback( ButtonList[ iTPButtons[ CLEAR_BUTTON ] ], MSYS_CALLBACK_REASON_LBUTTON_UP ); - break; - case 'g': - if(islocked!=1)GroupPlacementsCallback( ButtonList[ iTPButtons[ GROUP_BUTTON ] ], MSYS_CALLBACK_REASON_LBUTTON_UP ); - break; - case 's': - if(islocked!=1)SpreadPlacementsCallback( ButtonList[ iTPButtons[ SPREAD_BUTTON ] ], MSYS_CALLBACK_REASON_LBUTTON_UP ); - break; - case 'x': - if( InputEvent.usKeyState & ALT_DOWN ) - { - HandleShortCutExitState(); - } - break; + #ifdef JA2TESTVERSION + case ESC: + //if (!is_networked) + KillTacticalPlacementGUI(); + break; + #endif + case ENTER: + if( ButtonList[ iTPButtons[ DONE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) + { + if(!is_client)KillTacticalPlacementGUI(); + if(is_client)send_donegui(0); + } + break; + case 'c': + if(islocked!=1)ClearPlacementsCallback( ButtonList[ iTPButtons[ CLEAR_BUTTON ] ], MSYS_CALLBACK_REASON_LBUTTON_UP ); + break; + case 'g': + if(islocked!=1)GroupPlacementsCallback( ButtonList[ iTPButtons[ GROUP_BUTTON ] ], MSYS_CALLBACK_REASON_LBUTTON_UP ); + break; + case 's': + if(islocked!=1)SpreadPlacementsCallback( ButtonList[ iTPButtons[ SPREAD_BUTTON ] ], MSYS_CALLBACK_REASON_LBUTTON_UP ); + break; + case 'x': + if( InputEvent.usKeyState & ALT_DOWN ) + { + HandleShortCutExitState(); + } + break; } } } @@ -1180,7 +1198,7 @@ void TacticalPlacementHandle() // WANNE - MP: Center if ( gfCenter && ( is_networked || (gGameExternalOptions.ubSkyriderHotLZ == 3 && gMercPlacement[ gbSelectedMercID ].pSoldier->bSoldierFlagMask & SOLDIER_AIRDROP)) ) { - if ( gMercPlacement[ gbCursorMercID ].ubStrategicInsertionCode == INSERTION_CODE_CENTER ) + if (gMercPlacement[ gbCursorMercID ].ubStrategicInsertionCode == INSERTION_CODE_CENTER ) { if (gusMouseYPos >= (iOffsetVertical + CENTERENTRYPTS_TOP_Y) && // N gusMouseYPos <= (iOffsetVertical + CENTERENTRYPTS_BOTTOM_Y) && // S @@ -1198,7 +1216,7 @@ void TacticalPlacementHandle() gusMouseXPos <= (iOffsetHorizontal + AIRDROPENTRYPTS_RIGHT_X)) // E { gfValidCursor = TRUE; - } + } } } @@ -1339,21 +1357,21 @@ void PlaceMercs() INT32 i; switch( gubDefaultButton ) { - case SPREAD_BUTTON: //Place mercs randomly along their side using map edgepoints. - ChooseRandomEdgepoints(); - break; - case CLEAR_BUTTON: - for( i = 0; i < giPlacements; i++ ) - { - PickUpMercPiece( i ); - } - gubSelectedGroupID = 0; - gbSelectedMercID = 0; - SetCursorMerc( 0 ); - gfEveryonePlaced = FALSE; - break; - default: - return; + case SPREAD_BUTTON: //Place mercs randomly along their side using map edgepoints. + ChooseRandomEdgepoints(); + break; + case CLEAR_BUTTON: + for( i = 0; i < giPlacements; i++ ) + { + PickUpMercPiece( i ); + } + gubSelectedGroupID = 0; + gbSelectedMercID = 0; + SetCursorMerc( 0 ); + gfEveryonePlaced = FALSE; + break; + default: + return; } gfTacticalPlacementGUIDirty = TRUE; } @@ -1440,27 +1458,27 @@ void MercClickCallback( MOUSE_REGION *reg, INT32 reason ) { if(islocked != 1)//hayden { - if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) + if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) + { + INT8 i; + for( i = 0; i < giPlacements; i++ ) { - INT8 i; - for( i = 0; i < giPlacements; i++ ) + if( &gMercPlacement[ i ].region == reg ) { - if( &gMercPlacement[ i ].region == reg ) + if( gbSelectedMercID != i ) { - if( gbSelectedMercID != i ) - { if ( gGameExternalOptions.ubSkyriderHotLZ == 3 && gMercPlacement[ i ].pSoldier->bSoldierFlagMask & SOLDIER_AIRDROP ) gubDefaultButton = GROUP_BUTTON; - gbSelectedMercID = i; - gpTacticalPlacementSelectedSoldier = gMercPlacement[ i ].pSoldier; - if( gubDefaultButton == GROUP_BUTTON ) - { - gubSelectedGroupID = gpTacticalPlacementSelectedSoldier->ubGroupID; - } + gbSelectedMercID = i; + gpTacticalPlacementSelectedSoldier = gMercPlacement[ i ].pSoldier; + if( gubDefaultButton == GROUP_BUTTON ) + { + gubSelectedGroupID = gpTacticalPlacementSelectedSoldier->ubGroupID; } - return; } + return; + } } } } diff --git a/Utils/Text.h b/Utils/Text.h index 76330c88..2c4dbb72 100644 --- a/Utils/Text.h +++ b/Utils/Text.h @@ -2470,6 +2470,7 @@ extern STR16 gszPocketPopupText[]; // Flugente: backgrounds extern STR16 szBackgroundText_Flags[]; extern STR16 szBackgroundText_Value[]; +extern STR16 szSoldierClassName[]; // Flugente: personality enum @@ -2516,6 +2517,142 @@ enum TEXT_SKILL_DENIAL_MAX, }; +// Flugente: campaign history website +enum +{ + TEXT_CAMPAIGNHISTORY_NAME_PRESSORGANISATION, + TEXT_CAMPAIGNHISTORY_NAME_MINISTRY, + TEXT_CAMPAIGNHISTORY_NAME_REBEL, + TEXT_CAMPAIGNHISTORY_NAME_NEUTRAL_1, + TEXT_CAMPAIGNHISTORY_NAME_NEUTRAL_2, + TEXT_CAMPAIGNHISTORY_NAME_RIS, + + TEXT_CAMPAIGNHISTORY_NAME_PRESSORGANISATION_SUBTITLE, + TEXT_CAMPAIGNHISTORY_DESCRIPTION_1, + //TEXT_CAMPAIGNHISTORY_DESCRIPTION_2, + //TEXT_CAMPAIGNHISTORY_DESCRIPTION_3, + + TEXT_CAMPAIGNHISTORY_LINK_CONFLICTSUMMARY, + TEXT_CAMPAIGNHISTORY_LINK_NEWS_MOSTIMPORTANT, + TEXT_CAMPAIGNHISTORY_LINK_NEWS_RECENT, + TEXT_CAMPAIGNHISTORY_LINK_HOME, + + TEXT_CAMPAIGNHISTORY_MAX, +}; + +extern STR16 szCampaignHistoryWebSite[]; + +enum +{ + TEXT_CAMPAIGNHISTORY_DETAIL_SETTING, + TEXT_CAMPAIGNHISTORY_DETAIL_REBELFORCES, + TEXT_CAMPAIGNHISTORY_DETAIL_ARMY, + + TEXT_CAMPAIGNHISTORY_DETAIL_ATTACKED, + TEXT_CAMPAIGNHISTORY_DETAIL_AMBUSHED, + TEXT_CAMPAIGNHISTORY_DETAIL_AIRDROPPED, + + TEXT_CAMPAIGNHISTORY_DETAIL_ATTACKERDIR, + TEXT_CAMPAIGNHISTORY_DETAIL_DEFENDERDIR, + TEXT_CAMPAIGNHISTORY_DETAIL_ATTACKERANDDEFENDERDIR, + TEXT_CAMPAIGNHISTORY_DETAIL_NORTH, + TEXT_CAMPAIGNHISTORY_DETAIL_EAST, + TEXT_CAMPAIGNHISTORY_DETAIL_SOUTH, + TEXT_CAMPAIGNHISTORY_DETAIL_WEST, + + TEXT_CAMPAIGNHISTORY_DETAIL_BUILDINGDAMAGE, + TEXT_CAMPAIGNHISTORY_DETAIL_REINFORCE_BOTH, + TEXT_CAMPAIGNHISTORY_DETAIL_REINFORCE, + TEXT_CAMPAIGNHISTORY_DETAIL_CHEMICAL_BOTH, + TEXT_CAMPAIGNHISTORY_DETAIL_CHEMICAL, + TEXT_CAMPAIGNHISTORY_DETAIL_TANKS_BOTH, + TEXT_CAMPAIGNHISTORY_DETAIL_TANKS, + TEXT_CAMPAIGNHISTORY_DETAIL_SNIPERS_BOTH, + TEXT_CAMPAIGNHISTORY_DETAIL_SNIPERS, + + TEXT_CAMPAIGNHISTORY_DETAIL_MAX, +}; + +extern STR16 szCampaignHistoryDetail[]; + +enum +{ + TEXT_CAMPAIGNHISTORY_TIME_DEEPNIGHT, + TEXT_CAMPAIGNHISTORY_TIME_DAWN, + TEXT_CAMPAIGNHISTORY_TIME_EARLYMORNING, + TEXT_CAMPAIGNHISTORY_TIME_MORNING, + TEXT_CAMPAIGNHISTORY_TIME_NOON, + TEXT_CAMPAIGNHISTORY_TIME_AFTERNOON, + TEXT_CAMPAIGNHISTORY_TIME_EVENING, + TEXT_CAMPAIGNHISTORY_TIME_NIGHT, +}; + +extern STR16 szCampaignHistoryTimeString[]; + +extern STR16 szCampaignHistoryMoneyTypeString[]; +extern STR16 szCampaignHistoryConsumptionTypeString[]; + +enum +{ + TEXT_CAMPAIGNHISTORY_RESULT_ONESIDED_REBEL, + TEXT_CAMPAIGNHISTORY_RESULT_EASY_REBEL, + TEXT_CAMPAIGNHISTORY_RESULT_EASY_REBEL_PRISONER, + TEXT_CAMPAIGNHISTORY_RESULT_MEDIUM_REBEL, + TEXT_CAMPAIGNHISTORY_RESULT_MEDIUM_REBEL_PRISONER, + TEXT_CAMPAIGNHISTORY_RESULT_HARD_REBEL, + + TEXT_CAMPAIGNHISTORY_RESULT_ONESIDED_ARMY_NUMBERS, + TEXT_CAMPAIGNHISTORY_RESULT_ONESIDED_ARMY_TRAINING, + TEXT_CAMPAIGNHISTORY_RESULT_EASY_ARMY_NUMBERS, + TEXT_CAMPAIGNHISTORY_RESULT_EASY_ARMY_TRAINING, + TEXT_CAMPAIGNHISTORY_RESULT_MEDIUM_ARMY_NUMBERS, + TEXT_CAMPAIGNHISTORY_RESULT_MEDIUM_ARMY_TRAINING, + TEXT_CAMPAIGNHISTORY_RESULT_HARD_ARMY, +}; + +extern STR16 szCampaignHistoryResultString[]; + +enum +{ + TEXT_CAMPAIGNHISTORY_IMPORTANCE_IRRELEVANT, + TEXT_CAMPAIGNHISTORY_IMPORTANCE_INSIGNIFICANT, + TEXT_CAMPAIGNHISTORY_IMPORTANCE_NOTABLE, + TEXT_CAMPAIGNHISTORY_IMPORTANCE_NOTEWORTHY, + TEXT_CAMPAIGNHISTORY_IMPORTANCE_SIGNIFICANT, + TEXT_CAMPAIGNHISTORY_IMPORTANCE_INTERESTING, + TEXT_CAMPAIGNHISTORY_IMPORTANCE_IMPORTANT, + TEXT_CAMPAIGNHISTORY_IMPORTANCE_VERYIMPORTANT, + TEXT_CAMPAIGNHISTORY_IMPORTANCE_GRAVE, + TEXT_CAMPAIGNHISTORY_IMPORTANCE_MAJOR, + TEXT_CAMPAIGNHISTORY_IMPORTANCE_MOMENTOUS, +}; + +extern STR16 szCampaignHistoryImportanceString[]; + +enum +{ + WEBPAGE_CAMPAIGNHISTORY_KILLED, + WEBPAGE_CAMPAIGNHISTORY_WOUNDED, + WEBPAGE_CAMPAIGNHISTORY_PRISONERS, + WEBPAGE_CAMPAIGNHISTORY_SHOTSFIRED, + + WEBPAGE_CAMPAIGNHISTORY_MONEYEARNED, + WEBPAGE_CAMPAIGNHISTORY_CONSUMPTION, + WEBPAGE_CAMPAIGNHISTORY_LOSSES, + WEBPAGE_CAMPAIGNHISTORY_PARTICIPANTS, + + WEBPAGE_CAMPAIGNHISTORY_PROMOTIONS, + WEBPAGE_CAMPAIGNHISTORY_SUMMARY, + WEBPAGE_CAMPAIGNHISTORY_DETAIL, + WEBPAGE_CAMPAIGNHISTORY_PREVIOUS, + + WEBPAGE_CAMPAIGNHISTORY_NEXT, + WEBPAGE_CAMPAIGNHISTORY_INCIDENT, + WEBPAGE_CAMPAIGNHISTORY_DAY, +}; + +extern STR16 szCampaignHistoryWebpageString[]; + // Enumeration support typedef struct Str8EnumLookupType { int value; diff --git a/Utils/_ChineseText.cpp b/Utils/_ChineseText.cpp index 03fffd76..964a1cc0 100644 --- a/Utils/_ChineseText.cpp +++ b/Utils/_ChineseText.cpp @@ -4157,6 +4157,7 @@ STR16 pBookMarkStrings[] = L"取消", L"百科全书", L"简报室", + L"Campaign History", // TODO.Translate }; STR16 pBookmarkTitle[] = @@ -4265,6 +4266,10 @@ STR16 pWebPagesTitles[] = L"McGillicutty 公墓", L"", L"无法找到URL", + L"Arulco Press Council - Conflict Summary", // TODO.Translate + L"Arulco Press Council - Battle Reports", + L"Arulco Press Council - Latest News", + L"Arulco Press Council - About us", L"Bobby Ray - 最近的运货", L"百科全书", L"百科全书 - 数据", @@ -8147,6 +8152,162 @@ STR16 sSpecialCharacters[] = L"%", // Percentage character }; +STR16 szSoldierClassName[]= // TODO.Translate +{ + L"Mercenary", + L"Green militia", + L"Regular militia", + L"Elite militia", + + L"Civilian", + + L"Administrator", + L"Army Soldier", + L"Elite Soldier", + L"Tank", + + L"Creature", + L"Zombie", +}; + +STR16 szCampaignHistoryWebSite[]= +{ + L"Arulco Press Council", + L"Ministry for Arulcan Information Distribution", + L"Arulco Revolutionary Movement", + L"The Times International", + L"International Times", + L"R.I.S. (Recon Intelligence Service)", + + L"A collection of press sources from Arulco", + L"We are a neutral source of information. We collect different news articles from Arulco. We do not judge these sources - we merely publish them, so you can judge yourself. We post articles from various sources, among them", + + L"Conflict Summary", + L"Battle reports", + L"News", + L"About us", +}; + +STR16 szCampaignHistoryDetail[]= +{ + L"%s, %s %s %s in %s.", + + L"rebel forces", + L"the army", + + L"attacked", + L"ambushed", + L"airdropped", + + L"The attack came from %s.", + L"%s were reinforced from %s.", + L"The attack came from %s, %s were reinforced from %s.", + L"north", + L"east", + L"south", + L"west", + + L"Buildings in the sector were damaged. %s civilians were killed and %s wounded.", + L"During the attack, %s and %s called reinforcements.", + L"During the attack, %s called reinforcements.", + L"Eyewitnesses report the use of chemical weapons from both sides.", + L"Chemical weapons were used by %s.", + L"In a serious escalation of the conflict, both sides deployed tanks.", + L"%d tanks were used by %s, %d of them were destroyed in the fierce fighting.", + L"Both sides are said to have used snipers.", + L"Unverified reports indicate %s snipers were involved in the firefight." +}; + +STR16 szCampaignHistoryTimeString[]= +{ + L"Deep in the night", // 23 - 3 + L"At dawn", // 3 - 6 + L"Early in the morning", // 6 - 8 + L"In the morning hours", // 8 - 11 + L"At noon", // 11 - 14 + L"On the afternoon", // 14 - 18 + L"On the evening", // 18 - 21 + L"During the night", // 21 - 23 +}; + +STR16 szCampaignHistoryMoneyTypeString[]= +{ + L"Initial funding", + L"Mine income", + L"Trade", + L"Other sources", +}; + +STR16 szCampaignHistoryConsumptionTypeString[]= +{ + L"Ammunition", + L"Explosives", + L"Food", + L"Medical gear", + L"Item maintenance", +}; + +STR16 szCampaignHistoryResultString[]= +{ + L"In an extremely one-sided battle, the army force was wiped out without much resistance.", + + L"The rebels easily defeated the army, inflicting heavy losses.", + L"Without much effort, the rebels inflicted heavy losses upon the army and took several prisoners.", + + L"In a bloody fight, the rebels finally overcame the opposition. The army had severe losses.", + L"The rebels had losses but defeated the royalists. Unverified information says several soldiers might have been taken prisoner.", + + L"In a phyrric victory, the rebels defeated the royalists but had severe casualties of their own. Wether they will be able to hold this position against continued attacks is doubtful.", + + L"The army's superiority in numbers came into full play. The rebels never had a chance and had to either retreat or be killed or captured.", + L"Despite the high number of rebels in this sector, the army easily dispatched them.", + + L"The rebels were clearly unprepared against the army's superiority in numbers an equipment. They were easily defeated.", + L"Even though the rebels had more boots on the ground, the army was better equipped. The rebels clearly lost.", + + L"Fierce fighting saw significant losses on both sides, but in the end, the army's higher number of bodies decided the battle. The rebel force was destroyed. There might have been survivors, but we cannot verify this at this point.", + L"In an intense firefight, the superior training of the arulcan armed forces tipped the scales. The rebels had to retreat.", + + L"Neither side was willing to yield. While the army ultimately removed the rebel threat in the area, the staggering losses have resulted in the army unit continuing to exist in name only. But it is clear the rebels will soon be out of men and women if the army can keep on this rate of attrition.", +}; + +STR16 szCampaignHistoryImportanceString[]= +{ + L"Irrelevant", + L"Insignificant", + L"Notable", + L"Noteworthy", + L"Significant", + L"Interesting", + L"Important", + L"Very important", + L"Grave", + L"Major", + L"Momentous", +}; + +STR16 szCampaignHistoryWebpageString[]= +{ + L"Killed", + L"Wounded", + L"Prisoners", + L"Shots fired", + + L"Money earned", + L"Consumption", + L"Losses", + L"Participants", + + L"Promotions", + L"Summary", + L"Detail", + L"Previous", + + L"Next", + L"Incident", + L"Day", +}; + // WANNE: Some Chinese specific strings that needs to be in unicode! STR16 ChineseSpecString1 = L"%%"; //defined in _ChineseText.cpp as this file is already unicode STR16 ChineseSpecString2 = L"*%3d%%%%"; //defined in _ChineseText.cpp as this file is already unicode diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp index e9ad6a46..46c38bd8 100644 --- a/Utils/_DutchText.cpp +++ b/Utils/_DutchText.cpp @@ -4156,6 +4156,7 @@ STR16 pBookMarkStrings[] = L"Stop", L"Encyclopedia", L"Briefing Room", + L"Campaign History", // TODO.Translate }; STR16 pBookmarkTitle[] = @@ -4264,6 +4265,10 @@ STR16 pWebPagesTitles[] = L"McGillicutty's Mortuarium", L"", L"URL niet gevonden.", + L"Arulco Press Council - Conflict Summary", // TODO.Translate + L"Arulco Press Council - Battle Reports", + L"Arulco Press Council - Latest News", + L"Arulco Press Council - About us", L"Bobby Ray's - Recentelijke Zendingen", L"Encyclopedia", L"Encyclopedia - Data", @@ -8161,4 +8166,160 @@ STR16 sSpecialCharacters[] = L"%", // Percentage character }; +STR16 szSoldierClassName[]= // TODO.Translate +{ + L"Mercenary", + L"Green militia", + L"Regular militia", + L"Elite militia", + + L"Civilian", + + L"Administrator", + L"Army Soldier", + L"Elite Soldier", + L"Tank", + + L"Creature", + L"Zombie", +}; + +STR16 szCampaignHistoryWebSite[]= +{ + L"Arulco Press Council", + L"Ministry for Arulcan Information Distribution", + L"Arulco Revolutionary Movement", + L"The Times International", + L"International Times", + L"R.I.S. (Recon Intelligence Service)", + + L"A collection of press sources from Arulco", + L"We are a neutral source of information. We collect different news articles from Arulco. We do not judge these sources - we merely publish them, so you can judge yourself. We post articles from various sources, among them", + + L"Conflict Summary", + L"Battle reports", + L"News", + L"About us", +}; + +STR16 szCampaignHistoryDetail[]= +{ + L"%s, %s %s %s in %s.", + + L"rebel forces", + L"the army", + + L"attacked", + L"ambushed", + L"airdropped", + + L"The attack came from %s.", + L"%s were reinforced from %s.", + L"The attack came from %s, %s were reinforced from %s.", + L"north", + L"east", + L"south", + L"west", + + L"Buildings in the sector were damaged. %s civilians were killed and %s wounded.", + L"During the attack, %s and %s called reinforcements.", + L"During the attack, %s called reinforcements.", + L"Eyewitnesses report the use of chemical weapons from both sides.", + L"Chemical weapons were used by %s.", + L"In a serious escalation of the conflict, both sides deployed tanks.", + L"%d tanks were used by %s, %d of them were destroyed in the fierce fighting.", + L"Both sides are said to have used snipers.", + L"Unverified reports indicate %s snipers were involved in the firefight." +}; + +STR16 szCampaignHistoryTimeString[]= +{ + L"Deep in the night", // 23 - 3 + L"At dawn", // 3 - 6 + L"Early in the morning", // 6 - 8 + L"In the morning hours", // 8 - 11 + L"At noon", // 11 - 14 + L"On the afternoon", // 14 - 18 + L"On the evening", // 18 - 21 + L"During the night", // 21 - 23 +}; + +STR16 szCampaignHistoryMoneyTypeString[]= +{ + L"Initial funding", + L"Mine income", + L"Trade", + L"Other sources", +}; + +STR16 szCampaignHistoryConsumptionTypeString[]= +{ + L"Ammunition", + L"Explosives", + L"Food", + L"Medical gear", + L"Item maintenance", +}; + +STR16 szCampaignHistoryResultString[]= +{ + L"In an extremely one-sided battle, the army force was wiped out without much resistance.", + + L"The rebels easily defeated the army, inflicting heavy losses.", + L"Without much effort, the rebels inflicted heavy losses upon the army and took several prisoners.", + + L"In a bloody fight, the rebels finally overcame the opposition. The army had severe losses.", + L"The rebels had losses but defeated the royalists. Unverified information says several soldiers might have been taken prisoner.", + + L"In a phyrric victory, the rebels defeated the royalists but had severe casualties of their own. Wether they will be able to hold this position against continued attacks is doubtful.", + + L"The army's superiority in numbers came into full play. The rebels never had a chance and had to either retreat or be killed or captured.", + L"Despite the high number of rebels in this sector, the army easily dispatched them.", + + L"The rebels were clearly unprepared against the army's superiority in numbers an equipment. They were easily defeated.", + L"Even though the rebels had more boots on the ground, the army was better equipped. The rebels clearly lost.", + + L"Fierce fighting saw significant losses on both sides, but in the end, the army's higher number of bodies decided the battle. The rebel force was destroyed. There might have been survivors, but we cannot verify this at this point.", + L"In an intense firefight, the superior training of the arulcan armed forces tipped the scales. The rebels had to retreat.", + + L"Neither side was willing to yield. While the army ultimately removed the rebel threat in the area, the staggering losses have resulted in the army unit continuing to exist in name only. But it is clear the rebels will soon be out of men and women if the army can keep on this rate of attrition.", +}; + +STR16 szCampaignHistoryImportanceString[]= +{ + L"Irrelevant", + L"Insignificant", + L"Notable", + L"Noteworthy", + L"Significant", + L"Interesting", + L"Important", + L"Very important", + L"Grave", + L"Major", + L"Momentous", +}; + +STR16 szCampaignHistoryWebpageString[]= +{ + L"Killed", + L"Wounded", + L"Prisoners", + L"Shots fired", + + L"Money earned", + L"Consumption", + L"Losses", + L"Participants", + + L"Promotions", + L"Summary", + L"Detail", + L"Previous", + + L"Next", + L"Incident", + L"Day", +}; + #endif //DUTCH diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index 6dffb121..aaccd035 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -1827,7 +1827,7 @@ STR16 pAssignmentStrings[] = L"M.Militia", //training moving militia units L"Trainer", // training a teammate L"Student", // being trained by someone else - L"Move Item", // move items + L"MoveItem", // move items L"Staff", // operating a strategic facility L"Eat", // eating at a facility (cantina etc.) L"Rest", // Resting at a facility @@ -1965,7 +1965,7 @@ STR16 pLongAssignmentStrings[] = L"Train Mobiles", // Missing L"Train Teammate", L"Student", - L"Move Item", // move items + L"MoveItem", // move items L"Staff Facility", // Missing L"Rest at Facility", // Missing L"Interrogate prisoners", // Flugente: interrogate prisoners @@ -2091,7 +2091,7 @@ STR16 pAssignMenuStrings[] = L"Repair", // the merc is repairing items L"Radio Scan", // Flugente: the merc is scanning for patrols in neighbouring sectors L"Train", // the merc is training - L"Move Item", // move items + L"MoveItem", // move items L"Facility", // the merc is using/staffing a facility L"Cancel", // cancel this menu }; @@ -4158,6 +4158,7 @@ STR16 pBookMarkStrings[] = L"Cancel", L"Encyclopedia", L"Briefing Room", + L"Campaign History", }; STR16 pBookmarkTitle[] = @@ -4266,6 +4267,10 @@ STR16 pWebPagesTitles[] = L"McGillicutty's Mortuary", L"", L"URL not found.", + L"Arulco Press Council - Conflict Summary", + L"Arulco Press Council - Battle Reports", + L"Arulco Press Council - Latest News", + L"Arulco Press Council - About us", L"Bobby Ray's - Recent Shipments", L"Encyclopedia", L"Encyclopedia - Data", @@ -7381,7 +7386,7 @@ STR16 szUDBGenExplosiveStatsExplanationsTooltipText[]= L"\n \nThis value represents a chance (out of 100) for this\nexplosive to spontaneously explode whenever it is damaged\n(for instance, when other explosions go off nearby).\n \nCarrying highly-volatile explosives into combat\nis therefore extremely risky and should be avoided.\n \nScale: 0-100.\nLower is better.", L"\n \nDetermines how difficult it is to repair these explosives.\n \ngreen = Anybody can repair them.\n \nred = This item can't be repaired.\n \nHigher is better.", }; - + STR16 szUDBGenCommonStatsTooltipText[]= { L"|R|e|p|a|i|r |E|a|s|e", @@ -8148,4 +8153,160 @@ STR16 sSpecialCharacters[] = L"%", // Percentage character }; +STR16 szSoldierClassName[]= +{ + L"Mercenary", + L"Green militia", + L"Regular militia", + L"Elite militia", + + L"Civilian", + + L"Administrator", + L"Army Soldier", + L"Elite Soldier", + L"Tank", + + L"Creature", + L"Zombie", +}; + +STR16 szCampaignHistoryWebSite[]= +{ + L"Arulco Press Council", + L"Ministry for Arulcan Information Distribution", + L"Arulco Revolutionary Movement", + L"The Times International", + L"International Times", + L"R.I.S. (Recon Intelligence Service)", + + L"A collection of press sources from Arulco", + L"We are a neutral source of information. We collect different news articles from Arulco. We do not judge these sources - we merely publish them, so you can judge yourself. We post articles from various sources, among them", + + L"Conflict Summary", + L"Battle reports", + L"News", + L"About us", +}; + +STR16 szCampaignHistoryDetail[]= +{ + L"%s, %s %s %s in %s.", + + L"rebel forces", + L"the army", + + L"attacked", + L"ambushed", + L"airdropped", + + L"The attack came from %s.", + L"%s were reinforced from %s.", + L"The attack came from %s, %s were reinforced from %s.", + L"north", + L"east", + L"south", + L"west", + + L"Buildings in the sector were damaged. %s civilians were killed and %s wounded.", + L"During the attack, %s and %s called reinforcements.", + L"During the attack, %s called reinforcements.", + L"Eyewitnesses report the use of chemical weapons from both sides.", + L"Chemical weapons were used by %s.", + L"In a serious escalation of the conflict, both sides deployed tanks.", + L"%d tanks were used by %s, %d of them were destroyed in the fierce fighting.", + L"Both sides are said to have used snipers.", + L"Unverified reports indicate %s snipers were involved in the firefight." +}; + +STR16 szCampaignHistoryTimeString[]= +{ + L"Deep in the night", // 23 - 3 + L"At dawn", // 3 - 6 + L"Early in the morning", // 6 - 8 + L"In the morning hours", // 8 - 11 + L"At noon", // 11 - 14 + L"On the afternoon", // 14 - 18 + L"On the evening", // 18 - 21 + L"During the night", // 21 - 23 +}; + +STR16 szCampaignHistoryMoneyTypeString[]= +{ + L"Initial funding", + L"Mine income", + L"Trade", + L"Other sources", +}; + +STR16 szCampaignHistoryConsumptionTypeString[]= +{ + L"Ammunition", + L"Explosives", + L"Food", + L"Medical gear", + L"Item maintenance", +}; + +STR16 szCampaignHistoryResultString[]= +{ + L"In an extremely one-sided battle, the army force was wiped out without much resistance.", + + L"The rebels easily defeated the army, inflicting heavy losses.", + L"Without much effort, the rebels inflicted heavy losses upon the army and took several prisoners.", + + L"In a bloody fight, the rebels finally overcame the opposition. The army had severe losses.", + L"The rebels had losses but defeated the royalists. Unverified information says several soldiers might have been taken prisoner.", + + L"In a phyrric victory, the rebels defeated the royalists but had severe casualties of their own. Wether they will be able to hold this position against continued attacks is doubtful.", + + L"The army's superiority in numbers came into full play. The rebels never had a chance and had to either retreat or be killed or captured.", + L"Despite the high number of rebels in this sector, the army easily dispatched them.", + + L"The rebels were clearly unprepared against the army's superiority in numbers an equipment. They were easily defeated.", + L"Even though the rebels had more boots on the ground, the army was better equipped. The rebels clearly lost.", + + L"Fierce fighting saw significant losses on both sides, but in the end, the army's higher number of bodies decided the battle. The rebel force was destroyed. There might have been survivors, but we cannot verify this at this point.", + L"In an intense firefight, the superior training of the arulcan armed forces tipped the scales. The rebels had to retreat.", + + L"Neither side was willing to yield. While the army ultimately removed the rebel threat in the area, the staggering losses have resulted in the army unit continuing to exist in name only. But it is clear the rebels will soon be out of men and women if the army can keep on this rate of attrition.", +}; + +STR16 szCampaignHistoryImportanceString[]= +{ + L"Irrelevant", + L"Insignificant", + L"Notable", + L"Noteworthy", + L"Significant", + L"Interesting", + L"Important", + L"Very important", + L"Grave", + L"Major", + L"Momentous", +}; + +STR16 szCampaignHistoryWebpageString[]= +{ + L"Killed", + L"Wounded", + L"Prisoners", + L"Shots fired", + + L"Money earned", + L"Consumption", + L"Losses", + L"Participants", + + L"Promotions", + L"Summary", + L"Detail", + L"Previous", + + L"Next", + L"Incident", + L"Day", +}; + #endif //ENGLISH diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp index 982b659b..3d9a9d34 100644 --- a/Utils/_FrenchText.cpp +++ b/Utils/_FrenchText.cpp @@ -4163,6 +4163,7 @@ STR16 pBookMarkStrings[] = L"Annuler", L"Encyclopedia", L"Briefing Room", + L"Campaign History", // TODO.Translate }; STR16 pBookmarkTitle[] = @@ -4271,6 +4272,10 @@ STR16 pWebPagesTitles[] = L"Morgue McGillicutty", L"", L"URL introuvable.", + L"Arulco Press Council - Conflict Summary", // TODO.Translate + L"Arulco Press Council - Battle Reports", + L"Arulco Press Council - Latest News", + L"Arulco Press Council - About us", L"Bobby Ray : Dernières commandes", L"Encyclopedia", L"Encyclopedia - Data", @@ -8137,4 +8142,160 @@ STR16 sSpecialCharacters[] = L"%", // Percentage character }; +STR16 szSoldierClassName[]= // TODO.Translate +{ + L"Mercenary", + L"Green militia", + L"Regular militia", + L"Elite militia", + + L"Civilian", + + L"Administrator", + L"Army Soldier", + L"Elite Soldier", + L"Tank", + + L"Creature", + L"Zombie", +}; + +STR16 szCampaignHistoryWebSite[]= +{ + L"Arulco Press Council", + L"Ministry for Arulcan Information Distribution", + L"Arulco Revolutionary Movement", + L"The Times International", + L"International Times", + L"R.I.S. (Recon Intelligence Service)", + + L"A collection of press sources from Arulco", + L"We are a neutral source of information. We collect different news articles from Arulco. We do not judge these sources - we merely publish them, so you can judge yourself. We post articles from various sources, among them", + + L"Conflict Summary", + L"Battle reports", + L"News", + L"About us", +}; + +STR16 szCampaignHistoryDetail[]= +{ + L"%s, %s %s %s in %s.", + + L"rebel forces", + L"the army", + + L"attacked", + L"ambushed", + L"airdropped", + + L"The attack came from %s.", + L"%s were reinforced from %s.", + L"The attack came from %s, %s were reinforced from %s.", + L"north", + L"east", + L"south", + L"west", + + L"Buildings in the sector were damaged. %s civilians were killed and %s wounded.", + L"During the attack, %s and %s called reinforcements.", + L"During the attack, %s called reinforcements.", + L"Eyewitnesses report the use of chemical weapons from both sides.", + L"Chemical weapons were used by %s.", + L"In a serious escalation of the conflict, both sides deployed tanks.", + L"%d tanks were used by %s, %d of them were destroyed in the fierce fighting.", + L"Both sides are said to have used snipers.", + L"Unverified reports indicate %s snipers were involved in the firefight." +}; + +STR16 szCampaignHistoryTimeString[]= +{ + L"Deep in the night", // 23 - 3 + L"At dawn", // 3 - 6 + L"Early in the morning", // 6 - 8 + L"In the morning hours", // 8 - 11 + L"At noon", // 11 - 14 + L"On the afternoon", // 14 - 18 + L"On the evening", // 18 - 21 + L"During the night", // 21 - 23 +}; + +STR16 szCampaignHistoryMoneyTypeString[]= +{ + L"Initial funding", + L"Mine income", + L"Trade", + L"Other sources", +}; + +STR16 szCampaignHistoryConsumptionTypeString[]= +{ + L"Ammunition", + L"Explosives", + L"Food", + L"Medical gear", + L"Item maintenance", +}; + +STR16 szCampaignHistoryResultString[]= +{ + L"In an extremely one-sided battle, the army force was wiped out without much resistance.", + + L"The rebels easily defeated the army, inflicting heavy losses.", + L"Without much effort, the rebels inflicted heavy losses upon the army and took several prisoners.", + + L"In a bloody fight, the rebels finally overcame the opposition. The army had severe losses.", + L"The rebels had losses but defeated the royalists. Unverified information says several soldiers might have been taken prisoner.", + + L"In a phyrric victory, the rebels defeated the royalists but had severe casualties of their own. Wether they will be able to hold this position against continued attacks is doubtful.", + + L"The army's superiority in numbers came into full play. The rebels never had a chance and had to either retreat or be killed or captured.", + L"Despite the high number of rebels in this sector, the army easily dispatched them.", + + L"The rebels were clearly unprepared against the army's superiority in numbers an equipment. They were easily defeated.", + L"Even though the rebels had more boots on the ground, the army was better equipped. The rebels clearly lost.", + + L"Fierce fighting saw significant losses on both sides, but in the end, the army's higher number of bodies decided the battle. The rebel force was destroyed. There might have been survivors, but we cannot verify this at this point.", + L"In an intense firefight, the superior training of the arulcan armed forces tipped the scales. The rebels had to retreat.", + + L"Neither side was willing to yield. While the army ultimately removed the rebel threat in the area, the staggering losses have resulted in the army unit continuing to exist in name only. But it is clear the rebels will soon be out of men and women if the army can keep on this rate of attrition.", +}; + +STR16 szCampaignHistoryImportanceString[]= +{ + L"Irrelevant", + L"Insignificant", + L"Notable", + L"Noteworthy", + L"Significant", + L"Interesting", + L"Important", + L"Very important", + L"Grave", + L"Major", + L"Momentous", +}; + +STR16 szCampaignHistoryWebpageString[]= +{ + L"Killed", + L"Wounded", + L"Prisoners", + L"Shots fired", + + L"Money earned", + L"Consumption", + L"Losses", + L"Participants", + + L"Promotions", + L"Summary", + L"Detail", + L"Previous", + + L"Next", + L"Incident", + L"Day", +}; + #endif //FRENCH diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index 96b0cc92..46349e94 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -4104,6 +4104,7 @@ STR16 pBookMarkStrings[] = L"Abbruch", L"Enzyklopädie", L"Einsatzbesprechung", + L"Campaign History", // TODO.Translate }; STR16 pBookmarkTitle[] = @@ -4204,13 +4205,15 @@ STR16 pWebPagesTitles[] = L"McGillicuttys Bestattungen", L"", L"URL nicht gefunden.", + L"Arulco Press Council - Conflict Summary", // TODO.Translate + L"Arulco Press Council - Battle Reports", + L"Arulco Press Council - Latest News", + L"Arulco Press Council - About us", L"Bobby Rays - Letzte Lieferungen", L"Enzyklopädie", L"Enzyklopädie - Daten", L"Einsatzbesprechung", - L"Einsatzbesprechung - Daten", - }; STR16 pShowBookmarkString[] = @@ -7970,4 +7973,160 @@ STR16 sSpecialCharacters[] = L"%", // Percentage character }; +STR16 szSoldierClassName[]= // TODO.Translate +{ + L"Mercenary", + L"Green militia", + L"Regular militia", + L"Elite militia", + + L"Civilian", + + L"Administrator", + L"Army Soldier", + L"Elite Soldier", + L"Tank", + + L"Creature", + L"Zombie", +}; + +STR16 szCampaignHistoryWebSite[]= +{ + L"Arulco Press Council", + L"Ministry for Arulcan Information Distribution", + L"Arulco Revolutionary Movement", + L"The Times International", + L"International Times", + L"R.I.S. (Recon Intelligence Service)", + + L"A collection of press sources from Arulco", + L"We are a neutral source of information. We collect different news articles from Arulco. We do not judge these sources - we merely publish them, so you can judge yourself. We post articles from various sources, among them", + + L"Conflict Summary", + L"Battle reports", + L"News", + L"About us", +}; + +STR16 szCampaignHistoryDetail[]= +{ + L"%s, %s %s %s in %s.", + + L"rebel forces", + L"the army", + + L"attacked", + L"ambushed", + L"airdropped", + + L"The attack came from %s.", + L"%s were reinforced from %s.", + L"The attack came from %s, %s were reinforced from %s.", + L"north", + L"east", + L"south", + L"west", + + L"Buildings in the sector were damaged. %s civilians were killed and %s wounded.", + L"During the attack, %s and %s called reinforcements.", + L"During the attack, %s called reinforcements.", + L"Eyewitnesses report the use of chemical weapons from both sides.", + L"Chemical weapons were used by %s.", + L"In a serious escalation of the conflict, both sides deployed tanks.", + L"%d tanks were used by %s, %d of them were destroyed in the fierce fighting.", + L"Both sides are said to have used snipers.", + L"Unverified reports indicate %s snipers were involved in the firefight." +}; + +STR16 szCampaignHistoryTimeString[]= +{ + L"Deep in the night", // 23 - 3 + L"At dawn", // 3 - 6 + L"Early in the morning", // 6 - 8 + L"In the morning hours", // 8 - 11 + L"At noon", // 11 - 14 + L"On the afternoon", // 14 - 18 + L"On the evening", // 18 - 21 + L"During the night", // 21 - 23 +}; + +STR16 szCampaignHistoryMoneyTypeString[]= +{ + L"Initial funding", + L"Mine income", + L"Trade", + L"Other sources", +}; + +STR16 szCampaignHistoryConsumptionTypeString[]= +{ + L"Ammunition", + L"Explosives", + L"Food", + L"Medical gear", + L"Item maintenance", +}; + +STR16 szCampaignHistoryResultString[]= +{ + L"In an extremely one-sided battle, the army force was wiped out without much resistance.", + + L"The rebels easily defeated the army, inflicting heavy losses.", + L"Without much effort, the rebels inflicted heavy losses upon the army and took several prisoners.", + + L"In a bloody fight, the rebels finally overcame the opposition. The army had severe losses.", + L"The rebels had losses but defeated the royalists. Unverified information says several soldiers might have been taken prisoner.", + + L"In a phyrric victory, the rebels defeated the royalists but had severe casualties of their own. Wether they will be able to hold this position against continued attacks is doubtful.", + + L"The army's superiority in numbers came into full play. The rebels never had a chance and had to either retreat or be killed or captured.", + L"Despite the high number of rebels in this sector, the army easily dispatched them.", + + L"The rebels were clearly unprepared against the army's superiority in numbers an equipment. They were easily defeated.", + L"Even though the rebels had more boots on the ground, the army was better equipped. The rebels clearly lost.", + + L"Fierce fighting saw significant losses on both sides, but in the end, the army's higher number of bodies decided the battle. The rebel force was destroyed. There might have been survivors, but we cannot verify this at this point.", + L"In an intense firefight, the superior training of the arulcan armed forces tipped the scales. The rebels had to retreat.", + + L"Neither side was willing to yield. While the army ultimately removed the rebel threat in the area, the staggering losses have resulted in the army unit continuing to exist in name only. But it is clear the rebels will soon be out of men and women if the army can keep on this rate of attrition.", +}; + +STR16 szCampaignHistoryImportanceString[]= +{ + L"Irrelevant", + L"Insignificant", + L"Notable", + L"Noteworthy", + L"Significant", + L"Interesting", + L"Important", + L"Very important", + L"Grave", + L"Major", + L"Momentous", +}; + +STR16 szCampaignHistoryWebpageString[]= +{ + L"Killed", + L"Wounded", + L"Prisoners", + L"Shots fired", + + L"Money earned", + L"Consumption", + L"Losses", + L"Participants", + + L"Promotions", + L"Summary", + L"Detail", + L"Previous", + + L"Next", + L"Incident", + L"Day", +}; + #endif //GERMAN diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp index 27a7f0aa..9e07e6aa 100644 --- a/Utils/_ItalianText.cpp +++ b/Utils/_ItalianText.cpp @@ -4144,6 +4144,7 @@ STR16 pBookMarkStrings[] = L"Fiorista", L"Assicurazione", L"Annulla", + L"Campaign History", // TODO.Translate }; STR16 pBookmarkTitle[] = @@ -4252,6 +4253,10 @@ STR16 pWebPagesTitles[] = L"Servizio di pompe funebri di McGillicutty", L"", L"URL non ritrovato.", + L"Arulco Press Council - Conflict Summary", // TODO.Translate + L"Arulco Press Council - Battle Reports", + L"Arulco Press Council - Latest News", + L"Arulco Press Council - About us", L"Bobby Ray - Spedizioni recenti", L"Encyclopedia", L"Encyclopedia - Data", @@ -8149,4 +8154,160 @@ STR16 sSpecialCharacters[] = L"%", // Percentage character }; +STR16 szSoldierClassName[]= // TODO.Translate +{ + L"Mercenary", + L"Green militia", + L"Regular militia", + L"Elite militia", + + L"Civilian", + + L"Administrator", + L"Army Soldier", + L"Elite Soldier", + L"Tank", + + L"Creature", + L"Zombie", +}; + +STR16 szCampaignHistoryWebSite[]= +{ + L"Arulco Press Council", + L"Ministry for Arulcan Information Distribution", + L"Arulco Revolutionary Movement", + L"The Times International", + L"International Times", + L"R.I.S. (Recon Intelligence Service)", + + L"A collection of press sources from Arulco", + L"We are a neutral source of information. We collect different news articles from Arulco. We do not judge these sources - we merely publish them, so you can judge yourself. We post articles from various sources, among them", + + L"Conflict Summary", + L"Battle reports", + L"News", + L"About us", +}; + +STR16 szCampaignHistoryDetail[]= +{ + L"%s, %s %s %s in %s.", + + L"rebel forces", + L"the army", + + L"attacked", + L"ambushed", + L"airdropped", + + L"The attack came from %s.", + L"%s were reinforced from %s.", + L"The attack came from %s, %s were reinforced from %s.", + L"north", + L"east", + L"south", + L"west", + + L"Buildings in the sector were damaged. %s civilians were killed and %s wounded.", + L"During the attack, %s and %s called reinforcements.", + L"During the attack, %s called reinforcements.", + L"Eyewitnesses report the use of chemical weapons from both sides.", + L"Chemical weapons were used by %s.", + L"In a serious escalation of the conflict, both sides deployed tanks.", + L"%d tanks were used by %s, %d of them were destroyed in the fierce fighting.", + L"Both sides are said to have used snipers.", + L"Unverified reports indicate %s snipers were involved in the firefight." +}; + +STR16 szCampaignHistoryTimeString[]= +{ + L"Deep in the night", // 23 - 3 + L"At dawn", // 3 - 6 + L"Early in the morning", // 6 - 8 + L"In the morning hours", // 8 - 11 + L"At noon", // 11 - 14 + L"On the afternoon", // 14 - 18 + L"On the evening", // 18 - 21 + L"During the night", // 21 - 23 +}; + +STR16 szCampaignHistoryMoneyTypeString[]= +{ + L"Initial funding", + L"Mine income", + L"Trade", + L"Other sources", +}; + +STR16 szCampaignHistoryConsumptionTypeString[]= +{ + L"Ammunition", + L"Explosives", + L"Food", + L"Medical gear", + L"Item maintenance", +}; + +STR16 szCampaignHistoryResultString[]= +{ + L"In an extremely one-sided battle, the army force was wiped out without much resistance.", + + L"The rebels easily defeated the army, inflicting heavy losses.", + L"Without much effort, the rebels inflicted heavy losses upon the army and took several prisoners.", + + L"In a bloody fight, the rebels finally overcame the opposition. The army had severe losses.", + L"The rebels had losses but defeated the royalists. Unverified information says several soldiers might have been taken prisoner.", + + L"In a phyrric victory, the rebels defeated the royalists but had severe casualties of their own. Wether they will be able to hold this position against continued attacks is doubtful.", + + L"The army's superiority in numbers came into full play. The rebels never had a chance and had to either retreat or be killed or captured.", + L"Despite the high number of rebels in this sector, the army easily dispatched them.", + + L"The rebels were clearly unprepared against the army's superiority in numbers an equipment. They were easily defeated.", + L"Even though the rebels had more boots on the ground, the army was better equipped. The rebels clearly lost.", + + L"Fierce fighting saw significant losses on both sides, but in the end, the army's higher number of bodies decided the battle. The rebel force was destroyed. There might have been survivors, but we cannot verify this at this point.", + L"In an intense firefight, the superior training of the arulcan armed forces tipped the scales. The rebels had to retreat.", + + L"Neither side was willing to yield. While the army ultimately removed the rebel threat in the area, the staggering losses have resulted in the army unit continuing to exist in name only. But it is clear the rebels will soon be out of men and women if the army can keep on this rate of attrition.", +}; + +STR16 szCampaignHistoryImportanceString[]= +{ + L"Irrelevant", + L"Insignificant", + L"Notable", + L"Noteworthy", + L"Significant", + L"Interesting", + L"Important", + L"Very important", + L"Grave", + L"Major", + L"Momentous", +}; + +STR16 szCampaignHistoryWebpageString[]= +{ + L"Killed", + L"Wounded", + L"Prisoners", + L"Shots fired", + + L"Money earned", + L"Consumption", + L"Losses", + L"Participants", + + L"Promotions", + L"Summary", + L"Detail", + L"Previous", + + L"Next", + L"Incident", + L"Day", +}; + #endif //ITALIAN diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp index 0b1977bf..e53e2471 100644 --- a/Utils/_PolishText.cpp +++ b/Utils/_PolishText.cpp @@ -4166,6 +4166,7 @@ STR16 pBookMarkStrings[] = L"Anuluj", L"Encyclopedia", L"Briefing Room", + L"Campaign History", // TODO.Translate }; STR16 pBookmarkTitle[] = @@ -4274,6 +4275,10 @@ STR16 pWebPagesTitles[] = L"McGillicutty - Zakład pogrzebowy", L"", L"Nie odnaleziono URL.", + L"Arulco Press Council - Conflict Summary", // TODO.Translate + L"Arulco Press Council - Battle Reports", + L"Arulco Press Council - Latest News", + L"Arulco Press Council - About us", L"Bobby Ray's - Ostatnie dostawy", L"Encyclopedia", L"Encyclopedia - Dane", @@ -8174,4 +8179,160 @@ STR16 sSpecialCharacters[] = L"%", // Percentage character }; +STR16 szSoldierClassName[]= // TODO.Translate +{ + L"Mercenary", + L"Green militia", + L"Regular militia", + L"Elite militia", + + L"Civilian", + + L"Administrator", + L"Army Soldier", + L"Elite Soldier", + L"Tank", + + L"Creature", + L"Zombie", +}; + +STR16 szCampaignHistoryWebSite[]= +{ + L"Arulco Press Council", + L"Ministry for Arulcan Information Distribution", + L"Arulco Revolutionary Movement", + L"The Times International", + L"International Times", + L"R.I.S. (Recon Intelligence Service)", + + L"A collection of press sources from Arulco", + L"We are a neutral source of information. We collect different news articles from Arulco. We do not judge these sources - we merely publish them, so you can judge yourself. We post articles from various sources, among them", + + L"Conflict Summary", + L"Battle reports", + L"News", + L"About us", +}; + +STR16 szCampaignHistoryDetail[]= +{ + L"%s, %s %s %s in %s.", + + L"rebel forces", + L"the army", + + L"attacked", + L"ambushed", + L"airdropped", + + L"The attack came from %s.", + L"%s were reinforced from %s.", + L"The attack came from %s, %s were reinforced from %s.", + L"north", + L"east", + L"south", + L"west", + + L"Buildings in the sector were damaged. %s civilians were killed and %s wounded.", + L"During the attack, %s and %s called reinforcements.", + L"During the attack, %s called reinforcements.", + L"Eyewitnesses report the use of chemical weapons from both sides.", + L"Chemical weapons were used by %s.", + L"In a serious escalation of the conflict, both sides deployed tanks.", + L"%d tanks were used by %s, %d of them were destroyed in the fierce fighting.", + L"Both sides are said to have used snipers.", + L"Unverified reports indicate %s snipers were involved in the firefight." +}; + +STR16 szCampaignHistoryTimeString[]= +{ + L"Deep in the night", // 23 - 3 + L"At dawn", // 3 - 6 + L"Early in the morning", // 6 - 8 + L"In the morning hours", // 8 - 11 + L"At noon", // 11 - 14 + L"On the afternoon", // 14 - 18 + L"On the evening", // 18 - 21 + L"During the night", // 21 - 23 +}; + +STR16 szCampaignHistoryMoneyTypeString[]= +{ + L"Initial funding", + L"Mine income", + L"Trade", + L"Other sources", +}; + +STR16 szCampaignHistoryConsumptionTypeString[]= +{ + L"Ammunition", + L"Explosives", + L"Food", + L"Medical gear", + L"Item maintenance", +}; + +STR16 szCampaignHistoryResultString[]= +{ + L"In an extremely one-sided battle, the army force was wiped out without much resistance.", + + L"The rebels easily defeated the army, inflicting heavy losses.", + L"Without much effort, the rebels inflicted heavy losses upon the army and took several prisoners.", + + L"In a bloody fight, the rebels finally overcame the opposition. The army had severe losses.", + L"The rebels had losses but defeated the royalists. Unverified information says several soldiers might have been taken prisoner.", + + L"In a phyrric victory, the rebels defeated the royalists but had severe casualties of their own. Wether they will be able to hold this position against continued attacks is doubtful.", + + L"The army's superiority in numbers came into full play. The rebels never had a chance and had to either retreat or be killed or captured.", + L"Despite the high number of rebels in this sector, the army easily dispatched them.", + + L"The rebels were clearly unprepared against the army's superiority in numbers an equipment. They were easily defeated.", + L"Even though the rebels had more boots on the ground, the army was better equipped. The rebels clearly lost.", + + L"Fierce fighting saw significant losses on both sides, but in the end, the army's higher number of bodies decided the battle. The rebel force was destroyed. There might have been survivors, but we cannot verify this at this point.", + L"In an intense firefight, the superior training of the arulcan armed forces tipped the scales. The rebels had to retreat.", + + L"Neither side was willing to yield. While the army ultimately removed the rebel threat in the area, the staggering losses have resulted in the army unit continuing to exist in name only. But it is clear the rebels will soon be out of men and women if the army can keep on this rate of attrition.", +}; + +STR16 szCampaignHistoryImportanceString[]= +{ + L"Irrelevant", + L"Insignificant", + L"Notable", + L"Noteworthy", + L"Significant", + L"Interesting", + L"Important", + L"Very important", + L"Grave", + L"Major", + L"Momentous", +}; + +STR16 szCampaignHistoryWebpageString[]= +{ + L"Killed", + L"Wounded", + L"Prisoners", + L"Shots fired", + + L"Money earned", + L"Consumption", + L"Losses", + L"Participants", + + L"Promotions", + L"Summary", + L"Detail", + L"Previous", + + L"Next", + L"Incident", + L"Day", +}; + #endif //POLISH diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index aaef118d..c580614e 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -4154,6 +4154,7 @@ STR16 pBookMarkStrings[] = L"Отмена", L"Энциклопедия", L"Briefing Room", + L"Campaign History", // TODO.Translate }; STR16 pBookmarkTitle[] = @@ -4262,6 +4263,10 @@ STR16 pWebPagesTitles[] = L"Похоронная служба Макгилликатти", L"", L"Адрес не найден.", + L"Arulco Press Council - Conflict Summary", // TODO.Translate + L"Arulco Press Council - Battle Reports", + L"Arulco Press Council - Latest News", + L"Arulco Press Council - About us", L"Бобби Рэй - последние поступления", L"Энциклопедия", L"Энциклопедия - данные", @@ -8147,4 +8152,160 @@ STR16 sSpecialCharacters[] = L"%", // Percentage character }; +STR16 szSoldierClassName[]= // TODO.Translate +{ + L"Mercenary", + L"Green militia", + L"Regular militia", + L"Elite militia", + + L"Civilian", + + L"Administrator", + L"Army Soldier", + L"Elite Soldier", + L"Tank", + + L"Creature", + L"Zombie", +}; + +STR16 szCampaignHistoryWebSite[]= +{ + L"Arulco Press Council", + L"Ministry for Arulcan Information Distribution", + L"Arulco Revolutionary Movement", + L"The Times International", + L"International Times", + L"R.I.S. (Recon Intelligence Service)", + + L"A collection of press sources from Arulco", + L"We are a neutral source of information. We collect different news articles from Arulco. We do not judge these sources - we merely publish them, so you can judge yourself. We post articles from various sources, among them", + + L"Conflict Summary", + L"Battle reports", + L"News", + L"About us", +}; + +STR16 szCampaignHistoryDetail[]= +{ + L"%s, %s %s %s in %s.", + + L"rebel forces", + L"the army", + + L"attacked", + L"ambushed", + L"airdropped", + + L"The attack came from %s.", + L"%s were reinforced from %s.", + L"The attack came from %s, %s were reinforced from %s.", + L"north", + L"east", + L"south", + L"west", + + L"Buildings in the sector were damaged. %s civilians were killed and %s wounded.", + L"During the attack, %s and %s called reinforcements.", + L"During the attack, %s called reinforcements.", + L"Eyewitnesses report the use of chemical weapons from both sides.", + L"Chemical weapons were used by %s.", + L"In a serious escalation of the conflict, both sides deployed tanks.", + L"%d tanks were used by %s, %d of them were destroyed in the fierce fighting.", + L"Both sides are said to have used snipers.", + L"Unverified reports indicate %s snipers were involved in the firefight." +}; + +STR16 szCampaignHistoryTimeString[]= +{ + L"Deep in the night", // 23 - 3 + L"At dawn", // 3 - 6 + L"Early in the morning", // 6 - 8 + L"In the morning hours", // 8 - 11 + L"At noon", // 11 - 14 + L"On the afternoon", // 14 - 18 + L"On the evening", // 18 - 21 + L"During the night", // 21 - 23 +}; + +STR16 szCampaignHistoryMoneyTypeString[]= +{ + L"Initial funding", + L"Mine income", + L"Trade", + L"Other sources", +}; + +STR16 szCampaignHistoryConsumptionTypeString[]= +{ + L"Ammunition", + L"Explosives", + L"Food", + L"Medical gear", + L"Item maintenance", +}; + +STR16 szCampaignHistoryResultString[]= +{ + L"In an extremely one-sided battle, the army force was wiped out without much resistance.", + + L"The rebels easily defeated the army, inflicting heavy losses.", + L"Without much effort, the rebels inflicted heavy losses upon the army and took several prisoners.", + + L"In a bloody fight, the rebels finally overcame the opposition. The army had severe losses.", + L"The rebels had losses but defeated the royalists. Unverified information says several soldiers might have been taken prisoner.", + + L"In a phyrric victory, the rebels defeated the royalists but had severe casualties of their own. Wether they will be able to hold this position against continued attacks is doubtful.", + + L"The army's superiority in numbers came into full play. The rebels never had a chance and had to either retreat or be killed or captured.", + L"Despite the high number of rebels in this sector, the army easily dispatched them.", + + L"The rebels were clearly unprepared against the army's superiority in numbers an equipment. They were easily defeated.", + L"Even though the rebels had more boots on the ground, the army was better equipped. The rebels clearly lost.", + + L"Fierce fighting saw significant losses on both sides, but in the end, the army's higher number of bodies decided the battle. The rebel force was destroyed. There might have been survivors, but we cannot verify this at this point.", + L"In an intense firefight, the superior training of the arulcan armed forces tipped the scales. The rebels had to retreat.", + + L"Neither side was willing to yield. While the army ultimately removed the rebel threat in the area, the staggering losses have resulted in the army unit continuing to exist in name only. But it is clear the rebels will soon be out of men and women if the army can keep on this rate of attrition.", +}; + +STR16 szCampaignHistoryImportanceString[]= +{ + L"Irrelevant", + L"Insignificant", + L"Notable", + L"Noteworthy", + L"Significant", + L"Interesting", + L"Important", + L"Very important", + L"Grave", + L"Major", + L"Momentous", +}; + +STR16 szCampaignHistoryWebpageString[]= +{ + L"Killed", + L"Wounded", + L"Prisoners", + L"Shots fired", + + L"Money earned", + L"Consumption", + L"Losses", + L"Participants", + + L"Promotions", + L"Summary", + L"Detail", + L"Previous", + + L"Next", + L"Incident", + L"Day", +}; + #endif //RUSSIAN diff --git a/Utils/_TaiwaneseText.cpp b/Utils/_TaiwaneseText.cpp index 7a7e2296..47d9429e 100644 --- a/Utils/_TaiwaneseText.cpp +++ b/Utils/_TaiwaneseText.cpp @@ -4160,6 +4160,7 @@ STR16 pBookMarkStrings[] = L"Cancel", L"Encyclopedia", L"Briefing Room", + L"Campaign History", // TODO.Translate }; STR16 pBookmarkTitle[] = @@ -4268,6 +4269,10 @@ STR16 pWebPagesTitles[] = L"McGillicutty's Mortuary", L"", L"URL not found.", + L"Arulco Press Council - Conflict Summary", // TODO.Translate + L"Arulco Press Council - Battle Reports", + L"Arulco Press Council - Latest News", + L"Arulco Press Council - About us", L"Bobby Ray's - Recent Shipments", L"Encyclopedia", L"Encyclopedia - Data", @@ -8165,4 +8170,160 @@ STR16 sSpecialCharacters[] = L"%", // Percentage character }; +STR16 szSoldierClassName[]= // TODO.Translate +{ + L"Mercenary", + L"Green militia", + L"Regular militia", + L"Elite militia", + + L"Civilian", + + L"Administrator", + L"Army Soldier", + L"Elite Soldier", + L"Tank", + + L"Creature", + L"Zombie", +}; + +STR16 szCampaignHistoryWebSite[]= +{ + L"Arulco Press Council", + L"Ministry for Arulcan Information Distribution", + L"Arulco Revolutionary Movement", + L"The Times International", + L"International Times", + L"R.I.S. (Recon Intelligence Service)", + + L"A collection of press sources from Arulco", + L"We are a neutral source of information. We collect different news articles from Arulco. We do not judge these sources - we merely publish them, so you can judge yourself. We post articles from various sources, among them", + + L"Conflict Summary", + L"Battle reports", + L"News", + L"About us", +}; + +STR16 szCampaignHistoryDetail[]= +{ + L"%s, %s %s %s in %s.", + + L"rebel forces", + L"the army", + + L"attacked", + L"ambushed", + L"airdropped", + + L"The attack came from %s.", + L"%s were reinforced from %s.", + L"The attack came from %s, %s were reinforced from %s.", + L"north", + L"east", + L"south", + L"west", + + L"Buildings in the sector were damaged. %s civilians were killed and %s wounded.", + L"During the attack, %s and %s called reinforcements.", + L"During the attack, %s called reinforcements.", + L"Eyewitnesses report the use of chemical weapons from both sides.", + L"Chemical weapons were used by %s.", + L"In a serious escalation of the conflict, both sides deployed tanks.", + L"%d tanks were used by %s, %d of them were destroyed in the fierce fighting.", + L"Both sides are said to have used snipers.", + L"Unverified reports indicate %s snipers were involved in the firefight." +}; + +STR16 szCampaignHistoryTimeString[]= +{ + L"Deep in the night", // 23 - 3 + L"At dawn", // 3 - 6 + L"Early in the morning", // 6 - 8 + L"In the morning hours", // 8 - 11 + L"At noon", // 11 - 14 + L"On the afternoon", // 14 - 18 + L"On the evening", // 18 - 21 + L"During the night", // 21 - 23 +}; + +STR16 szCampaignHistoryMoneyTypeString[]= +{ + L"Initial funding", + L"Mine income", + L"Trade", + L"Other sources", +}; + +STR16 szCampaignHistoryConsumptionTypeString[]= +{ + L"Ammunition", + L"Explosives", + L"Food", + L"Medical gear", + L"Item maintenance", +}; + +STR16 szCampaignHistoryResultString[]= +{ + L"In an extremely one-sided battle, the army force was wiped out without much resistance.", + + L"The rebels easily defeated the army, inflicting heavy losses.", + L"Without much effort, the rebels inflicted heavy losses upon the army and took several prisoners.", + + L"In a bloody fight, the rebels finally overcame the opposition. The army had severe losses.", + L"The rebels had losses but defeated the royalists. Unverified information says several soldiers might have been taken prisoner.", + + L"In a phyrric victory, the rebels defeated the royalists but had severe casualties of their own. Wether they will be able to hold this position against continued attacks is doubtful.", + + L"The army's superiority in numbers came into full play. The rebels never had a chance and had to either retreat or be killed or captured.", + L"Despite the high number of rebels in this sector, the army easily dispatched them.", + + L"The rebels were clearly unprepared against the army's superiority in numbers an equipment. They were easily defeated.", + L"Even though the rebels had more boots on the ground, the army was better equipped. The rebels clearly lost.", + + L"Fierce fighting saw significant losses on both sides, but in the end, the army's higher number of bodies decided the battle. The rebel force was destroyed. There might have been survivors, but we cannot verify this at this point.", + L"In an intense firefight, the superior training of the arulcan armed forces tipped the scales. The rebels had to retreat.", + + L"Neither side was willing to yield. While the army ultimately removed the rebel threat in the area, the staggering losses have resulted in the army unit continuing to exist in name only. But it is clear the rebels will soon be out of men and women if the army can keep on this rate of attrition.", +}; + +STR16 szCampaignHistoryImportanceString[]= +{ + L"Irrelevant", + L"Insignificant", + L"Notable", + L"Noteworthy", + L"Significant", + L"Interesting", + L"Important", + L"Very important", + L"Grave", + L"Major", + L"Momentous", +}; + +STR16 szCampaignHistoryWebpageString[]= +{ + L"Killed", + L"Wounded", + L"Prisoners", + L"Shots fired", + + L"Money earned", + L"Consumption", + L"Losses", + L"Participants", + + L"Promotions", + L"Summary", + L"Detail", + L"Previous", + + L"Next", + L"Incident", + L"Day", +}; + #endif //TAIWANESE