Merge
authorMedo <smaxein@googlemail.com>
Tue, 29 May 2012 22:33:10 +0200
changeset 7149 08a30dd92900
parent 7123 9fe1c4091dd1 (current diff)
parent 7146 a822413207c9 (diff)
child 7152 f49254ddfc67
Merge
--- a/QTfrontend/drawmapscene.cpp	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/drawmapscene.cpp	Tue May 29 22:33:10 2012 +0200
@@ -271,7 +271,8 @@
 
             quint8 penWidth = flags & 0x3f;
             m_pen.setWidth(deserializePenWidth(penWidth));
-            if(flags & 0x40)
+            params.erasing = flags & 0x40;
+            if(params.erasing)
                 m_pen.setBrush(m_eraser);
             else
                 m_pen.setBrush(m_brush);
--- a/QTfrontend/game.cpp	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/game.cpp	Tue May 29 22:33:10 2012 +0200
@@ -124,7 +124,7 @@
 
     HWTeam team1;
     team1.setDifficulty(0);
-    team1.setColor(QColor(colors[0]));
+    team1.setColor(0);
     team1.setNumHedgehogs(4);
     HWNamegen::teamRandomNames(team1,true);
     HWProto::addStringListToBuffer(teamscfg,
@@ -132,7 +132,7 @@
 
     HWTeam team2;
     team2.setDifficulty(4);
-    team2.setColor(QColor(colors[1]));
+    team2.setColor(1);
     team2.setNumHedgehogs(4);
     do
         HWNamegen::teamRandomNames(team2,true);
--- a/QTfrontend/hwconsts.cpp.in	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/hwconsts.cpp.in	Tue May 29 22:33:10 2012 +0200
@@ -16,6 +16,8 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
+#include <QStandardItemModel>
+
 #include "hwconsts.h"
 
 QString * cProtoVer = new QString("${HEDGEWARS_PROTO_VER}");
@@ -70,3 +72,19 @@
 
 int season = SEASON_NONE;
 int years_since_foundation = 0;
+
+QStandardItemModel * colorsModel;
+
+void hwConstsInit()
+{
+    colorsModel = new QStandardItemModel();
+
+    int i = 0;
+    while(colors[i])
+    {
+        QStandardItem * item = new QStandardItem();
+        item->setData(QColor(colors[i]));
+        colorsModel->appendRow(item);
+        ++i;
+    }
+}
--- a/QTfrontend/hwconsts.h	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/hwconsts.h	Tue May 29 22:33:10 2012 +0200
@@ -38,13 +38,14 @@
 extern int cMaxTeams;
 extern int cMinServerVersion;
 
-class QStringListModel;
+class QStandardItemModel;
 
 extern QString * cDefaultAmmoStore;
 extern int cAmmoNumber;
 extern QList< QPair<QString, QString> > cDefaultAmmos;
 
-extern unsigned int colors[];
+//extern unsigned int colors[];
+extern QStandardItemModel * colorsModel;
 
 extern QString * netHost;
 extern quint16 netPort;
@@ -59,6 +60,8 @@
 //Could be used to implement a text/graphic like "This is the xxth birthday of hedgewars" or similar
 extern int years_since_foundation;
 
+void hwConstsInit();
+
 #endif
 
 #define HEDGEHOGS_PER_TEAM           8
--- a/QTfrontend/hwform.cpp	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/hwform.cpp	Tue May 29 22:33:10 2012 +0200
@@ -1484,9 +1484,9 @@
         ui.pageNetGame->setRoomName(hwnet->getRoom());
         ui.pageNetGame->restrictJoins->disconnect(hwnet);
         ui.pageNetGame->restrictTeamAdds->disconnect(hwnet);
+        ui.pageNetGame->disconnect(hwnet, SLOT(updateRoomName(const QString&)));
         connect(ui.pageNetGame->BtnStart, SIGNAL(clicked()), hwnet, SLOT(startGame()));
-        connect(ui.pageNetGame, SIGNAL(askForUpdateRoomName(const QString &)),
-                hwnet, SLOT(updateRoomName(const QString &)));
+        connect(ui.pageNetGame, SIGNAL(askForUpdateRoomName(const QString &)), hwnet, SLOT(updateRoomName(const QString &)));
         connect(ui.pageNetGame->restrictJoins, SIGNAL(triggered()), hwnet, SLOT(toggleRestrictJoins()));
         connect(ui.pageNetGame->restrictTeamAdds, SIGNAL(triggered()), hwnet, SLOT(toggleRestrictTeamAdds()));
         connect(ui.pageNetGame->pGameCFG->GameSchemes->model(),
--- a/QTfrontend/main.cpp	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/main.cpp	Tue May 29 22:33:10 2012 +0200
@@ -103,6 +103,9 @@
 int main(int argc, char *argv[])
 {
     HWApplication app(argc, argv);
+
+    hwConstsInit();
+
     app.setAttribute(Qt::AA_DontShowIconsInMenus,false);
 
     QStringList arguments = app.arguments();
--- a/QTfrontend/net/newnetclient.cpp	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/net/newnetclient.cpp	Tue May 29 22:33:10 2012 +0200
@@ -106,7 +106,7 @@
 {
     QString cmd = QString("ADD_TEAM") + delimeter +
                   team.name() + delimeter +
-                  team.color().name() + delimeter +
+                  QString::number(team.color()) + delimeter +
                   team.grave() + delimeter +
                   team.fort() + delimeter +
                   team.voicepack() + delimeter +
@@ -613,7 +613,7 @@
             return;
         }
         HWTeam tmptm(lst[1]);
-        tmptm.setColor(QColor(lst[2]));
+        tmptm.setColor(lst[2].toInt());
         emit teamColorChanged(tmptm);
         return;
     }
@@ -687,7 +687,7 @@
         RawSendNet(QString("TEAM_COLOR%1%2%1%3")
                    .arg(delimeter)
                    .arg(team.name())
-                   .arg(team.color().name()));
+                   .arg(team.color()));
 }
 
 void HWNewNet::onParamChanged(const QString & param, const QStringList & value)
--- a/QTfrontend/team.cpp	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/team.cpp	Tue May 29 22:33:10 2012 +0200
@@ -22,6 +22,7 @@
 #include <QLineEdit>
 #include <QCryptographicHash>
 #include <QSettings>
+#include <QStandardItemModel>
 
 #include "team.h"
 #include "hwform.h"
@@ -36,6 +37,7 @@
     OldTeamName = m_name;
     for (int i = 0; i < HEDGEHOGS_PER_TEAM; i++)
     {
+        m_hedgehogs.append(HWHog());
         m_hedgehogs[i].Name = (QLineEdit::tr("hedgehog %1").arg(i+1));
         m_hedgehogs[i].Hat = "NoHat";
     }
@@ -45,12 +47,14 @@
     m_flag = "hedgewars";
     for(int i = 0; i < BINDS_NUMBER; i++)
     {
+        m_binds.append(BindAction());
         m_binds[i].action = cbinds[i].action;
         m_binds[i].strbind = cbinds[i].strbind;
     }
     m_rounds = 0;
     m_wins = 0;
     m_campaignProgress = 0;
+    m_color = 0;
 }
 
 HWTeam::HWTeam(const QStringList& strLst) :
@@ -69,6 +73,7 @@
     m_difficulty = strLst[6].toUInt();
     for(int i = 0; i < HEDGEHOGS_PER_TEAM; i++)
     {
+        m_hedgehogs.append(HWHog());
         m_hedgehogs[i].Name=strLst[i * 2 + 7];
         m_hedgehogs[i].Hat=strLst[i * 2 + 8];
 // Somehow claymore managed an empty hat.  Until we figure out how, this should avoid a repeat
@@ -78,6 +83,7 @@
     m_rounds = 0;
     m_wins = 0;
     m_campaignProgress = 0;
+    m_color = 0;
 }
 
 HWTeam::HWTeam() :
@@ -89,6 +95,7 @@
     m_name = QString("Team");
     for (int i = 0; i < HEDGEHOGS_PER_TEAM; i++)
     {
+        m_hedgehogs.append(HWHog());
         m_hedgehogs[i].Name.sprintf("hedgehog %d", i);
         m_hedgehogs[i].Hat = "NoHat";
     }
@@ -100,12 +107,14 @@
 
     for(int i = 0; i < BINDS_NUMBER; i++)
     {
+        m_binds.append(BindAction());
         m_binds[i].action = cbinds[i].action;
         m_binds[i].strbind = cbinds[i].strbind;
     }
     m_rounds = 0;
     m_wins = 0;
     m_campaignProgress = 0;
