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 "campaign.h"
20 #include "hwconsts.h"
21 #include "DataManager.h"
22 #include <QSettings>
23 #include <QObject>
24 #include <QLocale>
25
getCampTeamFile(QString & campaignName,QString & teamName)26 QSettings* getCampTeamFile(QString & campaignName, QString & teamName)
27 {
28 QSettings* teamfile = new QSettings(cfgdir->absolutePath() + "/Teams/" + teamName + ".hwt", QSettings::IniFormat, 0);
29 teamfile->setIniCodec("UTF-8");
30 // if entry not found check if there is written without _
31 // if then is found rename it to use _
32 QString spaceCampName = campaignName;
33 spaceCampName = spaceCampName.replace(QString("_"),QString(" "));
34 if (!teamfile->childGroups().contains("Campaign " + campaignName) &&
35 teamfile->childGroups().contains("Campaign " + spaceCampName)){
36 teamfile->beginGroup("Campaign " + spaceCampName);
37 QStringList keys = teamfile->childKeys();
38 teamfile->endGroup();
39 for (int i=0;i<keys.size();i++) {
40 QVariant value = teamfile->value("Campaign " + spaceCampName + "/" + keys[i]);
41 teamfile->setValue("Campaign " + campaignName + "/" + keys[i], value);
42 }
43 teamfile->remove("Campaign " + spaceCampName);
44 }
45
46 return teamfile;
47 }
48
49 /**
50 Returns true if the specified mission has been completed
51 campaignName: Name of the campaign in question
52 missionInList: QComboBox index of the mission as selected in the mission widget
53 teamName: Name of the playing team
54 */
isCampMissionWon(QString & campaignName,int missionInList,QString & teamName)55 bool isCampMissionWon(QString & campaignName, int missionInList, QString & teamName)
56 {
57 QSettings* teamfile = getCampTeamFile(campaignName, teamName);
58 int progress = teamfile->value("Campaign " + campaignName + "/Progress", 0).toInt();
59 int unlockedMissions = teamfile->value("Campaign " + campaignName + "/UnlockedMissions", 0).toInt();
60 // The CowardMode cheat unlocks all campaign missions,
61 // but as "punishment", none of them will be marked as completed.
62 // Added to make it easier to test campaigns.
63 bool cheat = teamfile->value("Team/CowardMode", false).toBool();
64 if(cheat)
65 {
66 return false;
67 }
68 else if(progress>0 && unlockedMissions==0)
69 {
70 QSettings campfile("physfs://Missions/Campaign/" + campaignName + "/campaign.ini", QSettings::IniFormat, 0);
71 campfile.setIniCodec("UTF-8");
72 int totalMissions = campfile.value("MissionNum", 1).toInt();
73 return (progress > (progress - missionInList)) || (progress >= totalMissions);
74 }
75 else if(unlockedMissions>0)
76 {
77 int fileMissionId = missionInList + 1;
78 int actualMissionId = teamfile->value(QString("Campaign %1/Mission%2").arg(campaignName, QString::number(fileMissionId)), false).toInt();
79 return teamfile->value(QString("Campaign %1/Mission%2Won").arg(campaignName, QString::number(actualMissionId)), false).toBool();
80 }
81 else
82 return false;
83 }
84
85 /** Returns true if the campaign has been won by the team */
isCampWon(QString & campaignName,QString & teamName)86 bool isCampWon(QString & campaignName, QString & teamName)
87 {
88 QSettings* teamfile = getCampTeamFile(campaignName, teamName);
89 bool won = teamfile->value("Campaign " + campaignName + "/Won", false).toBool();
90 bool cheat = teamfile->value("Team/CowardMode", false).toBool();
91 return won && !cheat;
92 }
93
getCampMetaInfo()94 QSettings* getCampMetaInfo()
95 {
96 DataManager & dataMgr = DataManager::instance();
97 // get locale
98 QSettings settings(dataMgr.settingsFileName(),
99 QSettings::IniFormat);
100 QString loc = QLocale().name();
101 QString campaignDescFile = QString("physfs://Locale/campaigns_" + loc + ".txt");
102 // if file is non-existant try with language only
103 if (!QFile::exists(campaignDescFile))
104 campaignDescFile = QString("physfs://Locale/campaigns_" + loc.remove(QRegExp("_.*$")) + ".txt");
105
106 // fallback if file for current locale is non-existant
107 if (!QFile::exists(campaignDescFile))
108 campaignDescFile = QString("physfs://Locale/campaigns_en.txt");
109
110 QSettings* m_info = new QSettings(campaignDescFile, QSettings::IniFormat, 0);
111 m_info->setIniCodec("UTF-8");
112
113 return m_info;
114 }
115
116 /** Returns the localized campaign name */
getRealCampName(const QString & campaignName)117 QString getRealCampName(const QString & campaignName)
118 {
119 QString campaignNameSpaces = QString(campaignName).replace(QString("_"), QString(" "));
120 return getCampMetaInfo()->value(campaignName+".name", campaignNameSpaces).toString();
121 }
122
getCampMissionList(QString & campaignName,QString & teamName)123 QList<MissionInfo> getCampMissionList(QString & campaignName, QString & teamName)
124 {
125 QList<MissionInfo> missionInfoList;
126 QSettings* teamfile = getCampTeamFile(campaignName, teamName);
127
128 int progress = teamfile->value("Campaign " + campaignName + "/Progress", 0).toInt();
129 int unlockedMissions = teamfile->value("Campaign " + campaignName + "/UnlockedMissions", 0).toInt();
130 bool cheat = teamfile->value("Team/CowardMode", false).toBool();
131
132 QSettings campfile("physfs://Missions/Campaign/" + campaignName + "/campaign.ini", QSettings::IniFormat, 0);
133 campfile.setIniCodec("UTF-8");
134
135 QSettings* m_info = getCampMetaInfo();
136
137 if(cheat)
138 {
139 progress = campfile.value("MissionNum", 1).toInt();
140 }
141 if((progress >= 0 && unlockedMissions == 0) || cheat)
142 {
143 for(unsigned int i = progress + 1; i > 0; i--)
144 {
145 MissionInfo missionInfo;
146 QString script = campfile.value(QString("Mission %1/Script").arg(i)).toString();
147 if(!script.isNull()) {
148 missionInfo.script = script;
149 missionInfo.name = campfile.value(QString("Mission %1/Name").arg(i)).toString();
150 QString scriptPrefix = campaignName+"-"+ script.replace(QString(".lua"),QString(""));
151 missionInfo.realName = m_info->value(scriptPrefix+".name", missionInfo.name).toString();
152 missionInfo.description = m_info->value(scriptPrefix + ".desc",
153 QObject::tr("No description available")).toString();
154 QString image = campfile.value(QString("Mission %1/Script").arg(i)).toString().replace(QString(".lua"),QString("@2x.png"));
155 missionInfo.image = "physfs://Graphics/Missions/Campaign/"+campaignName+"/"+image;
156 if (!QFile::exists(missionInfo.image))
157 missionInfo.image = ":/res/CampaignDefault.png";
158 missionInfoList.append(missionInfo);
159 }
160 }
161 }
162 else if(unlockedMissions>0)
163 {
164 for(int i=1;i<=unlockedMissions;i++)
165 {
166 QString missionNum = QString("%1").arg(i);
167 int missionNumber = teamfile->value("Campaign " + campaignName + "/Mission"+missionNum, -1).toInt();
168 MissionInfo missionInfo;
169 QString script = campfile.value(QString("Mission %1/Script").arg(missionNumber)).toString();
170 missionInfo.script = script;
171 missionInfo.name = campfile.value(QString("Mission %1/Name").arg(missionNumber)).toString();
172 QString scriptPrefix = campaignName+"-"+ script.replace(QString(".lua"),QString(""));
173 missionInfo.realName = m_info->value(scriptPrefix+".name", missionInfo.name).toString();
174 missionInfo.description = m_info->value(scriptPrefix + ".desc",
175 QObject::tr("No description available")).toString();
176 QString image = campfile.value(QString("Mission %1/Script").arg(missionNumber)).toString().replace(QString(".lua"),QString("@2x.png"));
177 missionInfo.image = "physfs://Graphics/Missions/Campaign/"+campaignName+"/"+image;
178 if (!QFile::exists(missionInfo.image))
179 missionInfo.image = ":/res/CampaignDefault.png";
180 missionInfoList.append(missionInfo);
181 }
182 }
183 return missionInfoList;
184 }
185