]> git.jsancho.org Git - lugaru.git/blob - Source/User/Account.cpp
82072fc1aa764580a1ad1000e579022a34542dd3
[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         funpackf(tfile, "Bf", &(campaignProgress[campaignName].time));
69         funpackf(tfile, "Bf", &(campaignProgress[campaignName].score));
70         funpackf(tfile, "Bf", &(campaignProgress[campaignName].fasttime));
71         funpackf(tfile, "Bf", &(campaignProgress[campaignName].highscore));
72         int campaignchoicesmade, campaignchoice;
73         funpackf(tfile, "Bi", &campaignchoicesmade);
74         for (int j = 0; j < campaignchoicesmade; j++) {
75             funpackf(tfile, "Bi", &campaignchoice);
76             if (campaignchoice >= 10) { // what is that for?
77                 campaignchoice = 0;
78             }
79             campaignProgress[campaignName].choices.push_back(campaignchoice);
80         }
81     }
82
83     currentCampaign = "";
84     int t;
85     char c;
86     funpackf(tfile, "Bi", &t);
87     for (int i = 0; i < t; i++) {
88         funpackf(tfile, "Bb", &c);
89         currentCampaign.append(1, c);
90     }
91
92     funpackf(tfile, "Bf", &points);
93     for (int i = 0; i < 50; i++) {
94         funpackf(tfile, "Bf", &(highscore[i]));
95         funpackf(tfile, "Bf", &(fasttime[i]));
96     }
97     for (int i = 0; i < 60; i++) {
98         funpackf(tfile, "Bb", &(unlocked[i]));
99     }
100     int temp;
101     char ctemp;
102     funpackf(tfile, "Bi", &temp);
103     for (int i = 0; i < temp; i++) {
104         funpackf(tfile, "Bb", &ctemp);
105         name.append(1, ctemp);
106     }
107     if (name.empty()) {
108         name = "Lugaru Player"; // no empty player name security.
109     }
110 }
111
112 void Account::save(FILE* tfile)
113 {
114     fpackf(tfile, "Bi", difficulty);
115     fpackf(tfile, "Bi", progress);
116     fpackf(tfile, "Bi", campaignProgress.size());
117
118     map<string, CampaignProgress>::const_iterator it;
119     for (it = campaignProgress.begin(); it != campaignProgress.end(); ++it) {
120         fpackf(tfile, "Bi", it->first.size());
121         for (unsigned j = 0; j < it->first.size(); j++) {
122             fpackf(tfile, "Bb", it->first[j]);
123         }
124         fpackf(tfile, "Bf", it->second.time);
125         fpackf(tfile, "Bf", it->second.score);
126         fpackf(tfile, "Bf", it->second.fasttime);
127         fpackf(tfile, "Bf", it->second.highscore);
128         fpackf(tfile, "Bi", it->second.choices.size());
129         for (unsigned j = 0; j < it->second.choices.size(); j++) {
130             fpackf(tfile, "Bi", it->second.choices[j]);
131         }
132     }
133
134     fpackf(tfile, "Bi", getCurrentCampaign().size());
135     for (unsigned j = 0; j < getCurrentCampaign().size(); j++) {
136         fpackf(tfile, "Bb", getCurrentCampaign()[j]);
137     }
138
139     fpackf(tfile, "Bf", points);
140     for (unsigned j = 0; j < 50; j++) {
141         fpackf(tfile, "Bf", highscore[j]);
142         fpackf(tfile, "Bf", fasttime[j]);
143     }
144     for (unsigned j = 0; j < 60; j++) {
145         fpackf(tfile, "Bb", unlocked[j]);
146     }
147     fpackf(tfile, "Bi", name.size());
148     for (unsigned j = 0; j < name.size(); j++) {
149         fpackf(tfile, "Bb", name[j]);
150     }
151 }
152
153 void Account::setCurrentCampaign(const string& name)
154 {
155     currentCampaign = name;
156 }
157
158 void Account::add(const string& name)
159 {
160     accounts.emplace_back(name);
161     i_active = accounts.size() - 1;
162 }
163
164 Account& Account::get(int i)
165 {
166     return accounts.at(i);
167 }
168
169 int Account::getNbAccounts()
170 {
171     return accounts.size();
172 }
173
174 bool Account::hasActive()
175 {
176     return (i_active >= 0);
177 }
178
179 Account& Account::active()
180 {
181     return accounts.at(i_active);
182 }
183
184 void Account::setActive(int i)
185 {
186     if ((i >= 0) && (i < int(accounts.size()))) {
187         i_active = i;
188     } else {
189         cerr << "Tried to set active account to " << i << " but there is not such account" << endl;
190         i_active = -1;
191     }
192 }
193
194 void Account::destroyActive()
195 {
196     if ((i_active >= 0) && (i_active < int(accounts.size()))) {
197         accounts.erase(accounts.begin() + i_active);
198         i_active = -1;
199     } else {
200         cerr << "Tried to destroy active account " << i_active << " but there is not such account" << endl;
201         i_active = -1;
202     }
203 }
204
205 int Account::getDifficulty()
206 {
207     return difficulty;
208 }
209
210 void Account::endGame()
211 {
212     campaignProgress[currentCampaign].choices.clear();
213     campaignProgress[currentCampaign].score = 0;
214     campaignProgress[currentCampaign].time = 0;
215 }
216
217 void Account::winCampaignLevel(int choice, float score, float time)
218 {
219     campaignProgress[currentCampaign].choices.push_back(choice);
220     setCampaignScore(campaignProgress[currentCampaign].score + score);
221     campaignProgress[currentCampaign].time = time;
222 }
223
224 void Account::winLevel(int level, float score, float time)
225 {
226     if (!devtools) {
227         if (score > highscore[level]) {
228             highscore[level] = score;
229         }
230         if (time < fasttime[level] || fasttime[level] == 0) {
231             fasttime[level] = time;
232         }
233     }
234     if (progress < level + 1) {
235         progress = level + 1;
236     }
237 }
238
239 void Account::loadFile(string filename)
240 {
241     FILE* tfile;
242     int numaccounts;
243     int iactive;
244     errno = 0;
245
246     tfile = fopen(filename.c_str(), "rb");
247
248     if (tfile) {
249         funpackf(tfile, "Bi", &numaccounts);
250         funpackf(tfile, "Bi", &iactive);
251         printf("Loading %d accounts\n", numaccounts);
252         for (int i = 0; i < numaccounts; i++) {
253             printf("Loading account %d/%d\n", i, numaccounts);
254             accounts.emplace_back(tfile);
255         }
256
257         fclose(tfile);
258         setActive(iactive);
259     } else {
260         perror(("Couldn't load users from " + filename).c_str());
261         i_active = -1;
262     }
263 }
264
265 void Account::saveFile(string filename)
266 {
267     FILE* tfile;
268     errno = 0;
269
270     tfile = fopen(filename.c_str(), "wb");
271     if (tfile) {
272         fpackf(tfile, "Bi", getNbAccounts());
273         fpackf(tfile, "Bi", i_active);
274
275         for (int i = 0; i < getNbAccounts(); i++) {
276             printf("writing account %d/%d (%s)\n", i + 1, getNbAccounts(), accounts[i].getName().c_str());
277             accounts[i].save(tfile);
278         }
279
280         fclose(tfile);
281     } else {
282         perror(("Couldn't save users in " + filename).c_str());
283     }
284 }