+    m_color = 0;
 }
 
 HWTeam::HWTeam(const HWTeam & other) :
@@ -151,6 +160,7 @@
         m_campaignProgress = other.m_campaignProgress;
         m_rounds = other.m_rounds;
         m_wins = other.m_wins;
+        m_color = other.m_color;
     }
 
     return *this;
@@ -248,10 +258,10 @@
     QStringList sl;
     if (m_isNetTeam)
     {
-        sl.push_back(QString("eaddteam %3 %1 %2").arg(m_color.rgb() & 0xffffff).arg(m_name).arg(QString(QCryptographicHash::hash(m_owner.toLatin1(), QCryptographicHash::Md5).toHex())));
+        sl.push_back(QString("eaddteam %3 %1 %2").arg(qcolor().rgb() & 0xffffff).arg(m_name).arg(QString(QCryptographicHash::hash(m_owner.toLatin1(), QCryptographicHash::Md5).toHex())));
         sl.push_back("erdriven");
     }
-    else sl.push_back(QString("eaddteam %3 %1 %2").arg(m_color.rgb() & 0xffffff).arg(m_name).arg(playerHash));
+    else sl.push_back(QString("eaddteam %3 %1 %2").arg(qcolor().rgb() & 0xffffff).arg(m_name).arg(playerHash));
 
     sl.push_back(QString("egrave " + m_grave));
     sl.push_back(QString("efort " + m_fort));
@@ -334,13 +344,19 @@
 }
 
 // color
-QColor HWTeam::color() const
+int HWTeam::color() const
 {
     return m_color;
 }
-void HWTeam::setColor(const QColor & color)
+
+QColor HWTeam::qcolor() const
 {
-    m_color = color;
+    return colorsModel->item(m_color)->data().value<QColor>();
+}
+
+void HWTeam::setColor(int color)
+{
+    m_color = color % colorsModel->rowCount();
 }
 
 
@@ -422,4 +438,3 @@
 {
     m_wins++;
 }
-
--- a/QTfrontend/team.h	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/team.h	Tue May 29 22:33:10 2012 +0200
@@ -63,7 +63,8 @@
 
         // attribute getters
         unsigned int campaignProgress() const;
-        QColor color() const;
+        int color() const;
+        QColor qcolor() const;
         unsigned int difficulty() const;
         QString flag() const;
         QString fort() const;
@@ -78,7 +79,6 @@
 
         // attribute setters
         void bindKey(unsigned int idx, const QString & key);
-        void setColor(const QColor & color);
         void setDifficulty(unsigned int level);
         void setFlag(const QString & flag);
         void setFort(const QString & fort);
@@ -100,6 +100,8 @@
         bool operator < (const HWTeam& t1) const;
         HWTeam & operator = (const HWTeam & other);
 
+public slots:
+        void setColor(int color);
 
     private:
 
@@ -111,13 +113,13 @@
         QString m_fort;
         QString m_flag;
         QString m_voicepack;
-        HWHog m_hedgehogs[HEDGEHOGS_PER_TEAM];
+        QList<HWHog> m_hedgehogs;
         quint8 m_difficulty;
-        BindAction m_binds[BINDS_NUMBER];
+        QList<BindAction> m_binds;
 
         // class members that contain info for the current game setup
         quint8 m_numHedgehogs;
-        QColor m_color;
+        int m_color;
         bool m_isNetTeam;
         QString m_owner;
 
--- a/QTfrontend/ui/page/pageplayrecord.cpp	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/ui/page/pageplayrecord.cpp	Tue May 29 22:33:10 2012 +0200
@@ -110,7 +110,7 @@
 
 void PagePlayDemo::refresh()
 {
-    if (this->isVisible());
+    if (this->isVisible())
         FillFromDir(recType);
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QTfrontend/ui/widget/colorwidget.cpp	Tue May 29 22:33:10 2012 +0200
@@ -0,0 +1,71 @@
+#include <QStandardItemModel>
+#include <QMouseEvent>
+#include <QWheelEvent>
+
+#include "colorwidget.h"
+#include "hwconsts.h"
+
+ColorWidget::ColorWidget(QStandardItemModel *colorsModel, QWidget *parent) :
+    QWidget(parent)
+{
+    m_colorsModel = colorsModel;
+
+    setColor(0);
+    setStyleSheet("");
+    setAutoFillBackground(true);
+
+    connect(m_colorsModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataChanged(QModelIndex,QModelIndex)));
+}
+
+ColorWidget::~ColorWidget()
+{
+
+}
+
+void ColorWidget::setColor(int color)
+{
+    Q_ASSERT_X(color >= 0 && color < m_colorsModel->rowCount(), "ColorWidget::setColor", "Color index out of range");
+
+    m_color = color;
+
+    QStandardItem * item = m_colorsModel->item(m_color);
+
+    QPalette p = palette();
+    p.setColor(QPalette::Window, item->data().value<QColor>());
+    setPalette(p);
+
+    emit colorChanged(m_color);
+}
+
+int ColorWidget::getColor()
+{
+    return m_color;
+}
+
+void ColorWidget::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+    if(m_color >= topLeft.row() && m_color <= bottomRight.row())
+        setColor(m_color);
+}
+
+void ColorWidget::mousePressEvent(QMouseEvent * event)
+{
+    switch(event->button())
+    {
+        case Qt::LeftButton:
+            setColor((m_color + 1) % m_colorsModel->rowCount());
+            break;
+        case Qt::RightButton:
+            setColor((m_color + m_colorsModel->rowCount() - 1) % m_colorsModel->rowCount());
+            break;
+        default:;
+    }
+}
+
+void ColorWidget::wheelEvent(QWheelEvent *event)
+{
+    if(event->delta() > 0)
+        setColor((m_color + 1) % m_colorsModel->rowCount());
+    else
+        setColor((m_color + m_colorsModel->rowCount() - 1) % m_colorsModel->rowCount());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QTfrontend/ui/widget/colorwidget.h	Tue May 29 22:33:10 2012 +0200
@@ -0,0 +1,40 @@
+#ifndef COLORWIDGET_H
+#define COLORWIDGET_H
+
+#include <QWidget>
+#include <QModelIndex>
+
+namespace Ui {
+class ColorWidget;
+}
+
+class QStandardItemModel;
+
+class ColorWidget : public QWidget
+{
+    Q_OBJECT
+    
+public:
+    explicit ColorWidget(QStandardItemModel *colorsModel, QWidget *parent = 0);
+    ~ColorWidget();
+
+    void setColors(QStandardItemModel * colorsModel);
+    void setColor(int color);
+    int getColor();
+
+signals:
+    void colorChanged(int color);
+    
+private:
+    int m_color;
+    QStandardItemModel * m_colorsModel;
+
+private slots:
+    void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+
+protected:
+    void mousePressEvent(QMouseEvent * event);
+    void wheelEvent(QWheelEvent * event);
+};
+
+#endif // COLORWIDGET_H
--- a/QTfrontend/ui/widget/frameTeam.cpp	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/ui/widget/frameTeam.cpp	Tue May 29 22:33:10 2012 +0200
@@ -20,6 +20,7 @@
 #include <QResizeEvent>
 #include <QCoreApplication>
 #include <QPalette>
+#include <QStandardItemModel>
 
 #include "frameTeam.h"
 #include "teamselhelper.h"
@@ -36,10 +37,6 @@
     mainLayout.setSpacing(1);
     mainLayout.setContentsMargins(4, 4, 4, 4);
 
-    int i = 0;
-    while(colors[i] != 0)
-        availableColors.push_back(QColor(colors[i++]));
-
     resetColors();
     this->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
 }
@@ -57,19 +54,13 @@
 
 void FrameTeams::resetColors()
 {
-    currentColor = availableColors.last(); // ensure next color is the first one
+    currentColor = colorsModel->rowCount() - 1; // ensure next color is the first one
 }
 
-QColor FrameTeams::getNextColor() const
+int FrameTeams::getNextColor()
 {
-    int idx = availableColors.indexOf(currentColor);
-
-    idx++;
-
-    if (idx >= availableColors.size())
-        idx = 0;
-
-    return availableColors.at(idx);
+    currentColor = (currentColor + 1) % colorsModel->rowCount();
+    return currentColor;
 }
 
 void FrameTeams::addTeam(HWTeam team, bool willPlay)
