]> git.jsancho.org Git - lugaru.git/blob - Source/User/Account.cpp
Empire: Restore Ash's black fur as intended by the author
[lugaru.git] / Source / User / Account.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
4
5 This file is part of Lugaru.
6
7 Lugaru is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 Lugaru is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "User/Account.hpp"
22
23 #include "MacCompatibility.hpp"
24 #include "Utils/binio.h"
25
26 #include <fstream>
27 #include <iostream>
28 #include <string.h>
29
30 using namespace std;
31
32 extern bool devtools;
33
34 vector<Account> Account::accounts;
35 int Account::i_active = -1;
36
37 Account::Account(const string& name)
38     : name(name)
39     , campaignProgress()
40 {
41     difficulty = 0;
42     progress = 0;
43     points = 0;
44     memset(highscore, 0, sizeof(highscore));
45     memset(fasttime, 0, sizeof(fasttime));
46     memset(unlocked, 0, sizeof(unlocked));
47
48     setCurrentCampaign("main");
49 }
50
51 Account::Account(FILE* tfile)
52     : Account("")
53 {
54     funpackf(tfile, "Bi", &difficulty);
55     funpackf(tfile, "Bi", &progress);
56     int nbCampaigns;
57     funpackf(tfile, "Bi", &nbCampaigns);
58
59     for (int k = 0; k < nbCampaigns; ++k) {
60         string campaignName = "";
61         int t;
62         char c;
63         funpackf(tfile, "Bi", &t);
64         for (int j = 0; j < t; j++) {
65             funpackf(tfile, "Bb", &c);
66             campaignName.append(1, c);
67         }
68         float fscore, fhighscore;
69         funpackf(tfile, "Bf", &(campaignProgress[campaignName].time));
70         funpackf(tfile, "Bf", &(fscore));
71         funpackf(tfile, "Bf", &(campaignProgress[campaignName].fasttime));
72         funpackf(tfile, "Bf", &(fhighscore));
73         campaignProgress[campaignName].score = fscore;
74         campaignProgress[campaignName].highscore = fhighscore;
75         int campaignchoicesmade, campaignchoice;
76         funpackf(tfile, "Bi", &campaignchoicesmade);
77         for (int j = 0; j < campaignchoicesmade; j++) {
78             funpackf(tfile, "Bi", &campaignchoice);
79             if (campaignchoice >= 10) { // what is that for?
80                 campaignchoice = 0;
81             }
82             campaignProgress[campaignName].choices.push_back(campaignchoice);
83         }
84     }
85
86     currentCampaign = "";
87     int t;
88     char c;
89     funpackf(tfile, "Bi", &t);
90     for (int i = 0; i < t; i++) {
91         funpackf(tfile, "Bb", &c);
92         currentCampaign.append(1, c);
93     }
94
95     funpackf(tfile, "Bf", &points);
96     for (int i = 0; i < 50; i++) {
97         float fscore;
98         funpackf(tfile, "Bf", &(fscore));
99         funpackf(tfile, "Bf", &(fasttime[i]));
100         highscore[i] = fscore;
101     }
102     for (int i = 0; i < 60; i++) {
103         funpackf(tfile, "Bb", &(unlocked[i]));
104     }
105     int temp;
106     char ctemp;
107     funpackf(tfile, "Bi", &temp);
108     for (int i = 0; i < temp; i++) {
109         funpackf(tfile, "Bb", &ctemp);
110         name.append(1, ctemp);
111     }
112     if (name.empty()) {
113         name = "Lugaru Player"; // no empty player name security.
114     }
115 }
116
117 void Account::save(FILE* tfile)
118 {
119     fpackf(tfile, "Bi", difficulty);
120     fpackf(tfile, "Bi", progress);
121     fpackf(tfile, "Bi", campaignProgress.size());
122
123     map<string, CampaignProgress>::const_iterator it;
124     for (it = campaignProgress.begin(); it != campaignProgress.end(); ++it) {
125         fpackf(tfile, "Bi", it->first.size());
126         for (unsigned j = 0; j < it->first.size(); j++) {
127             fpackf(tfile, "Bb", it->first[j]);
128         }
129         fpackf(tfile, "Bf", it->second.time);
130         fpackf(tfile, "Bf", float(it->second.score));
131         fpackf(tfile, "Bf", it->second.fasttime);
132         fpackf(tfile, "Bf", float(it->second.highscore));
133         fpackf(tfile, "Bi", it->second.choices.size());
134         for (unsigned j = 0; j < it->second.choices.size(); j++) {
135             fpackf(tfile, "Bi", it->second.choices[j]);
136         }
137     }
138
139     fpackf(tfile, "Bi", getCurrentCampaign().size());
140     for (unsigned j = 0; j < getCurrentCampaign().size(); j++) {
141         fpackf(tfile, "Bb", getCurrentCampaign()[j]);
142     }
143
144     fpackf(tfile, "Bf", points);
145     for (unsigned j = 0; j < 50; j++) {
146         fpackf(tfile, "Bf", float(highscore[j]));
147         fpackf(tfile, "Bf", fasttime[j]);
148     }
149     for (unsigned j = 0; j < 60; j++) {
150         fpackf(tfile, "Bb", unlocked[j]);
151     }
152     fpackf(tfile, "Bi", name.size());
153     for (unsigned j = 0; j < name.size(); j++) {
154         fpackf(tfile, "Bb", name[j]);
155     }
156 }
157
158 void Account::setCurrentCampaign(const string& name)
159 {
160     currentCampaign = name;
161 }
162
163 void Account::add(const string& name)
164 {
165     accounts.emplace_back(name);
166     i_active = accounts.size() - 1;
167 }
168
169 Account& Account::get(int i)
170 {
171     return accounts.at(i);
172 }
173
174 int Account::getNbAccounts()
175 {
176     return accounts.size();
177 }
178
179 bool Account::hasActive()
180 {
181     return (i_active >= 0);
182 }
183
184 Account& Account::active()
185 {
186     return accounts.at(i_active);
187 }
188
189 void Account::setActive(int i)
190 {
191     if ((i >= 0) && (i < int(accounts.size()))) {
192         i_active = i;
193     } else {
194         cerr << "Tried to set active account to " << i << " but there is not such account" << endl;
195         i_active = -1;
196     }
197 }
198
199 void Account::destroyActive()
200 {
201     if ((i_active >= 0) && (i_active < int(accounts.size()))) {
202         accounts.erase(accounts.begin() + i_active);
203         i_active = -1;
204     } else {
205         cerr << "Tried to destroy active account " << i_active << " but there is not such account" << endl;
206         i_active = -1;
207     }
208 }
209
210 int Account::getDifficulty()
211 {
212     return difficulty;
213 }
214
215 void Account::endGame()
216 {
217     campaignProgress[currentCampaign].choices.clear();
218     campaignProgress[currentCampaign].score = 0;
219     campaignProgress[currentCampaign].time = 0;
220 }
221
222 void Account::winCampaignLevel(int choice, int score, float time)
223 {
224     campaignProgress[currentCampaign].choices.push_back(choice);
225     setCampaignScore(campaignProgress[currentCampaign].score + score);
226     campaignProgress[currentCampaign].time = time;
227 }
228
229 void Account::winLevel(int level, int score, float time)
230 {
231     if (!devtools) {
232         if (score > highscore[level]) {
233             highscore[level] = score;
234         }
235         if (time < fasttime[level] || fasttime[level] == 0) {
236             fasttime[level] = time;
237         }
238     }
239     if (progress < level + 1) {
240         progress = level + 1;
241     }
242 }
243
244 void Account::loadFile(string filename)
245 {
246     FILE* tfile;
247     int numaccounts;
248     int iactive;
249     errno = 0;
250
251     tfile = fopen(filename.c_str(), "rb");
252
253     if (tfile) {
254         funpackf(tfile, "Bi", &numaccounts);
255         funpackf(tfile, "Bi", &iactive);
256         printf("Loading %d accounts\n", numaccounts);
257         for (int i = 0; i < numaccounts; i++) {
258             printf("Loading account %d/%d\n", i, numaccounts);
259             accounts.emplace_back(tfile);
260         }
261
262         fclose(tfile);
263         setActive(iactive);
264     } else {
265         perror(("Couldn't load users from " + filename).c_str());
266         i_active = -1;
267     }
268 }
269
270 void Account::saveFile(string filename)
271 {
272     FILE* tfile;
273     errno = 0;
274
275     tfile = fopen(filename.c_str(), "wb");
276     if (tfile) {
277         fpackf(tfile, "Bi", getNbAccounts());
278         fpackf(tfile, "Bi", i_active);
279
280         for (int i = 0; i < getNbAccounts(); i++) {
281             printf("writing account %d/%d (%s)\n", i + 1, getNbAccounts(), accounts[i].getName().c_str());
282             accounts[i].save(tfile);
283         }
284
285         fclose(tfile);
286     } else {
287         perror(("Couldn't save users in " + filename).c_str());
288     }
289 }