1 /*
2 * Hedgewars, a free turn based strategy game
3 * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <QFile>
20 #include <QTextStream>
21 #include <QStringList>
22 #include <QLineEdit>
23 #include <QCryptographicHash>
24 #include <QSettings>
25 #include <QStandardItemModel>
26 #include <QDebug>
27
28 #include "team.h"
29 #include "hwform.h"
30 #include "DataManager.h"
31 #include "gameuiconfig.h"
32
HWTeam(const QString & teamname)33 HWTeam::HWTeam(const QString & teamname) :
34 QObject(0)
35 , m_difficulty(0)
36 , m_numHedgehogs(4)
37 , m_isNetTeam(false)
38 , m_isMissionTeam(false)
39 {
40 m_name = teamname;
41 OldTeamName = m_name;
42 for (int i = 0; i < HEDGEHOGS_PER_TEAM; i++)
43 {
44 m_hedgehogs.append(HWHog());
45 m_hedgehogs[i].Name = (QLineEdit::tr("Hedgehog %1").arg(i+1));
46 m_hedgehogs[i].Hat = "NoHat";
47 }
48 m_grave = "Statue";
49 m_fort = "Plane";
50 m_voicepack = "Default";
51 m_flag = "hedgewars";
52 for(int i = 0; i < BINDS_NUMBER; i++)
53 {
54 m_binds.append(BindAction());
55 m_binds[i].action = cbinds[i].action;
56 m_binds[i].strbind = QString();
57 }
58 m_color = 0;
59 }
60
HWTeam(const QStringList & strLst)61 HWTeam::HWTeam(const QStringList& strLst) :
62 QObject(0)
63 , m_numHedgehogs(4)
64 , m_isNetTeam(true)
65 , m_isMissionTeam(false)
66 {
67 // net teams are configured from QStringList
68 if(strLst.size() != 23) throw HWTeamConstructException();
69 m_name = strLst[0];
70 m_grave = strLst[1];
71 m_fort = strLst[2];
72 m_voicepack = strLst[3];
73 m_flag = strLst[4];
74 m_owner = strLst[5];
75 m_difficulty = strLst[6].toUInt();
76 for(int i = 0; i < HEDGEHOGS_PER_TEAM; i++)
77 {
78 m_hedgehogs.append(HWHog());
79 m_hedgehogs[i].Name=strLst[i * 2 + 7];
80 m_hedgehogs[i].Hat=strLst[i * 2 + 8];
81 // Somehow claymore managed an empty hat. Until we figure out how, this should avoid a repeat
82 // Checking net teams is probably pointless, but can't hurt.
83 if (m_hedgehogs[i].Hat.isEmpty()) m_hedgehogs[i].Hat = "NoHat";
84 }
85 m_color = 0;
86 }
87
HWTeam()88 HWTeam::HWTeam() :
89 QObject(0)
90 , m_difficulty(0)
91 , m_numHedgehogs(4)
92 , m_isNetTeam(false)
93 , m_isMissionTeam(false)
94 {
95 m_name = QString("Team");
96 for (int i = 0; i < HEDGEHOGS_PER_TEAM; i++)
97 {
98 m_hedgehogs.append(HWHog());
99 m_hedgehogs[i].Name.sprintf("hedgehog %d", i);
100 m_hedgehogs[i].Hat = "NoHat";
101 }
102
103 m_grave = QString("Simple"); // default
104 m_fort = QString("Island"); // default
105 m_voicepack = "Default";
106 m_flag = "hedgewars";
107
108 for(int i = 0; i < BINDS_NUMBER; i++)
109 {
110 m_binds.append(BindAction());
111 m_binds[i].action = cbinds[i].action;
112 m_binds[i].strbind = QString();
113 }
114 m_color = 0;
115 }
116
HWTeam(const HWTeam & other)117 HWTeam::HWTeam(const HWTeam & other) :
118 QObject(0)
119 , OldTeamName(other.OldTeamName)
120 , m_name(other.m_name)
121 , m_grave(other.m_grave)
122 , m_fort(other.m_fort)
123 , m_flag(other.m_flag)
124 , m_voicepack(other.m_voicepack)
125 , m_hedgehogs(other.m_hedgehogs)
126 , m_difficulty(other.m_difficulty)
127 , m_binds(other.m_binds)
128 , m_numHedgehogs(other.m_numHedgehogs)
129 , m_color(other.m_color)
130 , m_isNetTeam(other.m_isNetTeam)
131 , m_isMissionTeam(other.m_isMissionTeam)
132 , m_owner(other.m_owner)
133 // , AchievementProgress(other.AchievementProgress)
134 {
135
136 }
137
operator =(const HWTeam & other)138 HWTeam & HWTeam::operator = (const HWTeam & other)
139 {
140 if(this != &other)
141 {
142 OldTeamName = other.OldTeamName;
143 m_name = other.m_name;
144 m_grave = other.m_grave;
145 m_fort = other.m_fort;
146 m_flag = other.m_flag;
147 m_voicepack = other.m_voicepack;
148 m_hedgehogs = other.m_hedgehogs;
149 m_difficulty = other.m_difficulty;
150 m_binds = other.m_binds;
151 m_numHedgehogs = other.m_numHedgehogs;
152 m_color = other.m_color;
153 m_isNetTeam = other.m_isNetTeam;
154 m_owner = other.m_owner;
155 m_color = other.m_color;
156 m_isMissionTeam = other.m_isMissionTeam;
157 }
158
159 return *this;
160 }
161
loadFromFile()162 bool HWTeam::loadFromFile()
163 {
164 QSettings teamfile(QString(cfgdir->absolutePath() + "/Teams/%1.hwt").arg(DataManager::safeFileName(m_name)), QSettings::IniFormat, 0);
165 teamfile.setIniCodec("UTF-8");
166 m_name = teamfile.value("Team/Name", m_name).toString();
167 m_grave = teamfile.value("Team/Grave", "Statue").toString();
168 m_fort = teamfile.value("Team/Fort", "Plane").toString();
169 m_voicepack = teamfile.value("Team/Voicepack", "Default").toString();
170 m_flag = teamfile.value("Team/Flag", "hedgewars").toString();
171 m_difficulty = teamfile.value("Team/Difficulty", 0).toInt();
172 for(int i = 0; i < HEDGEHOGS_PER_TEAM; i++)
173 {
174 QString hh = QString("Hedgehog%1/").arg(i);
175 m_hedgehogs[i].Name = teamfile.value(hh + "Name", QString("Hedgehog %1").arg(i+1)).toString();
176 m_hedgehogs[i].Hat = teamfile.value(hh + "Hat", "NoHat").toString();
177 }
178 for(int i = 0; i < BINDS_NUMBER; i++)
179 m_binds[i].strbind = teamfile.value(QString("Binds/%1").arg(m_binds[i].action), QString()).toString();
180 for(int i = 0; i < MAX_ACHIEVEMENTS; i++)
181 if(achievements[i][0][0])
182 AchievementProgress[i] = teamfile.value(QString("Achievements/%1").arg(achievements[i][0]), 0).toUInt();
183 else
184 break;
185 return true;
186 }
187
fileExists()188 bool HWTeam::fileExists()
189 {
190 QFile f(QString(cfgdir->absolutePath() + "/Teams/%1.hwt").arg(DataManager::safeFileName(m_name)));
191 return f.exists();
192 }
193
194 // Returns true if the team name has been changed but a file with the same team name already exists.
195 // So if this team would be saved, another team file would be overwritten, which is generally not
196 // desired.
wouldOverwriteOtherFile()197 bool HWTeam::wouldOverwriteOtherFile()
198 {
199 return (m_name != OldTeamName) && fileExists();
200 }
201
deleteFile()202 bool HWTeam::deleteFile()
203 {
204 if(m_isNetTeam)
205 return false;
206 QFile cfgfile(QString(cfgdir->absolutePath() + "/Teams/%1.hwt").arg(DataManager::safeFileName(m_name)));
207 cfgfile.remove();
208 return true;
209 }
210
saveToFile()211 bool HWTeam::saveToFile()
212 {
213 if (OldTeamName != m_name)
214 {
215 QFile cfgfile(QString(cfgdir->absolutePath() + "/Teams/%1.hwt").arg(DataManager::safeFileName(OldTeamName)));
216 cfgfile.remove();
217 OldTeamName = m_name;
218 }
219
220 QString fileName = QString(cfgdir->absolutePath() + "/Teams/%1.hwt").arg(DataManager::safeFileName(m_name));
221 DataManager::ensureFileExists(fileName);
222 QSettings teamfile(fileName, QSettings::IniFormat, 0);
223 teamfile.setIniCodec("UTF-8");
224 teamfile.setValue("Team/Name", m_name);
225 teamfile.setValue("Team/Grave", m_grave);
226 teamfile.setValue("Team/Fort", m_fort);
227 teamfile.setValue("Team/Voicepack", m_voicepack);
228 teamfile.setValue("Team/Flag", m_flag);
229 teamfile.setValue("Team/Difficulty", m_difficulty);
230
231 for(int i = 0; i < HEDGEHOGS_PER_TEAM; i++)
232 {
233 QString hh = QString("Hedgehog%1/").arg(i);
234 teamfile.setValue(hh + "Name", m_hedgehogs[i].Name);
235 teamfile.setValue(hh + "Hat", m_hedgehogs[i].Hat);
236 }
237 for(int i = 0; i < BINDS_NUMBER; i++)
238 {
239 if(QString(m_binds[i].action) != QString("!MULTI"))
240 teamfile.setValue(QString("Binds/%1").arg(m_binds[i].action), m_binds[i].strbind);
241 }
242 for(int i = 0; i < MAX_ACHIEVEMENTS; i++)
243 if(achievements[i][0][0])
244 teamfile.setValue(QString("Achievements/%1").arg(achievements[i][0]), AchievementProgress[i]);
245 else
246 break;
247
248 return true;
249 }
250
teamGameConfig(quint32 InitHealth) const251 QStringList HWTeam::teamGameConfig(quint32 InitHealth) const
252 {
253 QStringList sl;
254 QString cmdAddHog = "eaddhh";
255
256 if (m_isNetTeam)
257 {
258 sl.push_back(QString("eaddteam %3 %1 %2").arg(qcolor().rgb() & 0xffffff).arg(m_name).arg(QString(QCryptographicHash::hash(m_owner.toUtf8(), QCryptographicHash::Md5).toHex())));
259 sl.push_back("erdriven");
260 }
261 else
262 {
263 if (m_isMissionTeam)
264 {
265 sl.push_back(QString("esetmissteam %3 %1 %2").arg(qcolor().rgb() & 0xffffff).arg(m_name).arg(playerHash));
266 cmdAddHog = "eaddmisshh";
267 }
268 else
269 {
270 sl.push_back(QString("eaddteam %3 %1 %2").arg(qcolor().rgb() & 0xffffff).arg(m_name).arg(playerHash));
271 }
272 }
273
274 sl.push_back(QString("egrave " + m_grave));
275 sl.push_back(QString("efort " + m_fort));
276 sl.push_back(QString("evoicepack " + m_voicepack));
277 sl.push_back(QString("eflag " + m_flag));
278
279 if(!m_owner.isEmpty())
280 sl.push_back(QString("eowner ") + m_owner);
281
282 for (int t = 0; t < m_numHedgehogs; t++)
283 {
284 sl.push_back(QString(cmdAddHog + " %1 %2 %3")
285 .arg(QString::number(m_difficulty),
286 QString::number(InitHealth),
287 m_hedgehogs[t].Name));
288 sl.push_back(QString("ehat %1")
289 .arg(m_hedgehogs[t].Hat));
290 }
291 return sl;
292 }
293
294
setNetTeam(bool isNetTeam)295 void HWTeam::setNetTeam(bool isNetTeam)
296 {
297 m_isNetTeam = isNetTeam;
298 }
299
isNetTeam() const300 bool HWTeam::isNetTeam() const
301 {
302 return m_isNetTeam;
303 }
304
setMissionTeam(bool isMissionTeam)305 void HWTeam::setMissionTeam(bool isMissionTeam)
306 {
307 m_isMissionTeam = isMissionTeam;
308 }
309
isMissionTeam() const310 bool HWTeam::isMissionTeam() const
311 {
312 return m_isMissionTeam;
313 }
314
operator ==(const HWTeam & t1) const315 bool HWTeam::operator==(const HWTeam& t1) const
316 {
317 return m_name==t1.m_name;
318 }
319
operator <(const HWTeam & t1) const320 bool HWTeam::operator<(const HWTeam& t1) const
321 {
322 return m_name<t1.m_name; // if names are equal - test if it is net team
323 }
324
325
326 //// Methods for member inspection+modification ////
327
328
329 // name
name() const330 QString HWTeam::name() const
331 {
332 return m_name;
333 }
setName(const QString & name)334 void HWTeam::setName(const QString & name)
335 {
336 m_name = name;
337 }
338
339 // single hedgehog
hedgehog(unsigned int idx) const340 const HWHog & HWTeam::hedgehog(unsigned int idx) const
341 {
342 return m_hedgehogs[idx];
343 }
setHedgehog(unsigned int idx,HWHog hh)344 void HWTeam::setHedgehog(unsigned int idx, HWHog hh)
345 {
346 m_hedgehogs[idx] = hh;
347 }
348
349 // owner
owner() const350 QString HWTeam::owner() const
351 {
352 return m_owner;
353 }
354
setOwner(const QString & owner)355 void HWTeam::setOwner(const QString & owner)
356 {
357 m_owner = owner;
358 }
359
360
361 // difficulty
difficulty() const362 unsigned int HWTeam::difficulty() const
363 {
364 return m_difficulty;
365 }
setDifficulty(unsigned int level)366 void HWTeam::setDifficulty(unsigned int level)
367 {
368 m_difficulty = level;
369 }
370
371 // color
color() const372 int HWTeam::color() const
373 {
374 return m_color;
375 }
376
qcolor() const377 QColor HWTeam::qcolor() const
378 {
379 return DataManager::instance().colorsModel()->item(m_color)->data().value<QColor>();
380 }
381
setColor(int color)382 void HWTeam::setColor(int color)
383 {
384 m_color = color % DataManager::instance().colorsModel()->rowCount();
385 }
386
387
388 // binds
keyBind(unsigned int idx) const389 QString HWTeam::keyBind(unsigned int idx) const
390 {
391 return m_binds[idx].strbind;
392 }
bindKey(unsigned int idx,const QString & key)393 void HWTeam::bindKey(unsigned int idx, const QString & key)
394 {
395 m_binds[idx].strbind = key;
396 }
397
398 // flag
setFlag(const QString & flag)399 void HWTeam::setFlag(const QString & flag)
400 {
401 m_flag = flag;
402 }
flag() const403 QString HWTeam::flag() const
404 {
405 return m_flag;
406 }
407
408 // fort
setFort(const QString & fort)409 void HWTeam::setFort(const QString & fort)
410 {
411 m_fort = fort;
412 }
fort() const413 QString HWTeam::fort() const
414 {
415 return m_fort;
416 }
417
418 // grave
setGrave(const QString & grave)419 void HWTeam::setGrave(const QString & grave)
420 {
421 m_grave = grave;
422 }
grave() const423 QString HWTeam::grave() const
424 {
425 return m_grave;
426 }
427
428 // voicepack - getter/setter
setVoicepack(const QString & voicepack)429 void HWTeam::setVoicepack(const QString & voicepack)
430 {
431 m_voicepack = voicepack;
432 }
voicepack() const433 QString HWTeam::voicepack() const
434 {
435 return m_voicepack;
436 }
437
438 // amount of hedgehogs
numHedgehogs() const439 unsigned char HWTeam::numHedgehogs() const
440 {
441 return m_numHedgehogs;
442 }
setNumHedgehogs(unsigned char num)443 void HWTeam::setNumHedgehogs(unsigned char num)
444 {
445 m_numHedgehogs = num;
446 }
447
448