--- a/QTfrontend/ui/widget/frameTeam.h	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/ui/widget/frameTeam.h	Tue May 29 22:33:10 2012 +0200
@@ -42,7 +42,7 @@
         void setHHNum(const HWTeam& team);
         void setTeamColor(const HWTeam& team);
         void setInteractivity(bool interactive);
-        QColor getNextColor() const;
+        int getNextColor();
         QSize sizeHint() const;
 
     signals:
@@ -55,8 +55,7 @@
     private:
         const int maxHedgehogsPerGame;
         int overallHedgehogs;
-        QList<QColor> availableColors;
-        QColor currentColor;
+        int currentColor;
 
         void emitTeamColorChanged(const HWTeam& team);
 
--- a/QTfrontend/ui/widget/teamselect.cpp	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/ui/widget/teamselect.cpp	Tue May 29 22:33:10 2012 +0200
@@ -169,8 +169,8 @@
         // return if max playing teams reached
         if(framePlaying->isFullTeams()) return;
         // dont playing team => playing
+        itDontPlay->setColor(framePlaying->getNextColor());
         team=*itDontPlay; // for net team info saving in framePlaying (we have only name with netID from network)
-        itDontPlay->setColor(framePlaying->getNextColor());
         curPlayingTeams.push_back(*itDontPlay);
         if(!m_acceptOuter) emit teamWillPlay(*itDontPlay);
         m_curNotPlayingTeams.erase(itDontPlay);
@@ -295,6 +295,6 @@
 
 void TeamSelWidget::pre_changeTeamStatus(HWTeam team)
 {
-    team.setColor(framePlaying->getNextColor());
+    //team.setColor(framePlaying->getNextColor());
     emit acceptRequested(team);
 }
--- a/QTfrontend/ui/widget/teamselhelper.cpp	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/ui/widget/teamselhelper.cpp	Tue May 29 22:33:10 2012 +0200
@@ -20,21 +20,23 @@
 #include <QPixmap>
 #include <QPainter>
 #include <QStyleFactory>
+#include <QDebug>
 
 #include <algorithm>
 
 #include "teamselhelper.h"
 #include "hwconsts.h"
 #include "frameTeam.h"
+#include "colorwidget.h"
 
 void TeamLabel::teamButtonClicked()
 {
     emit teamActivated(text());
 }
 
-TeamShowWidget::TeamShowWidget(HWTeam team, bool isPlaying, FrameTeams * parent) :
+TeamShowWidget::TeamShowWidget(const HWTeam & team, bool isPlaying, FrameTeams * parent) :
     QWidget(parent), mainLayout(this), m_team(team), m_isPlaying(isPlaying), phhoger(0),
-    colorButt(0)
+    colorWidget(0)
 {
     m_parentFrameTeams = parent;
     QPalette newPalette = palette();
@@ -67,17 +69,14 @@
     if(m_isPlaying)
     {
         // team color
-        colorButt = new QPushButton(this);
-        colorButt->setMaximumWidth(26);
-        colorButt->setMinimumHeight(26);
-        colorButt->setGeometry(0, 0, 26, 26);
-
-        incrementTeamColor();
-        connect(colorButt, SIGNAL(clicked()), this, SLOT(incrementTeamColor()));
-
-        colorButt->setContextMenuPolicy(Qt::CustomContextMenu);
-        connect(colorButt, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(decrementTeamColor()));
-        mainLayout.addWidget(colorButt);
+        colorWidget = new ColorWidget(colorsModel, this);
+        colorWidget->setMinimumWidth(26);
+        colorWidget->setMaximumWidth(26);
+        colorWidget->setMinimumHeight(26);
+        colorWidget->setMaximumHeight(26);
+        colorWidget->setColor(team.color());
+        connect(colorWidget, SIGNAL(colorChanged(int)), this, SLOT(onColorChanged(int)));
+        mainLayout.addWidget(colorWidget);
 
         phhoger = new CHedgehogerWidget(QImage(":/res/hh25x25.png"), QImage(":/res/hh25x25grey.png"), this);
         connect(phhoger, SIGNAL(hedgehogsNumChanged()), this, SLOT(hhNumChanged()));
@@ -99,7 +98,7 @@
         butt->setEnabled(interactive);
     }
 
-    colorButt->setEnabled(interactive);
+    colorWidget->setEnabled(interactive);
     phhoger->setEnabled(interactive);
 }
 
@@ -128,35 +127,16 @@
   return params;
 }*/
 
-void TeamShowWidget::incrementTeamColor()
-{
-    changeTeamColor(m_parentFrameTeams->getNextColor());
-}
-void TeamShowWidget::decrementTeamColor()
+
+void TeamShowWidget::changeTeamColor(int color)
 {
-    const QList<QColor> & availColors = m_parentFrameTeams->availableColors;
-    int idx = availColors.indexOf(m_parentFrameTeams->currentColor);
-
-    idx--;
-
-    if (idx < 0)
-        idx = availColors.size() - 1;
-
-    changeTeamColor(availColors.at(idx));
+    colorWidget->setColor(color);
 }
 
-void TeamShowWidget::changeTeamColor(QColor color)
+void TeamShowWidget::onColorChanged(int color)
 {
-    QColor & curColor = m_parentFrameTeams->currentColor;
-    curColor = color;
+    m_team.setColor(color);
 
-    colorButt->setStyleSheet(QString("QPushButton{"
-                                     "background-color: %1;"
-                                     "border-width: 1px;"
-                                     "border-radius: 2px;"
-                                     "}").arg(curColor.name()));
-
-    m_team.setColor(color);
     emit teamColorChanged(m_team);
 }
 
--- a/QTfrontend/ui/widget/teamselhelper.h	Wed May 23 22:46:37 2012 +0200
+++ b/QTfrontend/ui/widget/teamselhelper.h	Tue May 29 22:33:10 2012 +0200
@@ -28,6 +28,8 @@
 #include "teamselect.h"
 #include "hedgehogerWidget.h"
 
