Files
source/Laptop/CampaignStats.h
Marco Antonio J. Costaandmajcosta 86ad401186 add newline at end of file where it's lacking
.editorconfig already enforces it but it's getting changed piecemeal in
every commit. just get it done with.

the script:
```

find . -type f -not -path "./.git/*" -not -path "./.vs/*" | while read -r file; do
	isFile=$(file -0 "$file" | cut -d $'\0' -f2)
	case "$isFile" in
		(*text*)
			echo "$file is text"
			if [[ $(tail -c 1 "$file" | wc -l) -ne 1 ]]; then
				echo "" >> "$file"
			fi
			;;
		(*)
			echo "file isn't text"
			;;
	esac
done
```
2024-12-14 19:05:48 -03:00

336 lines
12 KiB
C++

#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<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);
INT32 GetPositionOfIncident( UINT32 aIncidentId );
STR16 GetIncidentName( UINT32 aIncidentId );
UINT32 GetIdOfCurrentlyOngoingIncident();
#endif // __CAMPAIGNSTATS_H