merge
authorWolfgang Steffens <WolfgangSteff@gmail.com>
Mon, 28 May 2012 10:34:33 +0200
changeset 7136 6f3c9ec79338
parent 7129 0ce4f478ea6c (current diff)
parent 7135 4d863aadd0b2 (diff)
child 7138 f8248bcba8f1
merge
--- a/QTfrontend/game.cpp	Fri May 25 09:00:54 2012 +0200
+++ b/QTfrontend/game.cpp	Mon May 28 10:34:33 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	Fri May 25 09:00:54 2012 +0200
+++ b/QTfrontend/hwconsts.cpp.in	Mon May 28 10:34:33 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	Fri May 25 09:00:54 2012 +0200
+++ b/QTfrontend/hwconsts.h	Mon May 28 10:34:33 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/main.cpp	Fri May 25 09:00:54 2012 +0200
+++ b/QTfrontend/main.cpp	Mon May 28 10:34:33 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	Fri May 25 09:00:54 2012 +0200
+++ b/QTfrontend/net/newnetclient.cpp	Mon May 28 10:34:33 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	Fri May 25 09:00:54 2012 +0200
+++ b/QTfrontend/team.cpp	Mon May 28 10:34:33 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,6 +47,7 @@
     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;
     }
@@ -69,6 +72,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
@@ -89,6 +93,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,6 +105,7 @@
 
     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;
     }
@@ -248,10 +254,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 +340,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 +434,3 @@
 {
     m_wins++;
 }
-
--- a/QTfrontend/team.h	Fri May 25 09:00:54 2012 +0200
+++ b/QTfrontend/team.h	Mon May 28 10:34:33 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	Fri May 25 09:00:54 2012 +0200
+++ b/QTfrontend/ui/page/pageplayrecord.cpp	Mon May 28 10:34:33 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	Mon May 28 10:34:33 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	Mon May 28 10:34:33 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	Fri May 25 09:00:54 2012 +0200
+++ b/QTfrontend/ui/widget/frameTeam.cpp	Mon May 28 10:34:33 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	Fri May 25 09:00:54 2012 +0200
+++ b/QTfrontend/ui/widget/frameTeam.h	Mon May 28 10:34:33 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/teamselhelper.cpp	Fri May 25 09:00:54 2012 +0200
+++ b/QTfrontend/ui/widget/teamselhelper.cpp	Mon May 28 10:34:33 2012 +0200
@@ -26,6 +26,7 @@
 #include "teamselhelper.h"
 #include "hwconsts.h"
 #include "frameTeam.h"
+#include "colorwidget.h"
 
 void TeamLabel::teamButtonClicked()
 {
@@ -34,7 +35,7 @@
 
 TeamShowWidget::TeamShowWidget(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 +68,15 @@
     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->setGeometry(0, 0, 26, 26);
+        connect(colorWidget, SIGNAL(colorChanged(int)), this, SLOT(onColorChanged(int)));
+        colorWidget->setColor(m_parentFrameTeams->getNextColor());
+        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	Fri May 25 09:00:54 2012 +0200
+++ b/QTfrontend/ui/widget/teamselhelper.h	Mon May 28 10:34:33 2012 +0200
@@ -28,6 +28,8 @@
 #include "teamselect.h"
 #include "hedgehogerWidget.h"
 
+class ColorWidget;
+
 class TeamLabel : public QLabel
 {
         Q_OBJECT
@@ -48,13 +50,12 @@
         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);
@@ -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	Fri May 25 09:00:54 2012 +0200
+++ b/gameServer/Actions.hs	Mon May 28 10:34:33 2012 +0200
@@ -312,17 +312,19 @@
     ri <- clientRoomA
     thisRoomChans <- liftM (map sendChan) $ roomClientsS ri
     clNick <- client's nick
-    
-    mapM_ processAction [
+    answerRemovedTeams <- io $ 
+         room'sM rnc (map (\t -> AnswerClients thisRoomChans ["REMOVE_TEAM", t]) . leftTeams . fromJust . gameInfo) ri
+         
+    mapM_ processAction $ 
         SaveReplay
-        , ModifyRoom
+        : ModifyRoom
             (\r -> r{
                 gameInfo = Nothing,
                 readyPlayers = 0
                 }
             )
-        , UnreadyRoomClients
-        ]
+        : UnreadyRoomClients
+        : answerRemovedTeams
 
         
 processAction (SendTeamRemovalMessage teamName) = do
@@ -352,7 +354,10 @@
     inGame <- io $ room'sM rnc (isJust . gameInfo) ri
     chans <- othersChans
     mapM_ processAction $ 
-        ModifyRoom (\r -> r{teams = Prelude.filter (\t -> teamName /= teamname t) $ teams r})
+        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]
 
--- a/gameServer/CoreTypes.hs	Fri May 25 09:00:54 2012 +0200
+++ b/gameServer/CoreTypes.hs	Mon May 28 10:34:33 2012 +0200
@@ -67,6 +67,7 @@
     GameInfo
     {
         roundMsgs :: Seq B.ByteString,
+        leftTeams :: [B.ByteString],
         teamsAtStart :: [TeamInfo],
         teamsInGameNumber :: Int,
         allPlayersHaveRegisteredAccounts :: Bool,
@@ -78,6 +79,7 @@
 newGameInfo = 
     GameInfo
         Data.Sequence.empty
+        []
 
 data RoomInfo =
     RoomInfo
--- a/hedgewars/GSHandlers.inc	Fri May 25 09:00:54 2012 +0200
+++ b/hedgewars/GSHandlers.inc	Mon May 28 10:34:33 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/uGears.pas	Fri May 25 09:00:54 2012 +0200
+++ b/hedgewars/uGears.pas	Mon May 28 10:34:33 2012 +0200
@@ -455,6 +455,7 @@
     end;
 
 ScriptCall('onGameTick');
+if GameTicks mod 20 = 0 then ScriptCall('onGameTick20');
 inc(GameTicks)
 end;
 
--- a/hedgewars/uScript.pas	Fri May 25 09:00:54 2012 +0200
+++ b/hedgewars/uScript.pas	Mon May 28 10:34:33 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/project_files/hedgewars.pro	Fri May 25 09:00:54 2012 +0200
+++ b/project_files/hedgewars.pro	Mon May 28 10:34:33 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/Space_Invasion.lua	Fri May 25 09:00:54 2012 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.lua	Mon May 28 10:34:33 2012 +0200
@@ -297,7 +297,6 @@
 -- tumbler goods
 ---------------------
 
-local moveTimer = 0
 local leftOn = false
 local rightOn = false
 local upOn = false
@@ -318,7 +317,6 @@
 local primShotsMax = 5
 local primShotsLeft = 0
 
-local TimeLeftCounter = 0
 local TimeLeft = 0
 local stopMovement = false
 local tumbleStarted = false
@@ -331,8 +329,6 @@
 local shockwaveHealth = 0
 local shockwaveRad = 300
 
-local Timer100 = 0
-
 local vTag = {}
 
 -----------------------------------------------
@@ -346,8 +342,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
@@ -1160,7 +1155,7 @@
 end
 
 
-function onGameTick()
+function onGameTick20()
 
 
 	--WriteLnToConsole("Start of GameTick")
@@ -1175,9 +1170,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 +1194,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 +1218,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 +1236,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 +1301,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
@@ -2261,10 +2250,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 +2258,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 +2273,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 +2291,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 +2335,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