~ubuntu-branches/ubuntu/quantal/hedgewars/quantal

« back to all changes in this revision

Viewing changes to QTfrontend/mapContainer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Dmitry E. Oboukhov
  • Date: 2010-11-14 22:45:48 UTC
  • mfrom: (1.2.9 upstream)
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20101114224548-tntbfzxa8qo9lhpn
* New upstream version.
 + New audio tracks
 + New forts: EvilChicken, Tank
 + New game modes: AI Survival Mode, Per Hedgehog Ammo,
   Reset Health, Reset Weapons, Unlimited Attacks
 + New grave: ring
 + Over 30 new hats
 + New themes: Art, Brick, Jungle, Stage
 + New maps: ShoppaKing, Sticks, TrophyRace (Mission)
 + New utilities: Portal Gun, Resurrector
 + New weapons: Flamethrower, Hammer, Old Limburger,
   Piano Strike, Sticky Mines
 + Weapons' projectiles will how be launched from their
   barrels instead of the hog's center
 + Flying Saucers may be used for moving below the water surface
 + New default game schemes: Clean Slate, Fort Mode, Timeless,
   Thinking with Portals, King Mode
 + New default weapon set: Clean Slate, Thinking with Portals
 + Bomb clusters/Melon parts inherit some of the original bomb's speed
 + Extended game statistics
 + Improved health bar updating
 + Hogs that blow themselves up will use triggers in they team color
 + Settings allow better control over the level of details/effects
 + Improved Lua support
 + On empty ammo switch to no weapon rather than the first available
   one (to avoid shooting by accident)
 + Display of hints in the frontend
 + Some improvements of existing Themes of Maps
 + Land destruction effects added
 + Improved fire effects
 + Improved Melon explosion effects
 + Online game lobby now features game filters
 + Other Frontend enhancements
 + Additional sounds
 + Show special game rules in Esc screen
 + Updated translation
 + Speed optimizations
 + Hedgewars will now use a sub directory of "My Documents"
   like other games instead of "%userprofile%/.hedgewars" under Windows
 + Added support for graphics cards/drivers that have a 512x512
   pixel textures limit
 + Team colors are more distinguishable from each other now
 * Fixed bug that allowed charging a weapon while on rope,
   leading to frozen timer
 * Various bug fixes
* Switched to 3.0 source format.
* Switched to cdbs build system.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Hedgewars, a free turn based strategy game
 
3
 * Copyright (c) 2006-2008 Igor Ulyanov <iulyanov@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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
17
 */
 
18
 
 
19
#include <QPushButton>
 
20
#include <QBuffer>
 
21
#include <QUuid>
 
22
#include <QBitmap>
 
23
#include <QPainter>
 
24
#include <QLinearGradient>
 
25
#include <QColor>
 
26
#include <QTextStream>
 
27
#include <QApplication>
 
28
#include <QLabel>
 
29
#include <QListWidget>
 
30
#include <QVBoxLayout>
 
31
#include <QIcon>
 
32
 
 
33
#include "hwconsts.h"
 
34
#include "mapContainer.h"
 
35
#include "igbox.h"
 
36
 
 
37
HWMapContainer::HWMapContainer(QWidget * parent) :
 
38
    QWidget(parent),
 
39
    mainLayout(this),
 
40
    pMap(0),
 
41
    mapgen(MAPGEN_REGULAR),
 
42
    maze_size(0)
 
43
{
 
44
    hhSmall.load(":/res/hh_small.png");
 
45
    hhLimit = 18;
 
46
    templateFilter = 0;
 
47
 
 
48
    mainLayout.setContentsMargins(QApplication::style()->pixelMetric(QStyle::PM_LayoutLeftMargin),
 
49
        1,
 
50
        QApplication::style()->pixelMetric(QStyle::PM_LayoutRightMargin),
 
51
        QApplication::style()->pixelMetric(QStyle::PM_LayoutBottomMargin));
 
52
 
 
53
    imageButt = new QPushButton(this);
 
54
    imageButt->setObjectName("imageButt");
 
55
    imageButt->setFixedSize(256 + 6, 128 + 6);
 
56
    imageButt->setFlat(true);
 
57
    imageButt->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);//QSizePolicy::Minimum, QSizePolicy::Minimum);
 
58
    mainLayout.addWidget(imageButt, 0, 0, 1, 2);
 
59
    connect(imageButt, SIGNAL(clicked()), this, SLOT(setRandomSeed()));
 
60
    connect(imageButt, SIGNAL(clicked()), this, SLOT(setRandomTheme()));
 
61
 
 
62
    chooseMap = new QComboBox(this);
 
