File: PlayerStats.h

package info (click to toggle)
7kaa 2.15.7%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 134,980 kB
  • sloc: cpp: 137,722; ansic: 3,599; asm: 3,523; perl: 1,665; makefile: 1,185; sh: 185; pascal: 27
file content (103 lines) | stat: -rw-r--r-- 3,193 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
* Seven Kingdoms: Ancient Adversaries
*
* Copyright 2019 Steven Lavoie
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*/

//Filename    : PlayerStats.h
//Description : Handles file IO for player statistics information

#ifndef __PLAYERSTATS_H
#define __PLAYERSTATS_H

#include <OGAME.h>
#ifndef __ODYNARR_H
#include <ODYNARR.h>
#endif


namespace nsPlayerStats {

enum PlayStatus : uint32_t { UNPLAYED = 0, PLAYED = 1, COMPLETED = 2 };
enum RecordType : uint32_t { ScenarioPlayStatus = 0 };

namespace detail {

char const * const scn_dat_file = "PLAYSTAT.DAT";
enum { MAX_FILE_PATH = 260 }; //HACK: This is repeated all over. Should be global constant.

//
// These structures are written as-is to PLAYSTAT.DAT and cannot be changed
// without breaking the format. To prevent breaking changes, just add a new
// record type that includes whatever additional data.
//

//
// Dictates the reading/writing of the file. Every type of statistic
// must be preceded by a RecordHeader. This struct is written as-is
// to/from an array and file so ensure any changes are 4-byte aligned.
//
struct RecordHeader {
	RecordType rec_type;
	uint32_t rec_count;
	uint32_t rec_size;
};
static_assert(sizeof(RecordHeader) == 12, "Changing RecordHeader is a breaking change for PLAYSTAT.DAT");

//
// Tracks whether a scenario has been played/completed. This
// struct is written as-is to/from an array and file so ensure
// any changes are 4-byte aligned.
//
struct ScenStat {
	//
	// The SAV format actually has MAX_FILE_PATH + 1, which was stupid. Since
	// this field is not actively used and even legacy scenario files only contain
	// an 8.3 filename, we'll dispense with the extra byte. Windows includes /0 in
	// its MAX_PATH's 260 bytes anyway.
	//
	char game_name[MAX_FILE_PATH];
	PlayStatus status;
};

static_assert(sizeof(ScenStat::game_name) == MAX_FILE_PATH, "Changing ScenStat is a breaking change for PLAYSTAT.DAT");
static_assert(sizeof(ScenStat) == 264, "Changing ScenStat is a breaking change for PLAYSTAT.DAT");

}

class PlayerStats
{
private:
	detail::ScenStat * scn_stat_arr;
	size_t scn_stat_arr_len;

	bool write_player_stats();

public:
	PlayStatus get_scenario_play_status(char const * game_name);
	bool set_scenario_play_status(char const * game_name, PlayStatus status);
	// If force_reload==true, the stats will be reloaded from the file or,
	// if the file is deleted, the UI will be updated to reflect that
	bool load_player_stats(bool force_reload = false);

	PlayerStats();
	~PlayerStats();
};
} // nsPlayerStats

extern nsPlayerStats::PlayerStats playerStats; // in AM.cpp
#endif