+class ColorWidget;
+
 class TeamLabel : public QLabel
 {
         Q_OBJECT
@@ -48,16 +50,15 @@
         Q_OBJECT
 
     public slots:
-        void incrementTeamColor();
-        void decrementTeamColor();
-        void changeTeamColor(QColor color=QColor());
+        void changeTeamColor(int color = 0);
         void hhNumChanged();
 
     private slots:
         void activateTeam();
+        void onColorChanged(int color);
 
     public:
-        TeamShowWidget(HWTeam team, bool isPlaying, FrameTeams * parent);
+        TeamShowWidget(const HWTeam &team, bool isPlaying, FrameTeams * parent);
         void setPlaying(bool isPlaying);
         void setHHNum(unsigned int num);
         void setInteractivity(bool interactive);
@@ -69,10 +70,9 @@
         HWTeam m_team;
         bool m_isPlaying;
         CHedgehogerWidget* phhoger;
-        QPushButton* colorButt;
+        ColorWidget* colorWidget;
         QPushButton* butt;
         FrameTeams * m_parentFrameTeams;
-// QPushButton* bText;
 
     signals:
         void teamStatusChanged(HWTeam team);
--- a/gameServer/Actions.hs	Wed May 23 22:46:37 2012 +0200
+++ b/gameServer/Actions.hs	Tue May 29 22:33:10 2012 +0200
@@ -314,8 +314,9 @@
     clNick <- client's nick
     answerRemovedTeams <- io $ 
          room'sM rnc (map (\t -> AnswerClients thisRoomChans ["REMOVE_TEAM", t]) . leftTeams . fromJust . gameInfo) ri
-    
-    mapM_ processAction $ SaveReplay
+         
+    mapM_ processAction $ 
+        SaveReplay
         : ModifyRoom
             (\r -> r{
                 gameInfo = Nothing,
@@ -332,9 +333,8 @@
         AnswerClients chans ["EM", rmTeamMsg],
         ModifyRoom (\r -> r{
                 gameInfo = liftM (\g -> g{
-                teamsInGameNumber = teamsInGameNumber g - 1
-                , roundMsgs = roundMsgs g Seq.|> rmTeamMsg
-                , leftTeams = teamName : leftTeams g
+                    teamsInGameNumber = teamsInGameNumber g - 1
+                    , roundMsgs = roundMsgs g Seq.|> rmTeamMsg
                 }) $ gameInfo r
             })
         ]
@@ -353,16 +353,13 @@
     ri <- clientRoomA
     inGame <- io $ room'sM rnc (isJust . gameInfo) ri
     chans <- othersChans
-    if not $ inGame then
-            mapM_ processAction [
-                ModifyRoom (\r -> r{teams = Prelude.filter (\t -> teamName /= teamname t) $ teams r})
-                , AnswerClients chans ["REMOVE_TEAM", teamName]
-                ]
-        else
-            mapM_ processAction [
-                ModifyRoom (\r -> r{teams = Prelude.filter (\t -> teamName /= teamname t) $ teams r})
-                , SendTeamRemovalMessage teamName
-                ]
+    mapM_ processAction $ 
+        ModifyRoom (\r -> r{
+            teams = Prelude.filter (\t -> teamName /= teamname t) $ teams r
+            , gameInfo = liftM (\g -> g{leftTeams = teamName : leftTeams g}) $ gameInfo r
+            })
+        : AnswerClients chans ["REMOVE_TEAM", teamName]
+        : [SendTeamRemovalMessage teamName | inGame]
 
 
 processAction (RemoveClientTeams clId) = do
--- a/hedgewars/GSHandlers.inc	Wed May 23 22:46:37 2012 +0200
+++ b/hedgewars/GSHandlers.inc	Tue May 29 22:33:10 2012 +0200
@@ -616,7 +616,7 @@
         // Solid pixel encountered
         else if ((xx and LAND_WIDTH_MASK) = 0) and (Land[yy, xx] <> 0) then
             begin
-            lf:= Land[yy, xx] and (lfObject or lfBasic);
+            lf:= Land[yy, xx] and (lfObject or lfBasic or lfIndestructible);
             // If there's room below keep falling
             if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (Land[yy-1, xx] = 0) then
                 begin
@@ -5439,7 +5439,8 @@
 var 
     HHGear, iter: PGear;
     ndX, ndY: hwFloat;
-    t, gX, gY: LongInt;
+    i, t, gX, gY: LongInt;
+    hogs: TPGearArray;
 begin
     HHGear := Gear^.Hedgehog^.Gear;
     if (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) then
@@ -5465,7 +5466,9 @@
         HedgehogChAngle(HHGear);
         ndX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _4;
         ndY:= -AngleCos(HHGear^.Angle) * _4;
-        if (ndX <> dX) or (ndY <> dY) then
+        if (ndX <> dX) or (ndY <> dY) or 
+           ((Target.X <> NoPointX) and (Target.X and LAND_WIDTH_MASK = 0) and 
+             (Target.Y and LAND_HEIGHT_MASK = 0) and ((Land[Target.Y, Target.X] = 0))) then
             begin
             dX:= ndX;
             dY:= ndY;
@@ -5474,7 +5477,7 @@
             LastDamage:= nil;
             X:= HHGear^.X;
             Y:= HHGear^.Y;
-// unfreeze all semifrozen hogs
+(* unfreeze all semifrozen hogs - make this generic hog cleanup
             iter := GearsList;
             while iter <> nil do
                 begin
@@ -5482,7 +5485,7 @@
                    (iter^.Hedgehog^.Effects[heFrozen] < 0) then 
                     iter^.Hedgehog^.Effects[heFrozen]:= 0;
                 iter:= iter^.NextGear
-                end
+                end *)
             end
         else
             begin
@@ -5498,33 +5501,30 @@
                     X:= HHGear^.X;
                     Y:= HHGear^.Y
                     end;
+// freeze nearby hogs
+                if GameTicks mod 10 = 0 then dec(Gear^.Health);
+                hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Radius);
+                if Length(hogs) > 0 then
+                    for i:= 0 to Length(hogs) - 1 do
+                        if hogs[i] <> HHGear then
+                            begin
+                            //if Gear^.Hedgehog^.Effects[heFrozen]:= 0;
+                            end;
                 inc(Pos)
                 end
-            else if (gY > cWaterLine) or
+            else if (t > 400) and ((gY > cWaterLine) or
                     (((gX and LAND_WIDTH_MASK = 0) and (gY and LAND_HEIGHT_MASK = 0))
-                        and ((Land[gY, gX] and $FF00 and not lfIce <> 0) or
-                             ((Land[gY, gX] and $00FF <> 0) and (t > 400)))) then
+                        and (Land[gY, gX] <> 0))) then
                 begin
                 Target.X:= gX;
                 Target.Y:= gY;
-                if (gX and LAND_WIDTH_MASK = 0) and (gY and LAND_HEIGHT_MASK = 0) then
-                    begin
-                    LandPixels[gY, gX]:= $FFFFFFFF; // just testing
-                    UpdateLandTexture(gX, 1, gY, 1);
-                    if Land[gY, gX] and $00FF <> 0 then // locate and tag hogs
-                        begin
-                    //GearsNear(X, Y, gtHedgehog, Radius);
-                        end
-                    end;
                 X:= HHGear^.X;
                 Y:= HHGear^.Y
                 end;
             if (gX > LAND_WIDTH*2) or
                     (gX < -LAND_WIDTH) or
                     (gY < -LAND_HEIGHT) or
-                    (gY > LAND_HEIGHT+512) or
-                    (((gX and LAND_WIDTH_MASK = 0) and (gY and LAND_HEIGHT_MASK = 0))
-                     and (Land[gy, gX] > $FF)) then
+                    (gY > LAND_HEIGHT+512) then
                 begin
                 X:= HHGear^.X;
                 Y:= HHGear^.Y
--- a/hedgewars/pas2c.h	Wed May 23 22:46:37 2012 +0200
+++ b/hedgewars/pas2c.h	Tue May 29 22:33:10 2012 +0200
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <stddef.h>
 #include <stdint.h>
 #include <stdbool.h>
 #include <wchar.h>
@@ -56,17 +57,6 @@
 typedef int PtrInt;
 typedef wchar_t widechar;
 
-#ifdef __GNUG__
-#define NULL __null
-#else   /* G++ */
-/* shield NULL definition for non-gnu parsers */
-#ifndef __cplusplus
-#define NULL ((void *)0)
-#else
-#define NULL 0
-#endif  /* __cplusplus */
-#endif  /* G++ */
-
 #define new(a) __new((void **)&a, sizeof(*(a)))
 void __new(void ** p, int size);
 #define dispose(a) __dispose(a, sizeof(*(a)))
@@ -85,6 +75,7 @@
 bool _strcomparec(string255 a, char b);
 bool _strncompare(string255 a, string255 b);
 char * _pchar(string255 s);
+string255 pchar2str(char * s);
 
 int Length(string255 a);
 string255 copy(string255 a, int s, int l);
@@ -113,6 +104,7 @@
 void close(int f);
 
 void write(string255 s);
+void writeLn(string255 s);
 
 bool DirectoryExists(string255 dir);
 bool FileExists(string255 filename);
--- a/hedgewars/pas2cSystem.pas	Wed May 23 22:46:37 2012 +0200
+++ b/hedgewars/pas2cSystem.pas	Tue May 29 22:33:10 2012 +0200
@@ -68,6 +68,7 @@
     Length, StrToInt : function : integer;
     SetLength, val : procedure;
     _pchar : function : PChar;
+    pchar2str : function : string;
     memcpy : procedure;
 
     assign, rewrite, reset, flush, BlockWrite, BlockRead, close : procedure;
--- a/hedgewars/uAI.pas	Wed May 23 22:46:37 2012 +0200
+++ b/hedgewars/uAI.pas	Tue May 29 22:33:10 2012 +0200
@@ -142,41 +142,41 @@
                     inc(BestActions.Score, Score);
                     BestActions.isWalkingToABetterPlace:= false;
 
-                if (ap.Angle > 0) then
-                    AddAction(BestActions, aia_LookRight, 0, 200, 0, 0)
-            else if (ap.Angle < 0) then
-                AddAction(BestActions, aia_LookLeft, 0, 200, 0, 0);
+                    AddAction(BestActions, aia_Weapon, Longword(a), 300 + random(400), 0, 0);
 
-                AddAction(BestActions, aia_Weapon, Longword(a), 300 + random(400), 0, 0);
-                
-                if (ap.Time <> 0) then
-                    AddAction(BestActions, aia_Timer, ap.Time div 1000, 400, 0, 0);
-                if (Ammoz[a].Ammo.Propz and ammoprop_NoCrosshair) = 0 then
-                    begin
-                    ap.Angle:= LongInt(Me^.Angle) - Abs(ap.Angle);
-                    if ap.Angle > 0 then
+                    if (ap.Angle > 0) then
+                        AddAction(BestActions, aia_LookRight, 0, 200, 0, 0)
+                    else if (ap.Angle < 0) then
+                        AddAction(BestActions, aia_LookLeft, 0, 200, 0, 0);
+                    
+                    if (ap.Time <> 0) then
+                        AddAction(BestActions, aia_Timer, ap.Time div 1000, 400, 0, 0);
+                    if (Ammoz[a].Ammo.Propz and ammoprop_NoCrosshair) = 0 then
                         begin