63
    chooseMap->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
 
64
    chooseMap->addItem(
 
65
// FIXME - need real icons. Disabling until then
 
66
//QIcon(":/res/mapRandom.png"), 
 
67
QComboBox::tr("generated map..."));
 
68
    chooseMap->addItem(
 
69
// FIXME - need real icons. Disabling until then
 
70
//QIcon(":/res/mapMaze.png"), 
 
71
QComboBox::tr("generated maze..."));
 
72
    chooseMap->insertSeparator(chooseMap->count()); // separator between generators and missions
 
73
 
 
74
    int missionindex = chooseMap->count();
 
75
    for (int i = 0; i < mapList->size(); ++i) {
 
76
        QString map = (*mapList)[i];
 
77
        QFile mapCfgFile(
 
78
                QString("%1/Maps/%2/map.cfg")
 
79
                .arg(datadir->absolutePath())
 
80
                .arg(map));
 
81
        QFile mapLuaFile(
 
82
                QString("%1/Maps/%2/map.lua")
 
83
                .arg(datadir->absolutePath())
 
84
                .arg(map));
 
85
 
 
86
        if (mapCfgFile.open(QFile::ReadOnly)) {
 
87
            QString theme;
 
88
            quint32 limit = 0;
 
89
            QList<QVariant> mapInfo;
 
90
            QTextStream input(&mapCfgFile);
 
91
            input >> theme;
 
92
            input >> limit;
 
93
            mapInfo.push_back(map);
 
94
            mapInfo.push_back(theme);
 
95
            if (limit)
 
96
                mapInfo.push_back(limit);
 
97
            else
 
98
                mapInfo.push_back(18);
 
99
            mapInfo.push_back(mapLuaFile.exists());
 
100
            if(mapLuaFile.exists())
 
101
                chooseMap->insertItem(missionindex++, 
 
102
// FIXME - need real icons. Disabling until then
 
103
//QIcon(":/res/mapMission.png"), 
 
104
QComboBox::tr("Mission") + ": " + map, mapInfo);
 
105
            else
 
106
                chooseMap->addItem(
 
107
// FIXME - need real icons. Disabling until then
 
108
//QIcon(":/res/mapCustom.png"),
 
109
 map, mapInfo);
 
110
            mapCfgFile.close();
 
111
        }
 
112
    }
 
113
    chooseMap->insertSeparator(missionindex); // separator between missions and maps
 
114
 
 
115
    connect(chooseMap, SIGNAL(currentIndexChanged(int)), this, SLOT(mapChanged(int)));
 
116
    mainLayout.addWidget(chooseMap, 1, 1);
 
117
 
 
118
    QLabel * lblMap = new QLabel(tr("Map"), this);
 
119
    mainLayout.addWidget(lblMap, 1, 0);
 
120
 
 
121
    lblFilter = new QLabel(tr("Filter"), this);
 
122
    mainLayout.addWidget(lblFilter, 2, 0);
 
123
 
 
124
    CB_TemplateFilter = new QComboBox(this);
 
125
    CB_TemplateFilter->addItem(tr("All"), 0);
 
126
    CB_TemplateFilter->addItem(tr("Small"), 1);
 
127
    CB_TemplateFilter->addItem(tr("Medium"), 2);
 
128
    CB_TemplateFilter->addItem(tr("Large"), 3);
 
129
    CB_TemplateFilter->addItem(tr("Cavern"), 4);
 
130
    CB_TemplateFilter->addItem(tr("Wacky"), 5);
 
131
    mainLayout.addWidget(CB_TemplateFilter, 2, 1);
 
132
 
 
133
    connect(CB_TemplateFilter, SIGNAL(currentIndexChanged(int)), this, SLOT(templateFilterChanged(int)));
 
134
 
 
135
    maze_size_label = new QLabel(tr("Type"), this);
 
136
    mainLayout.addWidget(maze_size_label, 2, 0);
 
137
    maze_size_label->hide();
 
138
    maze_size_selection = new QComboBox(this);
 
139
    maze_size_selection->addItem(tr("Small tunnels"), 0);
 
140
    maze_size_selection->addItem(tr("Medium tunnels"), 1);
 
141
    maze_size_selection->addItem(tr("Large tunnels"), 2);
 
142
    maze_size_selection->addItem(tr("Small floating islands"), 3);
 
143
    maze_size_selection->addItem(tr("Medium floating islands"), 4);
 
144
    maze_size_selection->addItem(tr("Large floating islands"), 5);
 
145
    maze_size_selection->setCurrentIndex(1);
 
