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