-                        AddAction(BestActions, aia_Up, aim_push, 300 + random(250), 0, 0);
-                        AddAction(BestActions, aia_Up, aim_release, ap.Angle, 0, 0)
-                        end
-                    else if ap.Angle < 0 then
+                        ap.Angle:= LongInt(Me^.Angle) - Abs(ap.Angle);
+                        if ap.Angle > 0 then
+                            begin
+                            AddAction(BestActions, aia_Up, aim_push, 300 + random(250), 0, 0);
+                            AddAction(BestActions, aia_Up, aim_release, ap.Angle, 0, 0)
+                            end
+                        else if ap.Angle < 0 then
+                            begin
+                            AddAction(BestActions, aia_Down, aim_push, 300 + random(250), 0, 0);
+                            AddAction(BestActions, aia_Down, aim_release, -ap.Angle, 0, 0)
+                            end
+                        end;
+                    if (Ammoz[a].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
                         begin
-                        AddAction(BestActions, aia_Down, aim_push, 300 + random(250), 0, 0);
-                        AddAction(BestActions, aia_Down, aim_release, -ap.Angle, 0, 0)
-                        end
-                    end;
-                if (Ammoz[a].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
-                    begin
-                    AddAction(BestActions, aia_Put, 0, 1, ap.AttackPutX, ap.AttackPutY)
-                    end;
-                if (Ammoz[a].Ammo.Propz and ammoprop_AttackingPut) = 0 then
-                    begin
-                    AddAction(BestActions, aia_attack, aim_push, 650 + random(300), 0, 0);
-                    AddAction(BestActions, aia_attack, aim_release, ap.Power, 0, 0);
-                    end;
-                if ap.ExplR > 0 then
-                    AddAction(BestActions, aia_AwareExpl, ap.ExplR, 10, ap.ExplX, ap.ExplY);
-                end
+                        AddAction(BestActions, aia_Put, 0, 1, ap.AttackPutX, ap.AttackPutY)
+                        end;
+                    if (Ammoz[a].Ammo.Propz and ammoprop_AttackingPut) = 0 then
+                        begin
+                        AddAction(BestActions, aia_attack, aim_push, 650 + random(300), 0, 0);
+                        AddAction(BestActions, aia_attack, aim_release, ap.Power, 0, 0);
+                        end;
+                    if ap.ExplR > 0 then
+                        AddAction(BestActions, aia_AwareExpl, ap.ExplR, 10, ap.ExplX, ap.ExplY);
+                    end
             end;
         if a = High(TAmmoType) then
             a:= Low(TAmmoType)
@@ -205,10 +205,6 @@
 
 BotLevel:= Me^.Hedgehog^.BotLevel;
 
-tmp:= random(2) + 1;
-Push(0, Actions, Me^, tmp);
-Push(0, Actions, Me^, tmp xor 3);
-
 if (Me^.State and gstAttacked) = 0 then
     maxticks:= Max(0, TurnTimeLeft - 5000 - LongWord(4000 * BotLevel))
 else
@@ -221,8 +217,12 @@
 BaseRate:= Max(BestRate, 0);
 
 if (Ammoz[Me^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
-    AddAction(Actions, aia_Weapon, Longword(amNothing), 100 + random(200), 0, 0);
+    AddAction(Actions, aia_Weapon, Longword(amSkip), 100 + random(200), 0, 0);
 
+tmp:= random(2) + 1;
+Push(0, Actions, Me^, tmp);
+Push(0, Actions, Me^, tmp xor 3);
+    
 while (Stack.Count > 0) and (not StopThinking) and (GameFlags and gfArtillery = 0) do
     begin
     Pop(ticks, Actions, Me^);
--- a/hedgewars/uAIActions.pas	Wed May 23 22:46:37 2012 +0200
+++ b/hedgewars/uAIActions.pas	Tue May 29 22:33:10 2012 +0200
@@ -176,7 +176,8 @@
                     exit
                     end
                 else
-                    begin CheckHang(Me);
+                    begin 
+                    CheckHang(Me);
                     exit
                     end;
                             
@@ -194,7 +195,8 @@
                     exit
                     end
                 else
-                    begin CheckHang(Me);
+                    begin 
+                    CheckHang(Me);
                     exit
                     end;
             aia_LookLeft:
--- a/hedgewars/uAIAmmoTests.pas	Wed May 23 22:46:37 2012 +0200
+++ b/hedgewars/uAIAmmoTests.pas	Tue May 29 22:33:10 2012 +0200
@@ -364,7 +364,7 @@
         Vx:= ((Targ.X+10) - meX) / (TestTime + tDelta)
     else
         Vx:= ((Targ.X-10) - meX) / (TestTime + tDelta);
-    Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Y-150) - meY) / (TestTime + tDelta);
+    Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Y-50) - meY) / (TestTime + tDelta);
     r:= sqr(Vx)+sqr(Vy);
     if not (r > 1) then
         begin
@@ -388,7 +388,7 @@
      if valueResult < Score then
         begin
         ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
-        ap.Power:= trunc(sqrt(r) * cMaxPower * 0.9) + AIrndSign(random(Level) * 15);
+        ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15);
         ap.Time:= TestTime;
         ap.ExplR:= 90;
         ap.ExplX:= EX;
@@ -416,7 +416,7 @@
 repeat
     inc(TestTime, 1000);
     Vx:= (Targ.X - meX) / (TestTime + tDelta);
-    Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Y-200) - meY) / (TestTime + tDelta);
+    Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Y-50) - meY) / (TestTime + tDelta);
     r:= sqr(Vx)+sqr(Vy);
     if not (r > 1) then
         begin
@@ -424,30 +424,31 @@
         y:= meY;
         dY:= -Vy;
         t:= TestTime;
-    repeat
-        x:= x + Vx;
-        y:= y + dY;
-        dY:= dY + cGravityf;
-        dec(t)
-    until TestCollExcludingMe(Me, trunc(x), trunc(y), 5) or (t = 0);
-    EX:= trunc(x);
-    EY:= trunc(y);
-    if t < 50 then 
-        Score:= RateExplosion(Me, EX, EY, 381)
-    else 
-        Score:= BadTurn;
+        repeat
+            x:= x + Vx;
+            y:= y + dY;
+            dY:= dY + cGravityf;
+            dec(t)
+        until TestCollExcludingMe(Me, trunc(x), trunc(y), 7) or (t = 0);
         
-    if valueResult < Score then
-        begin
-        ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
-        ap.Power:= trunc(sqrt(r) * cMaxPower * 0.9) + AIrndSign(random(Level) * 15);
-        ap.Time:= TestTime;
-        ap.ExplR:= 300;
-        ap.ExplX:= EX;
-        ap.ExplY:= EY;
-        valueResult:= Score
-        end;
-    end
+        EX:= trunc(x);
+        EY:= trunc(y);
+        if t < 50 then 
+            Score:= RateExplosion(Me, EX, EY, 200) + RateExplosion(Me, EX, EY + 120, 200)
+        else 
+            Score:= BadTurn;
+            
+        if valueResult < Score then
+            begin
+            ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
+            ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15);
+            ap.Time:= TestTime;
+            ap.ExplR:= 300;
+            ap.ExplX:= EX;
+            ap.ExplY:= EY;
+            valueResult:= Score
+            end;
+        end
 until (TestTime = 4000);
 TestWatermelon:= valueResult
 end;
@@ -457,15 +458,15 @@
     var A, B, D, T: real;
         C: LongInt;
     begin
-        A:= sqr(cGravityf) * 0.25;
+        A:= sqr(cGravityf);
         B:= - cGravityf * (TY - MY) - 1;
         C:= sqr(TY - MY) + sqr(TX - MX);
-        D:= sqr(B) - (A * C * 4);
+        D:= sqr(B) - A * C;
         if D >= 0 then
             begin
-            D:= ( - B + sqrt(D)) * 0.5 / A;
+            D:= sqrt(D) - B;
             if D >= 0 then
-                T:= sqrt(D)
+                T:= sqrt(D * 2 / A)
             else
                 T:= 0;
             Solve:= trunc(T)
@@ -662,14 +663,15 @@
     x, y: real;
 begin
 Level:= Level; // avoid compiler hint