146
    maze_size = 1;
 
147
    mainLayout.addWidget(maze_size_selection, 2, 1);
 
148
    maze_size_selection->hide();
 
149
    connect(maze_size_selection, SIGNAL(currentIndexChanged(int)), this, SLOT(setMaze_size(int)));
 
150
 
 
151
    gbThemes = new IconedGroupBox(this);
 
152
    gbThemes->setTitleTextPadding(60);
 
153
    gbThemes->setContentTopPadding(6);
 
154
    gbThemes->setTitle(tr("Themes"));
 
155
 
 
156
    //gbThemes->setStyleSheet("padding: 0px"); // doesn't work - stylesheet is set with icon
 
157
    mainLayout.addWidget(gbThemes, 0, 2, 3, 1);
 
158
 
 
159
    QVBoxLayout * gbTLayout = new QVBoxLayout(gbThemes);
 
160
    gbTLayout->setContentsMargins(0, 0, 0 ,0);
 
161
    gbTLayout->setSpacing(0);
 
162
    lwThemes = new QListWidget(this);
 
163
    lwThemes->setMinimumHeight(30);
 
164
    lwThemes->setFixedWidth(140);
 
165
    for (int i = 0; i < Themes->size(); ++i) {
 
166
        QListWidgetItem * lwi = new QListWidgetItem();
 
167
        lwi->setText(Themes->at(i));
 
168
        lwi->setIcon(QIcon(QString("%1/Themes/%2/icon.png").arg(datadir->absolutePath()).arg(Themes->at(i))));
 
169
        //lwi->setTextAlignment(Qt::AlignHCenter);
 
170
        lwThemes->addItem(lwi);
 
171
    }
 
172
    connect(lwThemes, SIGNAL(currentRowChanged(int)), this, SLOT(themeSelected(int)));
 
173
 
 
174
    // override default style to tighten up theme scroller
 
175
    lwThemes->setStyleSheet(QString(
 
176
        "QListWidget{"
 
177
            "border: solid;"
 
178
            "border-width: 0px;"
 
179
            "border-radius: 0px;"
 
180
            "border-color: transparent;"
 
181
            "background-color: #0d0544;"
 
182
            "color: #ffcc00;"
 
183
            "font: bold 13px;"
 
184
            "}"
 
185
        )
 
186
    );
 
187
 
 
188
    gbTLayout->addWidget(lwThemes);
 
189
    lwThemes->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum);
 
190
 
 
191
    mainLayout.setSizeConstraint(QLayout::SetFixedSize);//SetMinimumSize
 
192
 
 
193
    setRandomSeed();
 
194
    setRandomTheme();
 
195
}
 
196
 
 
197
void HWMapContainer::setImage(const QImage newImage)
 
198
{
 
199
    QPixmap px(256, 128);
 
200
    QPixmap pxres(256, 128);
 
201
    QPainter p(&pxres);
 
202
 
 
203
    px.fill(Qt::yellow);
 
204
    QBitmap bm = QBitmap::fromImage(newImage);
 
205
    px.setMask(bm);
 
206
 
 
207
    QLinearGradient linearGrad(QPoint(128, 0), QPoint(128, 128));
 
208
    linearGrad.setColorAt(1, QColor(0, 0, 192));
 
209
    linearGrad.setColorAt(0, QColor(66, 115, 225));
 
210
    p.fillRect(QRect(0, 0, 256, 128), linearGrad);
 
211
    p.drawPixmap(QPoint(0, 0), px);
 
212
 
 
213
    addInfoToPreview(pxres);
 
214
    chooseMap->setCurrentIndex(mapgen);
 
215
    pMap = 0;
 
216
}
 
217
 
 
218
void HWMapContainer::setHHLimit(int newHHLimit)
 
219
{
 
220
    hhLimit = newHHLimit;
 
221
}
 
222
 
 
223
void HWMapContainer::mapChanged(int index)
 
