#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 INCIDENT_SAMSITE_SABOTAGED 0x08000000 //134217728 // SAM site controls were destroyed #define INCIDENT_SPYACTION_ENEMY 0x10000000 //268435456 // side used spies. Depending on the other actions, this report might not even show up, as nobody knows there WAS any action... #define INCIDENT_SPYACTION_PLAYERSIDE 0x20000000 //536870912 #define INCIDENT_SPYACTION_UNCOVERED 0x40000000 //1073741824 // a spy was uncovered //#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) #define INCIDENT_EVENT 0x0E00FF3F // any interesting event that might have happened // ---------------------------------------------------------------- // -------- 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 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); INT32 GetPositionOfIncident( UINT32 aIncidentId ); STR16 GetIncidentName( UINT32 aIncidentId ); UINT32 GetIdOfCurrentlyOngoingIncident(); #endif // __CAMPAIGNSTATS_H