+TestFirePunch:= BadTurn;
 ap.ExplR:= 0;
 ap.Time:= 0;
 ap.Power:= 1;
 ap.Angle:= hwSign(Me^.dX);
 x:= hwFloat2Float(Me^.X);
 y:= hwFloat2Float(Me^.Y);
-if (Abs(trunc(x) - Targ.X) > 25)
-or (Abs(trunc(y) - 50 - Targ.Y) > 50) then
+if (Abs(trunc(x) - Targ.X) < 25)
+    and (Abs(trunc(y) - 50 - Targ.Y) < 50) then
     begin
 // TODO - find out WTH this works.
     if TestColl(trunc(x), trunc(y) - 16, 6) and 
@@ -772,6 +774,7 @@
 if (Level > 3) then
     exit(BadTurn);
 
+ap.Angle:= 0;
 ap.AttackPutX:= Targ.X;
 ap.AttackPutY:= Targ.Y;
 
--- a/hedgewars/uConsole.pas	Wed May 23 22:46:37 2012 +0200
+++ b/hedgewars/uConsole.pas	Tue May 29 22:33:10 2012 +0200
@@ -49,8 +49,10 @@
 end;
 
 procedure WriteToConsole(s: shortstring);
+{$IFNDEF NOCONSOLE}
 var Len: LongInt;
     done: boolean;
+{$ENDIF}
 begin
 {$IFNDEF NOCONSOLE}
 AddFileLog('[Con] ' + s);
--- a/hedgewars/uDebug.pas	Wed May 23 22:46:37 2012 +0200
+++ b/hedgewars/uDebug.pas	Tue May 29 22:33:10 2012 +0200
@@ -47,9 +47,13 @@
 end;
 
 procedure SDLTry(Assert: boolean; isFatal: boolean);
+var s: shortstring;
 begin
 if not Assert then
-    OutError(SDL_GetError, isFatal)
+    begin
+    s:= SDL_GetError();
+    OutError(s, isFatal)
+    end
 end;
 
 end.
--- a/hedgewars/uGears.pas	Wed May 23 22:46:37 2012 +0200
+++ b/hedgewars/uGears.pas	Tue May 29 22:33:10 2012 +0200
@@ -455,6 +455,7 @@
     end;
 
 ScriptCall('onGameTick');
+if GameTicks mod 20 = 0 then ScriptCall('onGameTick20');
 inc(GameTicks)
 end;
 
--- a/hedgewars/uInputHandler.pas	Wed May 23 22:46:37 2012 +0200
+++ b/hedgewars/uInputHandler.pas	Tue May 29 22:33:10 2012 +0200
@@ -45,7 +45,7 @@
 implementation
 uses uConsole, uCommands, uMisc, uVariables, uConsts, uUtils, uDebug;
 
-var tkbd: TKeyboardState;
+var tkbd: array[0..cKeyMaxIndex] of boolean;
     quitKeyCode: Byte;
     KeyNames: array [0..cKeyMaxIndex] of string[15];
     CurrentBinds: TBinds;
@@ -64,35 +64,40 @@
     Trusted: boolean;
     s      : string;
 begin
+
+if not(tkbd[code] xor KeyDown) then exit;
+tkbd[code]:= KeyDown;
+
+
 hideAmmoMenu:= false;
 Trusted:= (CurrentTeam <> nil)
           and (not CurrentTeam^.ExtDriven)
           and (CurrentHedgehog^.BotLevel = 0);
 
-tkbd[code]:= ord(KeyDown);
+
 
 // ctrl/cmd + q to close engine and frontend
 if(KeyDown and (code = quitKeyCode)) then
     begin
 {$IFDEF DARWIN}
-    if ((tkbd[KeyNameToCode('left_meta')] = 1) or (tkbd[KeyNameToCode('right_meta')] = 1)) then
+    if tkbd[KeyNameToCode('left_meta')] or tkbd[KeyNameToCode('right_meta')] then
 {$ELSE}
-    if ((tkbd[KeyNameToCode('left_ctrl')] = 1) or (tkbd[KeyNameToCode('right_ctrl')] = 1)) then
+    if tkbd[KeyNameToCode('left_ctrl')] or tkbd[KeyNameToCode('right_ctrl')] then
 {$ENDIF}
         ParseCommand('halt', true);    
     end;
 
 if CurrentBinds[code][0] <> #0 then
     begin
-    if (code > 3) and (KeyDown) and not ((CurrentBinds[code] = 'put') or (CurrentBinds[code] = 'ammomenu') or (CurrentBinds[code] = '+cur_u') or (CurrentBinds[code] = '+cur_d') or (CurrentBinds[code] = '+cur_l') or (CurrentBinds[code] = '+cur_r')) then hideAmmoMenu:= true;
+    if (code > 3) and KeyDown and not ((CurrentBinds[code] = 'put') or (CurrentBinds[code] = 'ammomenu') or (CurrentBinds[code] = '+cur_u') or (CurrentBinds[code] = '+cur_d') or (CurrentBinds[code] = '+cur_l') or (CurrentBinds[code] = '+cur_r')) then hideAmmoMenu:= true;
 
-    if (KeyDown) then
+    if KeyDown then
         begin
         ParseCommand(CurrentBinds[code], Trusted);
         if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then
             ParseCommand('gencmd R', true)
         end
-    else if (CurrentBinds[code][1] = '+') and not KeyDown then
+    else if (CurrentBinds[code][1] = '+') then
         begin
         s:= CurrentBinds[code];
         s[1]:= '-';
@@ -101,7 +106,6 @@
             ParseCommand('gencmd R', true)
         end;
     end
-
 end;
 
 procedure ProcessKey(event: TSDL_KeyboardEvent); inline;
@@ -129,7 +133,7 @@
 var t: LongInt;
 begin
 for t:= 0 to cKeyMaxIndex do
-    if(tkbd[t] <> 0) then
+    if tkbd[t] then
         ProcessKey(t, False);
 end;
 
@@ -251,10 +255,10 @@
 
 procedure FreezeEnterKey;
 begin
-    tkbd[3]:= 1;
-    tkbd[13]:= 1;
-    tkbd[27]:= 1;
-    tkbd[271]:= 1;
+    tkbd[3]:= True;
+    tkbd[13]:= True;
+    tkbd[27]:= True;
+    tkbd[271]:= True;
 end;
 
 var Controller: array [0..5] of PSDL_Joystick;
--- a/hedgewars/uScript.pas	Wed May 23 22:46:37 2012 +0200
+++ b/hedgewars/uScript.pas	Tue May 29 22:33:10 2012 +0200
@@ -150,7 +150,7 @@
         lua_pushnil(L);
         end
     else
-        lua_pushinteger(L, lua_tointeger(L, 2) div lua_tointeger(L, 1));
+        lua_pushinteger(L, lua_tointeger(L, 1) div lua_tointeger(L, 2));
     lc_div := 1;
 end;
 
--- a/hedgewars/uStore.pas	Wed May 23 22:46:37 2012 +0200
+++ b/hedgewars/uStore.pas	Tue May 29 22:33:10 2012 +0200
@@ -825,7 +825,7 @@
 if caption = '' then
     caption:= '???';
 if subcaption = '' then
-    subcaption:= ' ';
+    subcaption:= _S' ';
 
 font:= CheckCJKFont(caption,fnt16);
 font:= CheckCJKFont(subcaption,font);
@@ -909,9 +909,9 @@
         r:= WriteInRect(tmpsurf, cFontBorder + 2, r.y + r.h, $ff707070, font, tmpline);
 
         // render highlighted caption (if there is a ':')
-        tmpline2:= '';
+        tmpline2:= _S'';
         SplitByChar(tmpline, tmpline2, ':');
-        if tmpline2 <> '' then
+        if tmpline2 <> _S'' then
             WriteInRect(tmpsurf, cFontBorder + 2, r2.y + r2.h, $ffc7c7c7, font, tmpline + ':');
         end
     end;
@@ -954,7 +954,7 @@
 r.h:= 32;
 
 // default (no extra text)
-extra:= '';
+extra:= _S'';
 extracolor:= 0;
 
 if (CurrentTeam <> nil) and (Ammoz[atype].SkipTurns >= CurrentTeam^.Clan^.TurnNumber) then // weapon or utility is not yet available
@@ -969,7 +969,7 @@
     end
 else
     begin
-    extra:= '';
+    extra:= _S'';
     extracolor:= 0;
     end;
 