224
{
 
225
    switch(index) {
 
226
    case MAPGEN_REGULAR:
 
227
        mapgen = MAPGEN_REGULAR;
 
228
        changeImage();
 
229
        gbThemes->show();
 
230
        lblFilter->show();
 
231
        CB_TemplateFilter->show();
 
232
        maze_size_label->hide();
 
233
        maze_size_selection->hide();
 
234
        emit mapChanged("+rnd+");
 
235
        emit mapgenChanged(mapgen);
 
236
        emit themeChanged(chooseMap->itemData(index).toList()[1].toString());
 
237
        break;
 
238
    case MAPGEN_MAZE:
 
239
        mapgen = MAPGEN_MAZE;
 
240
        changeImage();
 
241
        gbThemes->show();
 
242
        lblFilter->hide();
 
243
        CB_TemplateFilter->hide();
 
244
        maze_size_label->show();
 
245
        maze_size_selection->show();
 
246
        emit mapChanged("+maze+");
 
247
        emit mapgenChanged(mapgen);
 
248
        emit themeChanged(chooseMap->itemData(index).toList()[1].toString());
 
249
        break;
 
250
    default:
 
251
        loadMap(index);
 
252
        gbThemes->hide();
 
253
        lblFilter->hide();
 
254
        CB_TemplateFilter->hide();
 
255
        maze_size_label->hide();
 
256
        maze_size_selection->hide();
 
257
        emit mapChanged(chooseMap->itemData(index).toList()[0].toString());
 
258
    }
 
259
}
 
260
 
 
261
void HWMapContainer::loadMap(int index)
 
262
{
 
263
    QPixmap mapImage;
 
264
    if(!mapImage.load(datadir->absolutePath() + "/Maps/" + chooseMap->itemData(index).toList()[0].toString() + "/preview.png")) {
 
265
        changeImage();
 
266
        chooseMap->setCurrentIndex(0);
 
267
        return;
 
268
    }
 
269
 
 
270
    hhLimit = chooseMap->itemData(index).toList()[2].toInt();
 
271
    addInfoToPreview(mapImage);
 
272
}
 
273
 
 
274
// Should this add text to identify map size?
 
275
void HWMapContainer::addInfoToPreview(QPixmap image)
 
276
{
 
277
    QPixmap finalImage = QPixmap(image.size());
 
278
    finalImage.fill(QColor(0, 0, 0, 0));
 
279
 
 
280
    QPainter p(&finalImage);
 
281
    p.drawPixmap(image.rect(), image);
 
282
    //p.setPen(QColor(0xf4,0x9e,0xe9));
 
283
    p.setPen(QColor(0xff,0xcc,0x00));
 
284
    p.setBrush(QColor(0, 0, 0));
 
285
    p.drawRect(image.rect().width() - hhSmall.rect().width() - 28, 3, 40, 20);
 
286
    p.setFont(QFont("MS Shell Dlg", 10));
 
287
    p.drawText(image.rect().width() - hhSmall.rect().width() - 14 - (hhLimit > 9 ? 10 : 0), 18, QString::number(hhLimit));
 
288
    p.drawPixmap(image.rect().width() - hhSmall.rect().width() - 5, 5, hhSmall.rect().width(), hhSmall.rect().height(), hhSmall);
 
289
 
 
290
    imageButt->setIcon(finalImage);
 
291
    imageButt->setIconSize(image.size());
 
292
}
 
293
 
 
294
void HWMapContainer::changeImage()
 
295
{
 
296
    if (pMap)
 
297
    {
 
298
        disconnect(pMap, 0, this, SLOT(setImage(const QImage)));
 
299
        disconnect(pMap, 0, this, SLOT(setHHLimit(int)));
 
300
        pMap = 0;
 
301
    }
 
302
 
 
303
    pMap = new HWMap();
 
304
    connect(pMap, SIGNAL(ImageReceived(const QImage)), this, SLOT(setImage(const QImage)));
 
305
    connect(pMap, SIGNAL(HHLimitReceived(int)), this, SLOT(setHHLimit(int)));
 
306
    pMap->getImage(m_seed.toStdString(), getTemplateFilter(), mapgen, maze_size);
 
307
}
 
308
 
 
309
void HWMapContainer::themeSelected(int currentRow)
 
310
{
 
311
    QString theme = Themes->at(currentRow);
 
312
    QList<QVariant> mapInfoRegular;
 
313
    mapInfoRegular.push_back(QString("+rnd+"));
 
314
    mapInfoRegular.push_back(theme);
 
315
    mapInfoRegular.push_back(18);
 
316
    mapInfoRegular.push_back(false);
 
317
    chooseMap->setItemData(0, mapInfoRegular);
 
318
    QList<QVariant> mapInfoMaze;
 
319
    mapInfoMaze.push_back(QString("+maze+"));
 
320
    mapInfoMaze.push_back(theme);
 
321
    mapInfoMaze.push_back(18);
 
322
    mapInfoMaze.push_back(false);
 
323
    chooseMap->setItemData(1, mapInfoMaze);
 
324
    gbThemes->setIcon(QIcon(QString("%1/Themes/%2/icon.png").arg(datadir->absolutePath()).arg(theme)));
 
325
    emit themeChanged(theme);
 
326
}
 
