1 #include <QApplication>
2
3 #include "gametools.h"
4
5 #include "scene_if.h"
6 #include "gamewidget.h"
7 #include "gamestock.h"
8 #include "gamebonus.h"
9 #include "gameprofile.h"
10 #include "gamesound.h"
11
12 #include "hammertool.h"
13 //#include "bighammertool.h"
14 //#include "smallhammertool.h"
15 #include "bombtool.h"
16 #include "thundertool.h"
17 #include "clocktool.h"
18 #include "randomkilltool.h"
19 #include "mixertool.h"
20 //#include "unblocktool.h"
21 #include "twintool.h"
22
23 #include "consttools.h"
24
25 #include "progressbar.h"
26
27 #include "particlecontrol.h"
28 #include "gamehintcontrol.h"
29
30 ToolSet * toolset = nullptr;
31
32 ////////////////////////////////////////////////////////////////////////////////
33
34 #define TOOL_STAGES 20
35
36 int GameTool::stage;
37
GameTool(int x,int y,int score)38 GameTool::GameTool(int x, int y, int score) :
39 myPos(x,y),
40 myScore(score),
41 myToolset(0),
42 myProgress(0),
43 myActive(false)
44 {
45 }
46
GameTool(int x,int y,int score,const QString & resource)47 GameTool::GameTool(int x, int y, int score, const QString &resource) :
48 myPos(x,y),
49 myScore(score),
50 myToolset(0),
51 myProgress(0),
52 myActive(false)
53 {
54 myPixmap = QPixmap(GameWidget::getResourcePath() + "/tools/" + resource + ".png")
55 .scaled(DX(48),DY(48), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
56 }
57
~GameTool()58 GameTool::~GameTool()
59 {
60 }
61
setCurrent()62 void GameTool::setCurrent()
63 {
64 stage = TOOL_STAGES;
65 }
66
advanceAndPaint(QPainter & p,int currentScore)67 void GameTool::advanceAndPaint(QPainter &p, int currentScore)
68 {
69 if (!myActive)
70 {
71 // if (currentScore >= myScore && !myToolset->isPuzzle())
72 // {
73 // setActive(true);
74 // animateActivation();
75 // myToolset->nextToolActivated();
76 // }
77 return;
78 }
79
80 p.setOpacity(currentScore >= myScore ? 1 : 0.5);
81
82 // p.setPen(QPen(Qt::white));
83 //
84 // p.drawText(QRect(myPos.x(), myPos.y()-DY(12), DX(48), DY(20)),
85 // Qt::AlignHCenter | Qt::AlignTop, QString::number(myScore));
86
87 if (myToolset->current() == this)
88 {
89 p.setOpacity((1.0/TOOL_STAGES) * stage);
90 if (!--stage) stage = TOOL_STAGES;
91 }
92
93 p.drawPixmap(myPos, myPixmap);
94 }
95
animateActivation()96 void GameTool::animateActivation()
97 {
98 scene->createPixmapPopup(myPos.x(), myPos.y(), -1, -1, myPixmap, 20);
99 scene->createPixmapPopup(myPos.x(), myPos.y(), 1, 1, myPixmap, 20);
100 scene->createPixmapPopup(myPos.x(), myPos.y(), -1, 1, myPixmap, 20);
101 scene->createPixmapPopup(myPos.x(), myPos.y(), 1, -1, myPixmap, 20);
102 }
103
hint() const104 QString GameTool::hint() const
105 {
106 return QString("%1: %2").arg(bonusInfo->name, bonusInfo->comment);
107 }
108
109 ////////////////////////////////////////////////////////////////////////////////
110
111 #define MAX_TOOL_SCORE 100
112
113 struct ToolSetPrivate
114 {
ToolSetPrivateToolSetPrivate115 ToolSetPrivate() : myActiveToolIndex(0), maxCount(MAX_TOOL_SCORE)
116 {
117 QLinearGradient gr2(0,0,40,0);
118 gr2.setColorAt(0, QColor(0x034912));
119 gr2.setColorAt(0.5, QColor(0x00ff07));
120 gr2.setColorAt(1, QColor(0x034912));
121
122 countBar = new ProgressBar(QRect(30,60, 40,630));
123 countBar->setUpSpeed(10);
124 countBar->setBrush(gr2);
125
126 countBar->setMax(maxCount);
127 }
128
~ToolSetPrivateToolSetPrivate129 ~ToolSetPrivate()
130 {
131 delete countBar;
132 }
133
134 int myActiveToolIndex;
135 int maxCount;
136
137 ProgressBar *countBar;
138
139 HammerTool *hammerTool;
140 BombTool *bombTool;
141 ThunderTool *thunderTool;
142 ClockTool *clockTool;
143 RandomKillTool *randomKillTool;
144 MixerTool *mixerTool;
145 TwinTool *twinTool;
146 //class MagBonus *magBonus;
147 //class TimerBonus *timerBonus;
148 //class ScoreBonus *scoreBonus;
149 //class ClockBonus *clockBonus;
150 };
151
152 ////////////////////////////////////////////////////////////////////////////////
153
ToolSet()154 ToolSet::ToolSet() : toolScore(0), currentTool(0)
155 {
156 priv = new ToolSetPrivate();
157
158 initGraphics();
159
160 // active by default
161 // smallHammerTool->setActive();
162 // unblockTool->setActive();
163 }
164
~ToolSet()165 ToolSet::~ToolSet()
166 {
167 qDeleteAll(tools);
168 }
169
170 //int ToolSet::bonusClock() const { return clockBonus->value(); }
171 //int ToolSet::bonusScore() const { return scoreBonus->value(); }
172 //int ToolSet::bonusTimer() const { return timerBonus->value(); }
173 //int ToolSet::bonusMag() const { return magBonus->value(); }
174
initGraphics()175 void ToolSet::initGraphics()
176 {
177 // int magBonusVal = 0;
178 // int timerBonusVal = 0;
179 // int clockBonusVal = 0;
180 // int scoreBonusVal = 0;
181
182 //QList<bool> activ;
183
184 if (tools.count())
185 {
186 // magBonusVal = magBonus->value();
187 // timerBonusVal = timerBonus->value();
188 // clockBonusVal = clockBonus->value();
189 // scoreBonusVal = scoreBonus->value();
190
191 // for (int i = 0; i < tools.count(); i++)
192 // activ.append(tools.at(i)->isActive());
193
194 qDeleteAll(tools);
195 tools.clear();
196 }
197
198 int x1 = DX(26);
199 int y1 = DY(6);
200
201 priv->clockTool = new ClockTool(x1, y1, MAX_TOOL_SCORE);
202 priv->mixerTool = new MixerTool(x1, y1, MAX_TOOL_SCORE);
203 priv->hammerTool = new HammerTool(x1, y1, MAX_TOOL_SCORE);
204 priv->bombTool = new BombTool(x1, y1, MAX_TOOL_SCORE);
205 priv->randomKillTool = new RandomKillTool(x1, y1, MAX_TOOL_SCORE);
206 priv->thunderTool = new ThunderTool(x1, y1, MAX_TOOL_SCORE);
207 priv->twinTool = new TwinTool(x1, y1, MAX_TOOL_SCORE);
208
209
210 // permanent tools
211 // y += DY(100);
212 // magBonus = new MagBonus(x1,y, 10000);
213 // timerBonus = new TimerBonus(x2,y, 12000);
214 // y += dy;
215 // clockBonus = new ClockBonus(x1,y, 15000);
216 // scoreBonus = new ScoreBonus(x2,y, 20000);
217
218 // order in which the tools are given
219 tools.append(priv->clockTool);
220 tools.append(priv->hammerTool);
221 tools.append(priv->bombTool);
222 tools.append(priv->mixerTool);
223 tools.append(priv->randomKillTool);
224 tools.append(priv->thunderTool);
225 tools.append(priv->twinTool);
226
227 // tools.append(magBonus);
228 // tools.append(timerBonus);
229 // tools.append(clockBonus);
230 // tools.append(scoreBonus);
231
232 // update bonus values
233 // magBonus->setValue(magBonusVal);
234 // timerBonus->setValue(timerBonusVal);
235 // clockBonus->setValue(clockBonusVal);
236 // scoreBonus->setValue(scoreBonusVal);
237
238 for (int i = 0; i < tools.count(); i++)
239 {
240 GameTool *tool = tools.at(i);
241 tool->setBase(this);
242 tool->setActive(priv->myActiveToolIndex == i);
243 }
244 }
245
readProfile(LevelPackInfo * lpi)246 void ToolSet::readProfile(LevelPackInfo *lpi)
247 {
248 // this is to enable animation
249 setScore(0);
250 setScore(lpi->toolScore);
251
252 currentTool = 0;
253
254 priv->myActiveToolIndex = lpi->activeToolIndex;
255 if (priv->myActiveToolIndex < 0 && priv->myActiveToolIndex >= tools.count())
256 priv->myActiveToolIndex = 0;
257
258 for (int i = 0; i < tools.count(); i++)
259 {
260 tools.at(i)->setActive(priv->myActiveToolIndex == i);
261 }
262
263 // scoreBonus->setValue(lpi->score_bonus);
264 // clockBonus->setValue(lpi->time_bonus);
265 // timerBonus->setValue(lpi->speed_bonus);
266 // magBonus->setValue(lpi->speed_mag_bonus);
267 }
268
writeProfile(LevelPackInfo * lpi)269 void ToolSet::writeProfile(LevelPackInfo *lpi)
270 {
271 lpi->toolScore = toolScore;
272 lpi->activeToolIndex = priv->myActiveToolIndex;
273
274 // lpi->score_bonus = scoreBonus->value();
275 // lpi->time_bonus = clockBonus->value();
276 // lpi->speed_bonus = timerBonus->value();
277 // lpi->speed_mag_bonus = magBonus->value();
278 }
279
activateRandomTool()280 void ToolSet::activateRandomTool()
281 {
282 priv->myActiveToolIndex = qrand() % tools.count();
283
284 for (int i = 0; i < tools.count(); i++)
285 {
286 tools.at(i)->setActive(priv->myActiveToolIndex == i);
287 }
288 }
289
updateScore()290 void ToolSet::updateScore()
291 {
292 static bool activated = false;
293
294 toolScore = (int)priv->countBar->value();
295
296 if (priv->countBar->isFull())
297 {
298 if (!activated)
299 {
300 activated = true;
301 tools.at(priv->myActiveToolIndex)->animateActivation();
302
303 sndEngine->playSound(GameSound::sndTool);
304
305 //hintControl->scheduleHint(hintControl->ToolsHint);
306 hintControl->scheduleHint(hintControl->ToolHint[priv->myActiveToolIndex]);
307 }
308 } else
309 activated = false;
310 }
311
addScore(int score)312 void ToolSet::addScore(int score)
313 {
314 priv->countBar->addValue(score);
315 updateScore();
316 }
317
setScore(int score)318 void ToolSet::setScore(int score)
319 {
320 priv->countBar->setValue(score);
321 updateScore();
322 }
323
setLongestChain(int value)324 void ToolSet::setLongestChain(int value)
325 {
326 priv->maxCount = MAX_TOOL_SCORE - (value-3)*2;
327 priv->countBar->setMax(priv->maxCount);
328
329 for (int i = 0; i < tools.count(); i++)
330 {
331 GameTool *tool = tools.at(i);
332 tool->setScore(priv->maxCount);
333 }
334
335 updateScore();
336 }
337
338 //void ToolSet::nextToolActivated()
339 //{
340 // if (puzzle || next_tool == ALL_TOOLS)
341 // return;
342 //
343 // if (next_tool < tools.count())
344 // {
345 // GameTool *tool = tools.at(next_tool);
346 // tool->setActive(true);
347 // tool->animateActivation();
348 // sndEngine->playSound(GameSound::sndTool);
349 //
350 // next_tool++;
351 // }
352 // else
353 // next_tool = ALL_TOOLS;
354 //}
355
356 //int ToolSet::activeToolIndex(int score)
357 //{
358 // int idx = 2;
359 // if (puzzle) return idx;
360 //
361 // while (idx < tools.count() && tools.at(idx)->score() <= score)
362 // idx++;
363 // if (idx == tools.count())
364 // idx = 0;
365 // return idx;
366 //}
367
updateTools(QPainter & p)368 void ToolSet::updateTools(QPainter &p)
369 {
370 // countBar
371 priv->countBar->paint(p);
372
373 // tool
374 p.setFont(gameStock->Font8);
375
376 tools.at(priv->myActiveToolIndex)->advanceAndPaint(p, toolScore);
377
378 // for (int i = 0; i < tools.count(); i++)
379 // {
380 // GameTool *tool = tools.at(i);
381 // tool->advanceAndPaint(p, toolScore);
382 // }
383 }
384
checkMouseActions(const QPoint & pos)385 bool ToolSet::checkMouseActions(const QPoint &pos)
386 {
387 for (int i = 0; i < tools.count(); i++)
388 {
389 GameTool *tool = tools.at(i);
390 if (!tool->isActive())
391 continue;
392
393 if (QRect(tool->pos(), QSize(DX(48),DY(48))).contains(pos))
394 {
395 if (tool == currentTool)
396 break;
397
398 if (tool->score() <= toolScore)
399 {
400 currentTool = tool;
401 currentTool->setCurrent();
402 QApplication::setOverrideCursor(currentTool->pixmap());
403
404 if (tool->type() != GameTool::ManualTool)
405 {
406 if (tool->checkToolClick())
407 {
408 toolAboutExecute();
409
410 if (!tool->inProgress())
411 {
412 toolExecuted();
413 }
414 return true;
415 }
416 }
417 else // manual tool
418 {
419
420 }
421
422 myOverRow = myOverCol = -1;
423 return true;
424 }
425
426 break;
427 }
428 }
429
430 currentTool = 0;
431 scene->setDefaultGameCursor();
432 return false;
433 }
434
progressCurrent()435 void ToolSet::progressCurrent()
436 {
437 if (!(currentTool->checkToolClick()))
438 {
439 toolExecuted();
440 }
441 }
442
toolAboutExecute()443 void ToolSet::toolAboutExecute()
444 {
445 setScore(0);
446
447 // emit particles
448 ParticleEmitter *pe = new ParticleEmitter(DX(40), DY(350));
449 pe->setDuration(80);
450 pe->setCount(40);
451 pe->setEmitRadius(DX(20), DY(350));
452 pe->setOpacityShift(0.3);
453 pe->setCreator(new UniformParticleCreator(3)); // green
454 partControl->addEmitter(pe);
455 }
456
toolExecuted()457 void ToolSet::toolExecuted()
458 {
459 myOverRow = myOverCol = -1;
460 currentTool = 0;
461 setScore(0);
462 activateRandomTool();
463 scene->setDefaultGameCursor();
464 }
465
checkItemClick(int row,int col)466 bool ToolSet::checkItemClick(int row, int col)
467 {
468 if (!currentTool->checkItemClick(row, col))
469 return false;
470
471 toolAboutExecute();
472
473 if (!currentTool->inProgress())
474 toolExecuted();
475
476 return true;
477 }
478
checkItemState(int row,int col)479 GameTool::ToolAction ToolSet::checkItemState(int row, int col)
480 {
481 if (!currentTool || myOverCol == -1 || myOverRow == -1)
482 return GameTool::ToolOutOfRange;
483
484 if (currentTool->inProgress())
485 return GameTool::ToolOutOfRange;
486
487 return currentTool->checkItemState(row, col);
488 }
489
checkMouseMoved(int row,int col)490 void ToolSet::checkMouseMoved(int row, int col)
491 {
492 if (col >= 0 && col < scene->numCols() && row >= 0 && row < scene->numRows())
493 {
494 myOverRow = row;
495 myOverCol = col;
496 }
497 else
498 myOverRow = myOverCol = -1;
499 }
500
checkMouseHover(const QPoint & pos)501 bool ToolSet::checkMouseHover(const QPoint &pos)
502 {
503 for (int i = 0; i < tools.count(); i++)
504 {
505 GameTool *tool = tools.at(i);
506
507 if (!tool->isActive())
508 continue;
509
510 if (QRect(tool->pos(), QSize(DX(48),DY(48))).contains(pos))
511 {
512 scene->showHint(tool->hint());
513 return true;
514 }
515 }
516
517 return false;
518 }
519