--- a/project_files/hedgewars.pro	Wed May 23 22:46:37 2012 +0200
+++ b/project_files/hedgewars.pro	Tue May 29 22:33:10 2012 +0200
@@ -26,7 +26,6 @@
     ../QTfrontend/model/MapModel.h \
     ../QTfrontend/model/ammoSchemeModel.h \
     ../QTfrontend/model/netserverslist.h \
-    ../QTfrontend/model/hats.h \
     ../QTfrontend/ui/page/pagedrawmap.h \
     ../QTfrontend/ui/page/pagedata.h \
     ../QTfrontend/ui/page/pagetraining.h \
@@ -102,12 +101,14 @@
     ../QTfrontend/ui/widget/qpushbuttonwithsound.h \
     ../QTfrontend/ui/page/pagefeedback.h \
     ../QTfrontend/model/roomslistmodel.h \
-    ../QTfrontend/ui/dialog/input_password.h
+    ../QTfrontend/ui/dialog/input_password.h \
+    ../QTfrontend/ui/widget/colorwidget.h \
+    ../QTfrontend/model/HatModel.h \
+    ../QTfrontend/model/GameStyleModel.h
 
 SOURCES += ../QTfrontend/model/ammoSchemeModel.cpp \
     ../QTfrontend/model/MapModel.cpp \
     ../QTfrontend/model/ThemeModel.cpp \
-    ../QTfrontend/model/hats.cpp \
     ../QTfrontend/model/netserverslist.cpp \
     ../QTfrontend/ui/qaspectratiolayout.cpp \
     ../QTfrontend/ui/page/pagemain.cpp \
@@ -182,7 +183,10 @@
     ../QTfrontend/ui/widget/qpushbuttonwithsound.cpp \
     ../QTfrontend/ui/page/pagefeedback.cpp \
     ../QTfrontend/model/roomslistmodel.cpp \
-    ../QTfrontend/ui/dialog/input_password.cpp
+    ../QTfrontend/ui/dialog/input_password.cpp \
+    ../QTfrontend/ui/widget/colorwidget.cpp \
+    ../QTfrontend/model/HatModel.cpp \
+    ../QTfrontend/model/GameStyleModel.cpp
 
 win32 {
     SOURCES += ../QTfrontend/xfire.cpp
@@ -236,3 +240,5 @@
     CONFIG += warn_on x86
     #CONFIG += x86 ppc x86_64 ppc64
 }
+
+FORMS +=
--- a/share/hedgewars/Data/Scripts/Multiplayer/Highlander.lua	Wed May 23 22:46:37 2012 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Highlander.lua	Tue May 29 22:33:10 2012 +0200
@@ -180,7 +180,7 @@
 end
 
 
-function onGameTick()
+function onGameTick20()
 
 	if (CurrentHedgehog ~= nil) then
 
--- a/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua	Wed May 23 22:46:37 2012 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua	Tue May 29 22:33:10 2012 +0200
@@ -107,7 +107,6 @@
 --------
 
 local cGear = nil
-local gTimer = 0
 
 local bestClan = nil
 local bestTime = nil
@@ -116,7 +115,6 @@
 local gameOver = false
 local racerActive = false
 local trackTime = 0
-local wpCheckCounter = 0
 
 local wpCirc = {}
 local wpX = {}
@@ -536,6 +534,7 @@
 			loc("NOT ENOUGH WAYPOINTS"),
 			loc("Place more waypoints using the 'Air Attack' weapon."), 2, 4000)
 			AddAmmo(CurrentHedgehog, amAirAttack, 4000)
+            ParseCommand("setweap " .. string.char(amAirAttack))
 		end
 	end
 
@@ -552,28 +551,32 @@
 
 end
 
-function onGameTick()
+function onGameTick20()
 
 	-- airstrike detected, convert this into a potential waypoint spot
 	if cGear ~= nil then
-		x,y = GetGearTarget(cGear)
+		x,y = GetGearPosition(cGear)
+        if x > -9000 then
+            x,y = GetGearTarget(cGear)
 
-		DeleteGear(cGear)
 
-		if TestRectForObstacle(x-20, y-20, x+20, y+20, true) then
-			AddCaption(loc("Please place the way-point in the open, within the map boundaries."))
-			PlaySound(sndDenied)
-		elseif (y > WaterLine-50) then
-			AddCaption(loc("Please place the way-point further from the waterline."))
-			PlaySound(sndDenied)
-		else
-			PlaceWayPoint(x, y)
-			if wpCount == wpLimit then
-				AddCaption(loc("Race complexity limit reached."))
-				DisableTumbler()
-			end
-		end
-
+            if TestRectForObstacle(x-20, y-20, x+20, y+20, true) then
+                AddCaption(loc("Please place the way-point in the open, within the map boundaries."))
+                PlaySound(sndDenied)
+            elseif (y > WaterLine-50) then
+                AddCaption(loc("Please place the way-point further from the waterline."))
+                PlaySound(sndDenied)
+            else
+                PlaceWayPoint(x, y)
+                if wpCount == wpLimit then
+                    AddCaption(loc("Race complexity limit reached."))
+                    DisableTumbler()
+                end
+            end
+        else
+            DeleteGear(cGear)
+        end
+        SetGearPosition(cGear, -10000, 0)
 	end
 
 
@@ -613,19 +616,19 @@
 		if (racerActive == true) and (gameBegun == true) then
 
 			--ghost
-			gTimer = gTimer + 1
-			if gTimer == 40 then
-				gTimer = 0
+			if GameTime%40 == 0 then
 				HandleGhost()
 			end
 
-			trackTime = trackTime + 1
+			trackTime = trackTime + 20
 
-			wpCheckCounter = wpCheckCounter + 1
-			if (wpCheckCounter == 100) then
-
-				wpCheckCounter = 0
-				AddCaption(trackTime/1000,GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2)
+			if GameTime%100 == 0 then
+                
+                if trackTime%1000 == 0 then
+                    AddCaption((trackTime/1000)..'.0',GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2)
+                else
+                    AddCaption(trackTime/1000,GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2)
+                end
 
 				if (CheckWaypoints() == true) then
 					AdjustScores()
@@ -640,7 +643,7 @@
 
 
 		-- if the player has expended his tunbling time, stop him tumbling
-		if TurnTimeLeft <= 1 then
+		if TurnTimeLeft <= 20 then
 			DisableTumbler()
 		end
 
--- a/share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.lua	Wed May 23 22:46:37 2012 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.lua	Tue May 29 22:33:10 2012 +0200
@@ -235,7 +235,6 @@
 -- some console stuff
 local shellID = 0
 local explosivesID = 0
-local luaGameTicks = 0
 
 -- gaudyRacer
 local boosterOn = false
@@ -297,7 +296,6 @@
 -- tumbler goods
 ---------------------
 
-local moveTimer = 0
 local leftOn = false
 local rightOn = false
 local upOn = false
@@ -318,7 +316,6 @@
 local primShotsMax = 5
 local primShotsLeft = 0
 
-local TimeLeftCounter = 0
 local TimeLeft = 0
 local stopMovement = false
 local tumbleStarted = false
@@ -331,8 +328,6 @@
 local shockwaveHealth = 0
 local shockwaveRad = 300
 
-local Timer100 = 0
-
 local vTag = {}
 
 -----------------------------------------------
@@ -346,8 +341,7 @@
 local FadeAlpha = 0 -- used to fade the circles out gracefully when player dies
 local pTimer = 0 -- tracking projectiles following player
 
-local circAdjustTimer = 0		-- handle adjustment of circs direction
-local m2Count = 0		-- handle speed of circs
+--local m2Count = 0		-- handle speed of circs
 
 local vCirc = {}
 local vCCount = 0
@@ -356,7 +350,6 @@
 local rCircX = {}
 local rCircY = {}
 local rAlpha = 255
-local rPingTimer = 0
 local radShotsLeft = 0
 
 local vCircActive = {}
@@ -1160,11 +1153,10 @@
 end
 
 
-function onGameTick()
+function onGameTick20()
 
 
 	--WriteLnToConsole("Start of GameTick")
-	luaGameTicks = luaGameTicks + 1 -- GameTime
 
 	HandleCircles()
 
@@ -1175,9 +1167,7 @@
 	--end
 
 
-	Timer100 = Timer100 + 1
-	if Timer100 >= 100 then
-		Timer100 = 0
+	if GameTime%100 == 0 then
 
 		if beam == true then
 			shieldHealth = shieldHealth - 1