327
 
 
328
QString HWMapContainer::getCurrentSeed() const
 
329
{
 
330
    return m_seed;
 
331
}
 
332
 
 
333
QString HWMapContainer::getCurrentMap() const
 
334
{
 
335
    if(chooseMap->currentIndex() <= 1) return QString();
 
336
    return chooseMap->itemData(chooseMap->currentIndex()).toList()[0].toString();
 
337
}
 
338
 
 
339
QString HWMapContainer::getCurrentTheme() const
 
340
{
 
341
    return chooseMap->itemData(chooseMap->currentIndex()).toList()[1].toString();
 
342
}
 
343
 
 
344
bool HWMapContainer::getCurrentIsMission() const
 
345
{
 
346
    if(!chooseMap->currentIndex()) return false;
 
347
    return chooseMap->itemData(chooseMap->currentIndex()).toList()[3].toBool();
 
348
}
 
349
 
 
350
int HWMapContainer::getCurrentHHLimit() const
 
351
{
 
352
    return hhLimit;
 
353
}
 
354
 
 
355
quint32 HWMapContainer::getTemplateFilter() const
 
356
{
 
357
    return CB_TemplateFilter->itemData(CB_TemplateFilter->currentIndex()).toInt();
 
358
}
 
359
 
 
360
void HWMapContainer::resizeEvent ( QResizeEvent * event )
 
361
{
 
362
  //imageButt->setIconSize(imageButt->size());
 
363
}
 
364
 
 
365
void HWMapContainer::setSeed(const QString & seed)
 
366
{
 
367
    m_seed = seed;
 
368
    changeImage();
 
369
}
 
370
 
 
371
void HWMapContainer::setMap(const QString & map)
 
372
{
 
373
    if(map == "+rnd+" || map == "+maze+")
 
374
    {
 
375
        changeImage();
 
376
        return;
 
377
    }
 
378
 
 
379
    int id = 0;
 
380
    for(int i = 0; i < chooseMap->count(); i++)
 
381
        if(!chooseMap->itemData(i).isNull() && chooseMap->itemData(i).toList()[0].toString() == map)
 
382
        {
 
383
            id = i;
 
384
            break;
 
385
        }
 
386
 
 
387
    if(id > 0) {
 
388
        if (pMap)
 
389
        {
 
390
            disconnect(pMap, 0, this, SLOT(setImage(const QImage)));
 
391
            disconnect(pMap, 0, this, SLOT(setHHLimit(int)));
 
392
            pMap = 0;
 
393
        }
 
394
        chooseMap->setCurrentIndex(id);
 
395
        loadMap(id);
 
396
    }
 
397
}
 
398
 
 
399
void HWMapContainer::setTheme(const QString & theme)
 
400
{
 
401
    QList<QListWidgetItem *> items = lwThemes->findItems(theme, Qt::MatchExactly);
 
402
    if(items.size())
 
403
        lwThemes->setCurrentItem(items.at(0));
 
404
}
 
405
 
 
406
void HWMapContainer::setRandomSeed()
 
407
{
 
408
    m_seed = QUuid::createUuid().toString();
 
409
    emit seedChanged(m_seed);
 
410
    changeImage();
 
411
}
 
412
 
 
413
void HWMapContainer::setRandomTheme()
 
414
{
 
415
    if(!Themes->size()) return;
 
416
    quint32 themeNum = rand() % Themes->size();
 
417
    lwThemes->setCurrentRow(themeNum);
 
418
}
 
419
 
 
420
void HWMapContainer::setTemplateFilter(int filter)
 
421
{
 
422
    CB_TemplateFilter->setCurrentIndex(filter);
 
423
}
 
424
 
 
425
void HWMapContainer::templateFilterChanged(int filter)
 
426
{
 
427
    emit newTemplateFilter(filter);
 
428
    changeImage();
 
429
}
 
430
 
 
431
MapGenerator HWMapContainer::get_mapgen(void) const
 
432
{
 
433
    return mapgen;
 
434
}
 
435
 
 
436
int HWMapContainer::get_maze_size(void) const
 
437
{
 
438
    return maze_size;
 
439
}
 
440
 
 
441
void HWMapContainer::setMaze_size(int size)
 
442
{
 
443
    maze_size = size;
 
444
    maze_size_selection->setCurrentIndex(size);
 
445
    emit maze_sizeChanged(size);
 
446
    changeImage();
 
447
}
 
448
 
 
449
void HWMapContainer::setMapgen(MapGenerator m)
 
450
{
 
451
    mapgen = m;
 
452
    emit mapgenChanged(m);
 
453
    changeImage();
 
454
}