35 HWGame::HWGame(GameUIConfig * config, GameCFGWidget * gamecfg, QString ammo, TeamSelWidget* pTeamSelWidget) : |
35 HWGame::HWGame(GameUIConfig * config, GameCFGWidget * gamecfg, QString ammo, TeamSelWidget* pTeamSelWidget) : |
36 TCPBase(true), |
36 TCPBase(true), |
37 ammostr(ammo), |
37 ammostr(ammo), |
38 m_pTeamSelWidget(pTeamSelWidget) |
38 m_pTeamSelWidget(pTeamSelWidget) |
39 { |
39 { |
40 this->config = config; |
40 this->config = config; |
41 this->gamecfg = gamecfg; |
41 this->gamecfg = gamecfg; |
42 TeamCount = 0; |
42 TeamCount = 0; |
43 } |
43 } |
44 |
44 |
45 HWGame::~HWGame() |
45 HWGame::~HWGame() |
46 { |
46 { |
47 SetGameState(gsDestroyed); |
47 SetGameState(gsDestroyed); |
48 } |
48 } |
49 |
49 |
50 void HWGame::onClientDisconnect() |
50 void HWGame::onClientDisconnect() |
51 { |
51 { |
52 switch (gameType) { |
52 switch (gameType) { |
53 case gtDemo: break; |
53 case gtDemo: break; |
54 case gtNet: |
54 case gtNet: |
55 emit HaveRecord(true, demo); |
55 emit HaveRecord(true, demo); |
56 break; |
56 break; |
57 default: |
57 default: |
58 if (gameState == gsInterrupted) emit HaveRecord(false, demo); |
58 if (gameState == gsInterrupted) emit HaveRecord(false, demo); |
59 else if (gameState == gsFinished) emit HaveRecord(true, demo); |
59 else if (gameState == gsFinished) emit HaveRecord(true, demo); |
60 } |
60 } |
61 SetGameState(gsStopped); |
61 SetGameState(gsStopped); |
62 } |
62 } |
63 |
63 |
64 void HWGame::commonConfig() |
64 void HWGame::commonConfig() |
65 { |
65 { |
66 QByteArray buf; |
66 QByteArray buf; |
67 QString gt; |
67 QString gt; |
68 switch (gameType) { |
68 switch (gameType) { |
69 case gtDemo: |
69 case gtDemo: |
70 gt = "TD"; |
70 gt = "TD"; |
71 break; |
71 break; |
72 case gtNet: |
72 case gtNet: |
73 gt = "TN"; |
73 gt = "TN"; |
74 break; |
74 break; |
75 default: |
75 default: |
76 gt = "TL"; |
76 gt = "TL"; |
77 } |
77 } |
78 HWProto::addStringToBuffer(buf, gt); |
78 HWProto::addStringToBuffer(buf, gt); |
79 |
79 |
80 HWProto::addStringListToBuffer(buf, gamecfg->getFullConfig()); |
80 HWProto::addStringListToBuffer(buf, gamecfg->getFullConfig()); |
81 |
81 |
82 if (m_pTeamSelWidget) |
82 if (m_pTeamSelWidget) |
83 { |
83 { |
84 QList<HWTeam> teams = m_pTeamSelWidget->getPlayingTeams(); |
84 QList<HWTeam> teams = m_pTeamSelWidget->getPlayingTeams(); |
85 for(QList<HWTeam>::iterator it = teams.begin(); it != teams.end(); ++it) |
85 for(QList<HWTeam>::iterator it = teams.begin(); it != teams.end(); ++it) |
86 { |
86 { |
87 HWProto::addStringListToBuffer(buf, |
87 HWProto::addStringListToBuffer(buf, |
88 (*it).TeamGameConfig(gamecfg->getInitHealth())); |
88 (*it).TeamGameConfig(gamecfg->getInitHealth())); |
89 HWProto::addStringToBuffer(buf, QString("eammstore %1").arg(ammostr)); |
89 HWProto::addStringToBuffer(buf, QString("eammstore %1").arg(ammostr)); |
90 } |
90 } |
91 } |
91 } |
92 RawSendIPC(buf); |
92 RawSendIPC(buf); |
93 } |
93 } |
94 |
94 |
95 void HWGame::SendConfig() |
95 void HWGame::SendConfig() |
96 { |
96 { |
97 commonConfig(); |
97 commonConfig(); |
98 } |
98 } |
99 |
99 |
100 void HWGame::SendQuickConfig() |
100 void HWGame::SendQuickConfig() |
101 { |
101 { |
102 QByteArray teamscfg; |
102 QByteArray teamscfg; |
103 |
103 |
104 HWProto::addStringToBuffer(teamscfg, "TL"); |
104 HWProto::addStringToBuffer(teamscfg, "TL"); |
105 HWProto::addStringToBuffer(teamscfg, QString("etheme %1") |
105 HWProto::addStringToBuffer(teamscfg, QString("etheme %1") |
106 .arg((Themes->size() > 0) ? Themes->at(rand() % Themes->size()) : "steel")); |
106 .arg((Themes->size() > 0) ? Themes->at(rand() % Themes->size()) : "steel")); |
107 HWProto::addStringToBuffer(teamscfg, "eseed " + QUuid::createUuid().toString()); |
107 HWProto::addStringToBuffer(teamscfg, "eseed " + QUuid::createUuid().toString()); |
108 |
108 |
109 HWNamegen namegen; |
109 HWNamegen namegen; |
110 |
110 |
111 HWTeam * team1; |
111 HWTeam * team1; |
112 team1 = new HWTeam; |
112 team1 = new HWTeam; |
113 team1->difficulty = 0; |
113 team1->difficulty = 0; |
114 team1->teamColor = *color1; |
114 team1->teamColor = *color1; |
115 team1->numHedgehogs = 4; |
115 team1->numHedgehogs = 4; |
116 namegen.TeamRandomNames(team1,TRUE); |
116 namegen.TeamRandomNames(team1,TRUE); |
117 HWProto::addStringListToBuffer(teamscfg, |
117 HWProto::addStringListToBuffer(teamscfg, |
118 team1->TeamGameConfig(100)); |
118 team1->TeamGameConfig(100)); |
119 |
119 |
120 HWTeam * team2; |
120 HWTeam * team2; |
121 team2 = new HWTeam; |
121 team2 = new HWTeam; |
122 team2->difficulty = 4; |
122 team2->difficulty = 4; |
123 team2->teamColor = *color2; |
123 team2->teamColor = *color2; |
124 team2->numHedgehogs = 4; |
124 team2->numHedgehogs = 4; |
125 namegen.TeamRandomNames(team2,TRUE); |
125 namegen.TeamRandomNames(team2,TRUE); |
126 HWProto::addStringListToBuffer(teamscfg, |
126 HWProto::addStringListToBuffer(teamscfg, |
127 team2->TeamGameConfig(100)); |
127 team2->TeamGameConfig(100)); |
128 |
128 |
129 HWProto::addStringToBuffer(teamscfg, "eammstore " + *cDefaultAmmoStore); |
129 HWProto::addStringToBuffer(teamscfg, "eammstore " + *cDefaultAmmoStore); |
130 HWProto::addStringToBuffer(teamscfg, "eammstore " + *cDefaultAmmoStore); |
130 HWProto::addStringToBuffer(teamscfg, "eammstore " + *cDefaultAmmoStore); |
131 RawSendIPC(teamscfg); |
131 RawSendIPC(teamscfg); |
132 } |
132 } |
133 |
133 |
134 void HWGame::SendTrainingConfig() |
134 void HWGame::SendTrainingConfig() |
135 { |
135 { |
136 QByteArray traincfg; |
136 QByteArray traincfg; |
137 HWProto::addStringToBuffer(traincfg, "TL"); |
137 HWProto::addStringToBuffer(traincfg, "TL"); |
138 |
138 |
139 HWProto::addStringToBuffer(traincfg, "escript " + datadir->absolutePath() + "/Missions/" + training + ".hwt"); |
139 HWProto::addStringToBuffer(traincfg, "escript " + datadir->absolutePath() + "/Missions/" + training + ".hwt"); |
140 |
140 |
141 RawSendIPC(traincfg); |
141 RawSendIPC(traincfg); |
142 } |
142 } |
143 |
143 |
144 void HWGame::SendNetConfig() |
144 void HWGame::SendNetConfig() |
145 { |
145 { |
146 commonConfig(); |
146 commonConfig(); |
147 } |
147 } |
148 |
148 |
149 void HWGame::ParseMessage(const QByteArray & msg) |
149 void HWGame::ParseMessage(const QByteArray & msg) |
150 { |
150 { |
151 switch(msg.at(1)) { |
151 switch(msg.at(1)) { |
152 case '?': { |
152 case '?': { |
153 SendIPC("!"); |
153 SendIPC("!"); |
154 break; |
154 break; |
155 } |
155 } |
156 case 'C': { |
156 case 'C': { |
157 switch (gameType) { |
157 switch (gameType) { |
158 case gtLocal: { |
158 case gtLocal: { |
159 SendConfig(); |
159 SendConfig(); |
160 break; |
160 break; |
161 } |
161 } |
162 case gtQLocal: { |
162 case gtQLocal: { |
163 SendQuickConfig(); |
163 SendQuickConfig(); |
164 break; |
164 break; |
165 } |
165 } |
166 case gtDemo: break; |
166 case gtDemo: break; |
167 case gtNet: { |
167 case gtNet: { |
168 SendNetConfig(); |
168 SendNetConfig(); |
169 break; |
169 break; |
170 } |
170 } |
171 case gtTraining: { |
171 case gtTraining: { |
172 SendTrainingConfig(); |
172 SendTrainingConfig(); |
173 break; |
173 break; |
174 } |
174 } |
175 } |
175 } |
176 break; |
176 break; |
177 } |
177 } |
178 case 'E': { |
178 case 'E': { |
179 int size = msg.size(); |
179 int size = msg.size(); |
180 emit ErrorMessage(QString("Last two engine messages:\n") + QString().append(msg.mid(2)).left(size - 4)); |
180 emit ErrorMessage(QString("Last two engine messages:\n") + QString().append(msg.mid(2)).left(size - 4)); |
181 return; |
181 return; |
182 } |
182 } |
183 case 'K': { |
183 case 'K': { |
184 ulong kb = msg.mid(2).toULong(); |
184 ulong kb = msg.mid(2).toULong(); |
185 if (kb==1) { |
185 if (kb==1) { |
186 qWarning("%s", KBMessages[kb - 1].toLocal8Bit().constData()); |
186 qWarning("%s", KBMessages[kb - 1].toLocal8Bit().constData()); |
187 return; |
187 return; |
188 } |
188 } |
189 if (kb && kb <= KBmsgsCount) |
189 if (kb && kb <= KBmsgsCount) |
190 { |
190 { |
191 emit ErrorMessage(KBMessages[kb - 1]); |
191 emit ErrorMessage(KBMessages[kb - 1]); |
192 } |
192 } |
193 return; |
193 return; |
194 } |
194 } |
195 case 'i': { |
195 case 'i': { |
196 emit GameStats(msg.at(2), QString::fromUtf8(msg.mid(3))); |
196 emit GameStats(msg.at(2), QString::fromUtf8(msg.mid(3))); |
197 break; |
197 break; |
198 } |
198 } |
199 case 'Q': { |
199 case 'Q': { |
200 SetGameState(gsInterrupted); |
200 SetGameState(gsInterrupted); |
201 break; |
201 break; |
202 } |
202 } |
203 case 'q': { |
203 case 'q': { |
204 SetGameState(gsFinished); |
204 SetGameState(gsFinished); |
205 break; |
205 break; |
206 } |
206 } |
207 case 's': { |
207 case 's': { |
208 int size = msg.size(); |
208 int size = msg.size(); |
209 QString msgbody = QString::fromUtf8(msg.mid(2).left(size - 4)); |
209 QString msgbody = QString::fromUtf8(msg.mid(2).left(size - 4)); |
210 emit SendChat(msgbody); |
210 emit SendChat(msgbody); |
211 // FIXME: /me command doesn't work here |
211 // FIXME: /me command doesn't work here |
212 QByteArray buf; |
212 QByteArray buf; |
213 HWProto::addStringToBuffer(buf, "s" + HWProto::formatChatMsg(config->netNick(), msgbody) + "\x20\x20"); |
213 HWProto::addStringToBuffer(buf, "s" + HWProto::formatChatMsg(config->netNick(), msgbody) + "\x20\x20"); |
214 demo.append(buf); |
214 demo.append(buf); |
215 break; |
215 break; |
216 } |
216 } |
217 case 'b': { |
217 case 'b': { |
218 int size = msg.size(); |
218 int size = msg.size(); |
219 QString msgbody = QString::fromUtf8(msg.mid(2).left(size - 4)); |
219 QString msgbody = QString::fromUtf8(msg.mid(2).left(size - 4)); |
220 emit SendTeamMessage(msgbody); |
220 emit SendTeamMessage(msgbody); |
221 break; |
221 break; |
222 } |
222 } |
223 default: { |
223 default: { |
224 if (gameType == gtNet) |
224 if (gameType == gtNet) |
225 { |
225 { |
226 emit SendNet(msg); |
226 emit SendNet(msg); |
227 } |
227 } |
228 if (msg.at(1) != 's') |
228 if (msg.at(1) != 's') |
229 demo.append(msg); |
229 demo.append(msg); |
230 } |
230 } |
231 } |
231 } |
232 } |
232 } |
233 |
233 |
234 void HWGame::FromNet(const QByteArray & msg) |
234 void HWGame::FromNet(const QByteArray & msg) |
235 { |
235 { |
236 RawSendIPC(msg); |
236 RawSendIPC(msg); |
237 } |
237 } |
238 |
238 |
239 void HWGame::FromNetChat(const QString & msg) |
239 void HWGame::FromNetChat(const QString & msg) |
240 { |
240 { |
241 QByteArray buf; |
241 QByteArray buf; |
242 HWProto::addStringToBuffer(buf, 's' + msg + "\x20\x20"); |
242 HWProto::addStringToBuffer(buf, 's' + msg + "\x20\x20"); |
243 RawSendIPC(buf); |
243 RawSendIPC(buf); |
244 } |
244 } |
245 |
245 |
246 void HWGame::onClientRead() |
246 void HWGame::onClientRead() |
247 { |
247 { |
248 quint8 msglen; |
248 quint8 msglen; |
249 quint32 bufsize; |
249 quint32 bufsize; |
250 while (!readbuffer.isEmpty() && ((bufsize = readbuffer.size()) > 0) && |
250 while (!readbuffer.isEmpty() && ((bufsize = readbuffer.size()) > 0) && |
251 ((msglen = readbuffer.data()[0]) < bufsize)) |
251 ((msglen = readbuffer.data()[0]) < bufsize)) |
252 { |
252 { |
253 QByteArray msg = readbuffer.left(msglen + 1); |
253 QByteArray msg = readbuffer.left(msglen + 1); |
254 readbuffer.remove(0, msglen + 1); |
254 readbuffer.remove(0, msglen + 1); |
255 ParseMessage(msg); |
255 ParseMessage(msg); |
256 } |
256 } |
257 } |
257 } |
258 |
258 |
259 QStringList HWGame::setArguments() |
259 QStringList HWGame::setArguments() |
260 { |
260 { |
261 QStringList arguments; |
261 QStringList arguments; |
262 QRect resolution = config->vid_Resolution(); |
262 QRect resolution = config->vid_Resolution(); |
263 arguments << cfgdir->absolutePath(); |
263 arguments << cfgdir->absolutePath(); |
264 arguments << QString::number(resolution.width()); |
264 arguments << QString::number(resolution.width()); |
265 arguments << QString::number(resolution.height()); |
265 arguments << QString::number(resolution.height()); |
266 arguments << QString::number(config->bitDepth()); // bpp |
266 arguments << QString::number(config->bitDepth()); // bpp |
267 arguments << QString("%1").arg(ipc_port); |
267 arguments << QString("%1").arg(ipc_port); |
268 arguments << (config->vid_Fullscreen() ? "1" : "0"); |
268 arguments << (config->vid_Fullscreen() ? "1" : "0"); |
269 arguments << (config->isSoundEnabled() ? "1" : "0"); |
269 arguments << (config->isSoundEnabled() ? "1" : "0"); |
270 #ifdef _WIN32 |
270 #ifdef _WIN32 |
271 arguments << (config->isSoundHardware() ? "1" : "0"); |
271 arguments << (config->isSoundHardware() ? "1" : "0"); |
272 #else |
272 #else |
273 arguments << "0"; |
273 arguments << "0"; |
274 #endif |
274 #endif |
275 arguments << (config->isWeaponTooltip() ? "1" : "0"); |
275 arguments << (config->isWeaponTooltip() ? "1" : "0"); |
276 arguments << tr("en.txt"); |
276 arguments << tr("en.txt"); |
277 arguments << QString::number(config->volume()); // sound volume |
277 arguments << QString::number(config->volume()); // sound volume |
278 arguments << QString::number(config->timerInterval()); |
278 arguments << QString::number(config->timerInterval()); |
279 arguments << datadir->absolutePath(); |
279 arguments << datadir->absolutePath(); |
280 arguments << (config->isShowFPSEnabled() ? "1" : "0"); |
280 arguments << (config->isShowFPSEnabled() ? "1" : "0"); |
281 arguments << (config->isAltDamageEnabled() ? "1" : "0"); |
281 arguments << (config->isAltDamageEnabled() ? "1" : "0"); |
282 arguments << config->netNick().toUtf8().toBase64(); |
282 arguments << config->netNick().toUtf8().toBase64(); |
283 arguments << (config->isMusicEnabled() ? "1" : "0"); |
283 arguments << (config->isMusicEnabled() ? "1" : "0"); |
284 arguments << (config->isReducedQuality() ? "1" : "0"); |
284 arguments << (config->isReducedQuality() ? "1" : "0"); |
285 return arguments; |
285 return arguments; |
286 } |
286 } |
287 |
287 |
288 void HWGame::AddTeam(const QString & teamname) |
288 void HWGame::AddTeam(const QString & teamname) |
289 { |
289 { |
290 if (TeamCount == 5) return; |
290 if (TeamCount == 5) return; |
291 teams[TeamCount] = teamname; |
291 teams[TeamCount] = teamname; |
292 TeamCount++; |
292 TeamCount++; |
293 } |
293 } |
294 |
294 |
295 void HWGame::PlayDemo(const QString & demofilename) |
295 void HWGame::PlayDemo(const QString & demofilename) |
296 { |
296 { |
297 gameType = gtDemo; |
297 gameType = gtDemo; |
298 QFile demofile(demofilename); |
298 QFile demofile(demofilename); |
299 if (!demofile.open(QIODevice::ReadOnly)) |
299 if (!demofile.open(QIODevice::ReadOnly)) |
300 { |
300 { |
301 emit ErrorMessage(tr("Cannot open demofile %1").arg(demofilename)); |
301 emit ErrorMessage(tr("Cannot open demofile %1").arg(demofilename)); |
302 return ; |
302 return ; |
303 } |
303 } |
304 |
304 |
305 // read demo |
305 // read demo |
306 toSendBuf = demofile.readAll(); |
306 toSendBuf = demofile.readAll(); |
307 |
307 |
308 // run engine |
308 // run engine |
309 demo.clear(); |
309 demo.clear(); |
310 Start(); |
310 Start(); |
311 SetGameState(gsStarted); |
311 SetGameState(gsStarted); |
312 } |
312 } |
313 |
313 |
314 void HWGame::StartNet() |
314 void HWGame::StartNet() |
315 { |
315 { |
316 gameType = gtNet; |
316 gameType = gtNet; |
317 demo.clear(); |
317 demo.clear(); |
318 Start(); |
318 Start(); |
319 SetGameState(gsStarted); |
319 SetGameState(gsStarted); |
320 } |
320 } |
321 |
321 |
322 void HWGame::StartLocal() |
322 void HWGame::StartLocal() |
323 { |
323 { |
324 gameType = gtLocal; |
324 gameType = gtLocal; |
325 demo.clear(); |
325 demo.clear(); |
326 Start(); |
326 Start(); |
327 SetGameState(gsStarted); |
327 SetGameState(gsStarted); |
328 } |
328 } |
329 |
329 |
330 void HWGame::StartQuick() |
330 void HWGame::StartQuick() |
331 { |
331 { |
332 gameType = gtQLocal; |
332 gameType = gtQLocal; |
333 demo.clear(); |
333 demo.clear(); |
334 Start(); |
334 Start(); |
335 SetGameState(gsStarted); |
335 SetGameState(gsStarted); |
336 } |
336 } |
337 |
337 |
338 void HWGame::StartTraining(const QString & file) |
338 void HWGame::StartTraining(const QString & file) |
339 { |
339 { |
340 gameType = gtTraining; |
340 gameType = gtTraining; |
341 training = file; |
341 training = file; |
342 demo.clear(); |
342 demo.clear(); |
343 Start(); |
343 Start(); |
344 SetGameState(gsStarted); |
344 SetGameState(gsStarted); |
345 } |
345 } |
346 |
346 |
347 void HWGame::SetGameState(GameState state) |
347 void HWGame::SetGameState(GameState state) |
348 { |
348 { |
349 gameState = state; |
349 gameState = state; |
350 emit GameStateChanged(state); |
350 emit GameStateChanged(state); |
351 } |
351 } |