@@ -1201,7 +1191,7 @@
 		--runOnGears(HandleLifeSpan)
 		--runOnGears(DeleteFarFlungBarrel)
 
-		if CirclesAreGo == true then
+		if CirclesAreGo == true and CurrentHedgehog ~= nil then
 			CheckDistances()
 			--runOnGears(CheckVarious)	-- used to be in handletracking for some bizarre reason
 			--runOnGears(ProjectileTrack)
@@ -1225,7 +1215,7 @@
 		if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then
 			--AddCaption(LOC_NOT("Good to go!"))
 			tumbleStarted = true
-			TimeLeft = (TurnTime/1000)	--45
+			TimeLeft = div(TurnTime, 1000)	--45
 			FadeAlpha = 0
 			rAlpha = 255
 			AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtGrenade, 0, 0, 0, 1)
@@ -1243,9 +1233,7 @@
 		--AddCaption(GetX(CurrentHedgehog) .. ";" .. GetY(CurrentHedgehog) )
 
 		-- Calculate and display turn time
-		TimeLeftCounter = TimeLeftCounter + 1
-		if TimeLeftCounter == 1000 then
-			TimeLeftCounter = 0
+		if GameTime%1000 == 0 then
 			TimeLeft = TimeLeft - 1
 
 			if TimeLeft >= 0 then
@@ -1310,10 +1298,8 @@
 			end
 
 			-- handle movement based on IO
-			moveTimer = moveTimer + 1
-			if moveTimer == 100 then -- 100
+			if GameTime%100 == 0 then -- 100
 				--nw WriteLnToConsole("Start of Player MoveTimer")
-				moveTimer = 0
 
 				---------------
 				-- new trail code
@@ -2143,9 +2129,7 @@
 
 	if rAlpha ~= 255 then
 
-		rPingTimer = rPingTimer + 1
-		if rPingTimer == 100 then
-			rPingTimer = 0
+		if GameTime%100 == 0 then
 
 			rAlpha = rAlpha + 5
 			if rAlpha >= 255 then
@@ -2261,10 +2245,7 @@
 	end
 
 	-- alter the circles velocities
-	circAdjustTimer = circAdjustTimer + 1
-	if circAdjustTimer == 2000 then
-
-		circAdjustTimer = 0
+	if GameTime%2000 == 0 then
 
 		for i = 0,(vCCount-1) do
 
@@ -2272,9 +2253,9 @@
 			-- or make them move in random directions
 
 			if vCircX[i] > 5500 then
-				vCircDX[i] = -5	--5 circmovchange
+				vCircDX[i] = -4	--5 circmovchange
 			elseif vCircX[i] < -1500 then
-				vCircDX[i] = 5	--5 circmovchange
+				vCircDX[i] = 4	--5 circmovchange
 			else
 
 				z = GetRandom(2)
@@ -2287,9 +2268,9 @@
 			end
 
 			if vCircY[i] > 1500 then
-				vCircDY[i] = -5	--5 circmovchange
+				vCircDY[i] = -4	--5 circmovchange
 			elseif vCircY[i] < -2900 then
-				vCircDY[i] = 5	--5 circmovchange
+				vCircDY[i] = 4	--5 circmovchange
 			else
 				z = GetRandom(2)
 				if z == 1 then
@@ -2305,10 +2286,10 @@
 	end
 
 	-- move the circles according to their current velocities
-	m2Count = m2Count + 1
-	if m2Count == 25 then	--25 circmovchange
-
-		m2Count = 0
+	--m2Count = m2Count + 1
+	--if m2Count == 25 then	--25 circmovchange
+
+	--	m2Count = 0
 		for i = 0,(vCCount-1) do
 			vCircX[i] = vCircX[i] + vCircDX[i]
 			vCircY[i] = vCircY[i] + vCircDY[i]
@@ -2349,7 +2330,7 @@
 
 
 
-	end
+	--end
 
 	for i = 0,(vCCount-1) do
 		g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(vCirc[i])		-- vCircCol[i] g10
--- a/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua	Wed May 23 22:46:37 2012 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua	Tue May 29 22:33:10 2012 +0200
@@ -217,17 +217,17 @@
 	switchStage = 0
 end
 
-function onGameTick()
+function onGameTick20()
 
 	if (CurrentHedgehog ~= nil) then
 
 		currName = GetHogName(CurrentHedgehog)
 
-		if (currName ~= lastName) and (switchStage > 100) then
+		if (currName ~= lastName) and (switchStage > 5) then
 			AddCaption(loc("Switched to ") .. currName .. "!")
 		end
 
-		if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) and (switchStage < 100) then
+		if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) and (switchStage < 5) then
 
 			AddCaption(loc("Prepare yourself") .. ", " .. currName .. "!")
 
@@ -246,12 +246,12 @@
 				elseif switchStage == 3 then
 					SetGearMessage(CurrentHedgehog,gmAttack)
 				elseif switchStage == 4 then
-					switchStage = 110
+					switchStage = 6
 					AddAmmo(CurrentHedgehog, amSwitch, 0)
 				end
 
 			else
-				switchStage = 110
+				switchStage = 6
 			end
 
 
--- a/tools/pas2c.hs	Wed May 23 22:46:37 2012 +0200
+++ b/tools/pas2c.hs	Tue May 29 22:33:10 2012 +0200
@@ -39,10 +39,11 @@
         uniqCounter :: Int,
         toMangle :: Set.Set String,
         currentUnit :: String,
+        currentFunctionResult :: String,
         namespaces :: Map.Map String Records
     }
     
-emptyState = RenderState Map.empty "" BTUnknown [] 0 Set.empty ""
+emptyState = RenderState Map.empty "" BTUnknown [] 0 Set.empty "" ""
 
 getUniq :: State RenderState Int
 getUniq = do
@@ -381,13 +382,19 @@
     t <- type2C returnType
     t'<- gets lastType
     n <- id2C IOInsert $ setBaseType (BTFunction (numberOfDeclarations params) t') name
-    (p, ph) <- withState' (\st -> st{currentScope = Map.insertWith un (map toLower rv) [(render res, t')] $ currentScope st}) $ do
+    
+    let isVoid = case returnType of
+            VoidType -> True
+            _ -> False
+            
+    (p, ph) <- withState' (\st -> st{currentScope = Map.insertWith un (map toLower rv) [(render res, t')] $ currentScope st
+            , currentFunctionResult = if isVoid then [] else render res}) $ do
         p <- functionParams2C params
         ph <- liftM2 ($+$) (typesAndVars2C False tvars) (phrase2C' phrase)
         return (p, ph)
-    let phrasesBlock = case returnType of
-            VoidType -> ph
-            _ -> t empty <+> res <> semi $+$ ph $+$ text "return" <+> res <> semi
+        
+    let phrasesBlock = if isVoid then ph else t empty <+> res <> semi $+$ ph $+$ text "return" <+> res <> semi
+    
     return [ 
         t empty <+> n <> parens p
         $+$
@@ -615,6 +622,18 @@
         (BTFunction {}, (Reference r')) -> do
             e <- ref2C r'
             return $ r <+> text "=" <+> e <> semi
+        (BTString, _) -> do
+            e <- expr2C expr
+            lt <- gets lastType
+            case lt of
+                -- assume pointer to char for simplicity
+                BTPointerTo _ -> do
+                    e <- expr2C $ Reference $ FunCall [Reference $ RefExpression expr] (SimpleReference (Identifier "pchar2str" BTUnknown))
+                    return $ r <+> text "=" <+> e <> semi
+                BTString -> do
+                    e <- expr2C expr
+                    return $ r <+> text "=" <+> e <> semi
+                _ -> error $ "Assignment to string from " ++ show lt
         (BTArray (Range _) _ _, _) -> phrase2C $ 
             ProcCall (FunCall
                 [
@@ -671,7 +690,12 @@
     return $ text "do" <+> p <+> text "while" <> parens (text "!" <> parens e) <> semi
 phrase2C NOP = return $ text ";"
 
-phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "exit" BTUnknown))) = return $ text "return" <> semi
+phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "exit" BTUnknown))) = do
+    f <- gets currentFunctionResult
+    if null f then
+        return $ text "return" <> semi
+        else
+        return $ text "return" <+> text f <> semi
 phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "break" BTUnknown))) = return $ text "break" <> semi
 phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "continue" BTUnknown))) = return $ text "continue" <> semi
 phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "exit" BTUnknown))) = liftM (\e -> text "return" <+> e <> semi) $ expr2C e