New Feature: Campaign History collects combat data and displays battle reports on the website.

requires GameDir >= r1901.

For more info, see http://www.bears-pit.com/board/ubbthreads.php/topics/329205.html#Post329205

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6705 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2013-12-22 23:22:45 +00:00
parent b3df6f55b5
commit f4dcc15ffa
57 changed files with 5074 additions and 220 deletions
+6
View File
@@ -0,0 +1,6 @@
#ifndef __CAMPAIGNHISTORY_DATA_H
#define __CAMPAIGNHISTORY_DATA_H
#endif // __CAMPAIGNHISTORY_DATA_H
+268
View File
@@ -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)
{
}
}
+46
View File
@@ -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
File diff suppressed because it is too large Load Diff
+30
View File
@@ -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
+715
View File
@@ -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<Incident_Stats>::iterator itend = mIncidentVector.end();
for (std::vector<Incident_Stats>::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;
}
+328
View File
@@ -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 nötig?
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<Incident_Stats> 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
+32
View File
@@ -417,7 +417,23 @@
<File
RelativePath=".\BrokenLink.h"
>
</File>
<File
RelativePath=".\CampaignHistoryData.h"
>
</File>
<File
RelativePath=".\CampaignHistoryMain.h"
>
</File>
<File
RelativePath=".\CampaignHistory_Summary.h"
>
</File>
<File
RelativePath=".\CampaignStats.h"
>
</File>
<File
RelativePath=".\CharProfile.h"
>
@@ -728,6 +744,18 @@
RelativePath=".\BrokenLink.cpp"
>
</File>
<File
RelativePath=".\CampaignHistoryMain.cpp"
>
</File>
<File
RelativePath=".\CampaignHistory_Summary.cpp"
>
</File>
<File
RelativePath=".\CampaignStats.cpp"
>
</File>
<File
RelativePath=".\CharProfile.cpp"
>
@@ -940,6 +968,10 @@
RelativePath=".\XML_BriefingRoom.cpp"
>
</File>
<File
RelativePath=".\XML_CampaignStatsEvents.cpp"
>
</File>
<File
RelativePath=".\XML_ConditionsForMercAvailability.cpp"
>
+32
View File
@@ -418,6 +418,22 @@
RelativePath="BrokenLink.h"
>
</File>
<File
RelativePath="CampaignHistoryData.h"
>
</File>
<File
RelativePath="CampaignHistoryMain.h"
>
</File>
<File
RelativePath="CampaignHistory_Summary.h"
>
</File>
<File
RelativePath="CampaignStats.h"
>
</File>
<File
RelativePath="CharProfile.h"
>
@@ -718,6 +734,18 @@
RelativePath="BrokenLink.cpp"
>
</File>
<File
RelativePath="CampaignHistoryMain.cpp"
>
</File>
<File
RelativePath="CampaignHistory_Summary.cpp"
>
</File>
<File
RelativePath="CampaignStats.cpp"
>
</File>
<File
RelativePath="CharProfile.cpp"
>
@@ -926,6 +954,10 @@
RelativePath=".\XML_BriefingRoom.cpp"
>
</File>
<File
RelativePath=".\XML_CampaignStatsEvents.cpp"
>
</File>
<File
RelativePath=".\XML_ConditionsForMercAvailability.cpp"
>
+8
View File
@@ -43,6 +43,10 @@
<ClInclude Include="BriefingRoomM.h" />
<ClInclude Include="BriefingRoom_Data.h" />
<ClInclude Include="BrokenLink.h" />
<ClInclude Include="CampaignHistoryData.h" />
<ClInclude Include="CampaignHistoryMain.h" />
<ClInclude Include="CampaignHistory_Summary.h" />
<ClInclude Include="CampaignStats.h" />
<ClInclude Include="CharProfile.h" />
<ClInclude Include="DropDown.h" />
<ClInclude Include="email.h" />
@@ -121,6 +125,9 @@
<ClCompile Include="BriefingRoomM.cpp" />
<ClCompile Include="BriefingRoom_Data.cpp" />
<ClCompile Include="BrokenLink.cpp" />
<ClCompile Include="CampaignHistoryMain.cpp" />
<ClCompile Include="CampaignHistory_Summary.cpp" />
<ClCompile Include="CampaignStats.cpp" />
<ClCompile Include="CharProfile.cpp" />
<ClCompile Include="DropDown.cpp" />
<ClCompile Include="email.cpp" />
@@ -175,6 +182,7 @@
<ClCompile Include="Store Inventory.cpp" />
<ClCompile Include="XML_AIMAvailability.cpp" />
<ClCompile Include="XML_BriefingRoom.cpp" />
<ClCompile Include="XML_CampaignStatsEvents.cpp" />
<ClCompile Include="XML_ConditionsForMercAvailability.cpp" />
<ClCompile Include="XML_DeliveryMethods.cpp" />
<ClCompile Include="XML_Email.cpp" />
+24
View File
@@ -237,6 +237,18 @@
<ClInclude Include="BriefingRoom_Data.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CampaignHistoryData.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CampaignHistoryMain.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CampaignHistory_Summary.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CampaignStats.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="aim.cpp">
@@ -485,5 +497,17 @@
<ClCompile Include="XML_BriefingRoom.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CampaignHistoryMain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CampaignHistory_Summary.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CampaignStats.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XML_CampaignStatsEvents.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
+243
View File
@@ -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,"<CAMPAIGNSTATSEVENTS>\r\n");
for(cnt = 0; cnt < NUM_CAMPAIGNSTATSEVENTS; ++cnt)
{
FilePrintf(hFile,"\t<EVENT>\r\n");
FilePrintf(hFile,"\t\t<uiIndex>%d</uiIndex>\r\n", cnt);
FilePrintf(hFile,"\t</EVENT>\r\n");
}
FilePrintf(hFile,"</CAMPAIGNSTATSEVENTS>\r\n");
}
FileClose( hFile );
return( TRUE );
}
+10 -10
View File
@@ -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
}
+2 -2
View File
@@ -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,
};
+13 -2
View File
@@ -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
+104 -3
View File
@@ -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
+8 -2
View File
@@ -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
};