...
authornemo
Mon, 05 Dec 2011 18:38:25 -0500
changeset 6503 854856e698b4
parent 6502 714e1a535864 (diff)
parent 6451 8c00b29bde8e (current diff)
child 6504 81d4c369b714
...
--- a/.hgeol	Mon Nov 28 06:55:55 2011 +0100
+++ b/.hgeol	Mon Dec 05 18:38:25 2011 -0500
@@ -6,3 +6,4 @@
 **.txt = native
 **.pas = native
 **.inc = native
+**.hs = native
--- a/.hgignore	Mon Nov 28 06:55:55 2011 +0100
+++ b/.hgignore	Mon Dec 05 18:38:25 2011 -0500
@@ -6,8 +6,10 @@
 glob:Makefile
 glob:bin
 glob:*.hi
+glob:*.ppu
 glob:*.*~
 glob:*.core
+glob:hedgewars.pro.user
 glob:config.inc
 glob:cmake_install.cmake
 glob:QTfrontend/hwconsts.cpp
--- a/QTfrontend/M3InstallController.m	Mon Nov 28 06:55:55 2011 +0100
+++ b/QTfrontend/M3InstallController.m	Mon Dec 05 18:38:25 2011 -0500
@@ -36,7 +36,7 @@
 @implementation M3InstallController
 
 - (id) init {
-	if (self = [super init]) {
+        if ((self = [super init])) {
 		NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
 		NSString *title = [NSString stringWithFormat:NSLocalizedString(@"%@ is currently running from a disk image", @"AppName is currently running from a disk image"), appName];
 		NSString *body = [NSString stringWithFormat:NSLocalizedString(@"Would you like to install %@ in your applications folder before quitting?", @"Would you like to install App Name in your applications folder before quitting?"), appName];
--- a/QTfrontend/NSWorkspace_RBAdditions.m	Mon Nov 28 06:55:55 2011 +0100
+++ b/QTfrontend/NSWorkspace_RBAdditions.m	Mon Dec 05 18:38:25 2011 -0500
@@ -9,6 +9,7 @@
 #import "NSWorkspace_RBAdditions.h"
 #include <IOKit/IOKitLib.h>
 #include <sys/mount.h>
+#include <mach/mach.h>
 
 NSString* NSWorkspace_RBfstypename = @"NSWorkspace_RBfstypename";
 NSString* NSWorkspace_RBmntonname = @"NSWorkspace_RBmntonname";
@@ -66,14 +67,14 @@
 				partition = [props objectForKey:@"Content"];
 			} else if (IOObjectConformsTo(nextParent,"IODiskImageBlockStorageDeviceOutKernel")) {
 				NSData* data = nil;
-				if (data = [[props objectForKey:@"Protocol Characteristics"] objectForKey:@"Virtual Interface Location Path"]) {
+                                if ((data = [[props objectForKey:@"Protocol Characteristics"] objectForKey:@"Virtual Interface Location Path"])) {
 					image = [[[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding] autorelease];
 				}
 			} else if (IOObjectConformsTo(nextParent,"IOHDIXHDDriveInKernel")) {
 				image = [props objectForKey:@"KDIURLPath"];
 			}
 			NSDictionary* subdict;
-			if (subdict = [props objectForKey:@"Protocol Characteristics"]) {
+                        if ((subdict = [props objectForKey:@"Protocol Characteristics"])) {
 				connection = [subdict objectForKey:@"Physical Interconnect"];
 			} else {
 				connection = [props objectForKey:@"Physical Interconnect"];
@@ -88,21 +89,21 @@
 				[dict setObject:image forKey:NSWorkspace_RBimagefilepath];
 			}
 			NSString* value;
-			if (subdict = [props objectForKey:@"Device Characteristics"]) {
-				if (value = [subdict objectForKey:@"Product Name"]) {
+                        if ((subdict = [props objectForKey:@"Device Characteristics"])) {
+                                if ((value = [subdict objectForKey:@"Product Name"])) {
 					result = AddPart(result,value);
 				}
-				if (value = [subdict objectForKey:@"Product Revision Level"]) {
+                                if ((value = [subdict objectForKey:@"Product Revision Level"])) {
 					result = AddPart(result,value);
 				}
-				if (value = [subdict objectForKey:@"Vendor Name"]) {
+                                if ((value = [subdict objectForKey:@"Vendor Name"])) {
 					result = AddPart(result,value);
 				}
 			}
-			if (value = [props objectForKey:@"USB Serial Number"]) {
+                        if ((value = [props objectForKey:@"USB Serial Number"])) {
 				result = AddPart(result,value);
 			}
-			if (value = [props objectForKey:@"USB Vendor Name"]) {
+                        if ((value = [props objectForKey:@"USB Vendor Name"])) {
 				result = AddPart(result,value);
 			}
 			NSString* cls = [(NSString*)IOObjectCopyClass(nextParent) autorelease];
@@ -124,6 +125,7 @@
 
 // This formats the (partially undocumented) AFPXMountInfo info into a string.
 
+/*
 static NSString* FormatAFPURL(AFPXVolMountInfoPtr mountInfo,NSString** devdesc) {
 	UInt8* work = ((UInt8*)mountInfo)+mountInfo->serverNameOffset;
 	if (devdesc) {
@@ -162,6 +164,7 @@
 	}
 	return [NSString stringWithFormat:@"afp://%@/%@",dns?:(ip?:@""),volname];
 }
+*/
 
 @implementation NSWorkspace (NSWorkspace_RBAdditions)
 
--- a/QTfrontend/hwconsts.h	Mon Nov 28 06:55:55 2011 +0100
+++ b/QTfrontend/hwconsts.h	Mon Dec 05 18:38:25 2011 -0500
@@ -61,19 +61,19 @@
 #define HEDGEHOGS_PER_TEAM           8
 
 #define AMMOLINE_DEFAULT_QT     "939192942219912103223511100120100000021111010101111101"
-#define AMMOLINE_DEFAULT_PROB   "040504054160065554655446477657666666615551010111541101"
+#define AMMOLINE_DEFAULT_PROB   "040504054160065554655446477657666666615551010111541111"
 #define AMMOLINE_DEFAULT_DELAY  "000000000000020550000004000700400000000022000000060000"
-#define AMMOLINE_DEFAULT_CRATE  "131111031211111112311411111111111111121111110111111101"
+#define AMMOLINE_DEFAULT_CRATE  "131111031211111112311411111111111111121111110111111111"
 
-#define AMMOLINE_CRAZY_QT       "999999999999999999299999999999999929999999990999999209"
-#define AMMOLINE_CRAZY_PROB     "111111011111111111111111111111111111111111110111111101"
+#define AMMOLINE_CRAZY_QT       "999999999999999999299999999999999929999999990999999229"
+#define AMMOLINE_CRAZY_PROB     "111111011111111111111111111111111111111111110111111111"
 #define AMMOLINE_CRAZY_DELAY    "000000000000000000000000000000000000000000000000000000"
-#define AMMOLINE_CRAZY_CRATE    "131111031211111112311411111111111111121111010111111101"
+#define AMMOLINE_CRAZY_CRATE    "131111031211111112311411111111111111121111010111111111"
 
 #define AMMOLINE_PROMODE_QT     "909000900000000000000900000000000000000000000000000000"
 #define AMMOLINE_PROMODE_PROB   "000000000000000000000000000000000000000000000000000000"
 #define AMMOLINE_PROMODE_DELAY  "000000000000020550000004000700400000000020000000000000"
-#define AMMOLINE_PROMODE_CRATE  "111111111111111111111111111111111111111110010111111101"
+#define AMMOLINE_PROMODE_CRATE  "111111111111111111111111111111111111111110010111111111"
 
 #define AMMOLINE_SHOPPA_QT      "000000990000000000000000000000000000000000000000000000"
 #define AMMOLINE_SHOPPA_PROB    "444441004424440221011212122242200000000200040001001100"
@@ -81,19 +81,19 @@
 #define AMMOLINE_SHOPPA_CRATE   "111111111111111111111111111111111111111110110111111100"
 
 #define AMMOLINE_CLEAN_QT       "101000900001000001100000000000000000000000000000100000"
-#define AMMOLINE_CLEAN_PROB     "040504054160065554655446477657666666615551010111541101"
+#define AMMOLINE_CLEAN_PROB     "040504054160065554655446477657666666615551010111541111"
 #define AMMOLINE_CLEAN_DELAY    "000000000000000000000000000000000000000000000000000000"
-#define AMMOLINE_CLEAN_CRATE    "131111031211111112311411111111111111121111110111111101"
+#define AMMOLINE_CLEAN_CRATE    "131111031211111112311411111111111111121111110111111111"
 
 #define AMMOLINE_MINES_QT       "000000990009000000030000000000000000000000000000000000"
 #define AMMOLINE_MINES_PROB     "000000000000000000000000000000000000000000000000000000"
 #define AMMOLINE_MINES_DELAY    "000000000000020550000004000700400000000020000000060000"
-#define AMMOLINE_MINES_CRATE    "111111111111111111111111111111111111111111110111111101"
+#define AMMOLINE_MINES_CRATE    "111111111111111111111111111111111111111111110111111111"
 
 #define AMMOLINE_PORTALS_QT     "900000900200000000210000000000000011000009000000000000"
-#define AMMOLINE_PORTALS_PROB   "040504054160065554655446477657666666615551010111541101"
+#define AMMOLINE_PORTALS_PROB   "040504054160065554655446477657666666615551010111541111"
 #define AMMOLINE_PORTALS_DELAY  "000000000000020550000004000700400000000020000000060000"
-#define AMMOLINE_PORTALS_CRATE  "131111031211111112311411111111111111121111110111111101"
+#define AMMOLINE_PORTALS_CRATE  "131111031211111112311411111111111111121111110111111111"
 
 
 #define NETGAME_DEFAULT_PORT 46631
--- a/QTfrontend/hwform.cpp	Mon Nov 28 06:55:55 2011 +0100
+++ b/QTfrontend/hwform.cpp	Mon Dec 05 18:38:25 2011 -0500
@@ -82,6 +82,7 @@
 #include "bgwidget.h"
 #include "xfire.h"
 #include "drawmapwidget.h"
+#include "mouseoverfilter.h"
 
 #include "HWDataManager.h"
 
@@ -282,6 +283,23 @@
        wBackground->startAnimation();
     }
 
+    //Install all eventFilters :
+
+    MouseOverFilter *filter = new MouseOverFilter();
+    filter->setUi(&ui);
+
+    QList<QWidget *> widgets;
+
+    for (int i=0; i < ui.Pages->count(); i++)
+    {
+        widgets = ui.Pages->widget(i)->findChildren<QWidget *>();
+
+        for (int i=0; i < widgets.size(); i++)
+        {
+            widgets.at(i)->installEventFilter(filter);
+        }
+    }
+
     PagesStack.push(ID_PAGE_MAIN);
     GoBack();
 }
@@ -562,7 +580,7 @@
     {
         /**Start animation :**/
         int coeff = 1;
-#ifndef Q_OS_OSX
+#ifndef Q_OS_MAC
         coeff = 2;
         QGraphicsOpacityEffect *effectNew = new QGraphicsOpacityEffect(ui.Pages->widget(id));
         ui.Pages->widget(id)->setGraphicsEffect(effectNew);
@@ -578,7 +596,7 @@
         animationNewSlide->setEndValue(QPoint(0, 0));
         animationNewSlide->setEasingCurve(QEasingCurve::OutExpo);
 
-#ifndef Q_OS_OSX
+#ifndef Q_OS_MAC
         animationNewOpacity = new QPropertyAnimation(effectNew, "opacity");
         animationNewOpacity->setDuration(500);
         animationNewOpacity->setStartValue(0.01);
@@ -595,7 +613,7 @@
         animationOldSlide->setEndValue(QPoint(-width()/coeff, 0));
         animationOldSlide->setEasingCurve(QEasingCurve::OutExpo);
 
-#ifndef Q_OS_OSX
+#ifndef Q_OS_MAC
         animationOldOpacity = new QPropertyAnimation(effectLast, "opacity");
         animationOldOpacity->setDuration(500);
         animationOldOpacity->setStartValue(1);
@@ -606,7 +624,7 @@
         QParallelAnimationGroup *group = new QParallelAnimationGroup;
         group->addAnimation(animationOldSlide);
         group->addAnimation(animationNewSlide);
-#ifndef Q_OS_OSX
+#ifndef Q_OS_MAC
         group->addAnimation(animationOldOpacity);
         group->addAnimation(animationNewOpacity);
 #endif
@@ -668,7 +686,7 @@
     if (curid != 0 && frontendEffects && !stopAnim)
     {
         int coeff = 1;
-#ifndef Q_OS_OSX
+#ifndef Q_OS_MAC
         coeff = 2;
         QGraphicsOpacityEffect *effectNew = new QGraphicsOpacityEffect(ui.Pages->widget(id));
         effectNew->setOpacity(1);
@@ -685,7 +703,7 @@
         animationOldSlide->setEndValue(QPoint(0, 0));
         animationOldSlide->setEasingCurve(QEasingCurve::OutExpo);
 
-#ifndef Q_OS_OSX
+#ifndef Q_OS_MAC
         animationOldOpacity = new QPropertyAnimation(effectLast, "opacity");
         animationOldOpacity->setDuration(500);
         animationOldOpacity->setStartValue(1);
@@ -701,7 +719,7 @@
         animationNewSlide->setEndValue(QPoint(width()/coeff, 0));
         animationNewSlide->setEasingCurve(QEasingCurve::OutExpo);
 
-#ifndef Q_OS_OSX
+#ifndef Q_OS_MAC
         animationNewOpacity = new QPropertyAnimation(effectNew, "opacity");
         animationNewOpacity->setDuration(500);
         animationNewOpacity->setStartValue(0.01);
@@ -712,7 +730,7 @@
         QParallelAnimationGroup *group = new QParallelAnimationGroup;
         group->addAnimation(animationOldSlide);
         group->addAnimation(animationNewSlide);
-#ifndef Q_OS_OSX
+#ifndef Q_OS_MAC
         group->addAnimation(animationOldOpacity);
         group->addAnimation(animationNewOpacity);
 #endif
--- a/QTfrontend/hwform.h	Mon Nov 28 06:55:55 2011 +0100
+++ b/QTfrontend/hwform.h	Mon Dec 05 18:38:25 2011 -0500
@@ -61,6 +61,8 @@
     void updateXfire();
     void PlayDemoQuick(const QString & demofilename);
     void exit();
+    void setButtonDescription(QString desc);
+    void backDescription();
 
 private slots:
     void GoToSaves();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QTfrontend/ui/mouseoverfilter.cpp	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,48 @@
+#include "mouseoverfilter.h"
+#include "ui/page/AbstractPage.h"
+#include "ui_hwform.h"
+
+#include <QEvent>
+#include <QWidget>
+#include <QStackedLayout>
+#include <QLabel>
+
+MouseOverFilter::MouseOverFilter(QObject *parent) :
+    QObject(parent)
+{
+}
+
+bool MouseOverFilter::eventFilter( QObject *dist, QEvent *event )
+{
+    if (event->type() == QEvent::Enter)
+    {
+        QWidget * widget = dynamic_cast<QWidget*>(dist);
+
+        abstractpage = qobject_cast<AbstractPage*>(ui->Pages->currentWidget());
+
+        if (widget->whatsThis() != NULL)
+            abstractpage->setButtonDescription(widget->whatsThis());
+        else if (widget->toolTip() != NULL)
+            abstractpage->setButtonDescription(widget->toolTip());
+
+        return true;
+    }
+    else if (event->type() == QEvent::Leave)
+    {
+        abstractpage = qobject_cast<AbstractPage*>(ui->Pages->currentWidget());
+
+        if (abstractpage->getDefautDescription() != NULL)
+        {
+            abstractpage->setButtonDescription( * abstractpage->getDefautDescription());
+        }
+        else
+            abstractpage->setButtonDescription("");
+    }
+
+    return false;
+}
+
+void MouseOverFilter::setUi(Ui_HWForm *uiForm)
+{
+    ui = uiForm;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QTfrontend/ui/mouseoverfilter.h	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,27 @@
+#ifndef MOUSEOVERFILTER_H
+#define MOUSEOVERFILTER_H
+
+#include <QObject>
+
+#include "ui_hwform.h"
+#include "ui/page/AbstractPage.h"
+
+class MouseOverFilter : public QObject
+{
+    Q_OBJECT
+public:
+    explicit MouseOverFilter(QObject *parent = 0);
+    void setUi(Ui_HWForm *uiForm);
+protected:
+    bool eventFilter( QObject *dist, QEvent *event );
+signals:
+
+public slots:
+
+private:
+    Ui_HWForm *ui;
+    AbstractPage* abstractpage;
+
+};
+
+#endif // MOUSEOVERFILTER_H
--- a/QTfrontend/ui/page/AbstractPage.cpp	Mon Nov 28 06:55:55 2011 +0100
+++ b/QTfrontend/ui/page/AbstractPage.cpp	Mon Dec 05 18:38:25 2011 -0500
@@ -22,10 +22,14 @@
  */
 
 #include "AbstractPage.h"
+#include <QLabel>
+#include <QSize>
+#include <QFontMetricsF>
 
 AbstractPage::AbstractPage(QWidget* parent)
 {
     Q_UNUSED(parent);
+    defautDesc = new QString();
 
     font14 = new QFont("MS Shell Dlg", 14);
 }
@@ -45,12 +49,20 @@
     pageLayout->addWidget(btnBack, 1, 0, 1, 1, Qt::AlignLeft | Qt::AlignBottom);
 
     // add body layout as defined by the subclass
-    pageLayout->addLayout(bodyLayoutDefinition(), 0, 0, 1, 2);
+    pageLayout->addLayout(bodyLayoutDefinition(), 0, 0, 1, 3);
+
+    descLabel = new QLabel();
+    descLabel->setAlignment(Qt::AlignCenter);
+    descLabel->setWordWrap(true);
+    descLabel->setOpenExternalLinks(true);
+    descLabel->setFixedHeight(50);
+    descLabel->setStyleSheet("font-size: 16px");
+    pageLayout->addWidget(descLabel, 1, 1);
 
     // add footer layout
     QLayout * fld = footerLayoutDefinition();
     if (fld != NULL)
-        pageLayout->addLayout(fld, 1, 1);
+        pageLayout->addLayout(fld, 1, 2);
 
     // connect signals
     connect(btnBack, SIGNAL(clicked()), this, SIGNAL(goBack()));
@@ -97,3 +109,19 @@
 {
     btnBack->setVisible(visible);
 }
+
+void AbstractPage::setButtonDescription(QString desc)
+{
+    descLabel->setText(desc);
+}
+
+void AbstractPage::setDefautDescription(QString text)
+{
+    *defautDesc = text;
+    descLabel->setText(text);
+}
+
+QString * AbstractPage::getDefautDescription()
+{
+    return defautDesc;
+}
--- a/QTfrontend/ui/page/AbstractPage.h	Mon Nov 28 06:55:55 2011 +0100
+++ b/QTfrontend/ui/page/AbstractPage.h	Mon Dec 05 18:38:25 2011 -0500
@@ -56,6 +56,27 @@
 {
     Q_OBJECT
 
+    public:
+
+        /**
+        * @brief Changes the desc text (should not be called manualy)
+        *
+        * @param desc the description of the widget focused
+        */
+        void setButtonDescription(QString desc);
+
+        /**
+        * @brief Changes the desc defaut text
+        *
+        * @param text the defaut desc
+        */
+        void setDefautDescription(QString text);
+
+        /**
+        * @brief Get the desc defaut text
+        */
+        QString * getDefautDescription();
+
     signals:
         /**
          * @brief This signal is emitted when going back to the previous is
@@ -153,6 +174,9 @@
 
         QFont * font14; ///< used font
 
+        QLabel * descLabel; ///< text description
+        QString * defautDesc;
+
     private:
 
         QPushButton * btnBack; ///< back button
--- a/QTfrontend/ui/page/pagemain.cpp	Mon Nov 28 06:55:55 2011 +0100
+++ b/QTfrontend/ui/page/pagemain.cpp	Mon Dec 05 18:38:25 2011 -0500
@@ -42,19 +42,25 @@
     pageLayout->setRowStretch(4, 1);
 
     BtnSinglePlayer = addButton(":/res/LocalPlay.png", pageLayout, 2, 0, 1, 2, true);
-    BtnSinglePlayer->setToolTip(tr("Local Game (Play a game on a single computer)"));
+    BtnSinglePlayer->setToolTip(tr("Local Game"));
+    BtnSinglePlayer->setWhatsThis(tr("Play a game on a single computer"));
     pageLayout->setAlignment(BtnSinglePlayer, Qt::AlignHCenter);
 
     BtnNet = addButton(":/res/NetworkPlay.png", pageLayout, 2, 2, 1, 2, true);
-    BtnNet->setToolTip(tr("Network Game (Play a game across a network)"));
+    BtnNet->setToolTip(tr("Network Game"));
+    BtnNet->setWhatsThis(tr("Play a game across a network"));
     pageLayout->setAlignment(BtnNet, Qt::AlignHCenter);
 
     // button order matters for overlapping (what's on top and what isn't)
     BtnInfo = addButton(":/res/HedgewarsTitle.png", pageLayout, 0, 0, 1, 4, true);
     BtnInfo->setStyleSheet("border: transparent;background: transparent;");
+    //BtnInfo->setToolTip(tr("Credits")); //tooltip looks horrible with transparent background buttons
+    BtnInfo->setWhatsThis(tr("Read about who is behind the Hedgewars Project"));
     pageLayout->setAlignment(BtnInfo, Qt::AlignHCenter);
 
     BtnDataDownload = addButton(tr("Downloadable Content"), pageLayout, 4, 0, 1, 4, false);
+    //BtnDataDownload->setToolTip(tr(Downloadable Content"));
+    BtnDataDownload->setWhatsThis(tr("Access the user created content downloadable from our website"));
     pageLayout->setAlignment(BtnDataDownload, Qt::AlignHCenter);
 
     return pageLayout;
@@ -91,10 +97,12 @@
 
     if(!isDevBuild)
     {
-        mainNote->setText(QLabel::tr("Tip: ") + randomTip());
+        setDefautDescription(QLabel::tr("Tip: ") + randomTip());
     }
     else
-        mainNote->setText(QLabel::tr("This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!"));
+    {
+        setDefautDescription(QLabel::tr("This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!"));
+    }
 
 }
 
--- a/QTfrontend/ui/widget/selectWeapon.cpp	Mon Nov 28 06:55:55 2011 +0100
+++ b/QTfrontend/ui/widget/selectWeapon.cpp	Mon Dec 05 18:38:25 2011 -0500
@@ -129,7 +129,6 @@
     int i = 0, k = 0;
     for(; i < m_numItems; ++i) {
         if (i == 6) continue;
-        if (i == 52) continue; // Disable structures for now
         if (k % 4 == 0) ++j;
         SelWeaponItem * swi = new SelWeaponItem(true, i, currentState[i].digitValue(), QImage(":/res/ammopic.png"), QImage(":/res/ammopicgrey.png"), this);
         weaponItems[i].append(swi);
@@ -255,7 +254,7 @@
     if(wconf->contains(newName)) {
         //name already used -> look for an appropriate name:
         int i=2;
-        while(wconf->contains(newName = tr("new")+QString::number(i++)));
+        while(wconf->contains(newName = tr("new")+QString::number(i++))) ;
     }
     setWeaponsName(newName);
 }
@@ -286,7 +285,7 @@
         if(wconf->contains(newName)) {
             //name already used -> look for an appropriate name:
             int i=2;
-            while(wconf->contains(newName = tr("copy of") + " " + curWeaponsName+QString::number(i++)));
+            while(wconf->contains(newName = tr("copy of") + " " + curWeaponsName+QString::number(i++))) ;
         }
         setWeaponsName(newName);
         setWeapons(ammo);
--- a/hedgewars/CMakeLists.txt	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/CMakeLists.txt	Mon Dec 05 18:38:25 2011 -0500
@@ -36,8 +36,10 @@
     uIO.pas
     uKeys.pas
     uLand.pas
+    uLandGenMaze.pas
     uLandGraphics.pas
     uLandObjects.pas
+    uLandOutline.pas
     uLandPainted.pas
     uLandTemplates.pas
     uLandTexture.pas
--- a/hedgewars/GSHandlers.inc	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/GSHandlers.inc	Mon Dec 05 18:38:25 2011 -0500
@@ -84,7 +84,7 @@
         if (gi^.Kind = gtHedgehog) then
             begin
             d := r - hwRound(Distance(gi^.X - x, gi^.Y - y));
-            if (d > 1) and not gi^.Invulnerable and (GetRandom(2) = 0) then
+            if (d > 1) and (not gi^.Invulnerable) and (GetRandom(2) = 0) then
                 begin
                 if (CurrentHedgehog^.Gear = gi) then
                     PlaySound(sndOops, gi^.Hedgehog^.Team^.voicepack)
@@ -114,8 +114,8 @@
     begin
     Z := cHHZ;
     Active := false;
-    State:= State and not (gstHHDriven or gstAttacking or gstAttacked);
-    Message := Message and not gmAttack;
+    State:= State and (not (gstHHDriven or gstAttacking or gstAttacked));
+    Message := Message and (not gmAttack);
     end;
 HH^.GearHidden:= HH^.Gear;
 HH^.Gear:= nil
@@ -126,102 +126,18 @@
 HH^.Gear:=HH^.GearHidden;
 HH^.GearHidden:= nil;
 InsertGearToList(HH^.Gear);
-HH^.Gear^.State:= (HH^.Gear^.State and not (gstHHDriven or gstInvisible or gstAttacking)) or gstAttacked;
+HH^.Gear^.State:= (HH^.Gear^.State and (not (gstHHDriven or gstInvisible or gstAttacking))) or gstAttacked;
 AddGearCI(HH^.Gear);
 HH^.Gear^.Active:= true;
 ScriptCall('onHogRestore', HH^.Gear^.Uid)
 end;
 
 ////////////////////////////////////////////////////////////////////////////////
-procedure doStepDrowningGear(Gear: PGear);
-forward;
-
-function CheckGearDrowning(Gear: PGear): boolean;
-var 
-    skipSpeed, skipAngle, skipDecay: hwFloat;
-    i, maxDrops, X, Y: LongInt;
-    vdX, vdY: real;
-    particle: PVisualGear;
-    isSubmersible: boolean;
-begin
-    isSubmersible:= (Gear = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.AmmoType = amJetpack);
-    // probably needs tweaking. might need to be in a case statement based upon gear type
-    Y:= hwRound(Gear^.Y);
-    if cWaterLine < Y + Gear^.Radius then
-        begin
-        skipSpeed := _0_25;
-        skipAngle := _1_9;
-        skipDecay := _0_87;
-        X:= hwRound(Gear^.X);
-        vdX:= hwFloat2Float(Gear^.dX);
-        vdY:= hwFloat2Float(Gear^.dY);
-        // this could perhaps be a tiny bit higher.
-        if  (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed) and
-           (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)) then
-            begin
-            Gear^.dY.isNegative := true;
-            Gear^.dY := Gear^.dY * skipDecay;
-            Gear^.dX := Gear^.dX * skipDecay;
-            CheckGearDrowning := false;
-            PlaySound(sndSkip)
-            end
-        else
-            begin
-            if not isSubmersible then
-                begin
-                CheckGearDrowning := true;
-                Gear^.State := gstDrowning;
-                Gear^.RenderTimer := false;
-                if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot) and 
-                   (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) then
-                    if Gear^.Kind = gtHedgehog then
-                        begin
-                        if Gear^.Hedgehog^.Effects[heResurrectable] then
-                            ResurrectHedgehog(Gear)
-                        else
-                            begin
-                            Gear^.doStep := @doStepDrowningGear;
-                            Gear^.State := Gear^.State and (not gstHHDriven);
-                            AddCaption(Format(GetEventString(eidDrowned), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
-                            end
-                        end
-                    else Gear^.doStep := @doStepDrowningGear;
-                    if Gear^.Kind = gtFlake then exit // skip splashes 
-                end;
-            if ((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius)) or
-               (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and ((CurAmmoGear^.Pos = 0) and (CurAmmoGear^.dY < _0_01))) then
-                // don't play splash if they are already way past the surface
-                PlaySound(sndSplash)
-            end;
-
-        if ((cReducedQuality and rqPlainSplash) = 0) and 
-           (((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius)) or
-             (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and ((CurAmmoGear^.Pos = 0) and (CurAmmoGear^.dY < _0_01)))) then
-            begin
-            AddVisualGear(X, cWaterLine, vgtSplash);
-
-            maxDrops := (Gear^.Radius div 2) + round(vdX * Gear^.Radius * 2) + round(vdY * Gear^.Radius * 2);
-            for i:= max(maxDrops div 3, min(32, Random(maxDrops))) downto 0 do
-                begin
-                particle := AddVisualGear(X - 3 + Random(6), cWaterLine, vgtDroplet);
-                if particle <> nil then
-                    begin
-                    particle^.dX := particle^.dX - vdX / 10;
-                    particle^.dY := particle^.dY - vdY / 5;
-                    end
-                end
-            end;
-        if isSubmersible and (CurAmmoGear^.Pos = 0) then CurAmmoGear^.Pos := 1000
-        end
-    else
-        CheckGearDrowning := false;
-end;
-
 procedure CheckCollision(Gear: PGear); inline;
 begin
     if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then
         Gear^.State := Gear^.State or gstCollision
-    else Gear^.State := Gear^.State and not gstCollision
+    else Gear^.State := Gear^.State and (not gstCollision)
 end;
 
 procedure CheckCollisionWithLand(Gear: PGear); inline;
@@ -229,55 +145,12 @@
     if TestCollisionX(Gear, hwSign(Gear^.dX)) or TestCollisionY(Gear, hwSign(Gear^.dY)
        )
         then Gear^.State := Gear^.State or      gstCollision
-    else Gear^.State := Gear^.State and not gstCollision
+    else Gear^.State := Gear^.State and (not gstCollision)
 end;
 
-procedure CheckHHDamage(Gear: PGear);
-var 
-    dmg: Longword;
-    i: LongInt;
-    particle: PVisualGear;
-begin
-    if _0_4 < Gear^.dY then
-        begin
-        dmg := ModifyDamage(1 + hwRound((hwAbs(Gear^.dY) - _0_4) * 70), Gear);
-        PlaySound(sndBump);
-        if dmg < 1 then exit;
-
-        for i:= min(12, (3 + dmg div 10)) downto 0 do
-            begin
-            particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
-            if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480);
-            end;
-
-        if (Gear^.Invulnerable) then exit;
-
-        //if _0_6 < Gear^.dY then
-        //    PlaySound(sndOw4, Gear^.Hedgehog^.Team^.voicepack)
-        //else
-        //    PlaySound(sndOw1, Gear^.Hedgehog^.Team^.voicepack);
-
-        if Gear^.LastDamage <> nil then
-            ApplyDamage(Gear, Gear^.LastDamage, dmg, dsFall)
-            else
-            ApplyDamage(Gear, CurrentHedgehog, dmg, dsFall);
-    end
-end;
 
 ////////////////////////////////////////////////////////////////////////////////
-procedure CalcRotationDirAngle(Gear: PGear);
-var 
-    dAngle: real;
-begin
-    dAngle := (Gear^.dX.QWordValue + Gear^.dY.QWordValue) / $80000000;
-    if not Gear^.dX.isNegative then
-        Gear^.DirAngle := Gear^.DirAngle + dAngle
-    else
-        Gear^.DirAngle := Gear^.DirAngle - dAngle;
-
-    if Gear^.DirAngle < 0 then Gear^.DirAngle := Gear^.DirAngle + 360
-    else if 360 < Gear^.DirAngle then Gear^.DirAngle := Gear^.DirAngle - 360
-end;
+
 
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepDrowningGear(Gear: PGear);
@@ -307,7 +180,7 @@
     // clip velocity at 1.9 - over 1 per pixel, but really shouldn't cause many actual problems.
     if Gear^.dX.QWordValue > 8160437862 then Gear^.dX.QWordValue:= 8160437862;
     if Gear^.dY.QWordValue > 8160437862 then Gear^.dY.QWordValue:= 8160437862;
-    Gear^.State := Gear^.State and not gstCollision;
+    Gear^.State := Gear^.State and (not gstCollision);
     collV := 0;
     collH := 0;
     tdX := Gear^.dX;
@@ -324,7 +197,7 @@
         if land <> 0 then
             begin
             collV := -1;
-            if land and lfIce <> 0 then Gear^.dX := Gear^.dX * (_1 - (_1 - Gear^.Friction) / _10)
+            if land and lfIce <> 0 then Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1)
             else Gear^.dX := Gear^.dX * Gear^.Friction;
 
             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
@@ -333,14 +206,16 @@
         else if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, 1) <> 0) then collV := 1;
         end
     else 
-        begin
+        begin // Gear^.dY.isNegative is false
         land:= TestCollisionYwithGear(Gear, 1);
         if land <> 0 then
             begin
             collV := 1;
             isFalling := false;
-            if land and lfIce <> 0 then Gear^.dX := Gear^.dX * (_1 - (_1 - Gear^.Friction) / _10)
-            else Gear^.dX := Gear^.dX * Gear^.Friction;
+            if land and lfIce <> 0 then 
+                Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1)
+            else 
+                Gear^.dX := Gear^.dX * Gear^.Friction;
 
             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
             Gear^.State := Gear^.State or gstCollision
@@ -348,7 +223,7 @@
         else
             begin
             isFalling := true;
-            if (Gear^.AdvBounce=1) and not Gear^.dY.isNegative and (TestCollisionYwithGear(Gear, -1) <> 0) then
+            if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, -1) <> 0) then
                 collV := -1
             end
         end;
@@ -388,9 +263,8 @@
     if Gear^.Kind <> gtBee then
         CheckGearDrowning(Gear);
     //if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and
-    if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) and
-       (not isFalling) then
-        Gear^.State := Gear^.State and not gstMoving
+    if (not isFalling) and ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) then
+        Gear^.State := Gear^.State and (not gstMoving)
     else
         Gear^.State := Gear^.State or      gstMoving;
 
@@ -503,29 +377,29 @@
         end;
     DeleteGear(Gear);
     exit
-end;
-
-CalcRotationDirAngle(Gear);
-
-if Gear^.Kind = gtHellishBomb then
-begin
-
-    if Gear^.Timer = 3000 then
+    end;
+
+    CalcRotationDirAngle(Gear);
+
+    if Gear^.Kind = gtHellishBomb then
     begin
-        Gear^.nImpactSounds := 0;
-        PlaySound(sndHellish);
+
+        if Gear^.Timer = 3000 then
+        begin
+            Gear^.nImpactSounds := 0;
+            PlaySound(sndHellish);
+        end;
+
+        if (GameTicks and $3F) = 0 then
+            if (Gear^.State and gstCollision) = 0 then
+                AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace);
     end;
-
-    if (GameTicks and $3F) = 0 then
-        if (Gear^.State and gstCollision) = 0 then
-            AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace);
-end;
 end;
 
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepMolotov(Gear: PGear);
 var 
-	s: Longword;
+    s: Longword;
     i, gX, gY: LongInt;
     dX, dY: hwFloat;
     smoke, glass: PVisualGear;
@@ -667,7 +541,7 @@
 draw:= false;
 if gun then
     begin
-    Gear^.State:= Gear^.State and not gstInvisible;
+    Gear^.State:= Gear^.State and (not gstInvisible);
     doStepFallingGear(Gear);
     CheckCollision(Gear);
     if ((Gear^.State and gstCollision) <> 0) or ((Gear^.State and gstMoving) = 0) then draw:= true;
@@ -678,7 +552,7 @@
     begin
     with Gear^ do
         begin
-        State:= State and not gstInvisible;
+        State:= State and (not gstInvisible);
         X:= X + cWindSpeed * 3200 + dX;
         Y:= Y + dY + cGravity * vobFallSpeed * 8;  // using same value as flakes to try and get similar results
         xx:= hwRound(X);
@@ -775,7 +649,7 @@
                                 end
                             else Land[ly, lx]:= lf;
                         if gun then
-                            LandPixels[ry, rx]:= (cExplosionBorderColor and not AMask) or (p^[px] and AMask)
+                            LandPixels[ry, rx]:= (cExplosionBorderColor and (not AMask)) or (p^[px] and AMask)
                         else LandPixels[ry, rx]:= addBgColor(LandPixels[ry, rx], p^[px]);
                         end
                     else allpx:= false
@@ -950,8 +824,8 @@
     dec(Gear^.Timer);
     if Gear^.Timer = 0 then
     begin
-        Gear^.Hedgehog^.Gear^.Message:= Gear^.Hedgehog^.Gear^.Message and not gmAttack;
-        Gear^.Hedgehog^.Gear^.State:= Gear^.Hedgehog^.Gear^.State and not gstAttacking;
+        Gear^.Hedgehog^.Gear^.Message:= Gear^.Hedgehog^.Gear^.Message and (not gmAttack);
+        Gear^.Hedgehog^.Gear^.State:= Gear^.Hedgehog^.Gear^.State and (not gstAttacking);
         AttackBar:= 0;
         
         Gear^.SoundChannel := LoopSound(sndBee);
@@ -1268,7 +1142,7 @@
         begin
         HHGear^.State := HHGear^.State or gstNoDamage;
         doMakeExplosion(x, y + 7, 6, Gear^.Hedgehog, EXPLDontDraw);
-        HHGear^.State := HHGear^.State and not gstNoDamage
+        HHGear^.State := HHGear^.State and (not gstNoDamage)
         end;
 
     if (Gear^.Timer mod 47) = 0 then
@@ -1398,7 +1272,7 @@
 
         if ((HHGear^.State and gstMoving) = 0) then
             begin
-            HHGear^.State := HHGear^.State and not gstAttacking;
+            HHGear^.State := HHGear^.State and (not gstAttacking);
             prevX := hwRound(HHGear^.X);
 
             // why the call to HedgehogStep then a further increment of X?
@@ -1425,7 +1299,7 @@
                 end;
             HHGear^.State := HHGear^.State or gstNoDamage;
             AmmoShove(Gear, 2, 15);
-            HHGear^.State := HHGear^.State and not gstNoDamage
+            HHGear^.State := HHGear^.State and (not gstNoDamage)
             end;
         end;
 
@@ -1490,7 +1364,7 @@
     if (GameFlags and gfMoreWind) <> 0 then HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density;
 
     if (Gear^.Message and gmAttack) <> 0 then
-    begin
+        begin
         Gear^.X := HHGear^.X;
         Gear^.Y := HHGear^.Y;
 
@@ -1498,11 +1372,33 @@
 
         Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX);
         Gear^.dY := -AngleCos(HHGear^.Angle);
-        Gear^.Friction := _450 * _0_01 * cRopePercent;
+        Gear^.Friction := _4_5 * cRopePercent;
         Gear^.Elasticity := _0;
-        Gear^.State := Gear^.State and not gsttmpflag;
+        Gear^.State := Gear^.State and (not gsttmpflag);
         Gear^.doStep := @doStepRope;
-    end
+        end
+end;
+
+procedure RopeDeleteMe(Gear, HHGear: PGear);
+begin
+    with HHGear^ do
+    begin
+        Message := Message and (not gmAttack);
+        State := (State or gstMoving) and (not gstWinner);
+    end;
+    DeleteGear(Gear)
+end;
+
+procedure RopeWaitCollision(Gear, HHGear: PGear);
+begin
+    with HHGear^ do
+    begin
+        Message := Message and (not gmAttack);
+        State := State or gstMoving;
+    end;
+    RopePoints.Count := 0;
+    Gear^.Elasticity := _0;
+    Gear^.doStep := @doStepRopeAfterAttack
 end;
 
 procedure doStepRopeWork(Gear: PGear);
@@ -1513,28 +1409,6 @@
     haveCollision,
     haveDivided: boolean;
 
-procedure DeleteMe;
-begin
-    with HHGear^ do
-    begin
-        Message := Message and not gmAttack;
-        State := (State or gstMoving) and not gstWinner;
-    end;
-    DeleteGear(Gear)
-end;
-
-procedure WaitCollision;
-begin
-    with HHGear^ do
-    begin
-        Message := Message and not gmAttack;
-        State := State or gstMoving;
-    end;
-    RopePoints.Count := 0;
-    Gear^.Elasticity := _0;
-    Gear^.doStep := @doStepRopeAfterAttack
-end;
-
 begin
     HHGear := Gear^.Hedgehog^.Gear;
 
@@ -1542,14 +1416,14 @@
        or (CheckGearDrowning(HHGear)) then
         begin
         PlaySound(sndRopeRelease);
-        DeleteMe;
+        RopeDeleteMe(Gear, HHGear);
         exit
         end;
 
-    if (Gear^.Message and gmLeft  <> 0) and not TestCollisionXwithGear(HHGear, -1) then
+    if (Gear^.Message and gmLeft  <> 0) and (not TestCollisionXwithGear(HHGear, -1)) then
         HHGear^.dX := HHGear^.dX - _0_0002;
 
-    if (Gear^.Message and gmRight <> 0) and not TestCollisionXwithGear(HHGear,  1) then
+    if (Gear^.Message and gmRight <> 0) and (not TestCollisionXwithGear(HHGear,  1)) then
         HHGear^.dX := HHGear^.dX + _0_0002;
 
     // vector between hedgehog and rope attaching point
@@ -1756,9 +1630,9 @@
                 begin
                 PlaySound(sndRopeRelease);
                 if CurAmmoType <> amParachute then
-                    WaitCollision
+                    RopeWaitCollision(Gear, HHGear)
                 else
-                    DeleteMe
+                    RopeDeleteMe(Gear, HHGear)
                 end
         end
     else
@@ -1766,12 +1640,7 @@
             Gear^.State := Gear^.State or gsttmpFlag;
 end;
 
-procedure doStepRopeAttach(Gear: PGear);
-var 
-    HHGear: PGear;
-    tx, ty, tt: hwFloat;
-
-procedure RemoveFromAmmo;
+procedure RopeRemoveFromAmmo(Gear, HHGear: PGear);
 begin
     if (Gear^.State and gstAttacked) = 0 then
     begin
@@ -1781,6 +1650,10 @@
     ApplyAmmoChanges(HHGear^.Hedgehog^)
 end;
 
+procedure doStepRopeAttach(Gear: PGear);
+var 
+    HHGear: PGear;
+    tx, ty, tt: hwFloat;
 begin
     Gear^.X := Gear^.X - Gear^.dX;
     Gear^.Y := Gear^.Y - Gear^.dY;
@@ -1801,7 +1674,7 @@
             begin
             CheckHHDamage(HHGear);
             HHGear^.dY := _0
-            //HHGear^.State:= HHGear^.State and not (gstHHJumping or gstHHHJump);
+            //HHGear^.State:= HHGear^.State and (not (gstHHJumping or gstHHHJump));
             end
         else
             begin
@@ -1825,11 +1698,11 @@
                 PlaySound(sndRopeAttach);
                 with HHGear^ do
                     begin
-                    State := State and not (gstAttacking or gstHHJumping or gstHHHJump);
-                    Message := Message and not gmAttack
+                    State := State and (not (gstAttacking or gstHHJumping or gstHHHJump));
+                    Message := Message and (not gmAttack)
                     end;
 
-                RemoveFromAmmo;
+                RopeRemoveFromAmmo(Gear, HHGear);
 
                 tt := _0;
                 exit
@@ -1851,11 +1724,11 @@
         PlaySound(sndRopeAttach);
         with HHGear^ do
             begin
-            State := State and not (gstAttacking or gstHHJumping or gstHHHJump);
-            Message := Message and not gmAttack
+            State := State and (not (gstAttacking or gstHHJumping or gstHHHJump));
+            Message := Message and (not gmAttack)
             end;
 
-        RemoveFromAmmo;
+        RopeRemoveFromAmmo(Gear, HHGear);
 
         exit
         end;
@@ -1867,8 +1740,8 @@
         begin
         with Gear^.Hedgehog^.Gear^ do
             begin
-            State := State and not gstAttacking;
-            Message := Message and not gmAttack
+            State := State and (not gstAttacking);
+            Message := Message and (not gmAttack)
             end;
         DeleteGear(Gear)
         end;
@@ -1914,7 +1787,7 @@
             else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
                  inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
         
-        if (Gear^.Damage > random(30)) and ((GameTicks and $FF) = 0) then
+        if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then
             begin
             vg:= AddVisualGear(hwRound(Gear^.X) - 4  + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
             if vg <> nil then vg^.Scale:= 0.5
@@ -1955,7 +1828,7 @@
                     PlaySound(sndVaporize);
                     Gear^.Health := 0;
                     Gear^.Damage := 0;
-                    Gear^.State := Gear^.State and not gstAttacking
+                    Gear^.State := Gear^.State and (not gstAttacking)
                     end;
                 exit
                 end;
@@ -1969,7 +1842,10 @@
 procedure doStepSMine(Gear: PGear);
 begin
     // TODO: do real calculation?
-    if TestCollisionXwithGear(Gear, 2) or (TestCollisionYwithGear(Gear, -2) <> 0) or TestCollisionXwithGear(Gear, -2) or (TestCollisionYwithGear(Gear, 2) <> 0) then
+    if TestCollisionXwithGear(Gear, 2) 
+        or (TestCollisionYwithGear(Gear, -2) <> 0) 
+        or TestCollisionXwithGear(Gear, -2) 
+        or (TestCollisionYwithGear(Gear, 2) <> 0) then
     begin
         if (hwAbs(Gear^.dX) > _0) or (hwAbs(Gear^.dY) > _0) then
         begin
@@ -1998,13 +1874,14 @@
         else // gstAttacking <> 0
         begin
             AllInactive := false;
-            if (Gear^.Timer and $FF) = 0 then PlaySound(sndMineTick);
             if Gear^.Timer = 0 then
             begin
                 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
                 DeleteGear(Gear);
                 exit
-            end;
+            end else
+                if (Gear^.Timer and $FF) = 0 then PlaySound(sndMineTick);
+
             dec(Gear^.Timer);
         end
     end
@@ -2128,7 +2005,7 @@
         SetAllToActive;
         // something (hh, mine, etc...) could be on top of the case
         with CurrentHedgehog^ do
-            if Gear <> nil then Gear^.Message := Gear^.Message and not (gmLJump or gmHJump);
+            if Gear <> nil then Gear^.Message := Gear^.Message and (not (gmLJump or gmHJump));
         exit
     end;
 
@@ -2441,7 +2318,7 @@
         HHGear^.State := HHGear^.State or gstNoDamage;
         Gear^.Y := HHGear^.Y;
         AmmoShove(Gear, 30, 40);
-        HHGear^.State := HHGear^.State and not gstNoDamage
+        HHGear^.State := HHGear^.State and (not gstNoDamage)
     end;
 
     HHGear^.dY := HHGear^.dY + cGravity;
@@ -2532,8 +2409,8 @@
 
     AfterAttack;
 
-    HHGear^.State := HHGear^.State and not (gstAttacking or gstAttacked or gstMoving);
-    HHGear^.Message := HHGear^.Message and not gmAttack;
+    HHGear^.State := HHGear^.State and (not (gstAttacking or gstAttacked or gstMoving));
+    HHGear^.Message := HHGear^.Message and (not gmAttack);
 
     Gear^.doStep := @doStepParachuteWork;
 
@@ -2642,13 +2519,13 @@
     y := HHGear^.Y;
 
     if (Distance(tx - x, ty - y) > _256) or
-       not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2,
+       (not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2,
        Gear^.Target.Y - SpritesData[sprAmGirder].Height div 2,
-       sprAmGirder, Gear^.State, true, false) then
+       sprAmGirder, Gear^.State, true, false)) then
     begin
         PlaySound(sndDenied);
-        HHGear^.Message := HHGear^.Message and not gmAttack;
-        HHGear^.State := HHGear^.State and not gstAttacking;
+        HHGear^.Message := HHGear^.Message and (not gmAttack);
+        HHGear^.State := HHGear^.State and (not gstAttacking);
         HHGear^.State := HHGear^.State or gstHHChooseTarget;
         isCursorVisible := true;
         DeleteGear(Gear)
@@ -2660,8 +2537,8 @@
         AfterAttack;
     end;
 
-    HHGear^.State := HHGear^.State and not (gstAttacking or gstAttacked);
-    HHGear^.Message := HHGear^.Message and not gmAttack;
+    HHGear^.State := HHGear^.State and (not (gstAttacking or gstAttacked));
+    HHGear^.Message := HHGear^.Message and (not gmAttack);
 end;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -2706,8 +2583,8 @@
        Gear^.Target.Y - SpritesData[sprHHTelepMask].Height div 2,
        sprHHTelepMask, 0, false, false) then
     begin
-        HHGear^.Message := HHGear^.Message and not gmAttack;
-        HHGear^.State := HHGear^.State and not gstAttacking;
+        HHGear^.Message := HHGear^.Message and (not gmAttack);
+        HHGear^.State := HHGear^.State and (not gstAttacking);
         HHGear^.State := HHGear^.State or gstHHChooseTarget;
         DeleteGear(Gear);
         isCursorVisible := true;
@@ -2741,10 +2618,10 @@
 begin
     AllInactive := false;
 
-    if ((Gear^.Message and not gmSwitch) <> 0) or (TurnTimeLeft = 0) then
+    if ((Gear^.Message and (not gmSwitch)) <> 0) or (TurnTimeLeft = 0) then
     begin
         HHGear := Gear^.Hedgehog^.Gear;
-        Msg := Gear^.Message and not gmSwitch;
+        Msg := Gear^.Message and (not gmSwitch);
         DeleteGear(Gear);
         ApplyAmmoChanges(HHGear^.Hedgehog^);
 
@@ -2757,8 +2634,8 @@
     if (Gear^.Message and gmSwitch) <> 0 then
     begin
         HHGear := CurrentHedgehog^.Gear;
-        HHGear^.Message := HHGear^.Message and not gmSwitch;
-        Gear^.Message := Gear^.Message and not gmSwitch;
+        HHGear^.Message := HHGear^.Message and (not gmSwitch);
+        Gear^.Message := Gear^.Message and (not gmSwitch);
         State := HHGear^.State;
         HHGear^.State := 0;
         HHGear^.Active := false;
@@ -2797,8 +2674,8 @@
     OnUsedAmmo(HHGear^.Hedgehog^);
     with HHGear^ do
     begin
-        State := State and not gstAttacking;
-        Message := Message and not gmAttack
+        State := State and (not gstAttacking);
+        Message := Message and (not gmAttack)
     end
 end;
 
@@ -3018,24 +2895,23 @@
 end;
 
 
+procedure PrevAngle(Gear: PGear; dA: LongInt);
+begin
+    Gear^.Angle := (LongInt(Gear^.Angle) + 4 - dA) mod 4
+end;
+
+procedure NextAngle(Gear: PGear; dA: LongInt);
+begin
+    Gear^.Angle := (LongInt(Gear^.Angle) + 4 + dA) mod 4
+end;
+
 procedure doStepCakeWork(Gear: PGear);
 
 const dirs: array[0..3] of TPoint =   ((x: 0; y: -1), (x: 1; y: 0),(x: 0; y: 1),(x: -1; y: 0));
 var 
     xx, yy, xxn, yyn: LongInt;
-    da: LongInt;
+    dA: LongInt;
     tdx, tdy: hwFloat;
-
-procedure PrevAngle;
-begin
-    Gear^.Angle := (LongInt(Gear^.Angle) + 4 - dA) mod 4
-end;
-
-procedure NextAngle;
-begin
-    Gear^.Angle := (LongInt(Gear^.Angle) + 4 + dA) mod 4
-end;
-
 begin
     AllInactive := false;
 
@@ -3050,7 +2926,7 @@
 
     if (xx = 0) then
         if TestCollisionYwithGear(Gear, yy) <> 0 then
-            PrevAngle
+            PrevAngle(Gear, dA)
     else
     begin
         Gear^.Tag := 0;
@@ -3058,13 +2934,13 @@
         if not TestCollisionXwithGear(Gear, xxn) then
         begin
             Gear^.X := Gear^.X + int2hwFloat(xxn);
-            NextAngle
+            NextAngle(Gear, dA)
         end;
     end;
 
     if (yy = 0) then
         if TestCollisionXwithGear(Gear, xx) then
-            PrevAngle
+            PrevAngle(Gear, dA)
     else
     begin
         Gear^.Tag := 0;
@@ -3072,7 +2948,7 @@
         if not TestCollisionY(Gear, yyn) then
         begin
             Gear^.Y := Gear^.Y + int2hwFloat(yyn);
-            NextAngle
+            NextAngle(Gear, dA)
         end;
     end;
 
@@ -3299,9 +3175,9 @@
     if (Gear^.Timer = 0) or (t^.Count <> 0) or 
        ( ((Gear^.State and gsttmpFlag) = 0) and
          (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0)
-         and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))
+         and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))))
 // CheckLandValue returns true if the type isn't matched
-       or not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible) then
+       or (not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible)) then
         begin
         //out of time or exited ground
         StopSound(Gear^.SoundChannel);
@@ -3312,7 +3188,7 @@
         DeleteGear(Gear);
         exit
         end
-    else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) then
+    else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) then
         begin
         StopSound(Gear^.SoundChannel);
         Gear^.Tag := 1;
@@ -3422,7 +3298,7 @@
     HHGear: PGear;
 begin
     HHGear := Gear^.Hedgehog^.Gear;
-    HHGear^.Message := HHGear^.Message and not (gmUp or gmDown);
+    HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown));
     HHGear^.State := HHGear^.State or gstNotKickable;
     Gear^.doStep := @doStepBallgunWork
 end;
@@ -3493,7 +3369,7 @@
 
     if ((HHGear^.Message and gmAttack) <> 0) and (Gear^.Health <> 0) then
     begin
-        HHGear^.Message := HHGear^.Message and not gmAttack;
+        HHGear^.Message := HHGear^.Message and (not gmAttack);
         AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY *
         _0_5, 0);
         dec(Gear^.Health)
@@ -3542,7 +3418,7 @@
             end;
 
         HHGear^.Message := 0;
-        ParseCommand('/taunt '#1, true)
+        ParseCommand('/taunt ' + #1, true)
     end
 end;
 
@@ -3647,9 +3523,9 @@
                      '%', cWhiteColor, fntSmall)
         end;
 
-    if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then Gear^
-        .State := Gear^.State and not gsttmpFlag;
-    HHGear^.Message := HHGear^.Message and not (gmUp or gmPrecise or gmLeft or gmRight);
+    if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then 
+        Gear^.State := Gear^.State and (not gsttmpFlag);
+    HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
     HHGear^.State := HHGear^.State or gstMoving;
 
     Gear^.X := HHGear^.X;
@@ -3699,8 +3575,8 @@
     AfterAttack;
     with HHGear^ do
     begin
-        State := State and not gstAttacking;
-        Message := Message and not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight);
+        State := State and (not gstAttacking);
+        Message := Message and (not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight));
         if (dY < _0_1) and (dY > -_0_1) then
         begin
             Gear^.State := Gear^.State or gsttmpFlag;
@@ -3770,7 +3646,7 @@
 
     if (HHGear^.Message and gmAttack <> 0) then
         begin
-        HHGear^.Message := HHGear^.Message and not gmAttack;
+        HHGear^.Message := HHGear^.Message and (not gmAttack);
         if Gear^.FlightTime > 0 then
             begin
             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) + 32, gtEgg, 0, Gear^.dX * _0_5, Gear^.dY, 0);
@@ -3780,8 +3656,8 @@
         end;
 
     if HHGear^.Message and (gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
-        Gear^.State := Gear^.State and not gsttmpFlag;
-    HHGear^.Message := HHGear^.Message and not (gmUp or gmPrecise or gmLeft or gmRight);
+        Gear^.State := Gear^.State and (not gsttmpFlag);
+    HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
     HHGear^.State := HHGear^.State or gstMoving;
 
     Gear^.X := HHGear^.X;
@@ -3833,7 +3709,7 @@
             exit
         end;
     HHGear := Gear^.Hedgehog^.Gear;
-    HHGear^.Message := HHGear^.Message and not (gmUp or gmPrecise or gmLeft or gmRight);
+    HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
     if abs(hwRound(HHGear^.Y - Gear^.Y)) > 32 then
     begin
         if Gear^.Timer = 0 then
@@ -3856,7 +3732,7 @@
         Gear^.Timer := 500;
         Gear^.dX := _0;
         Gear^.dY := _0;
-        Gear^.State :=  Gear^.State and not gstAnimation;
+        Gear^.State :=  Gear^.State and (not gstAnimation);
         Gear^.doStep := @doStepBirdyDescend;
     end
 end;
@@ -3865,7 +3741,7 @@
 var 
     HHGear: PGear;
 begin
-    gear^.State :=  gear^.State or gstAnimation and not gstTmpFlag;
+    gear^.State :=  gear^.State or gstAnimation and (not gstTmpFlag);
     Gear^.doStep := @doStepBirdyAppear;
     if CurrentHedgehog = nil then
     begin
@@ -3884,8 +3760,8 @@
     FollowGear := HHGear;
     with HHGear^ do
         begin
-        State := State and not gstAttacking;
-        Message := Message and not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight)
+        State := State and (not gstAttacking);
+        Message := Message and (not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight))
         end
 end;
 
@@ -3928,10 +3804,10 @@
     if (CurrentHedgehog <> nil)
        and (CurrentHedgehog^.Gear <> nil)
        and ((CurrentHedgehog^.Gear^.Message and gmSwitch) <> 0) then
-        With CurrentHedgehog^ do
+        with CurrentHedgehog^ do
             if (CurAmmoType = amPortalGun) then
             begin
-                CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and not gmSwitch;
+                CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSwitch);
                 
                 CurWeapon:= GetAmmoEntry(CurrentHedgehog^);
                 if CurWeapon^.Pos <> 0 then
@@ -4041,11 +3917,11 @@
         // won't port stuff that does not move towards the front/portal entrance
         if iscake then
         begin
-            if not ((iterator^.X - Gear^.X)*ox + (iterator^.Y - Gear^.Y)*oy).isNegative then
+            if not (((iterator^.X - Gear^.X)*ox + (iterator^.Y - Gear^.Y)*oy).isNegative) then
                 continue;
         end
         else
-            if not (Gear^.dX*ox + Gear^.dY*oy).isNegative then
+            if not ((Gear^.dX*ox + Gear^.dY*oy).isNegative) then
                 continue;
 
         isbullet:= (iterator^.Kind in [gtShotgunShot, gtDEagleShot, gtSniperRifleShot, gtSineGunShot]);
@@ -4084,7 +3960,7 @@
             continue;
 
         // only port bullets close to the portal
-        if isBullet and not (hwAbs(poffs) < _3) then
+        if isBullet and (not (hwAbs(poffs) < _3)) then
             continue;
 
         //
@@ -4105,7 +3981,7 @@
         ny := Gear^.dX;
         // ... decide where the top is based on the hog's direction when firing the portal
         if Gear^.Elasticity.isNegative then
-            nx.isNegative := not nx.isNegative
+            nx.isNegative := (not nx.isNegative)
         else
             ny.isNegative := not ny.isNegative;
 
@@ -4137,7 +4013,7 @@
         nx := conPortal^.dY;
         ny := conPortal^.dX;
         if conPortal^.Elasticity.isNegative then
-            nx.isNegative := not nx.isNegative
+            nx.isNegative := (not nx.isNegative)
         else
             ny.isNegative := not ny.isNegative;
 
@@ -4174,7 +4050,7 @@
         iterator^.X := conPortal^.X + poffs * conPortal^.dX + noffs * nx;
         iterator^.Y := conPortal^.Y + poffs * conPortal^.dY + noffs * ny;
 
-        if not hasdxy and not (conPortal^.dY.isNegative) then
+        if not hasdxy and (not (conPortal^.dY.isNegative)) then
         begin
             iterator^.dY:= iterator^.dY + hwAbs(cGravity * (iterator^.Y - conPortal^.Y))
         end;
@@ -4229,7 +4105,7 @@
         else
             begin
             inc(iterator^.PortalCounter);
-            iterator^.State:= iterator^.State and not gstHHHJump
+            iterator^.State:= iterator^.State and (not gstHHHJump)
             end;
 
         if not isbullet and (iterator^.Kind <> gtFlake) then
@@ -4262,10 +4138,7 @@
     end;
 end;
 
-procedure doStepMovingPortal_real(Gear: PGear);
-var 
-    x, y, tx, ty: LongInt;
-    s: hwFloat;
+
 
 procedure loadNewPortalBall(oldPortal: PGear; destroyGear: Boolean);
 var
@@ -4293,6 +4166,10 @@
     if destroyGear then oldPortal^.Timer:= 0;
 end;
 
+procedure doStepMovingPortal_real(Gear: PGear);
+var 
+    x, y, tx, ty: LongInt;
+    s: hwFloat;
 begin
     x := hwRound(Gear^.X);
     y := hwRound(Gear^.Y);
@@ -4303,7 +4180,7 @@
     if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then
     begin
         Gear^.State := Gear^.State or gstCollision;
-        Gear^.State := Gear^.State and not gstMoving;
+        Gear^.State := Gear^.State and (not gstMoving);
         if not CalcSlopeTangent(Gear, x, y, tx, ty, 255)
            or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
         begin
@@ -4364,13 +4241,13 @@
     newPortal^.IntersectGear := nil;
 
     if CurrentHedgehog <> nil then
-        With CurrentHedgehog^ do
+        with CurrentHedgehog^ do
         begin
             CurWeapon:= GetAmmoEntry(CurrentHedgehog^);
             // let's save the HH's dX's direction so we can decide where the "top" of the portal hole
             newPortal^.Elasticity.isNegative := CurrentHedgehog^.Gear^.dX.isNegative;
             // when doing a backjump the dx is the opposite of the facing direction
-            if ((Gear^.State and gstHHHJump) <> 0) and not cArtillery then
+            if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then
                 newPortal^.Elasticity.isNegative := not newPortal^.Elasticity.isNegative;
 
             // make portal gun look unloaded
@@ -4399,7 +4276,7 @@
                 iterator := iterator^.NextGear
             end;
         end;
-    newPortal^.State := newPortal^.State and not gstCollision;
+    newPortal^.State := newPortal^.State and (not gstCollision);
     newPortal^.State := newPortal^.State or gstMoving;
     newPortal^.doStep := @doStepMovingPortal;
 end;
@@ -4427,7 +4304,7 @@
         end;
         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote);
         CurrentHedgehog^.Gear^.MsgParam := 0;
-        CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and not gmSlot;
+        CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSlot);
         end;
 
     if (*((Gear^.Pos = 3) and ((GameFlags and gfSolidLand) <> 0)) or*) (Gear^.Pos = 5) then
@@ -4698,7 +4575,7 @@
     HHGear: PGear;
 begin
     HHGear := Gear^.Hedgehog^.Gear;
-    HHGear^.Message := HHGear^.Message and not (gmUp or gmDown or gmLeft or gmRight);
+    HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight));
     HHGear^.State := HHGear^.State or gstNotKickable;
     Gear^.doStep := @doStepFlamethrowerWork
 end;
@@ -4748,7 +4625,7 @@
 
     if (Gear^.Health = 0) or (HHGear^.Damage <> 0) or ((HHGear^.Message and gmAttack) <> 0) then
         begin
-        HHGear^.Message:= HHGear^.Message and not gmAttack;
+        HHGear^.Message:= HHGear^.Message and (not gmAttack);
         DeleteGear(Gear);
         AfterAttack
         end
@@ -4770,7 +4647,7 @@
     HHGear: PGear;
 begin
     HHGear := Gear^.Hedgehog^.Gear;
-    HHGear^.Message := HHGear^.Message and not (gmUp or gmDown or gmLeft or gmRight or gmAttack);
+    HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight or gmAttack));
     HHGear^.State := HHGear^.State or gstNotKickable;
     Gear^.doStep := @doStepLandGunWork
 end;
@@ -4828,7 +4705,7 @@
             end
     end;
 
-HHGear^.State:= HHGear^.State and not gstNoDamage;
+HHGear^.State:= HHGear^.State and (not gstNoDamage);
 Gear^.Timer:= 250;
 Gear^.doStep:= @doStepIdle
 end;
@@ -5069,53 +4946,79 @@
 procedure doStepStructure(Gear: PGear);
 var 
     x, y: LongInt;
+    HH: PHedgehog;
+    t: PGear;
 begin
+    HH:= Gear^.Hedgehog;
+
     if (Gear^.State and gstMoving) <> 0 then
         begin
         AddGearCI(Gear);
         Gear^.dX:= _0;
         Gear^.dY:= _0;
-        Gear^.State:= Gear^.State and not gstMoving;
-        end;
-
-    if CurAmmoGear = Gear then
-        begin
-        if (CurrentHedgehog = nil) or (CurrentHedgehog^.Gear = nil) then
-            begin
-            DeleteGear(Gear);
-            exit
-            end;
-        if Gear = CurAmmoGear then CurAmmoGear := nil;
-        Gear^.Hedgehog:= CurrentHedgehog;
-        RemoveGearFromList(CurrentHedgehog^.Gear);
-        CurrentHedgehog^.Gear^.Z := cHHZ;
-        CurrentHedgehog^.Gear^.Active := false;
-        CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State and not gstHHDriven;
-        CurrentHedgehog^.GearHidden:= CurrentHedgehog^.Gear;
-        CurrentHedgehog^.Gear:= nil;
-        Gear^.Tag:= TotalRounds + Gear^.Tag;
-        AddGearCI(Gear);
+        Gear^.State:= Gear^.State and (not gstMoving);
         end;
 
     dec(Gear^.Health, Gear^.Damage);
-    Gear^.Damage := 0;
+    Gear^.Damage:= 0;
         
-    if (Gear^.Tag = TotalRounds) or (Gear^.Health <= 0) then
+    if Gear^.Pos = 1 then
         begin
-        if Gear^.Hedgehog <> nil then
+        AddGearCI(Gear);
+        AfterAttack;
+        if Gear = CurAmmoGear then CurAmmoGear:= nil;
+        if HH^.Gear <> nil then HideHog(HH);
+        Gear^.Pos:= 2
+        end;
+        
+    if Gear^.Pos = 2 then
+        begin
+        if ((GameTicks mod 100) = 0) and (Gear^.Timer < 1000) then
             begin
-            Gear^.Hedgehog^.Gear:= Gear^.Hedgehog^.GearHidden;
-            Gear^.Hedgehog^.GearHidden:= nil;
-            Gear^.Hedgehog^.Gear^.X:= Gear^.X;
-            Gear^.Hedgehog^.Gear^.Y:= Gear^.Y - int2hwFloat(Gear^.Radius + cHHRadius);
-            InsertGearToList(Gear^.Hedgehog^.Gear);
-            Gear^.Hedgehog:= nil;
-            SetAllHHToActive;
+            if (Gear^.Timer mod 10) = 0 then
+                begin
+                DeleteCI(Gear);
+                Gear^.Y:= Gear^.Y - _0_5;
+                AddGearCI(Gear);
+                end;
+            inc(Gear^.Timer);
             end;
+        if Gear^.Tag <= TotalRounds then Gear^.Pos:= 3;
         end;
         
+    if Gear^.Pos = 3 then
+        if Gear^.Timer < 1000 then
+            begin
+            if (Gear^.Timer mod 10) = 0 then
+                begin
+                DeleteCI(Gear);
+                Gear^.Y:= Gear^.Y - _0_5;
+                AddGearCI(Gear);
+                end;
+            inc(Gear^.Timer);
+            end
+        else
+            begin
+            if HH^.GearHidden <> nil then RestoreHog(HH);
+            Gear^.Pos:= 4;
+            end;
+        
+    if Gear^.Pos = 4 then
+        if ((GameTicks mod 1000) = 0) and ((GameFlags and gfInvulnerable) = 0) then
+            begin
+            t:= GearsList;
+            while t <> nil do
+                begin
+                if (t^.Kind = gtHedgehog) and (t^.Hedgehog^.Team^.Clan = HH^.Team^.Clan) then
+                    t^.Invulnerable:= true;
+                t:= t^.NextGear;
+                end;
+            end;
+        
     if Gear^.Health <= 0 then
         begin
+        if HH^.GearHidden <> nil then RestoreHog(HH);
+        
         x := hwRound(Gear^.X);
         y := hwRound(Gear^.Y);
 
@@ -5179,10 +5082,10 @@
        ((HH^.Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
         with HH^.Gear^ do
             begin
-	        State:= State or gstAnimation;
-	        Tag:= 2;
-	        Timer:= 0;
-	        Pos:= 0
+            State:= State or gstAnimation;
+            Tag:= 2;
+            Timer:= 0;
+            Pos:= 0
             end
     end;
 if (Gear^.Pos = 3) and (GameTicks and $1F = 0) and (Gear^.Power > 0) then dec(Gear^.Power);
@@ -5246,8 +5149,8 @@
         begin
         if HH^.Gear <> nil then
             begin
-            HH^.Gear^.Message := HH^.Gear^.Message and not gmAttack;
-            HH^.Gear^.State:= HH^.Gear^.State and not gstAttacking;
+            HH^.Gear^.Message := HH^.Gear^.Message and (not gmAttack);
+            HH^.Gear^.State:= HH^.Gear^.State and (not gstAttacking);
             end;
         PlaySound(sndDenied);
         DeleteGear(gear);
@@ -5264,8 +5167,8 @@
         begin
         if HH^.Gear <> nil then
             begin
-            HH^.Gear^.Message := HH^.Gear^.Message and not gmAttack;
-            HH^.Gear^.State:= HH^.Gear^.State and not gstAttacking;
+            HH^.Gear^.Message := HH^.Gear^.Message and (not gmAttack);
+            HH^.Gear^.State:= HH^.Gear^.State and (not gstAttacking);
             end;
             PlaySound(sndDenied);
             DeleteGear(gear);
--- a/hedgewars/HHHandlers.inc	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/HHHandlers.inc	Mon Dec 05 18:38:25 2011 -0500
@@ -17,1138 +17,3 @@
  *)
 
 ////////////////////////////////////////////////////////////////////////////////
-
-procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource);
-begin
-if (Source = dsFall) or (Source = dsExplosion) then
-    case random(3) of
-        0: PlaySound(sndOoff1, Hedgehog^.Team^.voicepack);
-        1: PlaySound(sndOoff2, Hedgehog^.Team^.voicepack);
-        2: PlaySound(sndOoff3, Hedgehog^.Team^.voicepack);
-    end
-else if (Source = dsPoison) then
-    case random(2) of
-        0: PlaySound(sndPoisonCough, Hedgehog^.Team^.voicepack);
-        1: PlaySound(sndPoisonMoan, Hedgehog^.Team^.voicepack);
-    end
-else
-    case random(4) of
-        0: PlaySound(sndOw1, Hedgehog^.Team^.voicepack);
-        1: PlaySound(sndOw2, Hedgehog^.Team^.voicepack);
-        2: PlaySound(sndOw3, Hedgehog^.Team^.voicepack);
-        3: PlaySound(sndOw4, Hedgehog^.Team^.voicepack);
-    end
-end;
-
-// Shouldn't more of this ammo switching stuff be moved to uAmmos ?
-function ChangeAmmo(HHGear: PGear): boolean;
-var slot, i: Longword;
-    ammoidx: LongInt;
-begin
-ChangeAmmo:= false;
-slot:= HHGear^.MsgParam;
-
-with HHGear^.Hedgehog^ do
-    begin
-    HHGear^.Message:= HHGear^.Message and not gmSlot;
-    ammoidx:= 0;
-    if ((HHGear^.State and (gstAttacking or gstAttacked)) <> 0) or
-       ((MultiShootAttacks > 0) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0)) or
-       ((HHGear^.State and gstHHDriven) = 0) then exit;
-    ChangeAmmo:= true;
-
-    while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do inc(ammoidx);
-
-    if ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) and (MultiShootAttacks > 0) then OnUsedAmmo(HHGear^.Hedgehog^);
-
-    MultiShootAttacks:= 0;
-    HHGear^.Message:= HHGear^.Message and not (gmLJump or gmHJump);
-    
-    if Ammoz[CurAmmoType].Slot = slot then
-        begin
-        i:= 0;
-        repeat
-        inc(ammoidx);
-        if (ammoidx > cMaxSlotAmmoIndex) then
-            begin
-            inc(i);
-            CurAmmoType:= amNothing;
-            ammoidx:= -1;
-            //TryDo(i < 2, 'Engine bug: no ammo in current slot', true)
-            end;
-        until (i = 1) or ((Ammo^[slot, ammoidx].Count > 0) and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns))
-        end 
-    else
-        begin
-        i:= 0;
-        // check whether there is ammo in slot
-        while (i <= cMaxSlotAmmoIndex)
-          and ((Ammo^[slot, i].Count = 0)
-               or (Team^.Clan^.TurnNumber <= Ammoz[Ammo^[slot, i].AmmoType].SkipTurns)) do inc(i);
-
-        if i <= cMaxSlotAmmoIndex then ammoidx:= i
-        else ammoidx:= -1
-        end;
-        if ammoidx >= 0 then CurAmmoType:= Ammo^[slot, ammoidx].AmmoType;
-    end
-end;
-
-procedure HHSetWeapon(HHGear: PGear);
-var t: LongInt;
-    weap: TAmmoType;
-    Hedgehog: PHedgehog;
-    s: boolean;
-begin
-s:= false;
-
-weap:= TAmmoType(HHGear^.MsgParam);
-Hedgehog:= HHGear^.Hedgehog;
-
-if Hedgehog^.Team^.Clan^.TurnNumber <= Ammoz[weap].SkipTurns then exit; // weapon is not activated yet
-
-HHGear^.MsgParam:= Ammoz[weap].Slot;
-
-t:= cMaxSlotAmmoIndex;
-
-HHGear^.Message:= HHGear^.Message and not gmWeapon;
-
-with Hedgehog^ do
-    while (CurAmmoType <> weap) and (t >= 0) do
-        begin
-        s:= ChangeAmmo(HHGear);
-        dec(t)
-        end;
-
-if s then ApplyAmmoChanges(HHGear^.Hedgehog^)
-end;
-
-procedure HHSetTimer(Gear: PGear);
-var CurWeapon: PAmmo;
-    color: LongWord;
-begin
-Gear^.Message:= Gear^.Message and not gmTimer;
-CurWeapon:= GetAmmoEntry(Gear^.Hedgehog^);
-with Gear^.Hedgehog^ do
-    if ((Gear^.Message and gmPrecise) <> 0) and ((CurWeapon^.Propz and ammoprop_SetBounce) <> 0) then
-        begin
-        color:= Gear^.Hedgehog^.Team^.Clan^.Color;
-        case Gear^.MsgParam of
-            1: begin
-               AddCaption(format(trmsg[sidBounce], trmsg[sidBounce1]), color, capgrpAmmostate);
-               CurWeapon^.Bounciness:= 350;
-               end;
-            2: begin
-               AddCaption(format(trmsg[sidBounce], trmsg[sidBounce2]), color, capgrpAmmostate);
-               CurWeapon^.Bounciness:= 700;
-               end;
-            3: begin
-               AddCaption(format(trmsg[sidBounce], trmsg[sidBounce3]), color, capgrpAmmostate);
-               CurWeapon^.Bounciness:= 1000;
-               end;
-            4: begin
-               AddCaption(format(trmsg[sidBounce], trmsg[sidBounce4]), color, capgrpAmmostate);
-               CurWeapon^.Bounciness:= 2000;
-               end;
-            5: begin
-               AddCaption(format(trmsg[sidBounce], trmsg[sidBounce5]), color, capgrpAmmostate);
-               CurWeapon^.Bounciness:= 4000;
-               end
-            end
-        end
-    else if (CurWeapon^.Propz and ammoprop_Timerable) <> 0 then
-        begin
-        CurWeapon^.Timer:= 1000 * Gear^.MsgParam;
-        with CurrentTeam^ do
-            ApplyAmmoChanges(Hedgehogs[CurrHedgehog]);
-        end;
-end;
-
-
-procedure Attack(Gear: PGear);
-var xx, yy, newDx, newDy, lx, ly: hwFloat;
-    speech: PVisualGear;
-    newGear:  PGear;
-    CurWeapon: PAmmo;
-    altUse: boolean;
-    elastic: hwFloat;
-begin
-newGear:= nil;
-bShowFinger:= false;
-CurWeapon:= GetAmmoEntry(Gear^.Hedgehog^);
-with Gear^,
-     Gear^.Hedgehog^ do
-     begin
-     if ((State and gstHHDriven) <> 0)and
-        ((State and (gstAttacked or gstHHChooseTarget)) = 0) and
-        (((State and gstMoving) = 0) or
-            (Power > 0) or
-            (CurAmmoType = amTeleport) or 
-            // Allow attacks while moving on ammo with AltAttack
-            ((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)) or
-            ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0)) and
-        ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then
-        begin
-        State:= State or gstAttacking;
-        if Power = cMaxPower then Message:= Message and not gmAttack
-        else if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) = 0 then Message:= Message and not gmAttack
-        else begin
-             if Power = 0 then
-                begin
-                AttackBar:= CurrentTeam^.AttackBar;
-                PlaySound(sndThrowPowerUp)
-                end;
-             inc(Power)
-             end;
-        if ((Message and gmAttack) <> 0) then exit;
-
-        if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0 then
-           begin
-           StopSound(sndThrowPowerUp);
-           PlaySound(sndThrowRelease);
-           end;
-
-        xx:= SignAs(AngleSin(Angle), dX);
-        yy:= -AngleCos(Angle);
-
-        lx:= X + int2hwfloat(round(GetLaunchX(CurAmmoType, hwSign(dX), Angle)));
-        ly:= Y + int2hwfloat(round(GetLaunchY(CurAmmoType, Angle)));
-
-        if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then xx:= - xx;
-        if Ammoz[CurAmmoType].Ammo.AttackVoice <> sndNone then
-           AddVoice(Ammoz[CurAmmoType].Ammo.AttackVoice, CurrentTeam^.voicepack);
-
-// Initiating alt attack
-        if  (CurAmmoGear <> nil) and
-            ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) and
-            ((Gear^.Message and gmLJump) <> 0) and
-            ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
-            begin
-            newDx:= dX / _2; 
-            newDy:= dY / _2;
-            altUse:= true;
-            end
-        else
-            begin
-            newDx:= xx*Power/cPowerDivisor;
-            newDy:= yy*Power/cPowerDivisor;
-            altUse:= false
-            end;
-
-             case CurAmmoType of
-                      amGrenade: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGrenade,         0, newDx, newDy, CurWeapon^.Timer);
-                      amMolotov: newGear:= AddGear(hwRound(lx), hwRound(ly), gtMolotov,      0, newDx, newDy, 0);
-                  amClusterBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb,  0, newDx, newDy, CurWeapon^.Timer);
-                      amGasBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGasBomb,      0, newDx, newDy, CurWeapon^.Timer);
-                      amBazooka: newGear:= AddGear(hwRound(lx), hwRound(ly), gtShell,        0, newDx, newDy, 0);
-                     amSnowball: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSnowball,     0, newDx, newDy, 0);
-                          amBee: newGear:= AddGear(hwRound(lx), hwRound(ly), gtBee,          0, newDx, newDy, 0);
-                      amShotgun: begin
-                                 PlaySound(sndShotgunReload);
-                                 newGear:= AddGear(hwRound(lx), hwRound(ly), gtShotgunShot,  0, xx * _0_5, yy * _0_5, 0);
-                                 end;
-                   amPickHammer: newGear:= AddGear(hwRound(lx), hwRound(ly) + cHHRadius, gtPickHammer, 0, _0, _0, 0);
-                         amSkip: ParseCommand('/skip', true);
-                         amRope: newGear:= AddGear(hwRound(lx), hwRound(ly), gtRope, 0, xx, yy, 0);
-                         amMine: if altUse then
-                                    newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, newDx, newDy, 3000)
-                                 else
-                                    newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000);
-                        amSMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSMine,    0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
-                       amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0);
-                      amSineGun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0);
-                    amPortalGun: begin
-                                 newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6, 
-                                 // set selected color
-                                 CurWeapon^.Pos);
-                                 end;
-                  amSniperRifle: begin
-                                 PlaySound(sndSniperReload);
-                                 newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSniperRifleShot, 0, xx * _0_5, yy * _0_5, 0);
-                                 end;
-                     amDynamite: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtDynamite, 0, SignAs(_0_03, dX), _0, 5000);
-                    amFirePunch: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtFirePunch, 0, xx, _0, 0);
-                         amWhip: begin
-                                 newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtWhip, 0, SignAs(_1, dX), - _0_8, 0);
-                                 PlaySound(sndWhipCrack)
-                                 end;
-                       amHammer: begin
-                                 newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtHammer, 0, SignAs(_1, dX), - _0_8, 0);
-                                 PlaySound(sndWhack)
-                                 end;
-                  amBaseballBat: begin
-                                 newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtShover, gsttmpFlag, xx * _0_5, yy * _0_5, 0);
-                                 PlaySound(sndBaseballBat) // TODO: Only play if something is hit?
-                                 end;
-                    amParachute: begin
-                                 newGear:= AddGear(hwRound(lx), hwRound(ly), gtParachute, 0, _0, _0, 0);
-                                 PlaySound(sndParachute)
-                                 end;
-                    // we save CurWeapon^.Pos (in this case: cursor direction) by using it as (otherwise irrelevant) X value of the new gear.
-                    amAirAttack: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 0, _0, _0, 0);
-                   amMineStrike: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 1, _0, _0, 0);
-                  amDrillStrike: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 3, _0, _0, CurWeapon^.Timer);
-                       amNapalm: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 2, _0, _0, 0);
-                    amBlowTorch: newGear:= AddGear(hwRound(lx), hwRound(ly), gtBlowTorch, 0, SignAs(_0_5, dX), _0, 0);
-                       amGirder: newGear:= AddGear(0, 0, gtGirder, CurWeapon^.Pos, _0, _0, 0);
-                     amTeleport: newGear:= AddGear(CurWeapon^.Pos, 0, gtTeleport, 0, _0, _0, 0);
-                       amSwitch: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSwitcher, 0, _0, _0, 0);
-                       amMortar: begin
-                                 playSound(sndMortar);
-                                 newGear:= AddGear(hwRound(lx), hwRound(ly), gtMortar,  0, xx*cMaxPower/cPowerDivisor, yy*cMaxPower/cPowerDivisor, 0);
-                                 end;
-                      amRCPlane: begin
-                                 newGear:= AddGear(hwRound(lx), hwRound(ly), gtRCPlane,  0, xx * cMaxPower / cPowerDivisor / 4, yy * cMaxPower / cPowerDivisor / 4, 0);
-                                 newGear^.SoundChannel:= LoopSound(sndRCPlane, nil)
-                                 end;
-                       amKamikaze: newGear:= AddGear(hwRound(lx), hwRound(ly), gtKamikaze, 0, xx * _0_5, yy * _0_5, 0);
-                         amCake: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 3, hwRound(ly), gtCake, 0, xx, _0, 0);
-                    amSeduction: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSeduction, 0, _0, _0, 0);
-                   amWatermelon: newGear:= AddGear(hwRound(lx), hwRound(ly), gtWatermelon,  0, newDx, newDy, CurWeapon^.Timer);
-                  amHellishBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtHellishBomb,    0, newDx, newDy, 0);
-                        amDrill: newGear:= AddGear(hwRound(lx), hwRound(ly), gtDrill, 0, newDx, newDy, 0);
-                      amBallgun: newGear:= AddGear(hwRound(X), hwRound(Y), gtBallgun,  0, xx * _0_5, yy * _0_5, 0);
-                    amJetpack: newGear:= AddGear(hwRound(lx), hwRound(ly), gtJetpack, 0, _0, _0, 0);
-                    amBirdy: begin
-                             PlaySound(sndWhistle);
-                             newGear:= AddGear(hwRound(lx), hwRound(ly) - 32, gtBirdy, 0, _0, _0, 0);
-                             end;
-                      amLowGravity: begin
-                                    PlaySound(sndLowGravity);
-                                    cGravity:= cMaxWindSpeed;
-                                    cGravityf:= 0.00025
-                                    end;
-                      amExtraDamage:begin 
-                                    PlaySound(sndHellishImpact4);
-                                    cDamageModifier:= _1_5
-                                    end;
-                      amInvulnerable: Invulnerable:= true;
-                      amExtraTime:  begin
-                                    PlaySound(sndSwitchHog);
-                                    TurnTimeLeft:= TurnTimeLeft + 30000
-                                    end;
-                      amLaserSight: cLaserSighting:= true;
-                      amVampiric: begin
-                                  PlaySound(sndOw1, Team^.voicepack);
-                                  cVampiric:= true;
-                                  end;
-                      amPiano: begin
-                               // Tuck the hedgehog away until the piano attack is completed
-                               Unplaced:= true;
-                               X:= _0;
-                               Y:= _0;
-                               newGear:= AddGear(TargetPoint.X, 0, gtPiano, 0, _0, _0, 0);
-                               PauseMusic
-                               end;
-                      amFlamethrower: newGear:= AddGear(hwRound(X), hwRound(Y), gtFlamethrower,  0, xx * _0_5, yy * _0_5, 0);
-                      amLandGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtLandGun,  0, xx * _0_5, yy * _0_5, 0);
-                    amResurrector: begin
-                        newGear:= AddGear(hwRound(lx), hwRound(ly),
-                                gtResurrector, 0, _0, _0, 0);
-                        newGear^.SoundChannel := LoopSound(sndResurrector);
-                    end;
-                   //amMelonStrike: AddGear(CurWeapon^.Pos, 0, gtAirAttack, 4, _0, _0, 0);
-                     amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
-                        amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
-                  end;
-             case CurAmmoType of
-                      amGrenade, amMolotov, 
-                  amClusterBomb, amGasBomb, 
-                      amBazooka, amSnowball, 
-                          amBee, amSMine,
-                       amMortar, amWatermelon,
-                  amHellishBomb, amDrill: FollowGear:= newGear;
-
-                      amShotgun, amPickHammer,
-                         amRope, amDEagle,
-                      amSineGun, amSniperRifle,
-                    amFirePunch, amWhip,
-                       amHammer, amBaseballBat,
-                    amParachute, amBlowTorch,
-                       amGirder, amTeleport,
-                       amSwitch, amRCPlane,
-                     amKamikaze, amCake,
-                    amSeduction, amBallgun,
-                      amJetpack, amBirdy,
-                 amFlamethrower, amLandGun,
-                  amResurrector, amStructure,
-                       amTardis, amPiano: CurAmmoGear:= newGear;
-                  end;
-              if (CurAmmoType = amMine) or (CurAmmoType = amSMine) and (GameFlags and gfInfAttack <> 0) then newGear^.FlightTime:= GameTicks + 1000;
-        if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
-            begin
-            newGear^.Target.X:= TargetPoint.X;
-            newGear^.Target.Y:= TargetPoint.Y
-            end;
-
-        // Clear FollowGear if using on a rope/parachute/saucer etc so focus stays with the hog's movement
-        if altUse then FollowGear:= nil;
-
-        if (newGear <> nil) and ((Ammoz[newGear^.AmmoType].Ammo.Propz and ammoprop_SetBounce) <> 0) then
-            begin
-            elastic:=  int2hwfloat(CurWeapon^.Bounciness) / _1000;
-
-            if elastic < _1 then newGear^.Elasticity:= newGear^.Elasticity * elastic
-            else if elastic > _1 then newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
-(* Experimented with friction modifier. Didn't seem helpful 
-            fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
-            if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
-            else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
-            end;
-
-
-        uStats.AmmoUsed(CurAmmoType);
-
-        if not (SpeechText = '') then
-            begin
-            speech:= AddVisualGear(0, 0, vgtSpeechBubble);
-            if speech <> nil then
-               begin
-               speech^.Text:= SpeechText;
-               speech^.Hedgehog:= Gear^.Hedgehog;
-               speech^.FrameTicks:= SpeechType;
-               end;
-            SpeechText:= ''
-            end;
-
-        Power:= 0;
-        if (CurAmmoGear <> nil)
-           and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
-           begin
-           Message:= Message or gmAttack;
-           CurAmmoGear^.Message:= Message
-           end else begin
-           if not CurrentTeam^.ExtDriven and
-             ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then SendIPC('a');
-           AfterAttack;
-           end
-        end else Message:= Message and not gmAttack;
-     end;
-     TargetPoint.X := NoPointX;
-     ScriptCall('onHogAttack');	
-end;
-
-procedure AfterAttack;
-var s: shortstring;
-    a: TAmmoType;
-begin
-with CurrentHedgehog^.Gear^,
-        CurrentHedgehog^ do
-    begin
-    a:= CurAmmoType;
-    State:= State and not gstAttacking;
-    if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then
-        begin
-        Inc(MultiShootAttacks);
-        
-        if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) then
-            begin
-            s:= inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1);
-            AddCaption(format(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate);
-            end;
-        
-        if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) or
-            ((GameFlags and gfMultiWeapon) <> 0) then
-            begin
-            isInMultiShoot:= true
-            end
-        else
-            begin
-            OnUsedAmmo(CurrentHedgehog^);
-            if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (((GameFlags and gfInfAttack) = 0) or PlacingHogs) then
-                begin
-                if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft;
-                TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100;
-                end;
-            if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) then State:= State or gstAttacked;
-            if (Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) <> 0 then ApplyAmmoChanges(CurrentHedgehog^)
-            end;
-        end
-    else
-        begin
-        OnUsedAmmo(CurrentHedgehog^);
-        ApplyAmmoChanges(CurrentHedgehog^);
-        end;
-    AttackBar:= 0
-    end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepHedgehogDead(Gear: PGear);
-const frametime = 200;
-      timertime = frametime * 6;
-begin
-if Gear^.Hedgehog^.Unplaced then exit;
-if Gear^.Timer > 1 then
-    begin
-    AllInactive:= false;
-    dec(Gear^.Timer);
-    if (Gear^.Timer mod frametime) = 0 then inc(Gear^.Pos)
-    end 
-else if Gear^.Timer = 1 then
-    begin
-    Gear^.State:= Gear^.State or gstNoDamage;
-    doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound);
-    AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
-    DeleteGear(Gear);
-    SetAllToActive
-    end 
-else // Gear^.Timer = 0
-    begin
-    AllInactive:= false;
-    Gear^.Z:= cCurrHHZ;
-    RemoveGearFromList(Gear);
-    InsertGearToList(Gear);
-    PlaySound(sndByeBye, Gear^.Hedgehog^.Team^.voicepack);
-    Gear^.Pos:= 0;
-    Gear^.Timer:= timertime
-    end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepHedgehogGone(Gear: PGear);
-const frametime = 65;
-      timertime = frametime * 11;
-begin
-if Gear^.Hedgehog^.Unplaced then exit;
-if Gear^.Timer > 1 then
-    begin
-    AllInactive:= false;
-    dec(Gear^.Timer);
-    if (Gear^.Timer mod frametime) = 0 then inc(Gear^.Pos)
-    end else
-if Gear^.Timer = 1 then
-    begin
-    DeleteGear(Gear);
-    SetAllToActive
-    end else // Gear^.Timer = 0
-    begin
-    AllInactive:= false;
-    Gear^.Z:= cCurrHHZ;
-    RemoveGearFromList(Gear);
-    InsertGearToList(Gear);
-    PlaySound(sndByeBye, Gear^.Hedgehog^.Team^.voicepack);
-    PlaySound(sndWarp);
-    Gear^.Pos:= 0;
-    Gear^.Timer:= timertime
-    end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure PickUp(HH, Gear: PGear);
-var s: shortstring;
-    a: TAmmoType;
-    i: LongInt;
-    vga: PVisualGear;
-begin
-Gear^.Message:= gmDestroy;
-PlaySound(sndShotgunReload);
-if (Gear^.Pos and posCaseExplode) <> 0 then
-    if (Gear^.Pos and posCasePoison) <> 0 then
-        doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound + EXPLPoisoned)
-    else
-        doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound)
-else if (Gear^.Pos and posCasePoison) <> 0 then
-    doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound + EXPLPoisoned + EXPLNoDamage)
-else
-case Gear^.Pos of
-       posCaseUtility,
-       posCaseAmmo: begin
-                    if Gear^.AmmoType <> amNothing then a:= Gear^.AmmoType 
-                    else
-                        begin
-                        for i:= 0 to GameTicks and $7F do GetRandom(2); // Burn some random numbers
-                        if Gear^.Pos = posCaseUtility then a:= GetUtility
-                        else a:= GetAmmo
-                        end;
-                    AddAmmo(HH^.Hedgehog^, a);
-// Possibly needs to check shared clan ammo game flag once added.
-// On the other hand, no obvious reason that clan members shouldn't know what ammo another clan member picked up
-                    if (not (HH^.Hedgehog^.Team^.ExtDriven 
-                      or (HH^.Hedgehog^.BotLevel > 0)))
-                      or (HH^.Hedgehog^.Team^.Clan^.ClanIndex = LocalClan)
-                      or (GameType = gmtDemo)  then
-                        begin
-                        s:= trammo[Ammoz[a].NameId] + ' (+' + IntToStr(Ammoz[a].NumberInCase) + ')';
-                        AddCaption(s, HH^.Hedgehog^.Team^.Clan^.Color, capgrpAmmoinfo);
-
-                        // show ammo icon
-                        vga:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtAmmo);
-                        if vga <> nil then
-                            vga^.Frame:= Longword(a);
-                        end;
-
-                    end;
-     posCaseHealth: begin
-                    inc(HH^.Health, Gear^.Health);
-                    HH^.Hedgehog^.Effects[hePoisoned] := false;
-                    str(Gear^.Health, s);
-                    s:= '+' + s;
-                    AddCaption(s, HH^.Hedgehog^.Team^.Clan^.Color, capgrpAmmoinfo);
-                    RenderHealth(HH^.Hedgehog^);
-                    RecountTeamHealth(HH^.Hedgehog^.Team);
-
-                    i:= 0;
-                    while i < Gear^.Health do
-                        begin
-                        vga:= AddVisualGear(hwRound(HH^.X), hwRound(HH^.Y), vgtStraightShot);
-                        if vga <> nil then
-                            with vga^ do
-                                begin
-                                Tint:= $00FF00FF;
-                                State:= ord(sprHealth)
-                                end;
-                        inc(i, 5);
-                        end;
-                    end;
-     end
-end;
-
-const StepTicks: LongWord = 0;
-
-procedure HedgehogStep(Gear: PGear);
-var PrevdX: LongInt;
-    CurWeapon: PAmmo;
-begin
-CurWeapon:= GetAmmoEntry(Gear^.Hedgehog^);
-if ((Gear^.State and (gstAttacking or gstMoving)) = 0) then
-   begin
-   if isCursorVisible then
-      with Gear^.Hedgehog^ do
-        with CurWeapon^ do
-          begin
-          if (Gear^.Message and gmLeft  ) <> 0 then
-             Pos:= (Pos - 1 + Ammoz[AmmoType].PosCount) mod Ammoz[AmmoType].PosCount
-          else
-          if (Gear^.Message and gmRight ) <> 0 then
-             Pos:= (Pos + 1) mod Ammoz[AmmoType].PosCount
-          else exit;
-          StepTicks:= 200;
-          exit
-          end;
-
-    if ((Gear^.Message and gmAnimate) <> 0) then
-        begin
-        Gear^.Message:= 0;
-        Gear^.State:= Gear^.State or gstAnimation;
-        Gear^.Tag:= Gear^.MsgParam;
-        Gear^.Timer:= 0;
-        Gear^.Pos:= 0
-        end;
-
-   if ((Gear^.Message and gmLJump ) <> 0) then
-      begin
-      Gear^.Message:= Gear^.Message and not gmLJump;
-      DeleteCI(Gear);
-      if TestCollisionYwithGear(Gear, -1) = 0 then
-         if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then Gear^.Y:= Gear^.Y - _2 else
-         if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then Gear^.Y:= Gear^.Y - _1;
-      if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX))
-         or   (TestCollisionYwithGear(Gear, -1) <> 0)) then
-         begin
-         Gear^.dY:= -_0_15;
-         if not cArtillery then Gear^.dX:= SignAs(_0_15, Gear^.dX);
-         Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
-         PlaySound(sndJump1, Gear^.Hedgehog^.Team^.voicepack);
-         exit
-         end;
-      end;
-
-   if ((Gear^.Message and gmHJump ) <> 0) then
-      begin
-      DeleteCI(Gear);
-      Gear^.Message:= Gear^.Message and not gmHJump;
-
-      Gear^.dY:= -_0_2;
-      SetLittle(Gear^.dX);
-      Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
-      PlaySound(sndJump3, Gear^.Hedgehog^.Team^.voicepack);
-      exit
-      end;
-
-   PrevdX:= hwSign(Gear^.dX);
-   if (Gear^.Message and gmLeft  )<>0 then Gear^.dX:= -cLittle else
-   if (Gear^.Message and gmRight )<>0 then Gear^.dX:=  cLittle else exit;
-
-   if (Gear^.Message and (gmLeft or gmRight)) <> 0 then
-      begin
-      StepSoundTimer:= cHHStepTicks;
-      end;
-   
-   StepTicks:= cHHStepTicks;
-   if PrevdX <> hwSign(Gear^.dX) then
-      begin
-      FollowGear:= Gear;
-      exit
-      end;
-   DeleteCI(Gear); // must be after exit!! (see previous line)
-
-   Gear^.Hedgehog^.visStepPos:= (Gear^.Hedgehog^.visStepPos + 1) and 7;
-   if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
-      begin
-      if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX))
-         or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
-      if not (TestCollisionXwithXYShift(Gear, _0, -5, hwSign(Gear^.dX))
-         or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
-      if not (TestCollisionXwithXYShift(Gear, _0, -4, hwSign(Gear^.dX))
-         or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
-      if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX))
-         or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
-      if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX))
-         or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
-      if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX))
-         or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
-      end;
-
-   if (not cArtillery) and ((Gear^.Message and gmPrecise) = 0) and (not TestCollisionXwithGear(Gear, hwSign(Gear^.dX))) then
-      Gear^.X:= Gear^.X + SignAs(_1, Gear^.dX);
-
-   SetAllHHToActive;
-
-   if TestCollisionYwithGear(Gear, 1) = 0 then
-   begin
-   Gear^.Y:= Gear^.Y + _1;
-   if TestCollisionYwithGear(Gear, 1) = 0 then
-   begin
-   Gear^.Y:= Gear^.Y + _1;
-   if TestCollisionYwithGear(Gear, 1) = 0 then
-   begin
-   Gear^.Y:= Gear^.Y + _1;
-   if TestCollisionYwithGear(Gear, 1) = 0 then
-   begin
-   Gear^.Y:= Gear^.Y + _1;
-   if TestCollisionYwithGear(Gear, 1) = 0 then
-   begin
-   Gear^.Y:= Gear^.Y + _1;
-   if TestCollisionYwithGear(Gear, 1) = 0 then
-   begin
-   Gear^.Y:= Gear^.Y + _1;
-   if TestCollisionYwithGear(Gear, 1) = 0 then
-      begin
-      Gear^.Y:= Gear^.Y - _6;
-      Gear^.dY:= _0;
-      Gear^.State:= Gear^.State or gstMoving;
-      exit
-      end;
-   end
-   end
-   end
-   end
-   end
-   end;
-   AddGearCI(Gear)
-   end
-end;
-
-procedure HedgehogChAngle(HHGear: PGear);
-var da: LongWord;
-begin
-with HHGear^.Hedgehog^ do
-    if ((CurAmmoType = amRope) and 
-        ((HHGear^.State and (gstMoving or gstHHJumping)) = gstMoving)) or
-       ((CurAmmoType = amPortalGun) and 
-        ((HHGear^.State and gstMoving) <> 0)) then da:= 2
-    else da:= 1;
-
-if (((HHGear^.Message and gmPrecise) = 0) or ((GameTicks mod 5) = 1)) then
-    if ((HHGear^.Message and gmUp) <> 0) and (HHGear^.Angle >= CurMinAngle + da) then dec(HHGear^.Angle, da)
-    else
-    if ((HHGear^.Message and gmDown) <> 0) and (HHGear^.Angle + da <= CurMaxAngle) then inc(HHGear^.Angle, da)
-end;
-
-procedure doStepHedgehog(Gear: PGear); forward;
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepHedgehogMoving(Gear: PGear);
-var isFalling, isUnderwater: boolean;
-    land: Word;
-begin
-land:= 0;
-isUnderwater:= cWaterLine < hwRound(Gear^.Y) + Gear^.Radius;
-if Gear^.dX.QWordValue > 8160437862 then Gear^.dX.QWordValue:= 8160437862;
-if Gear^.dY.QWordValue > 8160437862 then Gear^.dY.QWordValue:= 8160437862;
-
-if Gear^.Hedgehog^.Unplaced then
-   begin
-   Gear^.dY:= _0;
-   Gear^.dX:= _0;
-   Gear^.State:= Gear^.State and not gstMoving;
-   exit
-   end;
-isFalling:= (Gear^.dY.isNegative) or not TestCollisionYKick(Gear, 1);
-if isFalling then
-   begin
-   if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then Gear^.dY:= _0;
-   Gear^.State:= Gear^.State or gstMoving;
-   if (CurrentHedgehog^.Gear = Gear)
-        and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then 
-        begin
-        FollowGear:= Gear;
-        end;
-   if isUnderwater then Gear^.dY:= Gear^.dY + cGravity / _2
-   else
-       begin
-       Gear^.dY:= Gear^.dY + cGravity;
-// this set of circumstances could be less complex if jumping was more clearly identified
-       if ((GameFlags and gfMoreWind) <> 0) and 
-          (((Gear^.Damage <> 0) or
-          ((CurAmmoGear <> nil) and
-            ((CurAmmoGear^.AmmoType = amJetpack) or
-            (CurAmmoGear^.AmmoType = amBirdy))) or
-          ((Gear^.dY.QWordValue + Gear^.dX.QWordValue) > _0_55.QWordValue)))
-          then Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
-       end
-   end 
-else
-   begin
-   land:= TestCollisionYwithGear(Gear, 1);
-   if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_55.QWordValue) and ((land and lfIce) = 0)
-      and ((Gear^.State and gstHHJumping) <> 0) then SetLittle(Gear^.dX);
-
-   if not Gear^.dY.isNegative then
-      begin
-      CheckHHDamage(Gear);
-
-      if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) and
-         (Gear^.dX.QWordValue < _0_02.QWordValue) then Gear^.dX.isNegative:= not Gear^.dX.isNegative; // landing after high jump
-
-      Gear^.State:= Gear^.State and not (gstHHJumping or gstHHHJump);
-      Gear^.dY:= _0;
-      end else Gear^.dY:= Gear^.dY + cGravity;
-
-   if ((Gear^.State and gstMoving) <> 0) then
-       begin
-       if land and lfIce <> 0 then
-           begin
-           Gear^.dX:= Gear^.dX * (_1 - (_1 - Gear^.Friction) / _2)
-           end
-       else Gear^.dX:= Gear^.dX * Gear^.Friction;
-       end
-   end;
-
-if (Gear^.State <> 0) then DeleteCI(Gear);
-
-if isUnderwater then
-   begin
-   Gear^.dY:= Gear^.dY * _0_999;
-   Gear^.dX:= Gear^.dX * _0_999;
-   end;
-
-if (Gear^.State and gstMoving) <> 0 then
-   if TestCollisionXKick(Gear, hwSign(Gear^.dX)) then
-      if not isFalling then
-         if hwAbs(Gear^.dX) > _0_01 then
-            if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_96; Gear^.Y:= Gear^.Y - _1 end else
-            if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_93; Gear^.Y:= Gear^.Y - _2 end else
-            if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_9 ; Gear^.Y:= Gear^.Y - _3 end else
-            if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -4, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_87; Gear^.Y:= Gear^.Y - _4 end else
-            if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -5, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_84; Gear^.Y:= Gear^.Y - _5 end else
-            if hwAbs(Gear^.dX) > _0_02 then Gear^.dX:= -Gear^.Elasticity * Gear^.dX
-                                   else begin
-                                        Gear^.State:= Gear^.State and not gstMoving;
-                                        while TestCollisionYWithGear(Gear,1) = 0 do Gear^.Y:= Gear^.Y+_1;
-                                        SetLittle(Gear^.dX)
-                                        end
-            else begin
-                 Gear^.State:= Gear^.State and not gstMoving;
-                 while TestCollisionYWithGear(Gear,1) = 0 do Gear^.Y:= Gear^.Y+_1;
-                 SetLittle(Gear^.dX)
-                 end
-         else if (hwAbs(Gear^.dX) > cLittle)
-                and ((Gear^.State and gstHHJumping) = 0)
-                then Gear^.dX:= -Gear^.Elasticity * Gear^.dX
-                else SetLittle(Gear^.dX);
-
-if (not isFalling) and
-   (hwAbs(Gear^.dX) + hwAbs(Gear^.dY) < _0_03) then
-   begin
-   Gear^.State:= Gear^.State and not gstWinner;
-   Gear^.State:= Gear^.State and not gstMoving;
-   while TestCollisionYWithGear(Gear,1) = 0 do Gear^.Y:= Gear^.Y+_1;
-   SetLittle(Gear^.dX);
-   Gear^.dY:= _0
-   end else Gear^.State:= Gear^.State or gstMoving;
-
-if (Gear^.State and gstMoving) <> 0 then
-   begin
-   Gear^.State:= Gear^.State and not gstAnimation;
-// ARTILLERY but not being moved by explosions
-   Gear^.X:= Gear^.X + Gear^.dX;
-   Gear^.Y:= Gear^.Y + Gear^.dY;
-   if (not Gear^.dY.isNegative) and
-      (not TestCollisionYKick(Gear, 1)) and
-       TestCollisionYwithXYShift(Gear, 0, 1, 1) then
-      begin
-      CheckHHDamage(Gear);
-      Gear^.dY:= _0;
-      Gear^.Y:= Gear^.Y + _1
-      end;
-   CheckGearDrowning(Gear);
-   // hide target cursor if current hog is drowning
-   if (Gear^.State and gstDrowning) <> 0 then
-       if (CurrentHedgehog^.Gear = Gear) then
-          isCursorVisible:= false
-   end;
-
-if (hwAbs(Gear^.dY) > _0) and (Gear^.FlightTime > 0) and ((GameFlags and gfLowGravity) = 0) then
-    begin
-    inc(Gear^.FlightTime);
-    if Gear^.FlightTime = 3000 then
-        begin
-        AddCaption(GetEventString(eidHomerun), cWhiteColor, capgrpMessage);
-        PlaySound(sndHomerun)
-        end;
-    end
-else
-    begin
-    uStats.hedgehogFlight(Gear, Gear^.FlightTime);
-    Gear^.FlightTime:= 0;
-    end;
-
-end;
-
-procedure doStepHedgehogDriven(HHGear: PGear);
-var t: PGear;
-    wasJumping: boolean;
-    Hedgehog: PHedgehog;
-begin
-Hedgehog:= HHGear^.Hedgehog;
-if isInMultiShoot then
-   HHGear^.Message:= 0;
-
-if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then 
-    AllInactive:= true
-else if not isInMultiShoot then AllInactive:= false;
-
-if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
-    begin
-    if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft;
-    TurnTimeLeft:= 0;
-    isCursorVisible:= false;
-    HHGear^.State:= HHGear^.State and not (gstHHDriven or gstAnimation or gstAttacking);
-    AttackBar:= 0;
-    if HHGear^.Damage > 0 then
-        HHGear^.State:= HHGear^.State and not (gstHHJumping or gstHHHJump);
-    exit
-    end;
-
-if (HHGear^.State and gstAnimation) <> 0 then
-    begin
-    HHGear^.Message:= 0;
-    if (HHGear^.Pos = Wavez[TWave(HHGear^.Tag)].VoiceDelay) and (HHGear^.Timer = 0) then PlaySound(Wavez[TWave(HHGear^.Tag)].Voice, Hedgehog^.Team^.voicepack);
-    inc(HHGear^.Timer);
-    if HHGear^.Timer = Wavez[TWave(HHGear^.Tag)].Interval then
-        begin
-        HHGear^.Timer:= 0;
-        inc(HHGear^.Pos);
-        if HHGear^.Pos = Wavez[TWave(HHGear^.Tag)].FramesCount then
-            HHGear^.State:= HHGear^.State and not gstAnimation
-        end;
-    exit
-    end;
-
-if ((HHGear^.State and gstMoving) <> 0)
-    or (StepTicks = cHHStepTicks)
-    or (CurAmmoGear <> nil) then // we are moving
-    begin
-    with Hedgehog^ do
-        if (CurAmmoGear = nil)
-        and (HHGear^.dY > _0_39)
-        and (CurAmmoType = amParachute) then HHGear^.Message:= HHGear^.Message or gmAttack;
-    // check for case with ammo
-    t:= CheckGearNear(HHGear, gtCase, 36, 36);
-    if t <> nil then
-        PickUp(HHGear, t)
-    end;
-
-if (CurAmmoGear = nil) then
-    if (((HHGear^.Message and gmAttack) <> 0)
-        or ((HHGear^.State and gstAttacking) <> 0)) then
-        Attack(HHGear) // should be before others to avoid desync with '/put' msg and changing weapon msgs
-    else
-else 
-    with Hedgehog^ do
-        if ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
-            and ((HHGear^.Message and gmLJump) <> 0)
-            and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
-            begin
-            Attack(HHGear);
-            HHGear^.Message:= HHGear^.Message and not gmLJump
-            end;
-
-if (CurAmmoGear = nil)
-    or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) 
-    or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) then
-    begin
-    if ((HHGear^.Message and gmSlot) <> 0) then
-        if ChangeAmmo(HHGear) then ApplyAmmoChanges(Hedgehog^);
-
-    if ((HHGear^.Message and gmWeapon) <> 0) then HHSetWeapon(HHGear);
-
-    if ((HHGear^.Message and gmTimer) <> 0) then HHSetTimer(HHGear);
-    end;
-
-if CurAmmoGear <> nil then
-   begin
-   CurAmmoGear^.Message:= HHGear^.Message;
-   exit
-   end;
-
-if not isInMultiShoot then
-   HedgehogChAngle(HHGear);
-
-if (HHGear^.State and gstMoving) <> 0 then
-    begin
-    wasJumping:= ((HHGear^.State and gstHHJumping) <> 0);
-
-    if ((HHGear^.Message and gmHJump) <> 0) and
-        wasJumping and
-        ((HHGear^.State and gstHHHJump) = 0) then
-        if (not (hwAbs(HHGear^.dX) > cLittle)) and (HHGear^.dY < -_0_02) then
-            begin
-            HHGear^.State:= HHGear^.State or gstHHHJump;
-            HHGear^.dY:= -_0_25;
-            if not cArtillery then HHGear^.dX:= -SignAs(_0_02, HHGear^.dX);
-            PlaySound(sndJump2, Hedgehog^.Team^.voicepack)
-            end;
-
-    HHGear^.Message:= HHGear^.Message and not (gmLJump or gmHJump);
-
-    if (not cArtillery) and wasJumping and
-        TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX);
-
-    if Hedgehog^.Gear <> nil then doStepHedgehogMoving(HHGear);
-
-    if ((HHGear^.State and (gstMoving or gstDrowning)) = 0) then
-        begin
-        AddGearCI(HHGear);
-        if wasJumping then
-            StepTicks:= 410
-        else
-            StepTicks:= 95
-        end;
-    exit
-    end;
-
-    if not isInMultiShoot and (Hedgehog^.Gear <> nil) then
-        begin
-        if StepTicks > 0 then dec(StepTicks);
-        if (StepTicks = 0) then HedgehogStep(HHGear)
-        end
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepHedgehogFree(Gear: PGear);
-var prevState: Longword;
-begin
-prevState:= Gear^.State;
-
-doStepHedgehogMoving(Gear);
-
-if (Gear^.State and (gstMoving or gstDrowning)) <> 0 then
-    begin
-    if Gear^.Damage > 0 then CalcRotationDirAngle(Gear);
-    AllInactive:= false;
-    exit
-    end;
-
-if (Gear^.Health = 0) then
-    begin
-    if PrvInactive or ((GameFlags and gfInfAttack) <> 0) then
-        begin
-        Gear^.Timer:= 0;
-        FollowGear:= Gear;
-        PrvInactive:= false;
-        AllInactive:= false;
-
-        if (Gear^.State and gstHHGone) = 0 then
-            begin
-            Gear^.Hedgehog^.Effects[hePoisoned] := false;
-            if Gear^.Hedgehog^.Effects[heResurrectable] then begin
-                ResurrectHedgehog(Gear);
-            end else 
-                begin
-                Gear^.State:= (Gear^.State or gstHHDeath) and not gstAnimation;
-                Gear^.doStep:= @doStepHedgehogDead;
-                // Death message
-                AddCaption(Format(GetEventString(eidDied), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
-                end;
-            end
-        else
-            begin
-            Gear^.State:= Gear^.State and not gstAnimation;
-            Gear^.doStep:= @doStepHedgehogGone;
-
-            // Gone message
-            AddCaption(Format(GetEventString(eidGone), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
-            end
-        end;
-    exit
-    end;
-
-if ((Gear^.State and gstWait) = 0) and
-    (prevState <> Gear^.State) then
-    begin
-    Gear^.State:= Gear^.State or gstWait;
-    Gear^.Timer:= 150
-    end else
-    begin
-    if Gear^.Timer = 0 then
-        begin
-        Gear^.State:= Gear^.State and not (gstWait or gstLoser or gstWinner or gstAttacked or gstNotKickable or gstHHChooseTarget);
-        Gear^.Active:= false;
-        AddGearCI(Gear);
-        exit
-        end else dec(Gear^.Timer)
-    end;
-
-AllInactive:= false
-end;
-
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepHedgehog(Gear: PGear);
-(*
-var x,y,tx,ty: LongInt;
-    tdX, tdY, slope: hwFloat; 
-    land: Word; *)
-var slope: hwFloat; 
-begin
-if (Gear^.Message and gmDestroy) <> 0 then
-    begin
-    DeleteGear(Gear);
-    exit
-    end;
-
-if (Gear^.State and gstHHDriven) = 0 then
-    doStepHedgehogFree(Gear)
-else
-    begin
-    with Gear^.Hedgehog^ do
-        if Team^.hasGone then
-            TeamGoneEffect(Team^)
-        else
-            doStepHedgehogDriven(Gear)
-    end;
-if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0) and
-   (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0) and
-   not Gear^.dY.isNegative and
-   (GameTicks mod (100*LongWOrd(hwRound(cMaxWindSpeed*2/cGravity))) = 0) and
-   (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
-    begin
-    slope:= CalcSlopeBelowGear(Gear);
-    Gear^.dX:=Gear^.dX+slope*_0_07;
-    if slope.QWordValue <> 0 then Gear^.State:= Gear^.State or gstMoving;
-(*
-    x:= hwRound(Gear^.X);
-    y:= hwRound(Gear^.Y);
-    AddVisualGear(x, y, vgtSmokeTrace);
-    AddVisualGear(x - hwRound(_5*slope), y + hwRound(_5*slope), vgtSmokeTrace);
-    AddVisualGear(x + hwRound(_5*slope), y - hwRound(_5*slope), vgtSmokeTrace);
-    AddVisualGear(x - hwRound(_20 * slope), y + hwRound(_20 * slope), vgtSmokeTrace);
-    AddVisualGear(x + hwRound(_20 * slope), y - hwRound(_20 * slope), vgtSmokeTrace);
-    AddVisualGear(x - hwRound(_30 * slope), y + hwRound(_30 * slope), vgtSmokeTrace);
-    AddVisualGear(x + hwRound(_30 * slope), y - hwRound(_30 * slope), vgtSmokeTrace);
-    AddVisualGear(x - hwRound(_40 * slope), y + hwRound(_40 * slope), vgtSmokeTrace);
-    AddVisualGear(x + hwRound(_40 * slope), y - hwRound(_40 * slope), vgtSmokeTrace);
-    AddVisualGear(x - hwRound(_50 * slope), y + hwRound(_50 * slope), vgtSmokeTrace);
-    AddVisualGear(x + hwRound(_50 * slope), y - hwRound(_50 * slope), vgtSmokeTrace); *)
-    end
-end;
--- a/hedgewars/LuaPas.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/LuaPas.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -15,7 +15,7 @@
 {$INCLUDE "config.inc"}
 
 type
-  size_t   = type Cardinal;
+  size_t   = Cardinal;
   Psize_t  = ^size_t;
   PPointer = ^Pointer;
 
@@ -45,8 +45,8 @@
 ** ===================================================================
 *)
 type
-  LUA_NUMBER_  = type Double;            // ending underscore is needed in Pascal
-  LUA_INTEGER_ = type PtrInt;
+  LUA_NUMBER_  = Double;            // ending underscore is needed in Pascal
+  LUA_INTEGER_ = PtrInt;
 
 (*
 @@ LUA_IDSIZE gives the maximum size for the description of the source
@@ -115,7 +115,7 @@
   LUA_AUTHORS     = 'R. Ierusalimschy, L. H. de Figueiredo & W. Celes';
 
   (* mark for precompiled code (`<esc>Lua') *)
-  LUA_SIGNATURE = #27'Lua';
+  LUA_SIGNATURE = #27 + 'Lua';
 
   (* option for multiple returns in `lua_pcall' and `lua_call' *)
   LUA_MULTRET = -1;
@@ -429,8 +429,8 @@
 function lua_getgccount(L : Plua_State) : LongInt;
 
 type
-  lua_Chuckreader = type lua_Reader;
-  lua_Chuckwriter = type lua_Writer;
+  lua_Chuckreader = lua_Reader;
+  lua_Chuckwriter = lua_Writer;
 
 (* ====================================================================== *)
 
@@ -983,7 +983,7 @@
 begin
   if not(B^.p < B^.buffer + LUAL_BUFFERSIZE) then
     luaL_prepbuffer(B);
-  B^.p^ := c;
+  (B^.p^) := c;
   Inc(B^.p);
 end;
 
--- a/hedgewars/options.inc	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/options.inc	Mon Dec 05 18:38:25 2011 -0500
@@ -34,6 +34,7 @@
   {$DEFINE GLunit:=gles11}
   {$DEFINE MOBILE}
   {$DEFINE Java_Prefix := 'Java_org_hedgewars_hedgeroid_EngineProtocol_PascalExports_'}
+  {$DEFINE USE_SDLTHREADS}
 {$ENDIF}
 
 {$IFDEF IPHONEOS}
--- a/hedgewars/uAI.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uAI.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -30,13 +30,17 @@
 
 implementation
 uses uConsts, SDLh, uAIMisc, uAIAmmoTests, uAIActions,
-     uAmmos, SysUtils{$IFDEF UNIX}{$IFNDEF ANDROID}, cthreads{$ENDIF}{$ENDIF}, uTypes,
+     uAmmos, SysUtils{$IFNDEF USE_SDLTHREADS} {$IFDEF UNIX}, cthreads{$ENDIF} {$ENDIF}, uTypes,
      uVariables, uCommands, uUtils, uDebug;
 
 var BestActions: TActions;
     CanUseAmmo: array [TAmmoType] of boolean;
     StopThinking: boolean;
+{$IFDEF USE_SDLTHREADS} 
     ThinkThread: PSDL_Thread = nil;
+{$ELSE}
+    ThinkThread: TThreadID;
+{$ENDIF}
     hasThread: LongInt;
 
 procedure FreeActionsList;
@@ -117,8 +121,11 @@
        with CurrentHedgehog^ do
             a:= CurAmmoType;
        aa:= a;
+{$IFDEF USE_SDLTHREADS}
        SDL_delay(0);    //ThreadSwitch was only a hint
-       
+{$ELSE}
+       ThreadSwitch();
+{$ENDIF}       
        repeat
         if (CanUseAmmo[a]) and
            ((not isMoved) or ((AmmoTests[a].flags and amtest_OnTurn) = 0)) then
@@ -365,11 +372,10 @@
 
 FillBonuses((Me^.State and gstAttacked) <> 0);
 AddFileLog('Enter Think Thread');
-{$IFDEF IPHONEOS}
-//TODO: sdl_thread works on device but crashes in simulator, most likely because of outdated toolchain
+{$IFDEF USE_SDLTHREADS}
+ThinkThread := SDL_CreateThread(@Think{$IFDEF SDL13}, nil{$ENDIF}, Me);
+{$ELSE}
 BeginThread(@Think, Me, ThinkThread);
-{$ELSE}
-ThinkThread := SDL_CreateThread(@Think{$IFDEF SDL13}, nil{$ENDIF}, Me);
 {$ENDIF}
 AddFileLog('Thread started');
 end;
--- a/hedgewars/uAIActions.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uAIActions.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -119,28 +119,27 @@
      end
 end;
 
+procedure CheckHang(Me: PGear);
+const PrevX: LongInt = 0;
+      timedelta: Longword = 0;
+begin
+if hwRound(Me^.X) <> PrevX then
+   begin
+   PrevX:= hwRound(Me^.X);
+   timedelta:= 0
+   end else
+   begin
+   inc(timedelta);
+   if timedelta > 1700 then
+      begin
+      timedelta:= 0;
+      FreeActionsList
+      end
+   end
+end;
+
 procedure ProcessAction(var Actions: TActions; Me: PGear);
 var s: shortstring;
-
-    procedure CheckHang;
-    const PrevX: LongInt = 0;
-          timedelta: Longword = 0;
-    begin
-    if hwRound(Me^.X) <> PrevX then
-       begin
-       PrevX:= hwRound(Me^.X);
-       timedelta:= 0
-       end else
-       begin
-       inc(timedelta);
-       if timedelta > 1700 then
-          begin
-          timedelta:= 0;
-          FreeActionsList
-          end
-       end
-    end;
-
 begin
 repeat
 if Actions.Pos >= Actions.Count then exit;
@@ -165,7 +164,7 @@
                                FreeActionsList;
                                exit
                                end
-                          else begin CheckHang; exit end;
+                          else begin CheckHang(Me); exit end;
            aia_WaitXR: if hwRound(Me^.X) = Param then
                           begin
                           Action:= aia_LookRight;
@@ -178,7 +177,7 @@
                                FreeActionsList;
                                exit
                                end
-                          else begin CheckHang; exit end;
+                          else begin CheckHang(Me); exit end;
          aia_LookLeft: if not Me^.dX.isNegative then
                           begin
                           ParseCommand('+left', true);
--- a/hedgewars/uAIAmmoTests.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uAIAmmoTests.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -124,33 +124,11 @@
 function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
 var Vx, Vy, r, mX, mY: real;
     rTime: LongInt;
-    Score, EX, EY: LongInt;
+    EX, EY: LongInt;
     valueResult: LongInt;
-
-    function CheckTrace: LongInt;
-    var x, y, dX, dY: real;
-        t: LongInt;
-        value: LongInt;
-    begin
-    x:= mX;
-    y:= mY;
-    dX:= Vx;
-    dY:= -Vy;
-    t:= rTime;
-    repeat
-      x:= x + dX;
-      y:= y + dY;
-      dX:= dX + cWindSpeedf;
-      dY:= dY + cGravityf;
-      dec(t)
-    until TestCollExcludingMe(Me, trunc(x), trunc(y), 5) or (t <= 0);
-    EX:= trunc(x);
-    EY:= trunc(y);
-    value:= RateExplosion(Me, EX, EY, 101);
-    if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
-    CheckTrace:= value;
-    end;
-
+    x, y, dX, dY: real;
+    t: LongInt;
+    value: LongInt;
 begin
 mX:= hwFloat2Float(Me^.X);
 mY:= hwFloat2Float(Me^.Y);
@@ -165,15 +143,30 @@
   r:= sqrt(sqr(Vx) + sqr(Vy));
   if not (r > 1) then
      begin
-     Score:= CheckTrace;
-     if valueResult <= Score then
+        x:= mX;
+        y:= mY;
+        dX:= Vx;
+        dY:= -Vy;
+        t:= rTime;
+        repeat
+              x:= x + dX;
+              y:= y + dY;
+              dX:= dX + cWindSpeedf;
+              dY:= dY + cGravityf;
+              dec(t)
+        until TestCollExcludingMe(Me, trunc(x), trunc(y), 5) or (t <= 0);
+        EX:= trunc(x);
+        EY:= trunc(y);
+        value:= RateExplosion(Me, EX, EY, 101);
+        if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
+     if valueResult <= value then
         begin
         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
         ap.Power:= trunc(r * cMaxPower) - random((Level - 1) * 17 + 1);
         ap.ExplR:= 100;
         ap.ExplX:= EX;
         ap.ExplY:= EY;
-        valueResult:= Score
+        valueResult:= value
         end;
      end
 until (rTime > 4250);
@@ -183,32 +176,11 @@
 function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
 var Vx, Vy, r: hwFloat;
     rTime: LongInt;
-    Score, EX, EY: LongInt;
+    EX, EY: LongInt;
     valueResult: LongInt;
-
-    function CheckTrace: LongInt;
-    var x, y, dX, dY: hwFloat;
-        t: LongInt;
-        value: LongInt;
-    begin
-    x:= Me^.X;
-    y:= Me^.Y;
-    dX:= Vx;
-    dY:= -Vy;
-    t:= rTime;
-    repeat
-      x:= x + dX;
-      y:= y + dY;
-      dX:= dX + cWindSpeed;
-      dY:= dY + cGravity;
-      dec(t)
-    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t <= 0);
-    EX:= hwRound(x);
-    EY:= hwRound(y);
-    value:= RateExplosion(Me, EX, EY, 5);
-    if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
-    CheckTrace:= value;
-    end;
+    x, y, dX, dY: hwFloat;
+    t: LongInt;
+    value: LongInt;
 
 begin
 ap.Time:= 0;
@@ -222,16 +194,32 @@
   r:= Distance(Vx, Vy);
   if not (r > _1) then
      begin
-     Score:= CheckTrace;
-     if valueResult <= Score then
-        begin
-        ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
-        ap.Power:= hwRound(r * cMaxPower) - random((Level - 1) * 17 + 1);
-        ap.ExplR:= 100;
-        ap.ExplX:= EX;
-        ap.ExplY:= EY;
-        valueResult:= Score
-        end;
+        x:= Me^.X;
+        y:= Me^.Y;
+        dX:= Vx;
+        dY:= -Vy;
+        t:= rTime;
+        repeat
+          x:= x + dX;
+          y:= y + dY;
+          dX:= dX + cWindSpeed;
+          dY:= dY + cGravity;
+          dec(t)
+        until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t <= 0);
+        EX:= hwRound(x);
+        EY:= hwRound(y);
+        value:= RateExplosion(Me, EX, EY, 5);
+        if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
+
+        if valueResult <= value then
+            begin
+            ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
+            ap.Power:= hwRound(r * cMaxPower) - random((Level - 1) * 17 + 1);
+            ap.ExplR:= 100;
+            ap.ExplX:= EX;
+            ap.ExplY:= EY;
+            valueResult:= value
+            end;
      end
 until (rTime > 4250);
 TestSnowball:= valueResult
@@ -241,26 +229,8 @@
 var Vx, Vy, r: hwFloat;
     Score, EX, EY, valueResult: LongInt;
     TestTime: Longword;
-
-    function CheckTrace: LongInt;
-    var x, y, dY: hwFloat;
-        t: LongInt;
-    begin
-    x:= Me^.X;
-    y:= Me^.Y;
-    dY:= -Vy;
-    t:= TestTime;
-    repeat
-      x:= x + Vx;
-      y:= y + dY;
-      dY:= dY + cGravity;
-      dec(t)
-    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 7) or (t = 0);
-    EX:= hwRound(x);
-    EY:= hwRound(y);
-    if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 97)  // average of 17 attempts, most good, but some failing spectacularly
-              else CheckTrace:= BadTurn
-    end;
+    x, y, dY: hwFloat;
+    t: LongInt;
 begin
 valueResult:= BadTurn;
 TestTime:= 0;
@@ -272,17 +242,31 @@
   r:= Distance(Vx, Vy);
   if not (r > _1) then
      begin
-     Score:= CheckTrace;
-     if valueResult < Score then
-        begin
-        ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
-        ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15);
-        ap.Time:= TestTime;
-        ap.ExplR:= 100;
-        ap.ExplX:= EX;
-        ap.ExplY:= EY;
-        valueResult:= Score
-        end;
+        x:= Me^.X;
+        y:= Me^.Y;
+        dY:= -Vy;
+        t:= TestTime;
+        repeat
+          x:= x + Vx;
+          y:= y + dY;
+          dY:= dY + cGravity;
+          dec(t)
+        until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 7) or (t = 0);
+        EX:= hwRound(x);
+        EY:= hwRound(y);
+        if t < 50 then Score:= RateExplosion(Me, EX, EY, 97)  // average of 17 attempts, most good, but some failing spectacularly
+                  else Score:= BadTurn;
+                  
+        if valueResult < Score then
+            begin
+            ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
+            ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15);
+            ap.Time:= TestTime;
+            ap.ExplR:= 100;
+            ap.ExplX:= EX;
+            ap.ExplY:= EY;
+            valueResult:= Score
+            end;
      end
 until (TestTime > 4250);
 TestMolotov:= valueResult
@@ -293,26 +277,8 @@
 var Vx, Vy, r: hwFloat;
     Score, EX, EY, valueResult: LongInt;
     TestTime: Longword;
-
-    function CheckTrace: LongInt;
-    var x, y, dY: hwFloat;
-        t: LongInt;
-    begin
-    x:= Me^.X;
-    y:= Me^.Y;
-    dY:= -Vy;
-    t:= TestTime;
-    repeat
-      x:= x + Vx;
-      y:= y + dY;
-      dY:= dY + cGravity;
-      dec(t)
-    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
-    EX:= hwRound(x);
-    EY:= hwRound(y);
-    if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 101)
-              else CheckTrace:= BadTurn
-    end;
+    x, y, dY: hwFloat;
+    t: LongInt;
 begin
 valueResult:= BadTurn;
 TestTime:= 0;
@@ -323,9 +289,25 @@
   Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime + tDelta);
   r:= Distance(Vx, Vy);
   if not (r > _1) then
-     begin
-     Score:= CheckTrace;
-     if valueResult < Score then
+    begin
+    x:= Me^.X;
+    y:= Me^.Y;
+    dY:= -Vy;
+    t:= TestTime;
+    repeat
+        x:= x + Vx;
+        y:= y + dY;
+        dY:= dY + cGravity;
+        dec(t)
+    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
+    EX:= hwRound(x);
+    EY:= hwRound(y);
+    if t < 50 then 
+        Score:= RateExplosion(Me, EX, EY, 101)
+    else 
+        Score:= BadTurn;
+
+    if valueResult < Score then
         begin
         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
         ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15);
@@ -335,7 +317,7 @@
         ap.ExplY:= EY;
         valueResult:= Score
         end;
-     end
+    end
 until (TestTime = 4000);
 TestGrenade:= valueResult
 end;
@@ -345,26 +327,8 @@
 var Vx, Vy, r: hwFloat;
     Score, EX, EY, valueResult: LongInt;
     TestTime: Longword;
-
-    function CheckTrace: LongInt;
-    var x, y, dY: hwFloat;
-        t: LongInt;
-    begin
-    x:= Me^.X;
-    y:= Me^.Y;
-    dY:= -Vy;
-    t:= TestTime;
-    repeat
-      x:= x + Vx;
-      y:= y + dY;
-      dY:= dY + cGravity;
-      dec(t)
-    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
-    EX:= hwRound(x);
-    EY:= hwRound(y);
-    if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 41)
-              else CheckTrace:= BadTurn
-    end;
+    x, y, dY: hwFloat;
+    t: LongInt;
 begin
 valueResult:= BadTurn;
 TestTime:= 0;
@@ -380,7 +344,23 @@
   r:= Distance(Vx, Vy);
   if not (r > _1) then
      begin
-     Score:= CheckTrace;
+    x:= Me^.X;
+    y:= Me^.Y;
+    dY:= -Vy;
+    t:= TestTime;
+    repeat
+        x:= x + Vx;
+        y:= y + dY;
+        dY:= dY + cGravity;
+        dec(t)
+    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
+    EX:= hwRound(x);
+    EY:= hwRound(y);
+    if t < 50 then 
+        Score:= RateExplosion(Me, EX, EY, 41)
+    else 
+        Score:= BadTurn;
+
      if valueResult < Score then
         begin
         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
@@ -401,26 +381,8 @@
 var Vx, Vy, r: hwFloat;
     Score, EX, EY, valueResult: LongInt;
     TestTime: Longword;
-
-    function CheckTrace: LongInt;
-    var x, y, dY: hwFloat;
-        t: LongInt;
-    begin
-    x:= Me^.X;
-    y:= Me^.Y;
-    dY:= -Vy;
-    t:= TestTime;
-    repeat
-      x:= x + Vx;
-      y:= y + dY;
-      dY:= dY + cGravity;
-      dec(t)
-    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
-    EX:= hwRound(x);
-    EY:= hwRound(y);
-    if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 381)
-              else CheckTrace:= BadTurn
-    end;
+    x, y, dY: hwFloat;
+    t: LongInt;
 begin
 valueResult:= BadTurn;
 TestTime:= 0;
@@ -431,9 +393,25 @@
   Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y-200) - Me^.Y) / int2hwFloat(TestTime + tDelta);
   r:= Distance(Vx, Vy);
   if not (r > _1) then
-     begin
-     Score:= CheckTrace;
-     if valueResult < Score then
+    begin
+    x:= Me^.X;
+    y:= Me^.Y;
+    dY:= -Vy;
+    t:= TestTime;
+    repeat
+        x:= x + Vx;
+        y:= y + dY;
+        dY:= dY + cGravity;
+        dec(t)
+    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
+    EX:= hwRound(x);
+    EY:= hwRound(y);
+    if t < 50 then 
+        Score:= RateExplosion(Me, EX, EY, 381)
+    else 
+        Score:= BadTurn;
+        
+    if valueResult < Score then
         begin
         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
         ap.Power:= hwRound(r * cMaxPower * _0_9) + AIrndSign(random(Level) * 15);
@@ -443,56 +421,19 @@
         ap.ExplY:= EY;
         valueResult:= Score
         end;
-     end
+    end
 until (TestTime = 4000);
 TestWatermelon:= valueResult
 end;
 
-function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-//const tDelta = 24;
-var Vx, Vy: hwFloat;
-    Score, EX, EY, valueResult: LongInt;
-    TestTime: Longword;
 
-    function CheckTrace: LongInt;
-    var x, y, dY: hwFloat;
-        value: LongInt;
-    begin
-        x:= Me^.X;
-        y:= Me^.Y;
-        dY:= -Vy;
-
-        repeat
-            x:= x + Vx;
-            y:= y + dY;
-            dY:= dY + cGravity;
-            EX:= hwRound(x);
-            EY:= hwRound(y);
-        until TestCollExcludingMe(Me, EX, EY, 5) or (EY > cWaterLine);
-
-        if (EY < cWaterLine) and not dY.isNegative then
-            begin
-            value:= RateExplosion(Me, EX, EY, 91);
-            if (value = 0) then
-                if (dY > _0_15) then
-                    value:= - abs(Targ.Y - EY) div 32
-                else
-                    value:= BadTurn
-            else if (value < 0) then value:= BadTurn
-            end
-        else
-            value:= BadTurn;
-
-        CheckTrace:= value;
-    end;
-
-    function Solve: LongWord;
+    function Solve(TX, TY, MX, MY: LongInt): LongWord;
     var A, B, D, T: hwFloat;
         C: LongInt;
     begin
         A:= hwSqr(cGravity) * _0_25;
-        B:= - cGravity * (Targ.Y - hwRound(Me^.Y)) - _1;
-        C:= sqr(Targ.Y - hwRound(Me^.Y)) + sqr(Targ.X - hwRound(Me^.X));
+        B:= - cGravity * (TY - MY) - _1;
+        C:= sqr(TY - MY) + sqr(TX - MX);
         D:= hwSqr(B) - (A * C * 4);
         if D.isNegative = false then
             begin
@@ -504,21 +445,51 @@
             Solve:= hwRound(T)
             end else Solve:= 0
     end;
-
+    
+function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+//const tDelta = 24;
+var Vx, Vy: hwFloat;
+    Score, EX, EY, valueResult: LongInt;
+    TestTime: Longword;
+    x, y, dY: hwFloat;
 begin
 valueResult:= BadTurn;
 ap.ExplR:= 0;
 
 if (Level > 2) then exit(BadTurn);
 
-TestTime:= Solve;
+TestTime:= Solve(Targ.X, Targ.Y, hwRound(Me^.X), hwRound(Me^.Y));
 
 if TestTime = 0 then exit(BadTurn);
 
     Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime);
     Vy:= cGravity * (TestTime div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime);
 
-    Score:= CheckTrace;
+    x:= Me^.X;
+    y:= Me^.Y;
+    dY:= -Vy;
+
+    repeat
+        x:= x + Vx;
+        y:= y + dY;
+        dY:= dY + cGravity;
+        EX:= hwRound(x);
+        EY:= hwRound(y);
+    until TestCollExcludingMe(Me, EX, EY, 5) or (EY > cWaterLine);
+
+    if (EY < cWaterLine) and (not dY.isNegative) then
+        begin
+        Score:= RateExplosion(Me, EX, EY, 91);
+        if (Score = 0) then
+            if (dY > _0_15) then
+                Score:= - abs(Targ.Y - EY) div 32
+            else
+                Score:= BadTurn
+        else if (Score < 0) then Score:= BadTurn
+        end
+    else
+        Score:= BadTurn;
+
     if valueResult < Score then
         begin
         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
--- a/hedgewars/uAIMisc.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uAIMisc.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -115,20 +115,19 @@
 else friendlyfactor:= max(30, 300 - f * 80 div max(1,e))
 end;
 
+procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt);
+begin
+bonuses.ar[bonuses.Count].x:= x;
+bonuses.ar[bonuses.Count].y:= y;
+bonuses.ar[bonuses.Count].Radius:= r;
+bonuses.ar[bonuses.Count].Score:= s;
+inc(bonuses.Count);
+TryDo(bonuses.Count <= MAXBONUS, 'Bonuses overflow', true)
+end;
+
 procedure FillBonuses(isAfterAttack: boolean; filter: TGearsType);
 var Gear: PGear;
     MyClan: PClan;
-
-    procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt);
-    begin
-    bonuses.ar[bonuses.Count].x:= x;
-    bonuses.ar[bonuses.Count].y:= y;
-    bonuses.ar[bonuses.Count].Radius:= r;
-    bonuses.ar[bonuses.Count].Score:= s;
-    inc(bonuses.Count);
-    TryDo(bonuses.Count <= MAXBONUS, 'Bonuses overflow', true)
-    end;
-
 begin
 bonuses.Count:= 0;
 MyClan:= ThinkingHH^.Hedgehog^.Team^.Clan;
--- a/hedgewars/uAmmos.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uAmmos.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -111,8 +111,7 @@
            ((a = amInvulnerable) and ((GameFlags and gfInvulnerable) <> 0)) or
            ((a = amLaserSight) and ((GameFlags and gfLaserSight) <> 0)) or
            ((a = amVampiric) and ((GameFlags and gfVampiric) <> 0)) or
-           ((a = amExtraTime) and (cHedgehogTurnTime >= 1000000)) or
-            (a = amStructure) then
+           ((a = amExtraTime) and (cHedgehogTurnTime >= 1000000)) then
             begin
             cnt:= 0;
             Ammoz[a].Probability:= 0
--- a/hedgewars/uChat.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uChat.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -327,7 +327,7 @@
     SendIPC('s' + s);
 
     if copy(s, 1, 4) = '/me ' then
-        s:= #2'* ' + UserNick + ' ' + copy(s, 5, Length(s) - 4)
+        s:= #2 + '* ' + UserNick + ' ' + copy(s, 5, Length(s) - 4)
     else
         s:= #1 + UserNick + ': ' + s;
 
--- a/hedgewars/uCollisions.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uCollisions.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -393,7 +393,7 @@
     i, j, k, mx, my, li, ri, jfr, jto, tmpo : ShortInt;
     tmpx, tmpy: LongWord;
     dx, dy, s: hwFloat;
-    offset: Array[0..7,0..1] of ShortInt;
+    offset: array[0..7,0..1] of ShortInt;
     isColl: Boolean;
 
 begin
@@ -523,7 +523,7 @@
 function CalcSlopeBelowGear(Gear: PGear): hwFloat;
 var dx, dy: hwFloat;
     collX, i, y, x, gx, sdx, sdy: LongInt;
-    isColl, succ: Boolean;
+    isColl, bSucc: Boolean;
 begin
 
 
@@ -560,13 +560,13 @@
 
     sdx:= 0;
     sdy:= 0;
-    succ := CalcSlopeTangent(Gear, collX, y, sdx, sdy, 255);
+    bSucc := CalcSlopeTangent(Gear, collX, y, sdx, sdy, 255);
 
     // restore original dx/dy
     Gear^.dX := dx;
     Gear^.dY := dy;
 
-    if succ and (sdx <> 0) and (sdy <> 0) then
+    if bSucc and (sdx <> 0) and (sdy <> 0) then
     begin
         dx := int2hwFloat(sdy) / (abs(sdx) + abs(sdy));
         dx.isNegative := (sdx * sdy) < 0;
--- a/hedgewars/uCommandHandlers.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uCommandHandlers.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -214,7 +214,7 @@
 if CheckNoTeamOrHH then exit;
 if not CurrentTeam^.ExtDriven then SendIPC('l');
 with CurrentHedgehog^.Gear^ do
-    Message:= Message and not (gmLeft and InputMask);
+    Message:= Message and (not (gmLeft and InputMask));
     ScriptCall('onLeftUp');
 end;
 
@@ -235,7 +235,7 @@
 if CheckNoTeamOrHH then exit;
 if not CurrentTeam^.ExtDriven then SendIPC('r');
 with CurrentHedgehog^.Gear^ do
-    Message:= Message and not (gmRight and InputMask);
+    Message:= Message and (not (gmRight and InputMask));
     ScriptCall('onRightUp');
 end;
 
@@ -256,7 +256,7 @@
 if CheckNoTeamOrHH then exit;
 if not CurrentTeam^.ExtDriven then SendIPC('u');
 with CurrentHedgehog^.Gear^ do
-    Message:= Message and not (gmUp and InputMask);
+    Message:= Message and (not (gmUp and InputMask));
     ScriptCall('onUpUp');
 end;
 
@@ -277,7 +277,7 @@
 if CheckNoTeamOrHH then exit;
 if not CurrentTeam^.ExtDriven then SendIPC('d');
 with CurrentHedgehog^.Gear^ do
-    Message:= Message and not (gmDown and InputMask);
+    Message:= Message and (not (gmDown and InputMask));
     ScriptCall('onDownUp');
 end;
 
@@ -298,7 +298,7 @@
 if CheckNoTeamOrHH then exit;
 if not CurrentTeam^.ExtDriven then SendIPC('z');
 with CurrentHedgehog^.Gear^ do
-    Message:= Message and not (gmPrecise and InputMask);
+    Message:= Message and (not (gmPrecise and InputMask));
     ScriptCall('onPreciseUp');
 end;
 
@@ -350,7 +350,7 @@
     begin
     if not CurrentTeam^.ExtDriven and
         ((Message and gmAttack) <> 0) then SendIPC('a');
-    Message:= Message and not (gmAttack and InputMask);
+    Message:= Message and (not (gmAttack and InputMask));
     ScriptCall('onAttackUp');
     end
 end;
@@ -505,7 +505,7 @@
             if bShowAmmoMenu then bShowAmmoMenu:= false
             else if ((Gear^.State and (gstAttacking or gstAttacked)) <> 0) or
                     ((MultiShootAttacks > 0) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0)) or
-                    ((Gear^.State and gstHHDriven) = 0) then else bShowAmmoMenu:= true
+                    ((Gear^.State and gstHHDriven) = 0) then begin end else bShowAmmoMenu:= true
             end;
     end
 end;
--- a/hedgewars/uCommands.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uCommands.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -23,7 +23,7 @@
 interface
 
 var isDeveloperMode: boolean;
-type TVariableType = (vtCommand, vtLongInt, vthwFloat, vtBoolean);
+type TVariableType = (vtCommand, vtLongInt, vtBoolean);
      TCommandHandler = procedure (var params: shortstring);
 
 procedure initModule;
@@ -75,7 +75,7 @@
 //WriteLnToConsole(CmdStr);
 if CmdStr[0]=#0 then exit;
 c:= CmdStr[1];
-if c in ['/', '$'] then Delete(CmdStr, 1, 1) else c:= '/';
+if (c = '/') or (c = '$') then Delete(CmdStr, 1, 1) else c:= '/';
 s:= '';
 SplitBySpace(CmdStr, s);
 AddFileLog('[Cmd] ' + c + CmdStr + ' (' + inttostr(length(s)) + ')');
@@ -96,12 +96,6 @@
                             str(PLongInt(t^.Handler)^, s);
                             WriteLnToConsole('$' + CmdStr + ' is "' + s + '"');
                             end else val(s, PLongInt(t^.Handler)^);
-              vthwFloat: if c='$' then
-                         if s[0]=#0 then
-                            begin
-                            //str(PhwFloat(t^.Handler)^:4:6, s);
-                            WriteLnToConsole('$' + CmdStr + ' is "' + s + '"');
-                            end else; //val(s, PhwFloat(t^.Handler)^, i);
              vtBoolean: if c='$' then
                          if s[0]=#0 then
                             begin
--- a/hedgewars/uFloat.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uFloat.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -148,6 +148,7 @@
               _2: hwFloat = (isNegative: false; QWordValue:  4294967296 * 2);
               _3: hwFloat = (isNegative: false; QWordValue:  4294967296 * 3);
               _4: hwFloat = (isNegative: false; QWordValue:  4294967296 * 4);
+            _4_5: hwFloat = (isNegative: false; QWordValue:  4294967296 * 9 div 2);
               _5: hwFloat = (isNegative: false; QWordValue:  4294967296 * 5);
               _6: hwFloat = (isNegative: false; QWordValue:  4294967296 * 6);
              _10: hwFloat = (isNegative: false; QWordValue:  4294967296 * 10);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uGearUtils.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,126 @@
+unit uGearUtils;
+interface
+uses uTypes;
+
+procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord = $FFFFFFFF); 
+
+implementation
+uses uGearsList;
+
+procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord);
+var Gear: PGear;
+    dmg, dmgRadius, dmgBase: LongInt;
+    fX, fY: hwFloat;
+    vg: PVisualGear;
+    i, cnt: LongInt;
+begin
+    if Radius > 4 then AddFileLog('Explosion: at (' + inttostr(x) + ',' + inttostr(y) + ')');
+    if Radius > 25 then KickFlakes(Radius, X, Y);
+
+    if ((Mask and EXPLNoGfx) = 0) then
+        begin
+        vg:= nil;
+        if Radius > 50 then vg:= AddVisualGear(X, Y, vgtBigExplosion)
+        else if Radius > 10 then vg:= AddVisualGear(X, Y, vgtExplosion);
+        if vg <> nil then
+            vg^.Tint:= Tint;
+        end;
+    if (Mask and EXPLAutoSound) <> 0 then PlaySound(sndExplosion);
+
+    if (Mask and EXPLAllDamageInRadius) = 0 then
+        dmgRadius:= Radius shl 1
+    else
+        dmgRadius:= Radius;
+    dmgBase:= dmgRadius + cHHRadius div 2;
+    fX:= int2hwFloat(X);
+    fY:= int2hwFloat(Y);
+    Gear:= GearsList;
+    while Gear <> nil do
+        begin
+        dmg:= 0;
+        //dmg:= dmgRadius  + cHHRadius div 2 - hwRound(Distance(Gear^.X - int2hwFloat(X), Gear^.Y - int2hwFloat(Y)));
+        //if (dmg > 1) and
+        if (Gear^.State and gstNoDamage) = 0 then
+            begin
+            case Gear^.Kind of
+                gtHedgehog,
+                    gtMine,
+                    gtBall,
+                    gtMelonPiece,
+                    gtGrenade,
+                    gtClusterBomb,
+                //    gtCluster, too game breaking I think
+                    gtSMine,
+                    gtCase,
+                    gtTarget,
+                    gtFlame,
+                    gtExplosives,
+                    gtStructure: begin
+    // Run the calcs only once we know we have a type that will need damage
+                            if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then
+                                dmg:= dmgBase - max(hwRound(Distance(Gear^.X - fX, Gear^.Y - fY)),Gear^.Radius);
+                            if dmg > 1 then
+                                begin
+                                dmg:= ModifyDamage(min(dmg div 2, Radius), Gear);
+                                //AddFileLog('Damage: ' + inttostr(dmg));
+                                if (Mask and EXPLNoDamage) = 0 then
+                                    begin
+                                    if not Gear^.Invulnerable then
+                                        ApplyDamage(Gear, AttackingHog, dmg, dsExplosion)
+                                    else
+                                        Gear^.State:= Gear^.State or gstWinner;
+                                    end;
+                                if ((Mask and EXPLDoNotTouchAny) = 0) and (((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog)) then
+                                    begin
+                                    DeleteCI(Gear);
+                                    if Gear^.Kind <> gtHedgehog then
+                                        begin
+                                        Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - fX)/Gear^.Density;
+                                        Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y - fY)/Gear^.Density;
+                                        end
+                                    else
+                                        begin
+                                        Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - fX);
+                                        Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y - fY);
+                                        end;
+
+                                    Gear^.State:= (Gear^.State or gstMoving) and (not gstLoser);
+                                    if not Gear^.Invulnerable then
+                                        Gear^.State:= (Gear^.State or gstMoving) and (not gstWinner);
+                                    Gear^.Active:= true;
+                                    if Gear^.Kind <> gtFlame then FollowGear:= Gear
+                                    end;
+                                if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (not Gear^.Invulnerable) then
+                                    Gear^.Hedgehog^.Effects[hePoisoned] := true;
+                                end;
+
+                            end;
+                    gtGrave: begin
+    // Run the calcs only once we know we have a type that will need damage
+                            if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then
+                                dmg:= dmgBase - hwRound(Distance(Gear^.X - fX, Gear^.Y - fY));
+                            if dmg > 1 then
+                                begin
+                                dmg:= ModifyDamage(min(dmg div 2, Radius), Gear);
+                                Gear^.dY:= - _0_004 * dmg;
+                                Gear^.Active:= true
+                                end
+                            end;
+                end;
+            end;
+        Gear:= Gear^.NextGear
+        end;
+
+    if (Mask and EXPLDontDraw) = 0 then
+        if (GameFlags and gfSolidLand) = 0 then
+            begin
+            cnt:= DrawExplosion(X, Y, Radius) div 1608; // approx 2 16x16 circles to erase per chunk
+            if (cnt > 0) and (SpritesData[sprChunk].Texture <> nil) then
+                for i:= 0 to cnt do
+                    AddVisualGear(X, Y, vgtChunk)
+            end;
+
+    uAIMisc.AwareOfExplosion(0, 0, 0)
+end;
+
+end.
--- a/hedgewars/uGears.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uGears.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -37,17 +37,14 @@
 
 procedure initModule;
 procedure freeModule;
-function  AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear;
 function  SpawnCustomCrateAt(x, y: LongInt; crate: TCrateType; content: Longword ): PGear;
 function  SpawnFakeCrateAt(x, y: LongInt; crate: TCrateType; explode: boolean; poison: boolean ): PGear;
 function  GetAmmo: TAmmoType;
 function  GetUtility: TAmmoType;
-procedure ResurrectHedgehog(gear: PGear);
 procedure HideHog(HH: PHedgehog);
 procedure RestoreHog(HH: PHedgehog);
 procedure ProcessGears;
 procedure EndTurnCleanup;
-procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource);
 procedure SetAllToActive;
 procedure SetAllHHToActive;
 procedure DrawGears;
@@ -57,27 +54,20 @@
 function  GearByUID(uid : Longword) : PGear;
 procedure InsertGearToList(Gear: PGear);
 procedure RemoveGearFromList(Gear: PGear);
-function  ModifyDamage(dmg: Longword; Gear: PGear): Longword;
-procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean = false);
 procedure DeleteGear(Gear: PGear); 
 
 
 implementation
 uses uStore, uSound, uTeams, uRandom, uCollisions, uIO, uLandGraphics,
      uAIMisc, uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uMobile, uVariables,
-     uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug, uLandTexture;
+     uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug, uLandTexture,
+     uGearsHedgehog;
 
 
-procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord = $FFFFFFFF); forward;
 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); forward;
 //procedure AmmoFlameWork(Ammo: PGear); forward;
 function  GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): TPGearArray; forward;
-function  CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear; forward;
 procedure SpawnBoxOfSmth; forward;
-procedure AfterAttack; forward;
-procedure HedgehogStep(Gear: PGear); forward;
-procedure doStepHedgehogMoving(Gear: PGear); forward;
-procedure HedgehogChAngle(HHGear: PGear); forward;
 procedure ShotgunShot(Gear: PGear); forward;
 procedure PickUp(HH, Gear: PGear); forward;
 procedure HHSetWeapon(HHGear: PGear); forward;
@@ -88,7 +78,6 @@
 // Note: step handlers of gears that are hedgehogs are in a different file
 //       than the handlers for all other gears.
 {$INCLUDE "GSHandlers.inc"}
-{$INCLUDE "HHHandlers.inc"}
 
 const doStepHandlers: array[TGearType] of TGearStepProcedure = (
             @doStepBomb,
@@ -154,523 +143,6 @@
             @doStepLandGun,
             @doStepTardis);
 
-procedure InsertGearToList(Gear: PGear);
-var tmp, ptmp: PGear;
-begin
-    tmp:= GearsList;
-    ptmp:= GearsList;
-    while (tmp <> nil) and (tmp^.Z <= Gear^.Z) do
-        begin
-        ptmp:= tmp;
-        tmp:= tmp^.NextGear
-        end;
-
-    if ptmp <> tmp then
-        begin
-        Gear^.NextGear:= ptmp^.NextGear;
-        Gear^.PrevGear:= ptmp;
-        if ptmp^.NextGear <> nil then ptmp^.NextGear^.PrevGear:= Gear;
-        ptmp^.NextGear:= Gear
-        end
-    else
-        begin
-        Gear^.NextGear:= GearsList;
-        if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear;
-        GearsList:= Gear;
-        end;
-end;
-
-procedure RemoveGearFromList(Gear: PGear);
-begin
-if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
-if Gear^.PrevGear <> nil then
-    Gear^.PrevGear^.NextGear:= Gear^.NextGear
-else
-    GearsList:= Gear^.NextGear
-end;
-
-procedure spawnHealthTagForHH(HHGear: PGear; dmg: Longword);
-var tag: PVisualGear;
-begin
-tag:= AddVisualGear(hwRound(HHGear^.X), hwRound(HHGear^.Y), vgtHealthTag, dmg);
-if (tag <> nil) then
-    tag^.Hedgehog:= HHGear^.Hedgehog; // the tag needs the tag to determine the text color
-AllInactive:= false;
-HHGear^.Active:= true;
-end;
-
-function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear;
-const Counter: Longword = 0;
-var gear: PGear;
-begin
-inc(Counter);
-AddFileLog('AddGear: #' + inttostr(Counter) + ' (' + inttostr(x) + ',' + inttostr(y) + '), d(' + floattostr(dX) + ',' + floattostr(dY) + ') type = ' + EnumToStr(Kind));
-
-New(gear);
-FillChar(gear^, sizeof(TGear), 0);
-gear^.X:= int2hwFloat(X);
-gear^.Y:= int2hwFloat(Y);
-gear^.Target.X:= NoPointX;
-gear^.Kind := Kind;
-gear^.State:= State;
-gear^.Active:= true;
-gear^.dX:= dX;
-gear^.dY:= dY;
-gear^.doStep:= doStepHandlers[Kind];
-gear^.CollisionIndex:= -1;
-gear^.Timer:= Timer;
-gear^.FlightTime:= 0;
-gear^.uid:= Counter;
-gear^.SoundChannel:= -1;
-gear^.ImpactSound:= sndNone;
-gear^.nImpactSounds:= 0;
-gear^.Density:= _1;
-// Define ammo association, if any.
-gear^.AmmoType:= GearKindAmmoTypeMap[Kind];
-if Ammoz[Gear^.AmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then gear^.Z:= cHHZ+1
-else gear^.Z:= cUsualZ;
-
-if CurrentHedgehog <> nil then
-    begin
-    gear^.Hedgehog:= CurrentHedgehog;
-    gear^.IntersectGear:= CurrentHedgehog^.Gear
-    end;
-    
-case Kind of
-     gtGrenade,
-     gtClusterBomb,
-     gtGasBomb: begin
-                gear^.ImpactSound:= sndGrenadeImpact;
-                gear^.nImpactSounds:= 1;
-                gear^.AdvBounce:= 1;
-                gear^.Radius:= 5;
-                gear^.Elasticity:= _0_8;
-                gear^.Friction:= _0_8;
-                gear^.Density:= _1_5;
-                gear^.RenderTimer:= true;
-                if gear^.Timer = 0 then gear^.Timer:= 3000
-                end;
-  gtWatermelon: begin
-                gear^.ImpactSound:= sndMelonImpact;
-                gear^.nImpactSounds:= 1;
-                gear^.AdvBounce:= 1;
-                gear^.Radius:= 6;
-                gear^.Elasticity:= _0_8;
-                gear^.Friction:= _0_995;
-                gear^.Density:= _2;
-                gear^.RenderTimer:= true;
-                if gear^.Timer = 0 then gear^.Timer:= 3000
-                end;
-  gtMelonPiece: begin
-                gear^.Density:= _2;
-                end;
-    gtHedgehog: begin
-                gear^.AdvBounce:= 1;
-                gear^.Radius:= cHHRadius;
-                gear^.Elasticity:= _0_35;
-                gear^.Friction:= _0_999;
-                gear^.Angle:= cMaxAngle div 2;
-                gear^.Density:= _3;
-                gear^.Z:= cHHZ;
-                if (GameFlags and gfAISurvival) <> 0 then
-                    if gear^.Hedgehog^.BotLevel > 0 then
-                        gear^.Hedgehog^.Effects[heResurrectable] := true;
-                end;
-       gtShell: begin
-                gear^.Radius:= 4;
-                gear^.Density:= _1;
-                end;
-       gtSnowball: begin
-                gear^.ImpactSound:= sndMudballImpact;
-                gear^.nImpactSounds:= 1;
-                gear^.Radius:= 4;
-                gear^.Elasticity:= _1;
-                gear^.Friction:= _1;
-                gear^.Density:= _0_5;
-                end;
-
-     gtFlake: begin
-                with Gear^ do
-                    begin
-                    Pos:= 0;
-                    Radius:= 1;
-                    DirAngle:= random * 360;
-                    if State and gstTmpFlag = 0 then
-                        begin
-                        dx.isNegative:= GetRandom(2) = 0;
-                        dx.QWordValue:= GetRandom(100000000);
-                        dy.isNegative:= false;
-                        dy.QWordValue:= GetRandom(70000000);
-                        if GetRandom(2) = 0 then dx := -dx
-                        end;
-                    State:= State or gstInvisible;
-                    Health:= random(vobFrameTicks);
-                    Timer:= random(vobFramesCount);
-                    Angle:= (random(2) * 2 - 1) * (1 + random(10000)) * vobVelocity
-                    end
-                end;
-       gtGrave: begin
-                gear^.ImpactSound:= sndGraveImpact;
-                gear^.nImpactSounds:= 1;
-                gear^.Radius:= 10;
-                gear^.Elasticity:= _0_6;
-                end;
-         gtBee: begin
-                gear^.Radius:= 5;
-                gear^.Timer:= 500;
-                gear^.RenderTimer:= true;
-                gear^.Elasticity:= _0_9;
-                gear^.Tag:= 0;
-                end;
-   gtSeduction: begin
-                gear^.Radius:= 250;
-                end;
- gtShotgunShot: begin
-                gear^.Timer:= 900;
-                gear^.Radius:= 2
-                end;
-  gtPickHammer: begin
-                gear^.Radius:= 10;
-                gear^.Timer:= 4000
-                end;
-   gtHammerHit: begin
-                gear^.Radius:= 8;
-                gear^.Timer:= 125
-                end;
-        gtRope: begin
-                gear^.Radius:= 3;
-                gear^.Friction:= _450 * _0_01 * cRopePercent;
-                RopePoints.Count:= 0;
-                end;
-        gtMine: begin
-                gear^.ImpactSound:= sndMineImpact;
-                gear^.nImpactSounds:= 1;
-                gear^.Health:= 10;
-                gear^.State:= gear^.State or gstMoving;
-                gear^.Radius:= 2;
-                gear^.Elasticity:= _0_55;
-                gear^.Friction:= _0_995;
-                gear^.Density:= _0_9;
-                if cMinesTime < 0 then
-                    gear^.Timer:= getrandom(51)*100
-                else
-                    gear^.Timer:= cMinesTime;
-                end;
-       gtSMine: begin
-                gear^.Health:= 10;
-                gear^.State:= gear^.State or gstMoving;
-                gear^.Radius:= 2;
-                gear^.Elasticity:= _0_55;
-                gear^.Friction:= _0_995;
-                gear^.Density:= _0_9;
-                gear^.Timer:= 500;
-                end;
-        gtCase: begin
-                gear^.ImpactSound:= sndGraveImpact;
-                gear^.nImpactSounds:= 1;
-                gear^.Radius:= 16;
-                gear^.Elasticity:= _0_3
-                end;
-  gtExplosives: begin
-                gear^.ImpactSound:= sndGrenadeImpact;
-                gear^.nImpactSounds:= 1;
-                gear^.Radius:= 16;
-                gear^.Elasticity:= _0_4;
-                gear^.Friction:= _0_995;
-                gear^.Density:= _6;
-                gear^.Health:= cBarrelHealth;
-                gear^.Z:= cHHZ-1
-                end;
-  gtDEagleShot: begin
-                gear^.Radius:= 1;
-                gear^.Health:= 50
-                end;
-  gtSniperRifleShot: begin
-                gear^.Radius:= 1;
-                gear^.Health:= 50
-                end;
-    gtDynamite: begin
-                gear^.Radius:= 3;
-                gear^.Elasticity:= _0_55;
-                gear^.Friction:= _0_03;
-                gear^.Density:= _2;
-                gear^.Timer:= 5000;
-                end;
-     gtCluster: begin
-                gear^.Radius:= 2;
-                gear^.Density:= _1_5;
-                gear^.RenderTimer:= true
-                end;
-      gtShover: gear^.Radius:= 20;
-       gtFlame: begin
-                gear^.Tag:= GetRandom(32);
-                gear^.Radius:= 1;
-                gear^.Health:= 5;
-                gear^.Density:= _1;
-                if (gear^.dY.QWordValue = 0) and (gear^.dX.QWordValue = 0) then
-                    begin
-                    gear^.dY:= (getrandom - _0_8) * _0_03;
-                    gear^.dX:= (getrandom - _0_5) * _0_4
-                    end
-                end;
-   gtFirePunch: begin
-                gear^.Radius:= 15;
-                gear^.Tag:= Y
-                end;
-     gtAirBomb: begin
-                gear^.Radius:= 5;
-                gear^.Density:= _2;
-                end;
-   gtBlowTorch: begin
-                gear^.Radius:= cHHRadius + cBlowTorchC;
-                gear^.Timer:= 7500
-                end;
-    gtSwitcher: begin
-                gear^.Z:= cCurrHHZ
-                end;
-      gtTarget: begin
-                gear^.ImpactSound:= sndGrenadeImpact;
-                gear^.nImpactSounds:= 1;
-                gear^.Radius:= 10;
-                gear^.Elasticity:= _0_3;
-                gear^.Timer:= 0
-                end;
-      gtTardis: begin
-                gear^.Timer:= 0;
-                gear^.Pos:= 1;
-                gear^.Z:= cCurrHHZ+1;
-                end;
-      gtMortar: begin
-                gear^.Radius:= 4;
-                gear^.Elasticity:= _0_2;
-                gear^.Friction:= _0_08;
-                gear^.Density:= _1;
-                end;
-        gtWhip: gear^.Radius:= 20;
-      gtHammer: gear^.Radius:= 20;
-    gtKamikaze: begin
-                gear^.Health:= 2048;
-                gear^.Radius:= 20
-                end;
-        gtCake: begin
-                gear^.Health:= 2048;
-                gear^.Radius:= 7;
-                gear^.Z:= cOnHHZ;
-                gear^.RenderTimer:= true;
-                gear^.DirAngle:= -90 * hwSign(Gear^.dX);
-                if not dX.isNegative then gear^.Angle:= 1 else gear^.Angle:= 3
-                end;
- gtHellishBomb: begin
-                gear^.ImpactSound:= sndHellishImpact1;
-                gear^.nImpactSounds:= 4;
-                gear^.AdvBounce:= 1;
-                gear^.Radius:= 4;
-                gear^.Elasticity:= _0_5;
-                gear^.Friction:= _0_96;
-                gear^.Density:= _1_5;
-                gear^.RenderTimer:= true;
-                gear^.Timer:= 5000
-                end;
-       gtDrill: begin
-                if gear^.Timer = 0 then gear^.Timer:= 5000;
-                // Tag for drill strike. if 1 then first impact occured already
-                gear^.Tag := 0;
-                gear^.Radius:= 4;
-                gear^.Density:= _1;
-                end;
-        gtBall: begin
-                gear^.ImpactSound:= sndGrenadeImpact;
-                gear^.nImpactSounds:= 1;
-                gear^.AdvBounce:= 1;
-                gear^.Radius:= 5;
-                gear^.Tag:= random(8);
-                gear^.Timer:= 5000;
-                gear^.Elasticity:= _0_7;
-                gear^.Friction:= _0_995;
-                gear^.Density:= _1_5;
-                end;
-     gtBallgun: begin
-                gear^.Timer:= 5001;
-                end;
-     gtRCPlane: begin
-                gear^.Timer:= 15000;
-                gear^.Health:= 3;
-                gear^.Radius:= 8
-                end;
-     gtJetpack: begin
-                gear^.Health:= 2000;
-                gear^.Damage:= 100
-                end;
-     gtMolotov: begin
-                gear^.Radius:= 6;
-                gear^.Density:= _2;
-                end;
-       gtBirdy: begin
-                gear^.Radius:= 16; // todo: check
-                gear^.Timer:= 0;
-                gear^.Health := 2000;
-                gear^.FlightTime := 2;
-                end;
-         gtEgg: begin
-                gear^.Radius:= 4;
-                gear^.Elasticity:= _0_6;
-                gear^.Friction:= _0_96;
-                gear^.Density:= _1;
-                if gear^.Timer = 0 then gear^.Timer:= 3000
-                end;
-      gtPortal: begin
-                gear^.ImpactSound:= sndMelonImpact;
-                gear^.nImpactSounds:= 1;
-                gear^.AdvBounce:= 0;
-                gear^.Radius:= 17;
-                // set color
-                gear^.Tag:= 2 * gear^.Timer;
-                gear^.Timer:= 15000;
-                gear^.RenderTimer:= false;
-                gear^.Health:= 100;
-                end;
-       gtPiano: begin
-                gear^.Radius:= 32;
-                gear^.Density:= _50;
-                end;
- gtSineGunShot: begin
-                gear^.Radius:= 5;
-                gear^.Health:= 6000;
-                end;
-gtFlamethrower: begin
-                gear^.Tag:= 10;
-                gear^.Timer:= 10;
-                gear^.Health:= 500;
-                gear^.Damage:= 100;
-                end;
-     gtLandGun: begin
-                gear^.Tag:= 10;
-                gear^.Timer:= 10;
-                gear^.Health:= 1000;
-                gear^.Damage:= 100;
-                end;
- gtPoisonCloud: begin
-                gear^.Timer:= 5000;
-                gear^.dY:= int2hwfloat(-4 + longint(getRandom(8))) / 1000;
-                end;
- gtResurrector: begin
-                gear^.Radius := 100;
-                gear^.Tag := 0
-                end;
-     gtWaterUp: begin
-                gear^.Tag := 47;
-                end;
-  gtNapalmBomb: begin
-                gear^.Timer:= 1000;
-                gear^.Radius:= 5;
-                gear^.Density:= _1_5;
-                end;
-   gtStructure: begin
-                gear^.Elasticity:= _0_55;
-                gear^.Friction:= _0_995;
-                gear^.Density:= _0_9;
-                gear^.Radius:= 13;
-                gear^.Health:= 200;
-                gear^.Tag:= 3;
-                end;
-    end;
-
-InsertGearToList(gear);
-AddGear:= gear;
-
-ScriptCall('onGearAdd', gear^.uid);
-end;
-
-procedure DeleteGear(Gear: PGear);
-var team: PTeam;
-    t,i: Longword;
-    k: boolean;
-begin
-
-ScriptCall('onGearDelete', gear^.uid);
-
-DeleteCI(Gear);
-
-FreeTexture(Gear^.Tex);
-Gear^.Tex:= nil;
-
-// make sure that portals have their link removed before deletion
-if (Gear^.Kind = gtPortal) then
-    begin
-    if (Gear^.IntersectGear <> nil) then
-        if (Gear^.IntersectGear^.IntersectGear = Gear) then
-            Gear^.IntersectGear^.IntersectGear:= nil;
-    end
-else if Gear^.Kind = gtHedgehog then
-    (*
-    This behaviour dates back to revision 4, and I accidentally encountered it with TARDIS.  I don't think it must apply to any modern weapon, since if it was actually hit, the best the gear could do would be to destroy itself immediately, and you'd still end up with two graves.  I believe it should be removed
-     if (CurAmmoGear <> nil) and (CurrentHedgehog^.Gear = Gear) then
-        begin
-        AttackBar:= 0;
-        Gear^.Message:= gmDestroy;
-        CurAmmoGear^.Message:= gmDestroy;
-        exit
-        end
-    else*)
-        begin
-        if (hwRound(Gear^.Y) >= cWaterLine) then
-            begin
-            t:= max(Gear^.Damage, Gear^.Health);
-            Gear^.Damage:= t;
-            if ((not SuddenDeathDmg and (cWaterOpacity < $FF)) or (SuddenDeathDmg and (cWaterOpacity < $FF))) and (hwRound(Gear^.Y) < cWaterLine + 256) then
-                spawnHealthTagForHH(Gear, t);
-            end;
-
-        team:= Gear^.Hedgehog^.Team;
-        if CurrentHedgehog^.Gear = Gear then
-            begin
-            AttackBar:= 0;
-            FreeActionsList; // to avoid ThinkThread on drawned gear
-            if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) and (CurrentHedgehog^.MultiShootAttacks > 0) then OnUsedAmmo(CurrentHedgehog^);
-            end;
-
-        Gear^.Hedgehog^.Gear:= nil;
-        if Gear^.Hedgehog^.King then
-            begin
-            // are there any other kings left? Just doing nil check.  Presumably a mortally wounded king will get reaped soon enough
-            k:= false;
-            for i:= 0 to Pred(team^.Clan^.TeamsNumber) do
-                if (team^.Clan^.Teams[i]^.Hedgehogs[0].Gear <> nil) then k:= true;
-            if not k then
-                for i:= 0 to Pred(team^.Clan^.TeamsNumber) do
-                    begin
-                    team^.Clan^.Teams[i]^.hasGone:= true;
-                    TeamGoneEffect(team^.Clan^.Teams[i]^)
-                    end
-            end;
-
-        // should be not CurrentHedgehog, but hedgehog of the last gear which caused damage to this hog
-        // same stand for CheckHHDamage
-        if (Gear^.LastDamage <> nil) then
-            uStats.HedgehogDamaged(Gear, Gear^.LastDamage, 0, true)
-        else
-            uStats.HedgehogDamaged(Gear, CurrentHedgehog, 0, true);
-
-        inc(KilledHHs);
-        RecountTeamHealth(team);
-        if (CurrentHedgehog <> nil) and CurrentHedgehog^.Effects[heResurrectable] and not Gear^.Hedgehog^.Effects[heResurrectable] then
-            with CurrentHedgehog^ do 
-                begin
-                inc(Team^.stats.AIKills);
-                FreeTexture(Team^.AIKillsTex);
-                Team^.AIKillsTex := RenderStringTex(inttostr(Team^.stats.AIKills), Team^.Clan^.Color, fnt16);
-                end
-        end;
-with Gear^ do
-    AddFileLog('Delete: #' + inttostr(uid) + ' (' + inttostr(hwRound(x)) + ',' + inttostr(hwRound(y)) + '), d(' + floattostr(dX) + ',' + floattostr(dY) + ') type = ' + EnumToStr(Kind));
-
-if CurAmmoGear = Gear then CurAmmoGear:= nil;
-if FollowGear = Gear then FollowGear:= nil;
-if lastGearByUID = Gear then lastGearByUID := nil;
-RemoveGearFromList(Gear);
-Dispose(Gear)
-end;
-
 function CheckNoDamage: boolean; // returns TRUE in case of no damaged hhs
 var Gear: PGear;
     dmg: LongInt;
@@ -698,9 +170,9 @@
 
             if (Gear^.Hedgehog^.Team = CurrentTeam) and
                (Gear^.Damage <> Gear^.Karma) and
-                not Gear^.Hedgehog^.King and
-                not Gear^.Hedgehog^.Effects[hePoisoned] and
-                not SuddenDeathDmg then
+                (not Gear^.Hedgehog^.King) and
+                (not Gear^.Hedgehog^.Effects[hePoisoned]) and
+                (not SuddenDeathDmg) then
                 Gear^.State:= Gear^.State or gstLoser;
 
             spawnHealthTagForHH(Gear, dmg);
@@ -863,7 +335,7 @@
     stHealth: begin
             if (cWaterRise <> 0) or (cHealthDecrease <> 0) then
                 begin
-                if (TotalRounds = cSuddenDTurns) and not SuddenDeath and not isInMultiShoot then
+                if (TotalRounds = cSuddenDTurns) and (not SuddenDeath) and (not isInMultiShoot) then
                     begin
                     SuddenDeath:= true;
                     if cHealthDecrease <> 0 then
@@ -881,16 +353,17 @@
                         end;
                     AddCaption(trmsg[sidSuddenDeath], cWhiteColor, capgrpGameState);
                     playSound(sndSuddenDeath);
-                    MusicFN:= SDMusic;
-                    ChangeMusic
+                    StopMusic //No SDMusic for now
+                    //MusicFN:= SDMusic;
+                    //ChangeMusic
                     end
-                else if (TotalRounds < cSuddenDTurns) and not isInMultiShoot then
+                else if (TotalRounds < cSuddenDTurns) and (not isInMultiShoot) then
                     begin
                     i:= cSuddenDTurns - TotalRounds;
                     s:= inttostr(i);
                     if i = 1 then
                         AddCaption(trmsg[sidRoundSD], cWhiteColor, capgrpGameState)
-                    else if i in [2, 5, 10, 15, 20, 25, 50, 100] then
+                    else if (i = 2) or ((i > 0) and ((i mod 50 = 0) or ((i <= 25) and (i mod 5 = 0)))) then
                         AddCaption(Format(trmsg[sidRoundsSD], s), cWhiteColor, capgrpGameState);
                     end;
                 end;
@@ -940,14 +413,14 @@
         begin
         dec(delay2);
 
-        if ((delay2 mod cInactDelay) = 0) and (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and not CurrentHedgehog^.Unplaced then
+        if ((delay2 mod cInactDelay) = 0) and (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and (not CurrentHedgehog^.Unplaced) then
             begin
             if (CurrentHedgehog^.Gear^.State and gstAttacked <> 0) and (Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0) then
                 begin
                 CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstHHChooseTarget;
                 isCursorVisible := true
                 end;
-            CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State and not gstAttacked;
+            CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State and (not gstAttacked);
             end;
         if delay2 = 0 then
             begin
@@ -969,7 +442,7 @@
 if TurnTimeLeft > 0 then
         if CurrentHedgehog^.Gear <> nil then
             if ((CurrentHedgehog^.Gear^.State and gstAttacking) = 0)
-                and not isInMultiShoot then
+                and (not isInMultiShoot) then
                 begin
                 if (TurnTimeLeft = 5000)
                     and (cHedgehogTurnTime >= 10000)
@@ -1067,7 +540,7 @@
         t:= t^.NextGear
         end;
    
-    if ((GameFlags and gfResetWeps) <> 0) and not PlacingHogs then
+    if ((GameFlags and gfResetWeps) <> 0) and (not PlacingHogs) then
         ResetWeapons;
 
     if (GameFlags and gfResetHealth) <> 0 then
@@ -1075,69 +548,6 @@
             RecountTeamHealth(TeamsArray[i])
 end;
 
-procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource);
-var s: shortstring;
-    vampDmg, tmpDmg, i: Longword;
-    vg: PVisualGear;
-begin
-  if Damage = 0 then exit; // nothing to apply
-
-    if (Gear^.Kind = gtHedgehog) then
-    begin
-    Gear^.LastDamage := AttackerHog;
-
-    Gear^.Hedgehog^.Team^.Clan^.Flawless:= false;
-    HHHurt(Gear^.Hedgehog, Source);
-    AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), Damage, Gear^.Hedgehog^.Team^.Clan^.Color);
-    tmpDmg:= min(Damage, max(0,Gear^.Health-Gear^.Damage));
-    if (Gear <> CurrentHedgehog^.Gear) and (CurrentHedgehog^.Gear <> nil) and (tmpDmg >= 1) then
-        begin
-        if cVampiric then
-            begin
-            vampDmg:= hwRound(int2hwFloat(tmpDmg)*_0_8);
-            if vampDmg >= 1 then
-                begin
-                // was considering pulsing on attack, Tiy thinks it should be permanent while in play
-                //CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstVampiric;
-                inc(CurrentHedgehog^.Gear^.Health,vampDmg);
-                str(vampDmg, s);
-                s:= '+' + s;
-                AddCaption(s, CurrentHedgehog^.Team^.Clan^.Color, capgrpAmmoinfo);
-                RenderHealth(CurrentHedgehog^);
-                RecountTeamHealth(CurrentHedgehog^.Team);
-                i:= 0;
-                while i < vampDmg do
-                    begin
-                    vg:= AddVisualGear(hwRound(CurrentHedgehog^.Gear^.X), hwRound(CurrentHedgehog^.Gear^.Y), vgtStraightShot);
-                    if vg <> nil then
-                        with vg^ do
-                            begin
-                            Tint:= $FF0000FF;
-                            State:= ord(sprHealth)
-                            end;
-                    inc(i, 5);
-                    end;
-                end
-            end;
-        if ((GameFlags and gfKarma) <> 0) and
-           ((GameFlags and gfInvulnerable) = 0) and
-           not CurrentHedgehog^.Gear^.Invulnerable then
-           begin // this cannot just use Damage or it interrupts shotgun and gets you called stupid
-           inc(CurrentHedgehog^.Gear^.Karma, tmpDmg);
-           CurrentHedgehog^.Gear^.LastDamage := CurrentHedgehog;
-           spawnHealthTagForHH(CurrentHedgehog^.Gear, tmpDmg);
-           end;
-        uStats.HedgehogDamaged(Gear, AttackerHog, Damage, false);    
-        end;
-    end else if Gear^.Kind <> gtStructure then // not gtHedgehog nor gtStructure
-        begin
-        Gear^.Hedgehog:= AttackerHog;
-        end;
-    inc(Gear^.Damage, Damage);
-    
-    ScriptCall('onGearDamage', Gear^.UID, Damage);
-end;
-
 procedure SetAllToActive;
 var t: PGear;
 begin
@@ -1328,7 +738,7 @@
                                 Gear^.Active:= true;
                                 if Gear^.Kind <> gtFlame then FollowGear:= Gear
                                 end;
-                            if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and not Gear^.Invulnerable then
+                            if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (not Gear^.Invulnerable) then
                                 Gear^.Hedgehog^.Effects[hePoisoned] := true;
                             end;
 
@@ -1479,7 +889,7 @@
                         Gear^.State:= Gear^.State or gstWinner;
                     if (Gear^.Kind = gtExplosives) and (Ammo^.Kind = gtBlowtorch) then 
                         begin
-                        if (Ammo^.Hedgehog^.Gear <> nil) then Ammo^.Hedgehog^.Gear^.State:= Ammo^.Hedgehog^.Gear^.State and not gstNotKickable;
+                        if (Ammo^.Hedgehog^.Gear <> nil) then Ammo^.Hedgehog^.Gear^.State:= Ammo^.Hedgehog^.Gear^.State and (not gstNotKickable);
                         ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch
                         end;
 
@@ -1600,24 +1010,6 @@
     end;
 end;
 
-function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
-var t: PGear;
-begin
-t:= GearsList;
-rX:= sqr(rX);
-rY:= sqr(rY);
-
-while t <> nil do
-    begin
-    if (t <> Gear) and (t^.Kind = Kind) then
-        if not((hwSqr(Gear^.X - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1) then
-        exit(t);
-    t:= t^.NextGear
-    end;
-
-CheckGearNear:= nil
-end;
-
 {procedure AmmoFlameWork(Ammo: PGear);
 var t: PGear;
 begin
@@ -1638,21 +1030,6 @@
     end;
 end;}
 
-function CheckGearsNear(mX, mY: LongInt; Kind: TGearsType; rX, rY: LongInt): PGear;
-var t: PGear;
-begin
-t:= GearsList;
-rX:= sqr(rX);
-rY:= sqr(rY);
-while t <> nil do
-    begin
-    if t^.Kind in Kind then
-        if not (hwSqr(int2hwFloat(mX) - t^.X) / rX + hwSqr(int2hwFloat(mY) - t^.Y) / rY > _1) then
-            exit(t);
-    t:= t^.NextGear
-    end;
-CheckGearsNear:= nil
-end;
 
 function CountGears(Kind: TGearType): Longword;
 var t: PGear;
@@ -1668,33 +1045,6 @@
 CountGears:= count;
 end;
 
-procedure ResurrectHedgehog(gear: PGear);
-var tempTeam : PTeam;
-begin
-    AttackBar:= 0;
-    gear^.dX := _0;
-    gear^.dY := _0;
-    gear^.Damage := 0;
-    gear^.Health := gear^.Hedgehog^.InitialHealth;
-    gear^.Hedgehog^.Effects[hePoisoned] := false;
-    if not CurrentHedgehog^.Effects[heResurrectable] then
-        with CurrentHedgehog^ do 
-            begin
-            inc(Team^.stats.AIKills);
-            FreeTexture(Team^.AIKillsTex);
-            Team^.AIKillsTex := RenderStringTex(inttostr(Team^.stats.AIKills), Team^.Clan^.Color, fnt16);
-            end;
-    tempTeam := gear^.Hedgehog^.Team;
-    DeleteCI(gear);
-    FindPlace(gear, false, 0, LAND_WIDTH, true); 
-    if gear <> nil then begin
-        RenderHealth(gear^.Hedgehog^);
-        ScriptCall('onGearResurrect', gear^.uid);
-        gear^.State := gstWait;
-    end;
-    RecountTeamHealth(tempTeam);
-end;
-
 function SpawnCustomCrateAt(x, y: LongInt; crate: TCrateType; content: Longword): PGear;
 begin
     FollowGear := AddGear(x, y, gtCase, 0, _0, _0, 0);
@@ -1886,119 +1236,6 @@
     end
 end;
 
-procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean = false);
-
-    function CountNonZeroz(x, y, r, c: LongInt): LongInt;
-    var i: LongInt;
-        count: LongInt = 0;
-    begin
-    if (y and LAND_HEIGHT_MASK) = 0 then
-        for i:= max(x - r, 0) to min(x + r, LAND_WIDTH - 4) do
-            if Land[y, i] <> 0 then
-               begin
-               inc(count);
-               if count = c then exit(count)
-               end;
-    CountNonZeroz:= count;
-    end;
-
-var x: LongInt;
-    y, sy: LongInt;
-    ar: array[0..511] of TPoint;
-    ar2: array[0..1023] of TPoint;
-    cnt, cnt2: Longword;
-    delta: LongInt;
-    reallySkip, tryAgain: boolean;
-begin
-reallySkip:= false; // try not skipping proximity at first
-tryAgain:= true;
-while tryAgain do
-    begin
-    delta:= 250;
-    cnt2:= 0;
-    repeat
-        x:= Left + LongInt(GetRandom(Delta));
-        repeat
-            inc(x, Delta);
-            cnt:= 0;
-            y:= min(1024, topY) - 2 * Gear^.Radius;
-            while y < cWaterLine do
-                begin
-                repeat
-                    inc(y, 2);
-                until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) = 0);
-
-                sy:= y;
-
-                repeat
-                    inc(y);
-                until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) <> 0);
-
-                if (y - sy > Gear^.Radius * 2) and
-                   (((Gear^.Kind = gtExplosives)
-                       and (y < cWaterLine)
-                       and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 60, 60) = nil))
-                       and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1) > Gear^.Radius))
-                   or
-                     ((Gear^.Kind <> gtExplosives)
-                       and (y < cWaterLine)
-                       and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 110, 110) = nil)))) then
-                    begin
-                    ar[cnt].X:= x;
-                    if withFall then ar[cnt].Y:= sy + Gear^.Radius
-                                else ar[cnt].Y:= y - Gear^.Radius;
-                    inc(cnt)
-                    end;
-
-                inc(y, 45)
-                end;
-
-            if cnt > 0 then
-                with ar[GetRandom(cnt)] do
-                    begin
-                    ar2[cnt2].x:= x;
-                    ar2[cnt2].y:= y;
-                    inc(cnt2)
-                    end
-        until (x + Delta > Right);
-
-        dec(Delta, 60)
-    until (cnt2 > 0) or (Delta < 70);
-    if (cnt2 = 0) and skipProximity and not reallySkip then tryAgain:= true
-    else tryAgain:= false;
-    reallySkip:= true;
-    end;
-
-if cnt2 > 0 then
-    with ar2[GetRandom(cnt2)] do
-        begin
-        Gear^.X:= int2hwFloat(x);
-        Gear^.Y:= int2hwFloat(y);
-        AddFileLog('Assigned Gear coordinates (' + inttostr(x) + ',' + inttostr(y) + ')');
-        end
-    else
-    begin
-    OutError('Can''t find place for Gear', false);
-    if Gear^.Kind = gtHedgehog then Gear^.Hedgehog^.Effects[heResurrectable] := false;
-    DeleteGear(Gear);
-    Gear:= nil
-    end
-end;
-
-function ModifyDamage(dmg: Longword; Gear: PGear): Longword;
-var i: hwFloat;
-begin
-(* Invulnerability cannot be placed in here due to still needing kicks
-   Not without a new damage machine.
-   King check should be in here instead of ApplyDamage since Tiy wants them kicked less
-*)
-i:= _1;
-if (CurrentHedgehog <> nil) and CurrentHedgehog^.King then i:= _1_5;
-if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.King) then
-   ModifyDamage:= hwRound(_0_01 * cDamageModifier * dmg * i * cDamagePercent * _0_5)
-else
-   ModifyDamage:= hwRound(_0_01 * cDamageModifier * dmg * i * cDamagePercent)
-end;
 
 function GearByUID(uid : Longword) : PGear;
 var gear: PGear;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uGearsHedgehog.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,1150 @@
+(*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2011 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *)
+
+{$INCLUDE "options.inc"}
+
+unit uGearsHedgehog;
+interface
+uses uTypes;
+
+procedure doStepHedgehog(Gear: PGear);
+procedure AfterAttack; 
+procedure HedgehogStep(Gear: PGear); 
+procedure doStepHedgehogMoving(Gear: PGear); 
+procedure HedgehogChAngle(HHGear: PGear); 
+
+implementation
+uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions, uMisc, 
+    uCommands, uLocale, uUtils, uVisualGears, uStats, uIO, uScript,
+    uGearsList, uGears, uCollisions, uRandom, uStore, uTeams, 
+    uGearsUtils;
+
+// Shouldn't more of this ammo switching stuff be moved to uAmmos ?
+function ChangeAmmo(HHGear: PGear): boolean;
+var slot, i: Longword;
+    ammoidx: LongInt;
+begin
+ChangeAmmo:= false;
+slot:= HHGear^.MsgParam;
+
+with HHGear^.Hedgehog^ do
+    begin
+    HHGear^.Message:= HHGear^.Message and (not gmSlot);
+    ammoidx:= 0;
+    if ((HHGear^.State and (gstAttacking or gstAttacked)) <> 0) or
+       ((MultiShootAttacks > 0) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0)) or
+       ((HHGear^.State and gstHHDriven) = 0) then exit;
+    ChangeAmmo:= true;
+
+    while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do inc(ammoidx);
+
+    if ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) and (MultiShootAttacks > 0) then OnUsedAmmo(HHGear^.Hedgehog^);
+
+    MultiShootAttacks:= 0;
+    HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
+    
+    if Ammoz[CurAmmoType].Slot = slot then
+        begin
+        i:= 0;
+        repeat
+        inc(ammoidx);
+        if (ammoidx > cMaxSlotAmmoIndex) then
+            begin
+            inc(i);
+            CurAmmoType:= amNothing;
+            ammoidx:= -1;
+            //TryDo(i < 2, 'Engine bug: no ammo in current slot', true)
+            end;
+        until (i = 1) or ((Ammo^[slot, ammoidx].Count > 0) and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns))
+        end 
+    else
+        begin
+        i:= 0;
+        // check whether there is ammo in slot
+        while (i <= cMaxSlotAmmoIndex)
+          and ((Ammo^[slot, i].Count = 0)
+               or (Team^.Clan^.TurnNumber <= Ammoz[Ammo^[slot, i].AmmoType].SkipTurns)) do inc(i);
+
+        if i <= cMaxSlotAmmoIndex then ammoidx:= i
+        else ammoidx:= -1
+        end;
+        if ammoidx >= 0 then CurAmmoType:= Ammo^[slot, ammoidx].AmmoType;
+    end
+end;
+
+procedure HHSetWeapon(HHGear: PGear);
+var t: LongInt;
+    weap: TAmmoType;
+    Hedgehog: PHedgehog;
+    s: boolean;
+begin
+s:= false;
+
+weap:= TAmmoType(HHGear^.MsgParam);
+Hedgehog:= HHGear^.Hedgehog;
+
+if Hedgehog^.Team^.Clan^.TurnNumber <= Ammoz[weap].SkipTurns then exit; // weapon is not activated yet
+
+HHGear^.MsgParam:= Ammoz[weap].Slot;
+
+t:= cMaxSlotAmmoIndex;
+
+HHGear^.Message:= HHGear^.Message and (not gmWeapon);
+
+with Hedgehog^ do
+    while (CurAmmoType <> weap) and (t >= 0) do
+        begin
+        s:= ChangeAmmo(HHGear);
+        dec(t)
+        end;
+
+if s then ApplyAmmoChanges(HHGear^.Hedgehog^)
+end;
+
+procedure HHSetTimer(Gear: PGear);
+var CurWeapon: PAmmo;
+    color: LongWord;
+begin
+Gear^.Message:= Gear^.Message and (not gmTimer);
+CurWeapon:= GetAmmoEntry(Gear^.Hedgehog^);
+with Gear^.Hedgehog^ do
+    if ((Gear^.Message and gmPrecise) <> 0) and ((CurWeapon^.Propz and ammoprop_SetBounce) <> 0) then
+        begin
+        color:= Gear^.Hedgehog^.Team^.Clan^.Color;
+        case Gear^.MsgParam of
+            1: begin
+               AddCaption(format(trmsg[sidBounce], trmsg[sidBounce1]), color, capgrpAmmostate);
+               CurWeapon^.Bounciness:= 350;
+               end;
+            2: begin
+               AddCaption(format(trmsg[sidBounce], trmsg[sidBounce2]), color, capgrpAmmostate);
+               CurWeapon^.Bounciness:= 700;
+               end;
+            3: begin
+               AddCaption(format(trmsg[sidBounce], trmsg[sidBounce3]), color, capgrpAmmostate);
+               CurWeapon^.Bounciness:= 1000;
+               end;
+            4: begin
+               AddCaption(format(trmsg[sidBounce], trmsg[sidBounce4]), color, capgrpAmmostate);
+               CurWeapon^.Bounciness:= 2000;
+               end;
+            5: begin
+               AddCaption(format(trmsg[sidBounce], trmsg[sidBounce5]), color, capgrpAmmostate);
+               CurWeapon^.Bounciness:= 4000;
+               end
+            end
+        end
+    else if (CurWeapon^.Propz and ammoprop_Timerable) <> 0 then
+        begin
+        CurWeapon^.Timer:= 1000 * Gear^.MsgParam;
+        with CurrentTeam^ do
+            ApplyAmmoChanges(Hedgehogs[CurrHedgehog]);
+        end;
+end;
+
+
+procedure Attack(Gear: PGear);
+var xx, yy, newDx, newDy, lx, ly: hwFloat;
+    speech: PVisualGear;
+    newGear:  PGear;
+    CurWeapon: PAmmo;
+    altUse: boolean;
+    elastic: hwFloat;
+begin
+newGear:= nil;
+bShowFinger:= false;
+CurWeapon:= GetAmmoEntry(Gear^.Hedgehog^);
+with Gear^,
+     Gear^.Hedgehog^ do
+     begin
+     if ((State and gstHHDriven) <> 0)and
+        ((State and (gstAttacked or gstHHChooseTarget)) = 0) and
+        (((State and gstMoving) = 0) or
+            (Power > 0) or
+            (CurAmmoType = amTeleport) or 
+            // Allow attacks while moving on ammo with AltAttack
+            ((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)) or
+            ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0)) and
+        ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then
+        begin
+        State:= State or gstAttacking;
+        if Power = cMaxPower then Message:= Message and (not gmAttack)
+        else if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) = 0 then Message:= Message and (not gmAttack)
+        else begin
+             if Power = 0 then
+                begin
+                AttackBar:= CurrentTeam^.AttackBar;
+                PlaySound(sndThrowPowerUp)
+                end;
+             inc(Power)
+             end;
+        if ((Message and gmAttack) <> 0) then exit;
+
+        if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0 then
+           begin
+           StopSound(sndThrowPowerUp);
+           PlaySound(sndThrowRelease);
+           end;
+
+        xx:= SignAs(AngleSin(Angle), dX);
+        yy:= -AngleCos(Angle);
+
+        lx:= X + int2hwfloat(round(GetLaunchX(CurAmmoType, hwSign(dX), Angle)));
+        ly:= Y + int2hwfloat(round(GetLaunchY(CurAmmoType, Angle)));
+
+        if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then xx:= - xx;
+        if Ammoz[CurAmmoType].Ammo.AttackVoice <> sndNone then
+           AddVoice(Ammoz[CurAmmoType].Ammo.AttackVoice, CurrentTeam^.voicepack);
+
+// Initiating alt attack
+        if  (CurAmmoGear <> nil) and
+            ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) and
+            ((Gear^.Message and gmLJump) <> 0) and
+            ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
+            begin
+            newDx:= dX / _2; 
+            newDy:= dY / _2;
+            altUse:= true;
+            end
+        else
+            begin
+            newDx:= xx*Power/cPowerDivisor;
+            newDy:= yy*Power/cPowerDivisor;
+            altUse:= false
+            end;
+
+             case CurAmmoType of
+                      amGrenade: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGrenade,         0, newDx, newDy, CurWeapon^.Timer);
+                      amMolotov: newGear:= AddGear(hwRound(lx), hwRound(ly), gtMolotov,      0, newDx, newDy, 0);
+                  amClusterBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb,  0, newDx, newDy, CurWeapon^.Timer);
+                      amGasBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGasBomb,      0, newDx, newDy, CurWeapon^.Timer);
+                      amBazooka: newGear:= AddGear(hwRound(lx), hwRound(ly), gtShell,        0, newDx, newDy, 0);
+                     amSnowball: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSnowball,     0, newDx, newDy, 0);
+                          amBee: newGear:= AddGear(hwRound(lx), hwRound(ly), gtBee,          0, newDx, newDy, 0);
+                      amShotgun: begin
+                                 PlaySound(sndShotgunReload);
+                                 newGear:= AddGear(hwRound(lx), hwRound(ly), gtShotgunShot,  0, xx * _0_5, yy * _0_5, 0);
+                                 end;
+                   amPickHammer: newGear:= AddGear(hwRound(lx), hwRound(ly) + cHHRadius, gtPickHammer, 0, _0, _0, 0);
+                         amSkip: ParseCommand('/skip', true);
+                         amRope: newGear:= AddGear(hwRound(lx), hwRound(ly), gtRope, 0, xx, yy, 0);
+                         amMine: if altUse then
+                                    newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, newDx, newDy, 3000)
+                                 else
+                                    newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000);
+                        amSMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSMine,    0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
+                       amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0);
+                      amSineGun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0);
+                    amPortalGun: begin
+                                 newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6, 
+                                 // set selected color
+                                 CurWeapon^.Pos);
+                                 end;
+                  amSniperRifle: begin
+                                 PlaySound(sndSniperReload);
+                                 newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSniperRifleShot, 0, xx * _0_5, yy * _0_5, 0);
+                                 end;
+                     amDynamite: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtDynamite, 0, SignAs(_0_03, dX), _0, 5000);
+                    amFirePunch: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtFirePunch, 0, xx, _0, 0);
+                         amWhip: begin
+                                 newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtWhip, 0, SignAs(_1, dX), - _0_8, 0);
+                                 PlaySound(sndWhipCrack)
+                                 end;
+                       amHammer: begin
+                                 newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtHammer, 0, SignAs(_1, dX), - _0_8, 0);
+                                 PlaySound(sndWhack)
+                                 end;
+                  amBaseballBat: begin
+                                 newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtShover, gsttmpFlag, xx * _0_5, yy * _0_5, 0);
+                                 PlaySound(sndBaseballBat) // TODO: Only play if something is hit?
+                                 end;
+                    amParachute: begin
+                                 newGear:= AddGear(hwRound(lx), hwRound(ly), gtParachute, 0, _0, _0, 0);
+                                 PlaySound(sndParachute)
+                                 end;
+                    // we save CurWeapon^.Pos (in this case: cursor direction) by using it as (otherwise irrelevant) X value of the new gear.
+                    amAirAttack: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 0, _0, _0, 0);
+                   amMineStrike: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 1, _0, _0, 0);
+                  amDrillStrike: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 3, _0, _0, CurWeapon^.Timer);
+                       amNapalm: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 2, _0, _0, 0);
+                    amBlowTorch: newGear:= AddGear(hwRound(lx), hwRound(ly), gtBlowTorch, 0, SignAs(_0_5, dX), _0, 0);
+                       amGirder: newGear:= AddGear(0, 0, gtGirder, CurWeapon^.Pos, _0, _0, 0);
+                     amTeleport: newGear:= AddGear(CurWeapon^.Pos, 0, gtTeleport, 0, _0, _0, 0);
+                       amSwitch: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSwitcher, 0, _0, _0, 0);
+                       amMortar: begin
+                                 playSound(sndMortar);
+                                 newGear:= AddGear(hwRound(lx), hwRound(ly), gtMortar,  0, xx*cMaxPower/cPowerDivisor, yy*cMaxPower/cPowerDivisor, 0);
+                                 end;
+                      amRCPlane: begin
+                                 newGear:= AddGear(hwRound(lx), hwRound(ly), gtRCPlane,  0, xx * cMaxPower / cPowerDivisor / 4, yy * cMaxPower / cPowerDivisor / 4, 0);
+                                 newGear^.SoundChannel:= LoopSound(sndRCPlane, nil)
+                                 end;
+                       amKamikaze: newGear:= AddGear(hwRound(lx), hwRound(ly), gtKamikaze, 0, xx * _0_5, yy * _0_5, 0);
+                         amCake: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 3, hwRound(ly), gtCake, 0, xx, _0, 0);
+                    amSeduction: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSeduction, 0, _0, _0, 0);
+                   amWatermelon: newGear:= AddGear(hwRound(lx), hwRound(ly), gtWatermelon,  0, newDx, newDy, CurWeapon^.Timer);
+                  amHellishBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtHellishBomb,    0, newDx, newDy, 0);
+                        amDrill: newGear:= AddGear(hwRound(lx), hwRound(ly), gtDrill, 0, newDx, newDy, 0);
+                      amBallgun: newGear:= AddGear(hwRound(X), hwRound(Y), gtBallgun,  0, xx * _0_5, yy * _0_5, 0);
+                    amJetpack: newGear:= AddGear(hwRound(lx), hwRound(ly), gtJetpack, 0, _0, _0, 0);
+                    amBirdy: begin
+                             PlaySound(sndWhistle);
+                             newGear:= AddGear(hwRound(lx), hwRound(ly) - 32, gtBirdy, 0, _0, _0, 0);
+                             end;
+                      amLowGravity: begin
+                                    PlaySound(sndLowGravity);
+                                    cGravity:= cMaxWindSpeed;
+                                    cGravityf:= 0.00025
+                                    end;
+                      amExtraDamage:begin 
+                                    PlaySound(sndHellishImpact4);
+                                    cDamageModifier:= _1_5
+                                    end;
+                      amInvulnerable: Invulnerable:= true;
+                      amExtraTime:  begin
+                                    PlaySound(sndSwitchHog);
+                                    TurnTimeLeft:= TurnTimeLeft + 30000
+                                    end;
+                      amLaserSight: cLaserSighting:= true;
+                      amVampiric: begin
+                                  PlaySound(sndOw1, Team^.voicepack);
+                                  cVampiric:= true;
+                                  end;
+                      amPiano: begin
+                               // Tuck the hedgehog away until the piano attack is completed
+                               Unplaced:= true;
+                               X:= _0;
+                               Y:= _0;
+                               newGear:= AddGear(TargetPoint.X, 0, gtPiano, 0, _0, _0, 0);
+                               PauseMusic
+                               end;
+                      amFlamethrower: newGear:= AddGear(hwRound(X), hwRound(Y), gtFlamethrower,  0, xx * _0_5, yy * _0_5, 0);
+                      amLandGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtLandGun,  0, xx * _0_5, yy * _0_5, 0);
+                    amResurrector: begin
+                        newGear:= AddGear(hwRound(lx), hwRound(ly),
+                                gtResurrector, 0, _0, _0, 0);
+                        newGear^.SoundChannel := LoopSound(sndResurrector);
+                    end;
+                   //amMelonStrike: AddGear(CurWeapon^.Pos, 0, gtAirAttack, 4, _0, _0, 0);
+                     amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
+                        amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
+                  end;
+             case CurAmmoType of
+                      amGrenade, amMolotov, 
+                  amClusterBomb, amGasBomb, 
+                      amBazooka, amSnowball, 
+                          amBee, amSMine,
+                       amMortar, amWatermelon,
+                  amHellishBomb, amDrill: FollowGear:= newGear;
+
+                      amShotgun, amPickHammer,
+                         amRope, amDEagle,
+                      amSineGun, amSniperRifle,
+                    amFirePunch, amWhip,
+                       amHammer, amBaseballBat,
+                    amParachute, amBlowTorch,
+                       amGirder, amTeleport,
+                       amSwitch, amRCPlane,
+                     amKamikaze, amCake,
+                    amSeduction, amBallgun,
+                      amJetpack, amBirdy,
+                 amFlamethrower, amLandGun,
+                  amResurrector, amStructure,
+                       amTardis, amPiano: CurAmmoGear:= newGear;
+                  end;
+              if (CurAmmoType = amMine) or (CurAmmoType = amSMine) and (GameFlags and gfInfAttack <> 0) then newGear^.FlightTime:= GameTicks + 1000;
+        if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
+            begin
+            newGear^.Target.X:= TargetPoint.X;
+            newGear^.Target.Y:= TargetPoint.Y
+            end;
+
+        // Clear FollowGear if using on a rope/parachute/saucer etc so focus stays with the hog's movement
+        if altUse then FollowGear:= nil;
+
+        if (newGear <> nil) and ((Ammoz[newGear^.AmmoType].Ammo.Propz and ammoprop_SetBounce) <> 0) then
+            begin
+            elastic:=  int2hwfloat(CurWeapon^.Bounciness) / _1000;
+
+            if elastic < _1 then newGear^.Elasticity:= newGear^.Elasticity * elastic
+            else if elastic > _1 then newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
+(* Experimented with friction modifier. Didn't seem helpful 
+            fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
+            if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
+            else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
+            end;
+
+
+        uStats.AmmoUsed(CurAmmoType);
+
+        if not (SpeechText = '') then
+            begin
+            speech:= AddVisualGear(0, 0, vgtSpeechBubble);
+            if speech <> nil then
+               begin
+               speech^.Text:= SpeechText;
+               speech^.Hedgehog:= Gear^.Hedgehog;
+               speech^.FrameTicks:= SpeechType;
+               end;
+            SpeechText:= ''
+            end;
+
+        Power:= 0;
+        if (CurAmmoGear <> nil)
+           and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
+           begin
+           Message:= Message or gmAttack;
+           CurAmmoGear^.Message:= Message
+           end else begin
+           if not CurrentTeam^.ExtDriven and
+             ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then SendIPC('a');
+           AfterAttack;
+           end
+        end else Message:= Message and (not gmAttack);
+     end;
+     TargetPoint.X := NoPointX;
+     ScriptCall('onHogAttack');
+end;
+
+procedure AfterAttack;
+var s: shortstring;
+    a: TAmmoType;
+begin
+with CurrentHedgehog^.Gear^,
+        CurrentHedgehog^ do
+    begin
+    a:= CurAmmoType;
+    State:= State and (not gstAttacking);
+    if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then
+        begin
+        Inc(MultiShootAttacks);
+        
+        if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) then
+            begin
+            s:= inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1);
+            AddCaption(format(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate);
+            end;
+        
+        if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) or
+            ((GameFlags and gfMultiWeapon) <> 0) then
+            begin
+            isInMultiShoot:= true
+            end
+        else
+            begin
+            OnUsedAmmo(CurrentHedgehog^);
+            if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (((GameFlags and gfInfAttack) = 0) or PlacingHogs) then
+                begin
+                if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft;
+                TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100;
+                end;
+            if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) then State:= State or gstAttacked;
+            if (Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) <> 0 then ApplyAmmoChanges(CurrentHedgehog^)
+            end;
+        end
+    else
+        begin
+        OnUsedAmmo(CurrentHedgehog^);
+        ApplyAmmoChanges(CurrentHedgehog^);
+        end;
+    AttackBar:= 0
+    end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepHedgehogDead(Gear: PGear);
+const frametime = 200;
+      timertime = frametime * 6;
+begin
+if Gear^.Hedgehog^.Unplaced then exit;
+if Gear^.Timer > 1 then
+    begin
+    AllInactive:= false;
+    dec(Gear^.Timer);
+    if (Gear^.Timer mod frametime) = 0 then inc(Gear^.Pos)
+    end 
+else if Gear^.Timer = 1 then
+    begin
+    Gear^.State:= Gear^.State or gstNoDamage;
+    doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound);
+    AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
+    DeleteGear(Gear);
+    SetAllToActive
+    end 
+else // Gear^.Timer = 0
+    begin
+    AllInactive:= false;
+    Gear^.Z:= cCurrHHZ;
+    RemoveGearFromList(Gear);
+    InsertGearToList(Gear);
+    PlaySound(sndByeBye, Gear^.Hedgehog^.Team^.voicepack);
+    Gear^.Pos:= 0;
+    Gear^.Timer:= timertime
+    end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepHedgehogGone(Gear: PGear);
+const frametime = 65;
+      timertime = frametime * 11;
+begin
+if Gear^.Hedgehog^.Unplaced then exit;
+if Gear^.Timer > 1 then
+    begin
+    AllInactive:= false;
+    dec(Gear^.Timer);
+    if (Gear^.Timer mod frametime) = 0 then inc(Gear^.Pos)
+    end else
+if Gear^.Timer = 1 then
+    begin
+    DeleteGear(Gear);
+    SetAllToActive
+    end else // Gear^.Timer = 0
+    begin
+    AllInactive:= false;
+    Gear^.Z:= cCurrHHZ;
+    RemoveGearFromList(Gear);
+    InsertGearToList(Gear);
+    PlaySound(sndByeBye, Gear^.Hedgehog^.Team^.voicepack);
+    PlaySound(sndWarp);
+    Gear^.Pos:= 0;
+    Gear^.Timer:= timertime
+    end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure PickUp(HH, Gear: PGear);
+var s: shortstring;
+    a: TAmmoType;
+    i: LongInt;
+    vga: PVisualGear;
+begin
+Gear^.Message:= gmDestroy;
+PlaySound(sndShotgunReload);
+if (Gear^.Pos and posCaseExplode) <> 0 then
+    if (Gear^.Pos and posCasePoison) <> 0 then
+        doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound + EXPLPoisoned)
+    else
+        doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound)
+else if (Gear^.Pos and posCasePoison) <> 0 then
+    doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound + EXPLPoisoned + EXPLNoDamage)
+else
+case Gear^.Pos of
+       posCaseUtility,
+       posCaseAmmo: begin
+                    if Gear^.AmmoType <> amNothing then a:= Gear^.AmmoType 
+                    else
+                        begin
+                        for i:= 0 to GameTicks and $7F do GetRandom(2); // Burn some random numbers
+                        if Gear^.Pos = posCaseUtility then a:= GetUtility
+                        else a:= GetAmmo
+                        end;
+                    AddAmmo(HH^.Hedgehog^, a);
+// Possibly needs to check shared clan ammo game flag once added.
+// On the other hand, no obvious reason that clan members shouldn't know what ammo another clan member picked up
+                    if (not (HH^.Hedgehog^.Team^.ExtDriven 
+                      or (HH^.Hedgehog^.BotLevel > 0)))
+                      or (HH^.Hedgehog^.Team^.Clan^.ClanIndex = LocalClan)
+                      or (GameType = gmtDemo)  then
+                        begin
+                        s:= trammo[Ammoz[a].NameId] + ' (+' + IntToStr(Ammoz[a].NumberInCase) + ')';
+                        AddCaption(s, HH^.Hedgehog^.Team^.Clan^.Color, capgrpAmmoinfo);
+
+                        // show ammo icon
+                        vga:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtAmmo);
+                        if vga <> nil then
+                            vga^.Frame:= Longword(a);
+                        end;
+
+                    end;
+     posCaseHealth: begin
+                    inc(HH^.Health, Gear^.Health);
+                    HH^.Hedgehog^.Effects[hePoisoned] := false;
+                    str(Gear^.Health, s);
+                    s:= '+' + s;
+                    AddCaption(s, HH^.Hedgehog^.Team^.Clan^.Color, capgrpAmmoinfo);
+                    RenderHealth(HH^.Hedgehog^);
+                    RecountTeamHealth(HH^.Hedgehog^.Team);
+
+                    i:= 0;
+                    while i < Gear^.Health do
+                        begin
+                        vga:= AddVisualGear(hwRound(HH^.X), hwRound(HH^.Y), vgtStraightShot);
+                        if vga <> nil then
+                            with vga^ do
+                                begin
+                                Tint:= $00FF00FF;
+                                State:= ord(sprHealth)
+                                end;
+                        inc(i, 5);
+                        end;
+                    end;
+     end
+end;
+
+const StepTicks: LongWord = 0;
+
+procedure HedgehogStep(Gear: PGear);
+var PrevdX: LongInt;
+    CurWeapon: PAmmo;
+begin
+CurWeapon:= GetAmmoEntry(Gear^.Hedgehog^);
+if ((Gear^.State and (gstAttacking or gstMoving)) = 0) then
+   begin
+   if isCursorVisible then
+      with Gear^.Hedgehog^ do
+        with CurWeapon^ do
+          begin
+          if (Gear^.Message and gmLeft  ) <> 0 then
+             Pos:= (Pos - 1 + Ammoz[AmmoType].PosCount) mod Ammoz[AmmoType].PosCount
+          else
+          if (Gear^.Message and gmRight ) <> 0 then
+             Pos:= (Pos + 1) mod Ammoz[AmmoType].PosCount
+          else exit;
+          StepTicks:= 200;
+          exit
+          end;
+
+    if ((Gear^.Message and gmAnimate) <> 0) then
+        begin
+        Gear^.Message:= 0;
+        Gear^.State:= Gear^.State or gstAnimation;
+        Gear^.Tag:= Gear^.MsgParam;
+        Gear^.Timer:= 0;
+        Gear^.Pos:= 0
+        end;
+
+   if ((Gear^.Message and gmLJump ) <> 0) then
+      begin
+      Gear^.Message:= Gear^.Message and (not gmLJump);
+      DeleteCI(Gear);
+      if TestCollisionYwithGear(Gear, -1) = 0 then
+         if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then Gear^.Y:= Gear^.Y - _2 else
+         if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then Gear^.Y:= Gear^.Y - _1;
+      if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX))
+         or   (TestCollisionYwithGear(Gear, -1) <> 0)) then
+         begin
+         Gear^.dY:= -_0_15;
+         if not cArtillery then Gear^.dX:= SignAs(_0_15, Gear^.dX);
+         Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
+         PlaySound(sndJump1, Gear^.Hedgehog^.Team^.voicepack);
+         exit
+         end;
+      end;
+
+   if ((Gear^.Message and gmHJump ) <> 0) then
+      begin
+      DeleteCI(Gear);
+      Gear^.Message:= Gear^.Message and (not gmHJump);
+
+      Gear^.dY:= -_0_2;
+      SetLittle(Gear^.dX);
+      Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
+      PlaySound(sndJump3, Gear^.Hedgehog^.Team^.voicepack);
+      exit
+      end;
+
+   PrevdX:= hwSign(Gear^.dX);
+   if (Gear^.Message and gmLeft  )<>0 then Gear^.dX:= -cLittle else
+   if (Gear^.Message and gmRight )<>0 then Gear^.dX:=  cLittle else exit;
+
+   if (Gear^.Message and (gmLeft or gmRight)) <> 0 then
+      begin
+      StepSoundTimer:= cHHStepTicks;
+      end;
+   
+   StepTicks:= cHHStepTicks;
+   if PrevdX <> hwSign(Gear^.dX) then
+      begin
+      FollowGear:= Gear;
+      exit
+      end;
+   DeleteCI(Gear); // must be after exit!! (see previous line)
+
+   Gear^.Hedgehog^.visStepPos:= (Gear^.Hedgehog^.visStepPos + 1) and 7;
+   if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
+      begin
+      if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX))
+         or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
+      if not (TestCollisionXwithXYShift(Gear, _0, -5, hwSign(Gear^.dX))
+         or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
+      if not (TestCollisionXwithXYShift(Gear, _0, -4, hwSign(Gear^.dX))
+         or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
+      if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX))
+         or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
+      if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX))
+         or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
+      if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX))
+         or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
+      end;
+
+   if (not cArtillery) and ((Gear^.Message and gmPrecise) = 0) and (not TestCollisionXwithGear(Gear, hwSign(Gear^.dX))) then
+      Gear^.X:= Gear^.X + SignAs(_1, Gear^.dX);
+
+   SetAllHHToActive;
+
+   if TestCollisionYwithGear(Gear, 1) = 0 then
+   begin
+   Gear^.Y:= Gear^.Y + _1;
+   if TestCollisionYwithGear(Gear, 1) = 0 then
+   begin
+   Gear^.Y:= Gear^.Y + _1;
+   if TestCollisionYwithGear(Gear, 1) = 0 then
+   begin
+   Gear^.Y:= Gear^.Y + _1;
+   if TestCollisionYwithGear(Gear, 1) = 0 then
+   begin
+   Gear^.Y:= Gear^.Y + _1;
+   if TestCollisionYwithGear(Gear, 1) = 0 then
+   begin
+   Gear^.Y:= Gear^.Y + _1;
+   if TestCollisionYwithGear(Gear, 1) = 0 then
+   begin
+   Gear^.Y:= Gear^.Y + _1;
+   if TestCollisionYwithGear(Gear, 1) = 0 then
+      begin
+      Gear^.Y:= Gear^.Y - _6;
+      Gear^.dY:= _0;
+      Gear^.State:= Gear^.State or gstMoving;
+      exit
+      end;
+   end
+   end
+   end
+   end
+   end
+   end;
+   AddGearCI(Gear)
+   end
+end;
+
+procedure HedgehogChAngle(HHGear: PGear);
+var da: LongWord;
+begin
+with HHGear^.Hedgehog^ do
+    if ((CurAmmoType = amRope) and 
+        ((HHGear^.State and (gstMoving or gstHHJumping)) = gstMoving)) or
+       ((CurAmmoType = amPortalGun) and 
+        ((HHGear^.State and gstMoving) <> 0)) then da:= 2
+    else da:= 1;
+
+if (((HHGear^.Message and gmPrecise) = 0) or ((GameTicks mod 5) = 1)) then
+    if ((HHGear^.Message and gmUp) <> 0) and (HHGear^.Angle >= CurMinAngle + da) then dec(HHGear^.Angle, da)
+    else
+    if ((HHGear^.Message and gmDown) <> 0) and (HHGear^.Angle + da <= CurMaxAngle) then inc(HHGear^.Angle, da)
+end;
+
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepHedgehogMoving(Gear: PGear);
+var isFalling, isUnderwater: boolean;
+    land: Word;
+begin
+land:= 0;
+isUnderwater:= cWaterLine < hwRound(Gear^.Y) + Gear^.Radius;
+if Gear^.dX.QWordValue > 8160437862 then Gear^.dX.QWordValue:= 8160437862;
+if Gear^.dY.QWordValue > 8160437862 then Gear^.dY.QWordValue:= 8160437862;
+
+if Gear^.Hedgehog^.Unplaced then
+   begin
+   Gear^.dY:= _0;
+   Gear^.dX:= _0;
+   Gear^.State:= Gear^.State and (not gstMoving);
+   exit
+   end;
+isFalling:= (Gear^.dY.isNegative) or not TestCollisionYKick(Gear, 1);
+if isFalling then
+   begin
+   if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then Gear^.dY:= _0;
+   Gear^.State:= Gear^.State or gstMoving;
+   if (CurrentHedgehog^.Gear = Gear)
+        and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then 
+        begin
+        FollowGear:= Gear;
+        end;
+   if isUnderwater then Gear^.dY:= Gear^.dY + cGravity / _2
+   else
+       begin
+       Gear^.dY:= Gear^.dY + cGravity;
+// this set of circumstances could be less complex if jumping was more clearly identified
+       if ((GameFlags and gfMoreWind) <> 0) and 
+          (((Gear^.Damage <> 0) or
+          ((CurAmmoGear <> nil) and
+            ((CurAmmoGear^.AmmoType = amJetpack) or
+            (CurAmmoGear^.AmmoType = amBirdy))) or
+          ((Gear^.dY.QWordValue + Gear^.dX.QWordValue) > _0_55.QWordValue)))
+          then Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
+       end
+   end 
+else
+   begin
+   land:= TestCollisionYwithGear(Gear, 1);
+   if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_55.QWordValue) and ((land and lfIce) = 0)
+      and ((Gear^.State and gstHHJumping) <> 0) then SetLittle(Gear^.dX);
+
+   if not Gear^.dY.isNegative then
+      begin
+      CheckHHDamage(Gear);
+
+      if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) and
+         (Gear^.dX.QWordValue < _0_02.QWordValue) then Gear^.dX.isNegative:= not Gear^.dX.isNegative; // landing after high jump
+
+      Gear^.State:= Gear^.State and (not (gstHHJumping or gstHHHJump));
+      Gear^.dY:= _0;
+      end else Gear^.dY:= Gear^.dY + cGravity;
+
+   if ((Gear^.State and gstMoving) <> 0) then
+       begin
+       if land and lfIce <> 0 then
+           begin
+           Gear^.dX:= Gear^.dX * (_1 - (_1 - Gear^.Friction) / _2)
+           end
+       else Gear^.dX:= Gear^.dX * Gear^.Friction;
+       end
+   end;
+
+if (Gear^.State <> 0) then DeleteCI(Gear);
+
+if isUnderwater then
+   begin
+   Gear^.dY:= Gear^.dY * _0_999;
+   Gear^.dX:= Gear^.dX * _0_999;
+   end;
+
+if (Gear^.State and gstMoving) <> 0 then
+   if TestCollisionXKick(Gear, hwSign(Gear^.dX)) then
+      if not isFalling then
+         if hwAbs(Gear^.dX) > _0_01 then
+            if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_96; Gear^.Y:= Gear^.Y - _1 end else
+            if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_93; Gear^.Y:= Gear^.Y - _2 end else
+            if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_9 ; Gear^.Y:= Gear^.Y - _3 end else
+            if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -4, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_87; Gear^.Y:= Gear^.Y - _4 end else
+            if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -5, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_84; Gear^.Y:= Gear^.Y - _5 end else
+            if hwAbs(Gear^.dX) > _0_02 then Gear^.dX:= -Gear^.Elasticity * Gear^.dX
+                                   else begin
+                                        Gear^.State:= Gear^.State and (not gstMoving);
+                                        while TestCollisionYWithGear(Gear,1) = 0 do Gear^.Y:= Gear^.Y+_1;
+                                        SetLittle(Gear^.dX)
+                                        end
+            else begin
+                 Gear^.State:= Gear^.State and (not gstMoving);
+                 while TestCollisionYWithGear(Gear,1) = 0 do Gear^.Y:= Gear^.Y+_1;
+                 SetLittle(Gear^.dX)
+                 end
+         else if (hwAbs(Gear^.dX) > cLittle)
+                and ((Gear^.State and gstHHJumping) = 0)
+                then Gear^.dX:= -Gear^.Elasticity * Gear^.dX
+                else SetLittle(Gear^.dX);
+
+if (not isFalling) and
+   (hwAbs(Gear^.dX) + hwAbs(Gear^.dY) < _0_03) then
+   begin
+   Gear^.State:= Gear^.State and (not gstWinner);
+   Gear^.State:= Gear^.State and (not gstMoving);
+   while TestCollisionYWithGear(Gear,1) = 0 do Gear^.Y:= Gear^.Y+_1;
+   SetLittle(Gear^.dX);
+   Gear^.dY:= _0
+   end else Gear^.State:= Gear^.State or gstMoving;
+
+if (Gear^.State and gstMoving) <> 0 then
+   begin
+   Gear^.State:= Gear^.State and (not gstAnimation);
+// ARTILLERY but not being moved by explosions
+   Gear^.X:= Gear^.X + Gear^.dX;
+   Gear^.Y:= Gear^.Y + Gear^.dY;
+   if (not Gear^.dY.isNegative) and
+      (not TestCollisionYKick(Gear, 1)) and
+       TestCollisionYwithXYShift(Gear, 0, 1, 1) then
+      begin
+      CheckHHDamage(Gear);
+      Gear^.dY:= _0;
+      Gear^.Y:= Gear^.Y + _1
+      end;
+   CheckGearDrowning(Gear);
+   // hide target cursor if current hog is drowning
+   if (Gear^.State and gstDrowning) <> 0 then
+       if (CurrentHedgehog^.Gear = Gear) then
+          isCursorVisible:= false
+   end;
+
+if (hwAbs(Gear^.dY) > _0) and (Gear^.FlightTime > 0) and ((GameFlags and gfLowGravity) = 0) then
+    begin
+    inc(Gear^.FlightTime);
+    if Gear^.FlightTime = 3000 then
+        begin
+        AddCaption(GetEventString(eidHomerun), cWhiteColor, capgrpMessage);
+        PlaySound(sndHomerun)
+        end;
+    end
+else
+    begin
+    uStats.hedgehogFlight(Gear, Gear^.FlightTime);
+    Gear^.FlightTime:= 0;
+    end;
+
+end;
+
+procedure doStepHedgehogDriven(HHGear: PGear);
+var t: PGear;
+    wasJumping: boolean;
+    Hedgehog: PHedgehog;
+begin
+Hedgehog:= HHGear^.Hedgehog;
+if isInMultiShoot then
+   HHGear^.Message:= 0;
+
+if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then 
+    AllInactive:= true
+else if not isInMultiShoot then AllInactive:= false;
+
+if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
+    begin
+    if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft;
+    TurnTimeLeft:= 0;
+    isCursorVisible:= false;
+    HHGear^.State:= HHGear^.State and (not (gstHHDriven or gstAnimation or gstAttacking));
+    AttackBar:= 0;
+    if HHGear^.Damage > 0 then
+        HHGear^.State:= HHGear^.State and (not (gstHHJumping or gstHHHJump));
+    exit
+    end;
+
+if (HHGear^.State and gstAnimation) <> 0 then
+    begin
+    HHGear^.Message:= 0;
+    if (HHGear^.Pos = Wavez[TWave(HHGear^.Tag)].VoiceDelay) and (HHGear^.Timer = 0) then PlaySound(Wavez[TWave(HHGear^.Tag)].Voice, Hedgehog^.Team^.voicepack);
+    inc(HHGear^.Timer);
+    if HHGear^.Timer = Wavez[TWave(HHGear^.Tag)].Interval then
+        begin
+        HHGear^.Timer:= 0;
+        inc(HHGear^.Pos);
+        if HHGear^.Pos = Wavez[TWave(HHGear^.Tag)].FramesCount then
+            HHGear^.State:= HHGear^.State and (not gstAnimation)
+        end;
+    exit
+    end;
+
+if ((HHGear^.State and gstMoving) <> 0)
+    or (StepTicks = cHHStepTicks)
+    or (CurAmmoGear <> nil) then // we are moving
+    begin
+    with Hedgehog^ do
+        if (CurAmmoGear = nil)
+        and (HHGear^.dY > _0_39)
+        and (CurAmmoType = amParachute) then HHGear^.Message:= HHGear^.Message or gmAttack;
+    // check for case with ammo
+    t:= CheckGearNear(HHGear, gtCase, 36, 36);
+    if t <> nil then
+        PickUp(HHGear, t)
+    end;
+
+if (CurAmmoGear = nil) then
+    if (((HHGear^.Message and gmAttack) <> 0)
+        or ((HHGear^.State and gstAttacking) <> 0)) then
+        Attack(HHGear) // should be before others to avoid desync with '/put' msg and changing weapon msgs
+    else
+else 
+    with Hedgehog^ do
+        if ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
+            and ((HHGear^.Message and gmLJump) <> 0)
+            and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
+            begin
+            Attack(HHGear);
+            HHGear^.Message:= HHGear^.Message and (not gmLJump)
+            end;
+
+if (CurAmmoGear = nil)
+    or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) 
+    or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) then
+    begin
+    if ((HHGear^.Message and gmSlot) <> 0) then
+        if ChangeAmmo(HHGear) then ApplyAmmoChanges(Hedgehog^);
+
+    if ((HHGear^.Message and gmWeapon) <> 0) then HHSetWeapon(HHGear);
+
+    if ((HHGear^.Message and gmTimer) <> 0) then HHSetTimer(HHGear);
+    end;
+
+if CurAmmoGear <> nil then
+   begin
+   CurAmmoGear^.Message:= HHGear^.Message;
+   exit
+   end;
+
+if not isInMultiShoot then
+   HedgehogChAngle(HHGear);
+
+if (HHGear^.State and gstMoving) <> 0 then
+    begin
+    wasJumping:= ((HHGear^.State and gstHHJumping) <> 0);
+
+    if ((HHGear^.Message and gmHJump) <> 0) and
+        wasJumping and
+        ((HHGear^.State and gstHHHJump) = 0) then
+        if (not (hwAbs(HHGear^.dX) > cLittle)) and (HHGear^.dY < -_0_02) then
+            begin
+            HHGear^.State:= HHGear^.State or gstHHHJump;
+            HHGear^.dY:= -_0_25;
+            if not cArtillery then HHGear^.dX:= -SignAs(_0_02, HHGear^.dX);
+            PlaySound(sndJump2, Hedgehog^.Team^.voicepack)
+            end;
+
+    HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
+
+    if (not cArtillery) and wasJumping and
+        TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX);
+
+    if Hedgehog^.Gear <> nil then doStepHedgehogMoving(HHGear);
+
+    if ((HHGear^.State and (gstMoving or gstDrowning)) = 0) then
+        begin
+        AddGearCI(HHGear);
+        if wasJumping then
+            StepTicks:= 410
+        else
+            StepTicks:= 95
+        end;
+    exit
+    end;
+
+    if not isInMultiShoot and (Hedgehog^.Gear <> nil) then
+        begin
+        if StepTicks > 0 then dec(StepTicks);
+        if (StepTicks = 0) then HedgehogStep(HHGear)
+        end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepHedgehogFree(Gear: PGear);
+var prevState: Longword;
+begin
+prevState:= Gear^.State;
+
+doStepHedgehogMoving(Gear);
+
+if (Gear^.State and (gstMoving or gstDrowning)) <> 0 then
+    begin
+    if Gear^.Damage > 0 then CalcRotationDirAngle(Gear);
+    AllInactive:= false;
+    exit
+    end;
+
+if (Gear^.Health = 0) then
+    begin
+    if PrvInactive or ((GameFlags and gfInfAttack) <> 0) then
+        begin
+        Gear^.Timer:= 0;
+        FollowGear:= Gear;
+        PrvInactive:= false;
+        AllInactive:= false;
+
+        if (Gear^.State and gstHHGone) = 0 then
+            begin
+            Gear^.Hedgehog^.Effects[hePoisoned] := false;
+            if Gear^.Hedgehog^.Effects[heResurrectable] then begin
+                ResurrectHedgehog(Gear);
+            end else 
+                begin
+                Gear^.State:= (Gear^.State or gstHHDeath) and (not gstAnimation);
+                Gear^.doStep:= @doStepHedgehogDead;
+                // Death message
+                AddCaption(Format(GetEventString(eidDied), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
+                end;
+            end
+        else
+            begin
+            Gear^.State:= Gear^.State and (not gstAnimation);
+            Gear^.doStep:= @doStepHedgehogGone;
+
+            // Gone message
+            AddCaption(Format(GetEventString(eidGone), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
+            end
+        end;
+    exit
+    end;
+
+if ((Gear^.State and gstWait) = 0) and
+    (prevState <> Gear^.State) then
+    begin
+    Gear^.State:= Gear^.State or gstWait;
+    Gear^.Timer:= 150
+    end else
+    begin
+    if Gear^.Timer = 0 then
+        begin
+        Gear^.State:= Gear^.State and (not (gstWait or gstLoser or gstWinner or gstAttacked or gstNotKickable or gstHHChooseTarget));
+        Gear^.Active:= false;
+        AddGearCI(Gear);
+        exit
+        end else dec(Gear^.Timer)
+    end;
+
+AllInactive:= false
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepHedgehog(Gear: PGear);
+(*
+var x,y,tx,ty: LongInt;
+    tdX, tdY, slope: hwFloat; 
+    land: Word; *)
+var slope: hwFloat; 
+begin
+if (Gear^.Message and gmDestroy) <> 0 then
+    begin
+    DeleteGear(Gear);
+    exit
+    end;
+
+if (Gear^.State and gstHHDriven) = 0 then
+    doStepHedgehogFree(Gear)
+else
+    begin
+    with Gear^.Hedgehog^ do
+        if Team^.hasGone then
+            TeamGoneEffect(Team^)
+        else
+            doStepHedgehogDriven(Gear)
+    end;
+if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0) and
+   (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0) and
+   (not Gear^.dY.isNegative) and
+   (GameTicks mod (100*LongWOrd(hwRound(cMaxWindSpeed*2/cGravity))) = 0) and
+   (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
+    begin
+    slope:= CalcSlopeBelowGear(Gear);
+    Gear^.dX:=Gear^.dX+slope*_0_07;
+    if slope.QWordValue <> 0 then Gear^.State:= Gear^.State or gstMoving;
+(*
+    x:= hwRound(Gear^.X);
+    y:= hwRound(Gear^.Y);
+    AddVisualGear(x, y, vgtSmokeTrace);
+    AddVisualGear(x - hwRound(_5*slope), y + hwRound(_5*slope), vgtSmokeTrace);
+    AddVisualGear(x + hwRound(_5*slope), y - hwRound(_5*slope), vgtSmokeTrace);
+    AddVisualGear(x - hwRound(_20 * slope), y + hwRound(_20 * slope), vgtSmokeTrace);
+    AddVisualGear(x + hwRound(_20 * slope), y - hwRound(_20 * slope), vgtSmokeTrace);
+    AddVisualGear(x - hwRound(_30 * slope), y + hwRound(_30 * slope), vgtSmokeTrace);
+    AddVisualGear(x + hwRound(_30 * slope), y - hwRound(_30 * slope), vgtSmokeTrace);
+    AddVisualGear(x - hwRound(_40 * slope), y + hwRound(_40 * slope), vgtSmokeTrace);
+    AddVisualGear(x + hwRound(_40 * slope), y - hwRound(_40 * slope), vgtSmokeTrace);
+    AddVisualGear(x - hwRound(_50 * slope), y + hwRound(_50 * slope), vgtSmokeTrace);
+    AddVisualGear(x + hwRound(_50 * slope), y - hwRound(_50 * slope), vgtSmokeTrace); *)
+    end
+end;
+
+end.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uGearsList.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,542 @@
+(*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2011 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *)
+
+{$INCLUDE "options.inc"}
+unit uGearsList;
+
+interface
+uses uFloat, uTypes;
+
+function  AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear;
+procedure DeleteGear(Gear: PGear);
+
+implementation
+
+uses uDebug, uRandom, uUtils, uConsts, uVariables, uAmmos, uTeams, uStats,
+    uTextures, uScript, uRenderUtils, uAI, uCollisions, uGearsHedgehog;
+
+procedure InsertGearToList(Gear: PGear);
+var tmp, ptmp: PGear;
+begin
+    tmp:= GearsList;
+    ptmp:= GearsList;
+    while (tmp <> nil) and (tmp^.Z <= Gear^.Z) do
+        begin
+        ptmp:= tmp;
+        tmp:= tmp^.NextGear
+        end;
+
+    if ptmp <> tmp then
+        begin
+        Gear^.NextGear:= ptmp^.NextGear;
+        Gear^.PrevGear:= ptmp;
+        if ptmp^.NextGear <> nil then ptmp^.NextGear^.PrevGear:= Gear;
+        ptmp^.NextGear:= Gear
+        end
+    else
+        begin
+        Gear^.NextGear:= GearsList;
+        if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear;
+        GearsList:= Gear;
+        end;
+end;
+
+procedure RemoveGearFromList(Gear: PGear);
+begin
+if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
+if Gear^.PrevGear <> nil then
+    Gear^.PrevGear^.NextGear:= Gear^.NextGear
+else
+    GearsList:= Gear^.NextGear
+end;
+    
+function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear;
+const Counter: Longword = 0;
+var gear: PGear;
+begin
+inc(Counter);
+AddFileLog('AddGear: #' + inttostr(Counter) + ' (' + inttostr(x) + ',' + inttostr(y) + '), d(' + floattostr(dX) + ',' + floattostr(dY) + ') type = ' + EnumToStr(Kind));
+
+New(gear);
+FillChar(gear^, sizeof(TGear), 0);
+gear^.X:= int2hwFloat(X);
+gear^.Y:= int2hwFloat(Y);
+gear^.Target.X:= NoPointX;
+gear^.Kind := Kind;
+gear^.State:= State;
+gear^.Active:= true;
+gear^.dX:= dX;
+gear^.dY:= dY;
+gear^.doStep:= doStepHandlers[Kind];
+gear^.CollisionIndex:= -1;
+gear^.Timer:= Timer;
+gear^.FlightTime:= 0;
+gear^.uid:= Counter;
+gear^.SoundChannel:= -1;
+gear^.ImpactSound:= sndNone;
+gear^.nImpactSounds:= 0;
+gear^.Density:= _1;
+// Define ammo association, if any.
+gear^.AmmoType:= GearKindAmmoTypeMap[Kind];
+if Ammoz[Gear^.AmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then gear^.Z:= cHHZ+1
+else gear^.Z:= cUsualZ;
+
+if CurrentHedgehog <> nil then
+    begin
+    gear^.Hedgehog:= CurrentHedgehog;
+    gear^.IntersectGear:= CurrentHedgehog^.Gear
+    end;
+    
+case Kind of
+     gtGrenade,
+     gtClusterBomb,
+     gtGasBomb: begin
+                gear^.ImpactSound:= sndGrenadeImpact;
+                gear^.nImpactSounds:= 1;
+                gear^.AdvBounce:= 1;
+                gear^.Radius:= 5;
+                gear^.Elasticity:= _0_8;
+                gear^.Friction:= _0_8;
+                gear^.Density:= _1_5;
+                gear^.RenderTimer:= true;
+                if gear^.Timer = 0 then gear^.Timer:= 3000
+                end;
+  gtWatermelon: begin
+                gear^.ImpactSound:= sndMelonImpact;
+                gear^.nImpactSounds:= 1;
+                gear^.AdvBounce:= 1;
+                gear^.Radius:= 6;
+                gear^.Elasticity:= _0_8;
+                gear^.Friction:= _0_995;
+                gear^.Density:= _2;
+                gear^.RenderTimer:= true;
+                if gear^.Timer = 0 then gear^.Timer:= 3000
+                end;
+  gtMelonPiece: begin
+                gear^.Density:= _2;
+                end;
+    gtHedgehog: begin
+                gear^.AdvBounce:= 1;
+                gear^.Radius:= cHHRadius;
+                gear^.Elasticity:= _0_35;
+                gear^.Friction:= _0_999;
+                gear^.Angle:= cMaxAngle div 2;
+                gear^.Density:= _3;
+                gear^.Z:= cHHZ;
+                if (GameFlags and gfAISurvival) <> 0 then
+                    if gear^.Hedgehog^.BotLevel > 0 then
+                        gear^.Hedgehog^.Effects[heResurrectable] := true;
+                end;
+       gtShell: begin
+                gear^.Radius:= 4;
+                gear^.Density:= _1;
+                end;
+       gtSnowball: begin
+                gear^.ImpactSound:= sndMudballImpact;
+                gear^.nImpactSounds:= 1;
+                gear^.Radius:= 4;
+                gear^.Elasticity:= _1;
+                gear^.Friction:= _1;
+                gear^.Density:= _0_5;
+                end;
+
+     gtFlake: begin
+                with Gear^ do
+                    begin
+                    Pos:= 0;
+                    Radius:= 1;
+                    DirAngle:= random * 360;
+                    if State and gstTmpFlag = 0 then
+                        begin
+                        dx.isNegative:= GetRandom(2) = 0;
+                        dx.QWordValue:= GetRandom(100000000);
+                        dy.isNegative:= false;
+                        dy.QWordValue:= GetRandom(70000000);
+                        if GetRandom(2) = 0 then dx := -dx
+                        end;
+                    State:= State or gstInvisible;
+                    Health:= random(vobFrameTicks);
+                    Timer:= random(vobFramesCount);
+                    Angle:= (random(2) * 2 - 1) * (1 + random(10000)) * vobVelocity
+                    end
+                end;
+       gtGrave: begin
+                gear^.ImpactSound:= sndGraveImpact;
+                gear^.nImpactSounds:= 1;
+                gear^.Radius:= 10;
+                gear^.Elasticity:= _0_6;
+                end;
+         gtBee: begin
+                gear^.Radius:= 5;
+                gear^.Timer:= 500;
+                gear^.RenderTimer:= true;
+                gear^.Elasticity:= _0_9;
+                gear^.Tag:= 0;
+                end;
+   gtSeduction: begin
+                gear^.Radius:= 250;
+                end;
+ gtShotgunShot: begin
+                gear^.Timer:= 900;
+                gear^.Radius:= 2
+                end;
+  gtPickHammer: begin
+                gear^.Radius:= 10;
+                gear^.Timer:= 4000
+                end;
+   gtHammerHit: begin
+                gear^.Radius:= 8;
+                gear^.Timer:= 125
+                end;
+        gtRope: begin
+                gear^.Radius:= 3;
+                gear^.Friction:= _450 * _0_01 * cRopePercent;
+                RopePoints.Count:= 0;
+                end;
+        gtMine: begin
+                gear^.ImpactSound:= sndMineImpact;
+                gear^.nImpactSounds:= 1;
+                gear^.Health:= 10;
+                gear^.State:= gear^.State or gstMoving;
+                gear^.Radius:= 2;
+                gear^.Elasticity:= _0_55;
+                gear^.Friction:= _0_995;
+                gear^.Density:= _0_9;
+                if cMinesTime < 0 then
+                    gear^.Timer:= getrandom(51)*100
+                else
+                    gear^.Timer:= cMinesTime;
+                end;
+       gtSMine: begin
+                gear^.Health:= 10;
+                gear^.State:= gear^.State or gstMoving;
+                gear^.Radius:= 2;
+                gear^.Elasticity:= _0_55;
+                gear^.Friction:= _0_995;
+                gear^.Density:= _0_9;
+                gear^.Timer:= 500;
+                end;
+        gtCase: begin
+                gear^.ImpactSound:= sndGraveImpact;
+                gear^.nImpactSounds:= 1;
+                gear^.Radius:= 16;
+                gear^.Elasticity:= _0_3
+                end;
+  gtExplosives: begin
+                gear^.ImpactSound:= sndGrenadeImpact;
+                gear^.nImpactSounds:= 1;
+                gear^.Radius:= 16;
+                gear^.Elasticity:= _0_4;
+                gear^.Friction:= _0_995;
+                gear^.Density:= _6;
+                gear^.Health:= cBarrelHealth;
+                gear^.Z:= cHHZ-1
+                end;
+  gtDEagleShot: begin
+                gear^.Radius:= 1;
+                gear^.Health:= 50
+                end;
+  gtSniperRifleShot: begin
+                gear^.Radius:= 1;
+                gear^.Health:= 50
+                end;
+    gtDynamite: begin
+                gear^.Radius:= 3;
+                gear^.Elasticity:= _0_55;
+                gear^.Friction:= _0_03;
+                gear^.Density:= _2;
+                gear^.Timer:= 5000;
+                end;
+     gtCluster: begin
+                gear^.Radius:= 2;
+                gear^.Density:= _1_5;
+                gear^.RenderTimer:= true
+                end;
+      gtShover: gear^.Radius:= 20;
+       gtFlame: begin
+                gear^.Tag:= GetRandom(32);
+                gear^.Radius:= 1;
+                gear^.Health:= 5;
+                gear^.Density:= _1;
+                if (gear^.dY.QWordValue = 0) and (gear^.dX.QWordValue = 0) then
+                    begin
+                    gear^.dY:= (getrandom - _0_8) * _0_03;
+                    gear^.dX:= (getrandom - _0_5) * _0_4
+                    end
+                end;
+   gtFirePunch: begin
+                gear^.Radius:= 15;
+                gear^.Tag:= Y
+                end;
+     gtAirBomb: begin
+                gear^.Radius:= 5;
+                gear^.Density:= _2;
+                end;
+   gtBlowTorch: begin
+                gear^.Radius:= cHHRadius + cBlowTorchC;
+                gear^.Timer:= 7500
+                end;
+    gtSwitcher: begin
+                gear^.Z:= cCurrHHZ
+                end;
+      gtTarget: begin
+                gear^.ImpactSound:= sndGrenadeImpact;
+                gear^.nImpactSounds:= 1;
+                gear^.Radius:= 10;
+                gear^.Elasticity:= _0_3;
+                gear^.Timer:= 0
+                end;
+      gtTardis: begin
+                gear^.Timer:= 0;
+                gear^.Pos:= 1;
+                gear^.Z:= cCurrHHZ+1;
+                end;
+      gtMortar: begin
+                gear^.Radius:= 4;
+                gear^.Elasticity:= _0_2;
+                gear^.Friction:= _0_08;
+                gear^.Density:= _1;
+                end;
+        gtWhip: gear^.Radius:= 20;
+      gtHammer: gear^.Radius:= 20;
+    gtKamikaze: begin
+                gear^.Health:= 2048;
+                gear^.Radius:= 20
+                end;
+        gtCake: begin
+                gear^.Health:= 2048;
+                gear^.Radius:= 7;
+                gear^.Z:= cOnHHZ;
+                gear^.RenderTimer:= true;
+                gear^.DirAngle:= -90 * hwSign(Gear^.dX);
+                if not dX.isNegative then gear^.Angle:= 1 else gear^.Angle:= 3
+                end;
+ gtHellishBomb: begin
+                gear^.ImpactSound:= sndHellishImpact1;
+                gear^.nImpactSounds:= 4;
+                gear^.AdvBounce:= 1;
+                gear^.Radius:= 4;
+                gear^.Elasticity:= _0_5;
+                gear^.Friction:= _0_96;
+                gear^.Density:= _1_5;
+                gear^.RenderTimer:= true;
+                gear^.Timer:= 5000
+                end;
+       gtDrill: begin
+                if gear^.Timer = 0 then gear^.Timer:= 5000;
+                // Tag for drill strike. if 1 then first impact occured already
+                gear^.Tag := 0;
+                gear^.Radius:= 4;
+                gear^.Density:= _1;
+                end;
+        gtBall: begin
+                gear^.ImpactSound:= sndGrenadeImpact;
+                gear^.nImpactSounds:= 1;
+                gear^.AdvBounce:= 1;
+                gear^.Radius:= 5;
+                gear^.Tag:= random(8);
+                gear^.Timer:= 5000;
+                gear^.Elasticity:= _0_7;
+                gear^.Friction:= _0_995;
+                gear^.Density:= _1_5;
+                end;
+     gtBallgun: begin
+                gear^.Timer:= 5001;
+                end;
+     gtRCPlane: begin
+                gear^.Timer:= 15000;
+                gear^.Health:= 3;
+                gear^.Radius:= 8
+                end;
+     gtJetpack: begin
+                gear^.Health:= 2000;
+                gear^.Damage:= 100
+                end;
+     gtMolotov: begin
+                gear^.Radius:= 6;
+                gear^.Density:= _2;
+                end;
+       gtBirdy: begin
+                gear^.Radius:= 16; // todo: check
+                gear^.Timer:= 0;
+                gear^.Health := 2000;
+                gear^.FlightTime := 2;
+                end;
+         gtEgg: begin
+                gear^.Radius:= 4;
+                gear^.Elasticity:= _0_6;
+                gear^.Friction:= _0_96;
+                gear^.Density:= _1;
+                if gear^.Timer = 0 then gear^.Timer:= 3000
+                end;
+      gtPortal: begin
+                gear^.ImpactSound:= sndMelonImpact;
+                gear^.nImpactSounds:= 1;
+                gear^.AdvBounce:= 0;
+                gear^.Radius:= 17;
+                // set color
+                gear^.Tag:= 2 * gear^.Timer;
+                gear^.Timer:= 15000;
+                gear^.RenderTimer:= false;
+                gear^.Health:= 100;
+                end;
+       gtPiano: begin
+                gear^.Radius:= 32;
+                gear^.Density:= _50;
+                end;
+ gtSineGunShot: begin
+                gear^.Radius:= 5;
+                gear^.Health:= 6000;
+                end;
+gtFlamethrower: begin
+                gear^.Tag:= 10;
+                gear^.Timer:= 10;
+                gear^.Health:= 500;
+                gear^.Damage:= 100;
+                end;
+     gtLandGun: begin
+                gear^.Tag:= 10;
+                gear^.Timer:= 10;
+                gear^.Health:= 1000;
+                gear^.Damage:= 100;
+                end;
+ gtPoisonCloud: begin
+                gear^.Timer:= 5000;
+                gear^.dY:= int2hwfloat(-4 + longint(getRandom(8))) / 1000;
+                end;
+ gtResurrector: begin
+                gear^.Radius := 100;
+                gear^.Tag := 0
+                end;
+     gtWaterUp: begin
+                gear^.Tag := 47;
+                end;
+  gtNapalmBomb: begin
+                gear^.Timer:= 1000;
+                gear^.Radius:= 5;
+                gear^.Density:= _1_5;
+                end;
+   gtStructure: begin
+                gear^.Elasticity:= _0_55;
+                gear^.Friction:= _0_995;
+                gear^.Density:= _0_9;
+                gear^.Radius:= 13;
+                gear^.Health:= 200;
+                gear^.Timer:= 0;
+                gear^.Tag:= TotalRounds + 3;
+                gear^.Pos:= 1;
+                end;
+    end;
+
+InsertGearToList(gear);
+AddGear:= gear;
+
+ScriptCall('onGearAdd', gear^.uid);
+end;
+
+procedure DeleteGear(Gear: PGear);
+var team: PTeam;
+    t,i: Longword;
+    k: boolean;
+begin
+
+ScriptCall('onGearDelete', gear^.uid);
+
+DeleteCI(Gear);
+
+FreeTexture(Gear^.Tex);
+Gear^.Tex:= nil;
+
+// make sure that portals have their link removed before deletion
+if (Gear^.Kind = gtPortal) then
+    begin
+    if (Gear^.IntersectGear <> nil) then
+        if (Gear^.IntersectGear^.IntersectGear = Gear) then
+            Gear^.IntersectGear^.IntersectGear:= nil;
+    end
+else if Gear^.Kind = gtHedgehog then
+    (*
+    This behaviour dates back to revision 4, and I accidentally encountered it with TARDIS.  I don't think it must apply to any modern weapon, since if it was actually hit, the best the gear could do would be to destroy itself immediately, and you'd still end up with two graves.  I believe it should be removed
+     if (CurAmmoGear <> nil) and (CurrentHedgehog^.Gear = Gear) then
+        begin
+        AttackBar:= 0;
+        Gear^.Message:= gmDestroy;
+        CurAmmoGear^.Message:= gmDestroy;
+        exit
+        end
+    else*)
+        begin
+        if (hwRound(Gear^.Y) >= cWaterLine) then
+            begin
+            t:= max(Gear^.Damage, Gear^.Health);
+            Gear^.Damage:= t;
+            if ((not SuddenDeathDmg and (cWaterOpacity < $FF)) or (SuddenDeathDmg and (cWaterOpacity < $FF))) and (hwRound(Gear^.Y) < cWaterLine + 256) then
+                spawnHealthTagForHH(Gear, t);
+            end;
+
+        team:= Gear^.Hedgehog^.Team;
+        if CurrentHedgehog^.Gear = Gear then
+            begin
+            AttackBar:= 0;
+            FreeActionsList; // to avoid ThinkThread on drawned gear
+            if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) and (CurrentHedgehog^.MultiShootAttacks > 0) then OnUsedAmmo(CurrentHedgehog^);
+            end;
+
+        Gear^.Hedgehog^.Gear:= nil;
+        if Gear^.Hedgehog^.King then
+            begin
+            // are there any other kings left? Just doing nil check.  Presumably a mortally wounded king will get reaped soon enough
+            k:= false;
+            for i:= 0 to Pred(team^.Clan^.TeamsNumber) do
+                if (team^.Clan^.Teams[i]^.Hedgehogs[0].Gear <> nil) then k:= true;
+            if not k then
+                for i:= 0 to Pred(team^.Clan^.TeamsNumber) do
+                    begin
+                    team^.Clan^.Teams[i]^.hasGone:= true;
+                    TeamGoneEffect(team^.Clan^.Teams[i]^)
+                    end
+            end;
+
+        // should be not CurrentHedgehog, but hedgehog of the last gear which caused damage to this hog
+        // same stand for CheckHHDamage
+        if (Gear^.LastDamage <> nil) then
+            uStats.HedgehogDamaged(Gear, Gear^.LastDamage, 0, true)
+        else
+            uStats.HedgehogDamaged(Gear, CurrentHedgehog, 0, true);
+
+        inc(KilledHHs);
+        RecountTeamHealth(team);
+        if (CurrentHedgehog <> nil) and CurrentHedgehog^.Effects[heResurrectable] and (not Gear^.Hedgehog^.Effects[heResurrectable]) then
+            with CurrentHedgehog^ do 
+                begin
+                inc(Team^.stats.AIKills);
+                FreeTexture(Team^.AIKillsTex);
+                Team^.AIKillsTex := RenderStringTex(inttostr(Team^.stats.AIKills), Team^.Clan^.Color, fnt16);
+                end
+        end;
+with Gear^ do
+    AddFileLog('Delete: #' + inttostr(uid) + ' (' + inttostr(hwRound(x)) + ',' + inttostr(hwRound(y)) + '), d(' + floattostr(dX) + ',' + floattostr(dY) + ') type = ' + EnumToStr(Kind));
+
+if CurAmmoGear = Gear then CurAmmoGear:= nil;
+if FollowGear = Gear then FollowGear:= nil;
+if lastGearByUID = Gear then lastGearByUID := nil;
+RemoveGearFromList(Gear);
+Dispose(Gear)
+end;
+
+end.
--- a/hedgewars/uGearsRender.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uGearsRender.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -74,20 +74,16 @@
 end;
 
 
-procedure DrawRope(Gear: PGear);
-var roplen: LongInt;
-    i: Longword;
-
-    procedure DrawRopeLine(X1, Y1, X2, Y2: LongInt);
-    var  eX, eY, dX, dY: LongInt;
-        i, sX, sY, x, y, d: LongInt;
-        b: boolean;
-    begin
+procedure DrawRopeLine(X1, Y1, X2, Y2, roplen: LongInt);
+var  eX, eY, dX, dY: LongInt;
+    i, sX, sY, x, y, d: LongInt;
+    b: boolean;
+begin
     if (X1 = X2) and (Y1 = Y2) then
-    begin
-    //OutError('WARNING: zero length rope line!', false);
-    exit
-    end;
+        begin
+        //OutError('WARNING: zero length rope line!', false);
+        exit
+        end;
     eX:= 0;
     eY:= 0;
     dX:= X2 - X1;
@@ -101,44 +97,50 @@
         dX:= -dX
         end else sX:= dX;
 
-    if (dY > 0) then sY:= 1
+    if (dY > 0) then 
+        sY:= 1
     else
-    if (dY < 0) then
-        begin
-        sY:= -1;
-        dY:= -dY
-        end else sY:= dY;
-
-        if (dX > dY) then d:= dX
-                    else d:= dY;
-
-        x:= X1;
-        y:= Y1;
-
-        for i:= 0 to d do
+        if (dY < 0) then
             begin
-            inc(eX, dX);
-            inc(eY, dY);
-            b:= false;
-            if (eX > d) then
-                begin
-                dec(eX, d);
-                inc(x, sX);
-                b:= true
-                end;
-            if (eY > d) then
-                begin
-                dec(eY, d);
-                inc(y, sY);
-                b:= true
-                end;
-            if b then
-                begin
-                inc(roplen);
-                if (roplen mod 4) = 0 then DrawSprite(sprRopeNode, x - 2, y - 2, 0)
-                end
-        end
-    end;
+            sY:= -1;
+            dY:= -dY
+            end else 
+            sY:= dY;
+
+    if (dX > dY) then d:= dX
+                else d:= dY;
+
+    x:= X1;
+    y:= Y1;
+
+    for i:= 0 to d do
+        begin
+        inc(eX, dX);
+        inc(eY, dY);
+        b:= false;
+        if (eX > d) then
+            begin
+            dec(eX, d);
+            inc(x, sX);
+            b:= true
+            end;
+        if (eY > d) then
+            begin
+            dec(eY, d);
+            inc(y, sY);
+            b:= true
+            end;
+        if b then
+            begin
+            inc(roplen);
+            if (roplen mod 4) = 0 then DrawSprite(sprRopeNode, x - 2, y - 2, 0)
+            end
+    end
+end;
+
+procedure DrawRope(Gear: PGear);
+var roplen: LongInt;
+    i: Longword;
 begin
     if (cReducedQuality and rqSimpleRope) <> 0 then
         DrawRopeLinesRQ(Gear)
@@ -151,17 +153,17 @@
             while i < Pred(RopePoints.Count) do
                     begin
                     DrawRopeLine(hwRound(RopePoints.ar[i].X) + WorldDx, hwRound(RopePoints.ar[i].Y) + WorldDy,
-                                hwRound(RopePoints.ar[Succ(i)].X) + WorldDx, hwRound(RopePoints.ar[Succ(i)].Y) + WorldDy);
+                                hwRound(RopePoints.ar[Succ(i)].X) + WorldDx, hwRound(RopePoints.ar[Succ(i)].Y) + WorldDy, roplen);
                     inc(i)
                     end;
             DrawRopeLine(hwRound(RopePoints.ar[i].X) + WorldDx, hwRound(RopePoints.ar[i].Y) + WorldDy,
-                        hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy);
+                        hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, roplen);
             DrawRopeLine(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy,
-                        hwRound(Gear^.Hedgehog^.Gear^.X) + WorldDx, hwRound(Gear^.Hedgehog^.Gear^.Y) + WorldDy);
+                        hwRound(Gear^.Hedgehog^.Gear^.X) + WorldDx, hwRound(Gear^.Hedgehog^.Gear^.Y) + WorldDy, roplen);
             end else
             if Gear^.Elasticity.QWordValue > 0 then
             DrawRopeLine(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy,
-                        hwRound(Gear^.Hedgehog^.Gear^.X) + WorldDx, hwRound(Gear^.Hedgehog^.Gear^.Y) + WorldDy);
+                        hwRound(Gear^.Hedgehog^.Gear^.X) + WorldDx, hwRound(Gear^.Hedgehog^.Gear^.Y) + WorldDy, roplen);
         end;
 
 
@@ -197,7 +199,7 @@
     HH:= Gear^.Hedgehog;
     if HH^.Unplaced then exit;
     m:= 1;
-    if ((Gear^.State and gstHHHJump) <> 0) and not cArtillery then m:= -1;
+    if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then m:= -1;
     sx:= ox + 1; // this offset is very common
     sy:= oy - 3;
     sign:= hwSign(Gear^.dX);
@@ -542,7 +544,7 @@
             begin
             if (TWave(Gear^.Tag) < Low(TWave)) or (TWave(Gear^.Tag) > High(TWave)) then
                 begin
-                Gear^.State:= Gear^.State and not gstAnimation;
+                Gear^.State:= Gear^.State and (not gstAnimation);
                 end
             else
                 begin
@@ -805,7 +807,7 @@
 
     with HH^ do
         begin
-        if ((Gear^.State and not gstWinner) = 0)
+        if ((Gear^.State and (not gstWinner)) = 0)
             or ((Gear^.State = gstWait) and (Gear^.dY.QWordValue = 0))
             or (bShowFinger and ((Gear^.State and gstHHDriven) <> 0)) then
             begin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uGearsUtils.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,557 @@
+(*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2011 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *)
+
+{$INCLUDE "options.inc"}
+
+unit uGearsUtils;
+interface
+uses uTypes;
+
+procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord = $FFFFFFFF); 
+function  ModifyDamage(dmg: Longword; Gear: PGear): Longword;
+procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource);
+procedure spawnHealthTagForHH(HHGear: PGear; dmg: Longword);
+procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource);
+procedure CheckHHDamage(Gear: PGear);
+procedure CalcRotationDirAngle(Gear: PGear);
+procedure ResurrectHedgehog(gear: PGear);
+procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean = false);
+function  CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
+function  CheckGearsNear(mX, mY: LongInt; Kind: TGearsType; rX, rY: LongInt): PGear;
+
+
+implementation
+uses uFloat, uSound, uCollisions, uUtils, uConsts, uVisualGears, uAIMisc,
+    uVariables, uLandGraphics, uScript, uStats, uCaptions, uTeams, uStore,
+    uLocale, uTextures, uRenderUtils, uRandom, uGearsList, SDLh, uDebug;
+
+procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord);
+var Gear: PGear;
+    dmg, dmgRadius, dmgBase: LongInt;
+    fX, fY: hwFloat;
+    vg: PVisualGear;
+    i, cnt: LongInt;
+begin
+    if Radius > 4 then AddFileLog('Explosion: at (' + inttostr(x) + ',' + inttostr(y) + ')');
+    if Radius > 25 then KickFlakes(Radius, X, Y);
+
+    if ((Mask and EXPLNoGfx) = 0) then
+        begin
+        vg:= nil;
+        if Radius > 50 then vg:= AddVisualGear(X, Y, vgtBigExplosion)
+        else if Radius > 10 then vg:= AddVisualGear(X, Y, vgtExplosion);
+        if vg <> nil then
+            vg^.Tint:= Tint;
+        end;
+    if (Mask and EXPLAutoSound) <> 0 then PlaySound(sndExplosion);
+
+    if (Mask and EXPLAllDamageInRadius) = 0 then
+        dmgRadius:= Radius shl 1
+    else
+        dmgRadius:= Radius;
+    dmgBase:= dmgRadius + cHHRadius div 2;
+    fX:= int2hwFloat(X);
+    fY:= int2hwFloat(Y);
+    Gear:= GearsList;
+    while Gear <> nil do
+        begin
+        dmg:= 0;
+        //dmg:= dmgRadius  + cHHRadius div 2 - hwRound(Distance(Gear^.X - int2hwFloat(X), Gear^.Y - int2hwFloat(Y)));
+        //if (dmg > 1) and
+        if (Gear^.State and gstNoDamage) = 0 then
+            begin
+            case Gear^.Kind of
+                gtHedgehog,
+                    gtMine,
+                    gtBall,
+                    gtMelonPiece,
+                    gtGrenade,
+                    gtClusterBomb,
+                //    gtCluster, too game breaking I think
+                    gtSMine,
+                    gtCase,
+                    gtTarget,
+                    gtFlame,
+                    gtExplosives,
+                    gtStructure: begin
+    // Run the calcs only once we know we have a type that will need damage
+                            if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then
+                                dmg:= dmgBase - max(hwRound(Distance(Gear^.X - fX, Gear^.Y - fY)),Gear^.Radius);
+                            if dmg > 1 then
+                                begin
+                                dmg:= ModifyDamage(min(dmg div 2, Radius), Gear);
+                                //AddFileLog('Damage: ' + inttostr(dmg));
+                                if (Mask and EXPLNoDamage) = 0 then
+                                    begin
+                                    if not Gear^.Invulnerable then
+                                        ApplyDamage(Gear, AttackingHog, dmg, dsExplosion)
+                                    else
+                                        Gear^.State:= Gear^.State or gstWinner;
+                                    end;
+                                if ((Mask and EXPLDoNotTouchAny) = 0) and (((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog)) then
+                                    begin
+                                    DeleteCI(Gear);
+                                    if Gear^.Kind <> gtHedgehog then
+                                        begin
+                                        Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - fX)/Gear^.Density;
+                                        Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y - fY)/Gear^.Density;
+                                        end
+                                    else
+                                        begin
+                                        Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - fX);
+                                        Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y - fY);
+                                        end;
+
+                                    Gear^.State:= (Gear^.State or gstMoving) and (not gstLoser);
+                                    if not Gear^.Invulnerable then
+                                        Gear^.State:= (Gear^.State or gstMoving) and (not gstWinner);
+                                    Gear^.Active:= true;
+                                    if Gear^.Kind <> gtFlame then FollowGear:= Gear
+                                    end;
+                                if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (not Gear^.Invulnerable) then
+                                    Gear^.Hedgehog^.Effects[hePoisoned] := true;
+                                end;
+
+                            end;
+                    gtGrave: begin
+    // Run the calcs only once we know we have a type that will need damage
+                            if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then
+                                dmg:= dmgBase - hwRound(Distance(Gear^.X - fX, Gear^.Y - fY));
+                            if dmg > 1 then
+                                begin
+                                dmg:= ModifyDamage(min(dmg div 2, Radius), Gear);
+                                Gear^.dY:= - _0_004 * dmg;
+                                Gear^.Active:= true
+                                end
+                            end;
+                end;
+            end;
+        Gear:= Gear^.NextGear
+        end;
+
+    if (Mask and EXPLDontDraw) = 0 then
+        if (GameFlags and gfSolidLand) = 0 then
+            begin
+            cnt:= DrawExplosion(X, Y, Radius) div 1608; // approx 2 16x16 circles to erase per chunk
+            if (cnt > 0) and (SpritesData[sprChunk].Texture <> nil) then
+                for i:= 0 to cnt do
+                    AddVisualGear(X, Y, vgtChunk)
+            end;
+
+    uAIMisc.AwareOfExplosion(0, 0, 0)
+end;
+
+function ModifyDamage(dmg: Longword; Gear: PGear): Longword;
+var i: hwFloat;
+begin
+(* Invulnerability cannot be placed in here due to still needing kicks
+   Not without a new damage machine.
+   King check should be in here instead of ApplyDamage since Tiy wants them kicked less
+*)
+i:= _1;
+if (CurrentHedgehog <> nil) and CurrentHedgehog^.King then i:= _1_5;
+if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.King) then
+   ModifyDamage:= hwRound(_0_01 * cDamageModifier * dmg * i * cDamagePercent * _0_5)
+else
+   ModifyDamage:= hwRound(_0_01 * cDamageModifier * dmg * i * cDamagePercent)
+end;
+
+procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource);
+var s: shortstring;
+    vampDmg, tmpDmg, i: Longword;
+    vg: PVisualGear;
+begin
+  if Damage = 0 then exit; // nothing to apply
+
+    if (Gear^.Kind = gtHedgehog) then
+    begin
+    Gear^.LastDamage := AttackerHog;
+
+    Gear^.Hedgehog^.Team^.Clan^.Flawless:= false;
+    HHHurt(Gear^.Hedgehog, Source);
+    AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), Damage, Gear^.Hedgehog^.Team^.Clan^.Color);
+    tmpDmg:= min(Damage, max(0,Gear^.Health-Gear^.Damage));
+    if (Gear <> CurrentHedgehog^.Gear) and (CurrentHedgehog^.Gear <> nil) and (tmpDmg >= 1) then
+        begin
+        if cVampiric then
+            begin
+            vampDmg:= hwRound(int2hwFloat(tmpDmg)*_0_8);
+            if vampDmg >= 1 then
+                begin
+                // was considering pulsing on attack, Tiy thinks it should be permanent while in play
+                //CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstVampiric;
+                inc(CurrentHedgehog^.Gear^.Health,vampDmg);
+                str(vampDmg, s);
+                s:= '+' + s;
+                AddCaption(s, CurrentHedgehog^.Team^.Clan^.Color, capgrpAmmoinfo);
+                RenderHealth(CurrentHedgehog^);
+                RecountTeamHealth(CurrentHedgehog^.Team);
+                i:= 0;
+                while i < vampDmg do
+                    begin
+                    vg:= AddVisualGear(hwRound(CurrentHedgehog^.Gear^.X), hwRound(CurrentHedgehog^.Gear^.Y), vgtStraightShot);
+                    if vg <> nil then
+                        with vg^ do
+                            begin
+                            Tint:= $FF0000FF;
+                            State:= ord(sprHealth)
+                            end;
+                    inc(i, 5);
+                    end;
+                end
+            end;
+        if ((GameFlags and gfKarma) <> 0) and
+           ((GameFlags and gfInvulnerable) = 0) and
+           (not CurrentHedgehog^.Gear^.Invulnerable) then
+           begin // this cannot just use Damage or it interrupts shotgun and gets you called stupid
+           inc(CurrentHedgehog^.Gear^.Karma, tmpDmg);
+           CurrentHedgehog^.Gear^.LastDamage := CurrentHedgehog;
+           spawnHealthTagForHH(CurrentHedgehog^.Gear, tmpDmg);
+           end;
+        uStats.HedgehogDamaged(Gear, AttackerHog, Damage, false);    
+        end;
+    end else if Gear^.Kind <> gtStructure then // not gtHedgehog nor gtStructure
+        begin
+        Gear^.Hedgehog:= AttackerHog;
+        end;
+    inc(Gear^.Damage, Damage);
+    
+    ScriptCall('onGearDamage', Gear^.UID, Damage);
+end;
+
+procedure spawnHealthTagForHH(HHGear: PGear; dmg: Longword);
+var tag: PVisualGear;
+begin
+tag:= AddVisualGear(hwRound(HHGear^.X), hwRound(HHGear^.Y), vgtHealthTag, dmg);
+if (tag <> nil) then
+    tag^.Hedgehog:= HHGear^.Hedgehog; // the tag needs the tag to determine the text color
+AllInactive:= false;
+HHGear^.Active:= true;
+end;
+    
+procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource);
+begin
+if (Source = dsFall) or (Source = dsExplosion) then
+    case random(3) of
+        0: PlaySound(sndOoff1, Hedgehog^.Team^.voicepack);
+        1: PlaySound(sndOoff2, Hedgehog^.Team^.voicepack);
+        2: PlaySound(sndOoff3, Hedgehog^.Team^.voicepack);
+    end
+else if (Source = dsPoison) then
+    case random(2) of
+        0: PlaySound(sndPoisonCough, Hedgehog^.Team^.voicepack);
+        1: PlaySound(sndPoisonMoan, Hedgehog^.Team^.voicepack);
+    end
+else
+    case random(4) of
+        0: PlaySound(sndOw1, Hedgehog^.Team^.voicepack);
+        1: PlaySound(sndOw2, Hedgehog^.Team^.voicepack);
+        2: PlaySound(sndOw3, Hedgehog^.Team^.voicepack);
+        3: PlaySound(sndOw4, Hedgehog^.Team^.voicepack);
+    end
+end;
+
+procedure CheckHHDamage(Gear: PGear);
+var 
+    dmg: Longword;
+    i: LongInt;
+    particle: PVisualGear;
+begin
+    if _0_4 < Gear^.dY then
+        begin
+        dmg := ModifyDamage(1 + hwRound((hwAbs(Gear^.dY) - _0_4) * 70), Gear);
+        PlaySound(sndBump);
+        if dmg < 1 then exit;
+
+        for i:= min(12, (3 + dmg div 10)) downto 0 do
+            begin
+            particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
+            if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480);
+            end;
+
+        if (Gear^.Invulnerable) then exit;
+
+        //if _0_6 < Gear^.dY then
+        //    PlaySound(sndOw4, Gear^.Hedgehog^.Team^.voicepack)
+        //else
+        //    PlaySound(sndOw1, Gear^.Hedgehog^.Team^.voicepack);
+
+        if Gear^.LastDamage <> nil then
+            ApplyDamage(Gear, Gear^.LastDamage, dmg, dsFall)
+            else
+            ApplyDamage(Gear, CurrentHedgehog, dmg, dsFall);
+    end
+end;
+
+
+procedure CalcRotationDirAngle(Gear: PGear);
+var 
+    dAngle: real;
+begin
+    dAngle := (Gear^.dX.QWordValue + Gear^.dY.QWordValue) / $80000000;
+    if not Gear^.dX.isNegative then
+        Gear^.DirAngle := Gear^.DirAngle + dAngle
+    else
+        Gear^.DirAngle := Gear^.DirAngle - dAngle;
+
+    if Gear^.DirAngle < 0 then Gear^.DirAngle := Gear^.DirAngle + 360
+    else if 360 < Gear^.DirAngle then Gear^.DirAngle := Gear^.DirAngle - 360
+end;
+
+function CheckGearDrowning(Gear: PGear): boolean;
+var 
+    skipSpeed, skipAngle, skipDecay: hwFloat;
+    i, maxDrops, X, Y: LongInt;
+    vdX, vdY: real;
+    particle: PVisualGear;
+    isSubmersible: boolean;
+begin
+    // probably needs tweaking. might need to be in a case statement based upon gear type
+    Y:= hwRound(Gear^.Y);
+    if cWaterLine < Y + Gear^.Radius then
+        begin
+        isSubmersible:= (Gear = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.AmmoType = amJetpack);
+        skipSpeed := _0_25;
+        skipAngle := _1_9;
+        skipDecay := _0_87;
+        X:= hwRound(Gear^.X);
+        vdX:= hwFloat2Float(Gear^.dX);
+        vdY:= hwFloat2Float(Gear^.dY);
+        // this could perhaps be a tiny bit higher.
+        if  (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed) and
+           (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)) then
+            begin
+            Gear^.dY.isNegative := true;
+            Gear^.dY := Gear^.dY * skipDecay;
+            Gear^.dX := Gear^.dX * skipDecay;
+            CheckGearDrowning := false;
+            PlaySound(sndSkip)
+            end
+        else
+            begin
+            if not isSubmersible then
+                begin
+                CheckGearDrowning := true;
+                Gear^.State := gstDrowning;
+                Gear^.RenderTimer := false;
+                if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot) and 
+                   (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) then
+                    if Gear^.Kind = gtHedgehog then
+                        begin
+                        if Gear^.Hedgehog^.Effects[heResurrectable] then
+                            ResurrectHedgehog(Gear)
+                        else
+                            begin
+                            Gear^.doStep := @doStepDrowningGear;
+                            Gear^.State := Gear^.State and (not gstHHDriven);
+                            AddCaption(Format(GetEventString(eidDrowned), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
+                            end
+                        end
+                    else Gear^.doStep := @doStepDrowningGear;
+                    if Gear^.Kind = gtFlake then exit // skip splashes 
+                end;
+            if ((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius)) or
+               (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and ((CurAmmoGear^.Pos = 0) and (CurAmmoGear^.dY < _0_01))) then
+                // don't play splash if they are already way past the surface
+                PlaySound(sndSplash)
+            end;
+
+        if ((cReducedQuality and rqPlainSplash) = 0) and 
+           (((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius)) or
+             (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and ((CurAmmoGear^.Pos = 0) and (CurAmmoGear^.dY < _0_01)))) then
+            begin
+            AddVisualGear(X, cWaterLine, vgtSplash);
+
+            maxDrops := (Gear^.Radius div 2) + round(vdX * Gear^.Radius * 2) + round(vdY * Gear^.Radius * 2);
+            for i:= max(maxDrops div 3, min(32, Random(maxDrops))) downto 0 do
+                begin
+                particle := AddVisualGear(X - 3 + Random(6), cWaterLine, vgtDroplet);
+                if particle <> nil then
+                    begin
+                    particle^.dX := particle^.dX - vdX / 10;
+                    particle^.dY := particle^.dY - vdY / 5;
+                    end
+                end
+            end;
+        if isSubmersible and (CurAmmoGear^.Pos = 0) then CurAmmoGear^.Pos := 1000
+        end
+    else
+        CheckGearDrowning := false;
+end;
+
+
+procedure ResurrectHedgehog(gear: PGear);
+var tempTeam : PTeam;
+begin
+    AttackBar:= 0;
+    gear^.dX := _0;
+    gear^.dY := _0;
+    gear^.Damage := 0;
+    gear^.Health := gear^.Hedgehog^.InitialHealth;
+    gear^.Hedgehog^.Effects[hePoisoned] := false;
+    if not CurrentHedgehog^.Effects[heResurrectable] then
+        with CurrentHedgehog^ do 
+            begin
+            inc(Team^.stats.AIKills);
+            FreeTexture(Team^.AIKillsTex);
+            Team^.AIKillsTex := RenderStringTex(inttostr(Team^.stats.AIKills), Team^.Clan^.Color, fnt16);
+            end;
+    tempTeam := gear^.Hedgehog^.Team;
+    DeleteCI(gear);
+    FindPlace(gear, false, 0, LAND_WIDTH, true); 
+    if gear <> nil then begin
+        RenderHealth(gear^.Hedgehog^);
+        ScriptCall('onGearResurrect', gear^.uid);
+        gear^.State := gstWait;
+    end;
+    RecountTeamHealth(tempTeam);
+end;
+
+function CountNonZeroz(x, y, r, c: LongInt): LongInt;
+var i: LongInt;
+    count: LongInt = 0;
+begin
+if (y and LAND_HEIGHT_MASK) = 0 then
+    for i:= max(x - r, 0) to min(x + r, LAND_WIDTH - 4) do
+        if Land[y, i] <> 0 then
+            begin
+            inc(count);
+            if count = c then exit(count)
+            end;
+CountNonZeroz:= count;
+end;
+
+procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean);
+var x: LongInt;
+    y, sy: LongInt;
+    ar: array[0..511] of TPoint;
+    ar2: array[0..1023] of TPoint;
+    cnt, cnt2: Longword;
+    delta: LongInt;
+    reallySkip, tryAgain: boolean;
+begin
+reallySkip:= false; // try not skipping proximity at first
+tryAgain:= true;
+while tryAgain do
+    begin
+    delta:= 250;
+    cnt2:= 0;
+    repeat
+        x:= Left + LongInt(GetRandom(Delta));
+        repeat
+            inc(x, Delta);
+            cnt:= 0;
+            y:= min(1024, topY) - 2 * Gear^.Radius;
+            while y < cWaterLine do
+                begin
+                repeat
+                    inc(y, 2);
+                until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) = 0);
+
+                sy:= y;
+
+                repeat
+                    inc(y);
+                until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) <> 0);
+
+                if (y - sy > Gear^.Radius * 2) and
+                   (((Gear^.Kind = gtExplosives)
+                       and (y < cWaterLine)
+                       and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 60, 60) = nil))
+                       and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1) > Gear^.Radius))
+                   or
+                     ((Gear^.Kind <> gtExplosives)
+                       and (y < cWaterLine)
+                       and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 110, 110) = nil)))) then
+                    begin
+                    ar[cnt].X:= x;
+                    if withFall then ar[cnt].Y:= sy + Gear^.Radius
+                                else ar[cnt].Y:= y - Gear^.Radius;
+                    inc(cnt)
+                    end;
+
+                inc(y, 45)
+                end;
+
+            if cnt > 0 then
+                with ar[GetRandom(cnt)] do
+                    begin
+                    ar2[cnt2].x:= x;
+                    ar2[cnt2].y:= y;
+                    inc(cnt2)
+                    end
+        until (x + Delta > Right);
+
+        dec(Delta, 60)
+    until (cnt2 > 0) or (Delta < 70);
+    if (cnt2 = 0) and skipProximity and (not reallySkip) then tryAgain:= true
+    else tryAgain:= false;
+    reallySkip:= true;
+    end;
+
+if cnt2 > 0 then
+    with ar2[GetRandom(cnt2)] do
+        begin
+        Gear^.X:= int2hwFloat(x);
+        Gear^.Y:= int2hwFloat(y);
+        AddFileLog('Assigned Gear coordinates (' + inttostr(x) + ',' + inttostr(y) + ')');
+        end
+    else
+    begin
+    OutError('Can''t find place for Gear', false);
+    if Gear^.Kind = gtHedgehog then Gear^.Hedgehog^.Effects[heResurrectable] := false;
+    DeleteGear(Gear);
+    Gear:= nil
+    end
+end;
+
+function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
+var t: PGear;
+begin
+t:= GearsList;
+rX:= sqr(rX);
+rY:= sqr(rY);
+
+while t <> nil do
+    begin
+    if (t <> Gear) and (t^.Kind = Kind) then
+        if not((hwSqr(Gear^.X - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1) then
+        exit(t);
+    t:= t^.NextGear
+    end;
+
+CheckGearNear:= nil
+end;
+
+
+function CheckGearsNear(mX, mY: LongInt; Kind: TGearsType; rX, rY: LongInt): PGear;
+var t: PGear;
+begin
+t:= GearsList;
+rX:= sqr(rX);
+rY:= sqr(rY);
+while t <> nil do
+    begin
+    if t^.Kind in Kind then
+        if not (hwSqr(int2hwFloat(mX) - t^.X) / rX + hwSqr(int2hwFloat(mY) - t^.Y) / rY > _1) then
+            exit(t);
+    t:= t^.NextGear
+    end;
+CheckGearsNear:= nil
+end;
+end.
--- a/hedgewars/uIO.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uIO.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -142,8 +142,7 @@
 procedure IPCCheckSock;
 const ss: shortstring = '';
 var i: LongInt;
-    buf: array[0..255] of byte;
-    s: shortstring absolute buf;
+    s: shortstring;
 begin
 if IPCSock = nil then
    exit;
@@ -153,10 +152,10 @@
 
 while SDLNet_CheckSockets(fds, 0) > 0 do
     begin
-    i:= SDLNet_TCP_Recv(IPCSock, @buf[1], 255 - Length(ss));
+    i:= SDLNet_TCP_Recv(IPCSock, @s[1], 255 - Length(ss));
     if i > 0 then
         begin
-        buf[0]:= i;
+        s[0]:= char(i);
         ss:= ss + s;
         while (Length(ss) > 1) and (Length(ss) > byte(ss[1])) do
             begin
@@ -171,8 +170,7 @@
 var f: file;
     ss: shortstring = '';
     i: LongInt;
-    buf: array[0..255] of byte;
-    s: shortstring absolute buf;
+    s: shortstring;
 begin
 
 // set RDNLY on file open
@@ -184,12 +182,12 @@
 tryDo(IOResult = 0, 'Error opening file ' + fileName, true);
 
 i:= 0; // avoid compiler hints
-buf[0]:= 0;
+s[0]:= #0;
 repeat
-    BlockRead(f, buf[1], 255 - Length(ss), i);
+    BlockRead(f, s[1], 255 - Length(ss), i);
     if i > 0 then
         begin
-        buf[0]:= i;
+        s[0]:= char(i);
         ss:= ss + s;
         while (Length(ss) > 1)and(Length(ss) > byte(ss[1])) do
             begin
@@ -315,7 +313,7 @@
             end;
         'b': begin
             s:= copy(headcmd^.str, 2, Pred(headcmd^.len));
-            ParseCommand('chatmsg '#4 + s, true);
+            ParseCommand('chatmsg ' + #4 + s, true);
             WriteLnToConsole(s)
             end;
 // TODO: deprecate 'F'
--- a/hedgewars/uKeys.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uKeys.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -329,6 +329,7 @@
 {$ENDIF}
 
 for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+IntToStr(i);
+for i:= 1 to 5  do DefaultBinds[KeyNameToCode(IntToStr(i))]:= 'timer '+IntToStr(i);
 
 SetDefaultBinds();
 end;
--- a/hedgewars/uLand.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uLand.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -22,12 +22,6 @@
 interface
 uses SDLh, uLandTemplates, uFloat, uConsts, GLunit, uTypes;
 
-type direction = record x, y: LongInt; end;
-const DIR_N: direction = (x: 0; y: -1);
-    DIR_E: direction = (x: 1; y: 0);
-    DIR_S: direction = (x: 0; y: 1);
-    DIR_W: direction = (x: -1; y: 0);
-
 procedure initModule;
 procedure freeModule;
 procedure DrawBottomBorder;
@@ -36,248 +30,9 @@
 
 implementation
 uses uConsole, uStore, uRandom, uLandObjects, uIO, uLandTexture, sysutils,
-     uVariables, uUtils, uCommands, Adler32, uDebug, uLandPainted, uTextures;
-
-operator=(const a, b: direction) c: Boolean;
-begin
-    c := (a.x = b.x) and (a.y = b.y);
-end;
-
-type TPixAr = record
-              Count: Longword;
-              ar: array[0..Pred(cMaxEdgePoints)] of TPoint;
-              end;
-
-procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword);
-var
-  eX, eY, dX, dY: LongInt;
-  i, sX, sY, x, y, d: LongInt;
-begin
-eX:= 0;
-eY:= 0;
-dX:= X2 - X1;
-dY:= Y2 - Y1;
-
-if (dX > 0) then sX:= 1
-else
-  if (dX < 0) then
-     begin
-     sX:= -1;
-     dX:= -dX
-     end else sX:= dX;
-
-if (dY > 0) then sY:= 1
-  else
-  if (dY < 0) then
-     begin
-     sY:= -1;
-     dY:= -dY
-     end else sY:= dY;
-
-if (dX > dY) then d:= dX
-             else d:= dY;
-
-x:= X1;
-y:= Y1;
-
-for i:= 0 to d do
-    begin
-    inc(eX, dX);
-    inc(eY, dY);
-    if (eX > d) then
-       begin
-       dec(eX, d);
-       inc(x, sX);
-       end;
-    if (eY > d) then
-       begin
-       dec(eY, d);
-       inc(y, sY);
-       end;
-
-    if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then
-       Land[y, x]:= Color;
-    end
-end;
-
-procedure DrawEdge(var pa: TPixAr; Color: Longword);
-var i: LongInt;
-begin
-i:= 0;
-with pa do
-while i < LongInt(Count) - 1 do
-    if (ar[i + 1].X = NTPX) then inc(i, 2)
-       else begin
-       DrawLine(ar[i].x, ar[i].y, ar[i + 1].x, ar[i + 1].y, Color);
-       inc(i)
-       end
-end;
-
-procedure Vector(p1, p2, p3: TPoint; var Vx, Vy: hwFloat);
-var d1, d2, d: hwFloat;
-begin
-Vx:= int2hwFloat(p1.X - p3.X);
-Vy:= int2hwFloat(p1.Y - p3.Y);
-d:= DistanceI(p2.X - p1.X, p2.Y - p1.Y);
-d1:= DistanceI(p2.X - p3.X, p2.Y - p3.Y);
-d2:= Distance(Vx, Vy);
-if d1 < d then d:= d1;
-if d2 < d then d:= d2;
-d:= d * _1div3;
-if d2.QWordValue = 0 then
-   begin
-   Vx:= _0;
-   Vy:= _0
-   end else
-   begin
-   d2:= _1 / d2;
-   Vx:= Vx * d2;
-   Vy:= Vy * d2;
-
-   Vx:= Vx * d;
-   Vy:= Vy * d
-   end
-end;
+     uVariables, uUtils, uCommands, Adler32, uDebug, uLandPainted, uTextures,
+     uLandGenMaze, uLandOutline;
 
-procedure AddLoopPoints(var pa, opa: TPixAr; StartI, EndI: LongInt; Delta: hwFloat);
-var i, pi, ni: LongInt;
-    NVx, NVy, PVx, PVy: hwFloat;
-    x1, x2, y1, y2: LongInt;
-    tsq, tcb, t, r1, r2, r3, cx1, cx2, cy1, cy2: hwFloat;
-    X, Y: LongInt;
-begin
-pi:= EndI;
-i:= StartI;
-ni:= Succ(StartI);
-{$HINTS OFF}
-Vector(opa.ar[pi], opa.ar[i], opa.ar[ni], NVx, NVy);
-{$HINTS ON}
-repeat
-    inc(pi);
-    if pi > EndI then pi:= StartI;
-    inc(i);
-    if i > EndI then i:= StartI;
-    inc(ni);
-    if ni > EndI then ni:= StartI;
-    PVx:= NVx;
-    PVy:= NVy;
-    Vector(opa.ar[pi], opa.ar[i], opa.ar[ni], NVx, NVy);
-
-    x1:= opa.ar[pi].x;
-    y1:= opa.ar[pi].y;
-    x2:= opa.ar[i].x;
-    y2:= opa.ar[i].y;
-    cx1:= int2hwFloat(x1) - PVx;
-    cy1:= int2hwFloat(y1) - PVy;
-    cx2:= int2hwFloat(x2) + NVx;
-    cy2:= int2hwFloat(y2) + NVy;
-    t:= _0;
-    while t.Round = 0 do
-          begin
-          tsq:= t * t;
-          tcb:= tsq * t;
-          r1:= (_1 - t*3 + tsq*3 - tcb);
-          r2:= (     t*3 - tsq*6 + tcb*3);
-          r3:= (           tsq*3 - tcb*3);
-          X:= hwRound(r1 * x1 + r2 * cx1 + r3 * cx2 + tcb * x2);
-          Y:= hwRound(r1 * y1 + r2 * cy1 + r3 * cy2 + tcb * y2);
-          t:= t + Delta;
-          pa.ar[pa.Count].x:= X;
-          pa.ar[pa.Count].y:= Y;
-          inc(pa.Count);
-          TryDo(pa.Count <= cMaxEdgePoints, 'Edge points overflow', true)
-          end;
-until i = StartI;
-pa.ar[pa.Count].x:= opa.ar[StartI].X;
-pa.ar[pa.Count].y:= opa.ar[StartI].Y;
-inc(pa.Count)
-end;
-
-procedure BezierizeEdge(var pa: TPixAr; Delta: hwFloat);
-var i, StartLoop: LongInt;
-    opa: TPixAr;
-begin
-opa:= pa;
-pa.Count:= 0;
-i:= 0;
-StartLoop:= 0;
-while i < LongInt(opa.Count) do
-    if (opa.ar[i + 1].X = NTPX) then
-       begin
-       AddLoopPoints(pa, opa, StartLoop, i, Delta);
-       inc(i, 2);
-       StartLoop:= i;
-       pa.ar[pa.Count].X:= NTPX;
-       pa.ar[pa.Count].Y:= 0;
-       inc(pa.Count);
-       end else inc(i)
-end;
-
-procedure FillLand(x, y: LongInt);
-var Stack: record
-           Count: Longword;
-           points: array[0..8192] of record
-                                     xl, xr, y, dir: LongInt;
-                                     end
-           end;
-
-    procedure Push(_xl, _xr, _y, _dir: LongInt);
-    begin
-    TryDo(Stack.Count <= 8192, 'FillLand: stack overflow', true);
-    _y:= _y + _dir;
-    if (_y < 0) or (_y >= LAND_HEIGHT) then exit;
-    with Stack.points[Stack.Count] do
-         begin
-         xl:= _xl;
-         xr:= _xr;
-         y:= _y;
-         dir:= _dir
-         end;
-    inc(Stack.Count)
-    end;
-
-    procedure Pop(var _xl, _xr, _y, _dir: LongInt);
-    begin
-    dec(Stack.Count);
-    with Stack.points[Stack.Count] do
-         begin
-         _xl:= xl;
-         _xr:= xr;
-         _y:= y;
-         _dir:= dir
-         end
-    end;
-
-var xl, xr, dir: LongInt;
-begin
-Stack.Count:= 0;
-xl:= x - 1;
-xr:= x;
-Push(xl, xr, y, -1);
-Push(xl, xr, y,  1);
-dir:= 0;
-while Stack.Count > 0 do
-      begin
-      Pop(xl, xr, y, dir);
-      while (xl > 0) and (Land[y, xl] <> 0) do dec(xl);
-      while (xr < LAND_WIDTH - 1) and (Land[y, xr] <> 0) do inc(xr);
-      while (xl < xr) do
-            begin
-            while (xl <= xr) and (Land[y, xl] = 0) do inc(xl);
-            x:= xl;
-            while (xl <= xr) and (Land[y, xl] <> 0) do
-                  begin
-                  Land[y, xl]:= 0;
-                  inc(xl)
-                  end;
-            if x < xl then
-               begin
-               Push(x, Pred(xl), y, dir);
-               Push(x, Pred(xl), y,-dir);
-               end;
-            end;
-      end;
-end;
 
 procedure ColorizeLand(Surface: PSDL_Surface);
 var tmpsurf: PSDL_Surface;
@@ -417,84 +172,6 @@
      end
 end;
 
-function CheckIntersect(V1, V2, V3, V4: TPoint): boolean;
-var c1, c2, dm: LongInt;
-begin
-dm:= (V4.y - V3.y) * (V2.x - V1.x) - (V4.x - V3.x) * (V2.y - V1.y);
-c1:= (V4.x - V3.x) * (V1.y - V3.y) - (V4.y - V3.y) * (V1.x - V3.x);
-if dm = 0 then exit(false);
-
-c2:= (V2.x - V3.x) * (V1.y - V3.y) - (V2.y - V3.y) * (V1.x - V3.x);
-if dm > 0 then
-   begin
-   if (c1 < 0) or (c1 > dm) then exit(false);
-   if (c2 < 0) or (c2 > dm) then exit(false)
-   end else
-   begin
-   if (c1 > 0) or (c1 < dm) then exit(false);
-   if (c2 > 0) or (c2 < dm) then exit(false)
-   end;
-
-//AddFileLog('1  (' + inttostr(V1.x) + ',' + inttostr(V1.y) + ')x(' + inttostr(V2.x) + ',' + inttostr(V2.y) + ')');
-//AddFileLog('2  (' + inttostr(V3.x) + ',' + inttostr(V3.y) + ')x(' + inttostr(V4.x) + ',' + inttostr(V4.y) + ')');
-CheckIntersect:= true
-end;
-
-function CheckSelfIntersect(var pa: TPixAr; ind: Longword): boolean;
-var i: Longword;
-begin
-if (ind <= 0) or (ind >= Pred(pa.Count)) then exit(false);
-for i:= 1 to pa.Count - 3 do
-    if (i <= ind - 1) or (i >= ind + 2) then
-      begin
-      if (i <> ind - 1) and
-         CheckIntersect(pa.ar[ind], pa.ar[ind - 1], pa.ar[i], pa.ar[i - 1]) then exit(true);
-      if (i <> ind + 2) and
-         CheckIntersect(pa.ar[ind], pa.ar[ind + 1], pa.ar[i], pa.ar[i - 1]) then exit(true);
-      end;
-CheckSelfIntersect:= false
-end;
-
-procedure RandomizePoints(var pa: TPixAr);
-const cEdge = 55;
-      cMinDist = 8;
-var radz: array[0..Pred(cMaxEdgePoints)] of LongInt;
-    i, k, dist, px, py: LongInt;
-begin
-for i:= 0 to Pred(pa.Count) do
-  begin
-  radz[i]:= 0;
-  with pa.ar[i] do
-    if x <> NTPX then
-      begin
-      radz[i]:= Min(Max(x - cEdge, 0), Max(LAND_WIDTH - cEdge - x, 0));
-      radz[i]:= Min(radz[i], Min(Max(y - cEdge, 0), Max(LAND_HEIGHT - cEdge - y, 0)));
-      if radz[i] > 0 then
-        for k:= 0 to Pred(i) do
-          begin
-          dist:= Max(abs(x - pa.ar[k].x), abs(y - pa.ar[k].y));
-          radz[k]:= Max(0, Min((dist - cMinDist) div 2, radz[k]));
-          radz[i]:= Max(0, Min(dist - radz[k] - cMinDist, radz[i]))
-        end
-      end;
-  end;
-
-for i:= 0 to Pred(pa.Count) do
-  with pa.ar[i] do
-    if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then
-      begin
-      px:= x;
-      py:= y;
-      x:= x + LongInt(GetRandom(7) - 3) * (radz[i] * 5 div 7) div 3;
-      y:= y + LongInt(GetRandom(7) - 3) * (radz[i] * 5 div 7) div 3;
-      if CheckSelfIntersect(pa, i) then
-         begin
-         x:= px;
-         y:= py
-         end;
-      end
-end;
-
 
 procedure GenBlank(var Template: TEdgeTemplate);
 var pa: TPixAr;
@@ -610,437 +287,6 @@
     SDL_UnlockSurface(Surface);
 end;
 
-procedure GenMaze;
-const small_cell_size = 128;
-    medium_cell_size = 192;
-    large_cell_size = 256;
-    braidness = 10;
-
-var x, y: LongInt;
-    cellsize: LongInt; //selected by the user in the gui
-    seen_cells_x, seen_cells_y: LongInt; //number of cells that can be visited by the generator, that is every second cell in x and y direction. the cells between there are walls that will be removed when we move from one cell to another
-    num_edges_x, num_edges_y: LongInt; //number of resulting edges that need to be vertexificated
-    num_cells_x, num_cells_y: LongInt; //actual number of cells, depending on cell size
-    seen_list: array of array of LongInt;
-    xwalls: array of array of Boolean;
-    ywalls: array of array of Boolean;
-    x_edge_list: array of array of Boolean;
-    y_edge_list: array of array of Boolean;
-    maze: array of array of Boolean;
-    pa: TPixAr;
-    num_vertices: LongInt;
-    off_y: LongInt;
-    num_steps: LongInt;
-    current_step: LongInt;
-    step_done: array of Boolean;
-    done: Boolean;
-    last_cell: array of record x, y: LongInt; end;
-    came_from: array of array of record x, y: LongInt; end;
-    came_from_pos: array of LongInt;
-    maze_inverted: Boolean;
-
-function when_seen(x: LongInt; y: LongInt): LongInt;
-begin
-if (x < 0) or (x >= seen_cells_x) or (y < 0) or (y >= seen_cells_y) then
-    when_seen := current_step
-else
-    when_seen := seen_list[x, y];
-end;
-
-function is_x_edge(x, y: LongInt): Boolean;
-begin
-if (x < 0) or (x > num_edges_x) or (y < 0) or (y > num_cells_y) then
-    is_x_edge := false
-else
-    is_x_edge := x_edge_list[x, y];
-end;
-
-function is_y_edge(x, y: LongInt): Boolean;
-begin
-if (x < 0) or (x > num_cells_x) or (y < 0) or (y > num_edges_y) then
-    is_y_edge := false
-else
-    is_y_edge := y_edge_list[x, y];
-end;
-
-procedure see_cell;
-var dir: direction;
-    tries: LongInt;
-    x, y: LongInt;
-    found_cell: Boolean;
-    next_dir_clockwise: Boolean;
-
-begin
-x := last_cell[current_step].x;
-y := last_cell[current_step].y;
-seen_list[x, y] := current_step;
-case GetRandom(4) of
-    0: dir := DIR_N;
-    1: dir := DIR_E;
-    2: dir := DIR_S;
-    3: dir := DIR_W;
-end;
-tries := 0;
-found_cell := false;
-if getrandom(2) = 1 then next_dir_clockwise := true
-else next_dir_clockwise := false;
-
-while (tries < 5) and not found_cell do
-begin
-    if when_seen(x + dir.x, y + dir.y) = current_step then //we are seeing ourselves, try another direction
-    begin
-        //we have already seen the target cell, decide if we should remove the wall anyway
-        //(or put a wall there if maze_inverted, but we are not doing that right now)
-        if not maze_inverted and (GetRandom(braidness) = 0) then
-        //or just warn that inverted+braid+indestructible terrain != good idea
-        begin
-            case dir.x of
-                -1: if x > 0 then ywalls[x-1, y] := false;
-                1: if x < seen_cells_x - 1 then ywalls[x, y] := false;
-            end;
-            case dir.y of
-                -1: if y > 0 then xwalls[x, y-1] := false;
-                1: if y < seen_cells_y - 1 then xwalls[x, y] := false;
-            end;
-        end;
-        if next_dir_clockwise then
-        begin
-            if dir = DIR_N then
-                dir := DIR_E
-            else if dir = DIR_E then
-                dir := DIR_S
-            else if dir = DIR_S then
-                dir := DIR_W
-            else
-                dir := DIR_N;
-        end
-        else
-        begin
-            if dir = DIR_N then
-                dir := DIR_W
-            else if dir = DIR_E then
-                dir := DIR_N
-            else if dir = DIR_S then
-                dir := DIR_E
-            else
-                dir := DIR_S;
-        end
-    end
-    else if when_seen(x + dir.x, y + dir.y) = -1 then //cell was not seen yet, go there
-    begin
-        case dir.y of
-            -1: xwalls[x, y-1] := false;
-            1: xwalls[x, y] := false;
-        end;
-        case dir.x of
-            -1: ywalls[x-1, y] := false;
-            1: ywalls[x, y] := false;
-        end;
-        last_cell[current_step].x := x+dir.x;
-        last_cell[current_step].y := y+dir.y;
-        came_from_pos[current_step] := came_from_pos[current_step] + 1;
-        came_from[current_step, came_from_pos[current_step]].x := x;
-        came_from[current_step, came_from_pos[current_step]].y := y;
-        found_cell := true;
-    end
-    else //we are seeing someone else, quit
-    begin
-        step_done[current_step] := true;
-        found_cell := true;
-    end;
-
-    tries := tries + 1;
-end;
-if not found_cell then
-begin
-    last_cell[current_step].x := came_from[current_step, came_from_pos[current_step]].x;
-    last_cell[current_step].y := came_from[current_step, came_from_pos[current_step]].y;
-    came_from_pos[current_step] := came_from_pos[current_step] - 1;
-    if came_from_pos[current_step] >= 0 then see_cell
-    else step_done[current_step] := true;
-end;
-end;
-
-procedure add_vertex(x, y: LongInt);
-var tmp_x, tmp_y: LongInt;
-begin
-if x = NTPX then
-begin
-    if pa.ar[num_vertices - 6].x = NTPX then
-    begin
-        num_vertices := num_vertices - 6;
-    end
-    else
-    begin
-        pa.ar[num_vertices].x := NTPX;
-        pa.ar[num_vertices].y := 0;
-    end
-end
-else
-begin
-    if maze_inverted or (x mod 2 = 0) then tmp_x := cellsize
-    else tmp_x := cellsize * 2 div 3;
-    if maze_inverted or (y mod 2 = 0) then tmp_y := cellsize
-    else tmp_y := cellsize * 2 div 3;
-
-    pa.ar[num_vertices].x := (x-1)*cellsize + tmp_x;
-    pa.ar[num_vertices].y := (y-1)*cellsize + tmp_y + off_y;
-end;
-num_vertices := num_vertices + 1;
-end;
-
-procedure add_edge(x, y: LongInt; dir: direction);
-var i: LongInt;
-begin
-if dir = DIR_N then
-begin
-    dir := DIR_W
-end
-else if dir = DIR_E then
-begin
-    dir := DIR_N
-end
-else if dir = DIR_S then
-begin
-    dir := DIR_E
-end
-else
-begin
-    dir := DIR_S;
-end;
-
-for i := 0 to 3 do
-begin
-        if dir = DIR_N then
-            dir := DIR_E
-        else if dir = DIR_E then
-            dir := DIR_S
-        else if dir = DIR_S then
-            dir := DIR_W
-        else
-            dir := DIR_N;
-
-    if (dir = DIR_N) and is_x_edge(x, y) then
-        begin
-            x_edge_list[x, y] := false;
-            add_vertex(x+1, y);
-            add_edge(x, y-1, DIR_N);
-            break;
-        end;
-
-    if (dir = DIR_E) and is_y_edge(x+1, y) then
-        begin
-            y_edge_list[x+1, y] := false;
-            add_vertex(x+2, y+1);
-            add_edge(x+1, y, DIR_E);
-            break;
-        end;
-
-    if (dir = DIR_S) and is_x_edge(x, y+1) then
-        begin
-            x_edge_list[x, y+1] := false;
-            add_vertex(x+1, y+2);
-            add_edge(x, y+1, DIR_S);
-            break;
-        end;
-
-    if (dir = DIR_W) and is_y_edge(x, y) then
-        begin
-            y_edge_list[x, y] := false;
-            add_vertex(x, y+1);
-            add_edge(x-1, y, DIR_W);
-            break;
-        end;
-end;
-
-end;
-
-begin
-case cTemplateFilter of
-    0: begin
-        cellsize := small_cell_size;
-        maze_inverted := false;
-    end;
-    1: begin
-        cellsize := medium_cell_size;
-        maze_inverted := false;
-    end;
-    2: begin
-        cellsize := large_cell_size;
-        maze_inverted := false;
-    end;
-    3: begin
-        cellsize := small_cell_size;
-        maze_inverted := true;
-    end;
-    4: begin
-        cellsize := medium_cell_size;
-        maze_inverted := true;
-    end;
-    5: begin
-        cellsize := large_cell_size;
-        maze_inverted := true;
-    end;
-end;
-
-num_cells_x := LAND_WIDTH div cellsize;
-if not odd(num_cells_x) then num_cells_x := num_cells_x - 1; //needs to be odd
-num_cells_y := LAND_HEIGHT div cellsize;
-if not odd(num_cells_y) then num_cells_y := num_cells_y - 1;
-num_edges_x := num_cells_x - 1;
-num_edges_y := num_cells_y - 1;
-seen_cells_x := num_cells_x div 2;
-seen_cells_y := num_cells_y div 2;
-
-if maze_inverted then
-    num_steps := 3 //TODO randomize, between 3 and 5?
-else
-    num_steps := 1;
-SetLength(step_done, num_steps);
-SetLength(last_cell, num_steps);
-SetLength(came_from_pos, num_steps);
-SetLength(came_from, num_steps, num_cells_x*num_cells_y);
-done := false;
-for current_step := 0 to num_steps - 1 do
-    step_done[current_step] := false;
-    came_from_pos[current_step] := 0;
-current_step := 0;
-
-SetLength(seen_list, seen_cells_x, seen_cells_y);
-SetLength(xwalls, seen_cells_x, seen_cells_y - 1);
-SetLength(ywalls, seen_cells_x - 1, seen_cells_y);
-SetLength(x_edge_list, num_edges_x, num_cells_y);
-SetLength(y_edge_list, num_cells_x, num_edges_y);
-SetLength(maze, num_cells_x, num_cells_y);
-
-num_vertices := 0;
-
-playHeight := num_cells_y * cellsize;
-playWidth := num_cells_x * cellsize;
-off_y := LAND_HEIGHT - playHeight;
-
-for x := 0 to playWidth do
-    for y := 0 to off_y - 1 do
-        Land[y, x] := 0;
-
-for x := 0 to playWidth do
-    for y := off_y to LAND_HEIGHT - 1 do
-        Land[y, x] := lfBasic;
-
-for y := 0 to num_cells_y - 1 do
-    for x := 0 to num_cells_x - 1 do
-        maze[x, y] := false;
-
-for x := 0 to seen_cells_x - 1 do
-    for y := 0 to seen_cells_y - 2 do
-        xwalls[x, y] := true;
-
-for x := 0 to seen_cells_x - 2 do
-    for y := 0 to seen_cells_y - 1 do
-        ywalls[x, y] := true;
-
-for x := 0 to seen_cells_x - 1 do
-    for y := 0 to seen_cells_y - 1 do
-        seen_list[x, y] := -1;
-
-for x := 0 to num_edges_x - 1 do
-    for y := 0 to num_cells_y - 1 do
-        x_edge_list[x, y] := false;
-
-for x := 0 to num_cells_x - 1 do
-    for y := 0 to num_edges_y - 1 do
-        y_edge_list[x, y] := false;
-
-for current_step := 0 to num_steps-1 do
-begin
-    x := GetRandom(seen_cells_x - 1) div LongWord(num_steps);
-    last_cell[current_step].x := x + current_step * seen_cells_x div num_steps;
-    last_cell[current_step].y := GetRandom(seen_cells_y);
-end;
-
-while not done do
-begin
-    done := true;
-    for current_step := 0 to num_steps-1 do
-    begin
-        if not step_done[current_step] then
-        begin
-            see_cell;
-            done := false;
-        end;
-    end;
-end;
-
-for x := 0 to seen_cells_x - 1 do
-    for y := 0 to seen_cells_y - 1 do
-        if seen_list[x, y] > -1 then
-            maze[(x+1)*2-1, (y+1)*2-1] := true;
-
-for x := 0 to seen_cells_x - 1 do
-    for y := 0 to seen_cells_y - 2 do
-        if not xwalls[x, y] then
-            maze[x*2 + 1, y*2 + 2] := true;
-
-
-for x := 0 to seen_cells_x - 2 do
-     for y := 0 to seen_cells_y - 1 do
-        if not ywalls[x, y] then
-            maze[x*2 + 2, y*2 + 1] := true;
-
-for x := 0 to num_edges_x - 1 do
-    for y := 0 to num_cells_y - 1 do
-        if maze[x, y] xor maze[x+1, y] then
-            x_edge_list[x, y] := true
-        else
-            x_edge_list[x, y] := false;
-
-for x := 0 to num_cells_x - 1 do
-    for y := 0 to num_edges_y - 1 do
-        if maze[x, y] xor maze[x, y+1] then
-            y_edge_list[x, y] := true
-        else
-            y_edge_list[x, y] := false;
-
-for x := 0 to num_edges_x - 1 do
-    for y := 0 to num_cells_y - 1 do
-        if x_edge_list[x, y] then
-        begin
-            x_edge_list[x, y] := false;
-            add_vertex(x+1, y+1);
-            add_vertex(x+1, y);
-            add_edge(x, y-1, DIR_N);
-            add_vertex(NTPX, 0);
-        end;
-
-pa.count := num_vertices;
-
-RandomizePoints(pa);
-BezierizeEdge(pa, _0_25);
-RandomizePoints(pa);
-BezierizeEdge(pa, _0_25);
-
-DrawEdge(pa, 0);
-
-if maze_inverted then
-    FillLand(1, 1+off_y)
-else
-begin
-    x := 0;
-    while Land[cellsize div 2 + cellsize + off_y, x] = lfBasic do
-        x := x + 1;
-    while Land[cellsize div 2 + cellsize + off_y, x] = 0 do
-        x := x + 1;
-    FillLand(x+1, cellsize div 2 + cellsize + off_y);
-end;
-
-MaxHedgehogs:= 32;
-if (GameFlags and gfDisableGirders) <> 0 then hasGirders:= false
-else hasGirders := true;
-leftX:= 0;
-rightX:= playWidth;
-topY:= off_y;
-hasBorder := false;
-end;
 
 procedure GenLandSurface;
 var tmpsurf: PSDL_Surface;
@@ -1076,7 +322,7 @@
                     else if (Land[y, x+1] = lfBasic) and (LandPixels[y, x+1] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y, x+1]
                     else if (Land[y-1, x] = lfBasic) and (LandPixels[y-1, x] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y-1, x]
                     else if (Land[y+1, x] = lfBasic) and (LandPixels[y+1, x] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y+1, x];
-                    if (((LandPixels[y,x] and AMask) shr AShift) > 10) then LandPixels[y,x]:= (LandPixels[y,x] and not AMask) or (128 shl AShift)
+                    if (((LandPixels[y,x] and AMask) shr AShift) > 10) then LandPixels[y,x]:= (LandPixels[y,x] and (not AMask)) or (128 shl AShift)
                     end;
                 Land[y,x]:= lfObject
             end
@@ -1096,7 +342,7 @@
                     else if (Land[y, x+1] = lfBasic) and (LandPixels[y,x+1] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y, x+1]
                     else if (Land[y+1, x] = lfBasic) and (LandPixels[y+1,x] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y+1, x]
                     else if (Land[y-1, x] = lfBasic) and (LandPixels[y-1,x] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y-1, x];
-                    if (((LandPixels[y,x] and AMask) shr AShift) > 10) then LandPixels[y,x]:= (LandPixels[y,x] and not AMask) or (64 shl AShift)
+                    if (((LandPixels[y,x] and AMask) shr AShift) > 10) then LandPixels[y,x]:= (LandPixels[y,x] and (not AMask)) or (64 shl AShift)
                     end;
                 Land[y,x]:= lfObject
             end;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uLandGenMaze.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,455 @@
+unit uLandGenMaze;
+
+interface
+
+procedure GenMaze;
+
+implementation
+
+uses uRandom, uLandOutline, uLandTemplates, uVariables, uFloat, uConsts;
+
+type direction = record x, y: LongInt; end;
+const DIR_N: direction = (x: 0; y: -1);
+    DIR_E: direction = (x: 1; y: 0);
+    DIR_S: direction = (x: 0; y: 1);
+    DIR_W: direction = (x: -1; y: 0);
+
+
+operator = (const a, b: direction) c: Boolean;
+begin
+    c := (a.x = b.x) and (a.y = b.y);
+end;
+
+const small_cell_size = 128;
+    medium_cell_size = 192;
+    large_cell_size = 256;
+    braidness = 10;
+
+var x, y: LongInt;
+    cellsize: LongInt; //selected by the user in the gui
+    seen_cells_x, seen_cells_y: LongInt; //number of cells that can be visited by the generator, that is every second cell in x and y direction. the cells between there are walls that will be removed when we move from one cell to another
+    num_edges_x, num_edges_y: LongInt; //number of resulting edges that need to be vertexificated
+    num_cells_x, num_cells_y: LongInt; //actual number of cells, depending on cell size
+    seen_list: array of array of LongInt;
+    xwalls: array of array of Boolean;
+    ywalls: array of array of Boolean;
+    x_edge_list: array of array of Boolean;
+    y_edge_list: array of array of Boolean;
+    maze: array of array of Boolean;
+    pa: TPixAr;
+    num_vertices: LongInt;
+    off_y: LongInt;
+    num_steps: LongInt;
+    current_step: LongInt;
+    step_done: array of Boolean;
+    done: Boolean;
+    last_cell: array of record x, y: LongInt; end;
+    came_from: array of array of record x, y: LongInt; end;
+    came_from_pos: array of LongInt;
+    maze_inverted: Boolean;
+
+function when_seen(x: LongInt; y: LongInt): LongInt;
+begin
+if (x < 0) or (x >= seen_cells_x) or (y < 0) or (y >= seen_cells_y) then
+    when_seen := current_step
+else
+    when_seen := seen_list[x, y];
+end;
+
+function is_x_edge(x, y: LongInt): Boolean;
+begin
+if (x < 0) or (x > num_edges_x) or (y < 0) or (y > num_cells_y) then
+    is_x_edge := false
+else
+    is_x_edge := x_edge_list[x, y];
+end;
+
+function is_y_edge(x, y: LongInt): Boolean;
+begin
+if (x < 0) or (x > num_cells_x) or (y < 0) or (y > num_edges_y) then
+    is_y_edge := false
+else
+    is_y_edge := y_edge_list[x, y];
+end;
+
+procedure see_cell;
+var dir: direction;
+    tries: LongInt;
+    x, y: LongInt;
+    found_cell: Boolean;
+    next_dir_clockwise: Boolean;
+
+begin
+x := last_cell[current_step].x;
+y := last_cell[current_step].y;
+seen_list[x, y] := current_step;
+case GetRandom(4) of
+    0: dir := DIR_N;
+    1: dir := DIR_E;
+    2: dir := DIR_S;
+    3: dir := DIR_W;
+end;
+tries := 0;
+found_cell := false;
+if getrandom(2) = 1 then next_dir_clockwise := true
+else next_dir_clockwise := false;
+
+while (tries < 5) and (not found_cell) do
+begin
+    if when_seen(x + dir.x, y + dir.y) = current_step then //we are seeing ourselves, try another direction
+    begin
+        //we have already seen the target cell, decide if we should remove the wall anyway
+        //(or put a wall there if maze_inverted, but we are not doing that right now)
+        if not maze_inverted and (GetRandom(braidness) = 0) then
+        //or just warn that inverted+braid+indestructible terrain != good idea
+        begin
+            case dir.x of
+                -1: if x > 0 then ywalls[x-1, y] := false;
+                1: if x < seen_cells_x - 1 then ywalls[x, y] := false;
+            end;
+            case dir.y of
+                -1: if y > 0 then xwalls[x, y-1] := false;
+                1: if y < seen_cells_y - 1 then xwalls[x, y] := false;
+            end;
+        end;
+        if next_dir_clockwise then
+        begin
+            if dir = DIR_N then
+                dir := DIR_E
+            else if dir = DIR_E then
+                dir := DIR_S
+            else if dir = DIR_S then
+                dir := DIR_W
+            else
+                dir := DIR_N;
+        end
+        else
+        begin
+            if dir = DIR_N then
+                dir := DIR_W
+            else if dir = DIR_E then
+                dir := DIR_N
+            else if dir = DIR_S then
+                dir := DIR_E
+            else
+                dir := DIR_S;
+        end
+    end
+    else if when_seen(x + dir.x, y + dir.y) = -1 then //cell was not seen yet, go there
+    begin
+        case dir.y of
+            -1: xwalls[x, y-1] := false;
+            1: xwalls[x, y] := false;
+        end;
+        case dir.x of
+            -1: ywalls[x-1, y] := false;
+            1: ywalls[x, y] := false;
+        end;
+        last_cell[current_step].x := x+dir.x;
+        last_cell[current_step].y := y+dir.y;
+        came_from_pos[current_step] := came_from_pos[current_step] + 1;
+        came_from[current_step, came_from_pos[current_step]].x := x;
+        came_from[current_step, came_from_pos[current_step]].y := y;
+        found_cell := true;
+    end
+    else //we are seeing someone else, quit
+    begin
+        step_done[current_step] := true;
+        found_cell := true;
+    end;
+
+    tries := tries + 1;
+end;
+if not found_cell then
+begin
+    last_cell[current_step].x := came_from[current_step, came_from_pos[current_step]].x;
+    last_cell[current_step].y := came_from[current_step, came_from_pos[current_step]].y;
+    came_from_pos[current_step] := came_from_pos[current_step] - 1;
+    if came_from_pos[current_step] >= 0 then see_cell
+    else step_done[current_step] := true;
+end;
+end;
+
+procedure add_vertex(x, y: LongInt);
+var tmp_x, tmp_y: LongInt;
+begin
+if x = NTPX then
+begin
+    if pa.ar[num_vertices - 6].x = NTPX then
+    begin
+        num_vertices := num_vertices - 6;
+    end
+    else
+    begin
+        pa.ar[num_vertices].x := NTPX;
+        pa.ar[num_vertices].y := 0;
+    end
+end
+else
+begin
+    if maze_inverted or (x mod 2 = 0) then tmp_x := cellsize
+    else tmp_x := cellsize * 2 div 3;
+    if maze_inverted or (y mod 2 = 0) then tmp_y := cellsize
+    else tmp_y := cellsize * 2 div 3;
+
+    pa.ar[num_vertices].x := (x-1)*cellsize + tmp_x;
+    pa.ar[num_vertices].y := (y-1)*cellsize + tmp_y + off_y;
+end;
+num_vertices := num_vertices + 1;
+end;
+
+procedure add_edge(x, y: LongInt; dir: direction);
+var i: LongInt;
+begin
+if dir = DIR_N then
+begin
+    dir := DIR_W
+end
+else if dir = DIR_E then
+begin
+    dir := DIR_N
+end
+else if dir = DIR_S then
+begin
+    dir := DIR_E
+end
+else
+begin
+    dir := DIR_S;
+end;
+
+for i := 0 to 3 do
+begin
+        if dir = DIR_N then
+            dir := DIR_E
+        else if dir = DIR_E then
+            dir := DIR_S
+        else if dir = DIR_S then
+            dir := DIR_W
+        else
+            dir := DIR_N;
+
+    if (dir = DIR_N) and is_x_edge(x, y) then
+        begin
+            x_edge_list[x, y] := false;
+            add_vertex(x+1, y);
+            add_edge(x, y-1, DIR_N);
+            break;
+        end;
+
+    if (dir = DIR_E) and is_y_edge(x+1, y) then
+        begin
+            y_edge_list[x+1, y] := false;
+            add_vertex(x+2, y+1);
+            add_edge(x+1, y, DIR_E);
+            break;
+        end;
+
+    if (dir = DIR_S) and is_x_edge(x, y+1) then
+        begin
+            x_edge_list[x, y+1] := false;
+            add_vertex(x+1, y+2);
+            add_edge(x, y+1, DIR_S);
+            break;
+        end;
+
+    if (dir = DIR_W) and is_y_edge(x, y) then
+        begin
+            y_edge_list[x, y] := false;
+            add_vertex(x, y+1);
+            add_edge(x-1, y, DIR_W);
+            break;
+        end;
+end;
+
+end;
+
+procedure GenMaze;
+begin
+case cTemplateFilter of
+    0: begin
+        cellsize := small_cell_size;
+        maze_inverted := false;
+    end;
+    1: begin
+        cellsize := medium_cell_size;
+        maze_inverted := false;
+    end;
+    2: begin
+        cellsize := large_cell_size;
+        maze_inverted := false;
+    end;
+    3: begin
+        cellsize := small_cell_size;
+        maze_inverted := true;
+    end;
+    4: begin
+        cellsize := medium_cell_size;
+        maze_inverted := true;
+    end;
+    5: begin
+        cellsize := large_cell_size;
+        maze_inverted := true;
+    end;
+end;
+
+num_cells_x := LAND_WIDTH div cellsize;
+if not odd(num_cells_x) then num_cells_x := num_cells_x - 1; //needs to be odd
+num_cells_y := LAND_HEIGHT div cellsize;
+if not odd(num_cells_y) then num_cells_y := num_cells_y - 1;
+num_edges_x := num_cells_x - 1;
+num_edges_y := num_cells_y - 1;
+seen_cells_x := num_cells_x div 2;
+seen_cells_y := num_cells_y div 2;
+
+if maze_inverted then
+    num_steps := 3 //TODO randomize, between 3 and 5?
+else
+    num_steps := 1;
+SetLength(step_done, num_steps);
+SetLength(last_cell, num_steps);
+SetLength(came_from_pos, num_steps);
+SetLength(came_from, num_steps, num_cells_x*num_cells_y);
+done := false;
+for current_step := 0 to num_steps - 1 do
+    step_done[current_step] := false;
+    came_from_pos[current_step] := 0;
+current_step := 0;
+
+SetLength(seen_list, seen_cells_x, seen_cells_y);
+SetLength(xwalls, seen_cells_x, seen_cells_y - 1);
+SetLength(ywalls, seen_cells_x - 1, seen_cells_y);
+SetLength(x_edge_list, num_edges_x, num_cells_y);
+SetLength(y_edge_list, num_cells_x, num_edges_y);
+SetLength(maze, num_cells_x, num_cells_y);
+
+num_vertices := 0;
+
+playHeight := num_cells_y * cellsize;
+playWidth := num_cells_x * cellsize;
+off_y := LAND_HEIGHT - playHeight;
+
+for x := 0 to playWidth do
+    for y := 0 to off_y - 1 do
+        Land[y, x] := 0;
+
+for x := 0 to playWidth do
+    for y := off_y to LAND_HEIGHT - 1 do
+        Land[y, x] := lfBasic;
+
+for y := 0 to num_cells_y - 1 do
+    for x := 0 to num_cells_x - 1 do
+        maze[x, y] := false;
+
+for x := 0 to seen_cells_x - 1 do
+    for y := 0 to seen_cells_y - 2 do
+        xwalls[x, y] := true;
+
+for x := 0 to seen_cells_x - 2 do
+    for y := 0 to seen_cells_y - 1 do
+        ywalls[x, y] := true;
+
+for x := 0 to seen_cells_x - 1 do
+    for y := 0 to seen_cells_y - 1 do
+        seen_list[x, y] := -1;
+
+for x := 0 to num_edges_x - 1 do
+    for y := 0 to num_cells_y - 1 do
+        x_edge_list[x, y] := false;
+
+for x := 0 to num_cells_x - 1 do
+    for y := 0 to num_edges_y - 1 do
+        y_edge_list[x, y] := false;
+
+for current_step := 0 to num_steps-1 do
+begin
+    x := GetRandom(seen_cells_x - 1) div LongWord(num_steps);
+    last_cell[current_step].x := x + current_step * seen_cells_x div num_steps;
+    last_cell[current_step].y := GetRandom(seen_cells_y);
+end;
+
+while not done do
+begin
+    done := true;
+    for current_step := 0 to num_steps-1 do
+    begin
+        if not step_done[current_step] then
+        begin
+            see_cell;
+            done := false;
+        end;
+    end;
+end;
+
+for x := 0 to seen_cells_x - 1 do
+    for y := 0 to seen_cells_y - 1 do
+        if seen_list[x, y] > -1 then
+            maze[(x+1)*2-1, (y+1)*2-1] := true;
+
+for x := 0 to seen_cells_x - 1 do
+    for y := 0 to seen_cells_y - 2 do
+        if not xwalls[x, y] then
+            maze[x*2 + 1, y*2 + 2] := true;
+
+
+for x := 0 to seen_cells_x - 2 do
+     for y := 0 to seen_cells_y - 1 do
+        if not ywalls[x, y] then
+            maze[x*2 + 2, y*2 + 1] := true;
+
+for x := 0 to num_edges_x - 1 do
+    for y := 0 to num_cells_y - 1 do
+        if maze[x, y] xor maze[x+1, y] then
+            x_edge_list[x, y] := true
+        else
+            x_edge_list[x, y] := false;
+
+for x := 0 to num_cells_x - 1 do
+    for y := 0 to num_edges_y - 1 do
+        if maze[x, y] xor maze[x, y+1] then
+            y_edge_list[x, y] := true
+        else
+            y_edge_list[x, y] := false;
+
+for x := 0 to num_edges_x - 1 do
+    for y := 0 to num_cells_y - 1 do
+        if x_edge_list[x, y] then
+        begin
+            x_edge_list[x, y] := false;
+            add_vertex(x+1, y+1);
+            add_vertex(x+1, y);
+            add_edge(x, y-1, DIR_N);
+            add_vertex(NTPX, 0);
+        end;
+
+pa.count := num_vertices;
+
+RandomizePoints(pa);
+BezierizeEdge(pa, _0_25);
+RandomizePoints(pa);
+BezierizeEdge(pa, _0_25);
+
+DrawEdge(pa, 0);
+
+if maze_inverted then
+    FillLand(1, 1+off_y)
+else
+begin
+    x := 0;
+    while Land[cellsize div 2 + cellsize + off_y, x] = lfBasic do
+        x := x + 1;
+    while Land[cellsize div 2 + cellsize + off_y, x] = 0 do
+        x := x + 1;
+    FillLand(x+1, cellsize div 2 + cellsize + off_y);
+end;
+
+MaxHedgehogs:= 32;
+if (GameFlags and gfDisableGirders) <> 0 then hasGirders:= false
+else hasGirders := true;
+leftX:= 0;
+rightX:= playWidth;
+topY:= off_y;
+hasBorder := false;
+end;
+
+end.
--- a/hedgewars/uLandGraphics.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uLandGraphics.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -38,6 +38,7 @@
 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword);
 procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet: boolean);
 function  LandBackPixel(x, y: LongInt): LongWord;
+procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword);
 
 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; indestructible: boolean): boolean;
 
@@ -298,7 +299,7 @@
                begin
                by:= t div 2; bx:= i div 2;
                end;
-           if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and not (disableLandBack) then
+           if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
                begin
                inc(cnt);
                LandPixels[by, bx]:= LandBackPixel(i, t)
@@ -676,7 +677,7 @@
      4: for y:= 0 to Pred(h) do
             begin
             for x:= 0 to Pred(w) do
-                if PLongword(@(p^[x * 4]))^ <> 0 then
+                if (PLongword(@(p^[x * 4]))^) <> 0 then
                    if ((cpY + y) <= Longint(topY)) or
                       ((cpY + y) >= LAND_HEIGHT) or
                       ((cpX + x) <= Longint(leftX)) or
@@ -705,7 +706,7 @@
      4: for y:= 0 to Pred(h) do
             begin
             for x:= 0 to Pred(w) do
-                if PLongword(@(p^[x * 4]))^ <> 0 then
+                if (PLongword(@(p^[x * 4]))^) <> 0 then
                    begin
                    if (cReducedQuality and rqBlurryLand) = 0 then
                        begin
@@ -781,7 +782,7 @@
 
     if c < 4 then // 0-3 neighbours
         begin
-        if ((Land[Y, X] and lfBasic) <> 0) and not disableLandBack then
+        if ((Land[Y, X] and lfBasic) <> 0) and (not disableLandBack) then
             LandPixels[yy, xx]:= LandBackPixel(X, Y)
         else
             LandPixels[yy, xx]:= 0;
@@ -804,7 +805,7 @@
         begin
         if (cReducedQuality and rqBlurryLand) = 0 then
             begin
-            if ((LandPixels[y,x] and AMask) shr AShift) < 10 then LandPixels[y,x]:= (cExplosionBorderColor and not AMask) or (128 shl AShift)
+            if ((LandPixels[y,x] and AMask) shr AShift) < 10 then LandPixels[y,x]:= (cExplosionBorderColor and (not AMask)) or (128 shl AShift)
             else
                 LandPixels[y,x]:=
                                 (((((LandPixels[y,x] and RMask shr RShift) div 2)+((cExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or
@@ -826,7 +827,7 @@
         begin
         if (cReducedQuality and rqBlurryLand) = 0 then
             begin
-            if ((LandPixels[y,x] and AMask) shr AShift) < 10 then LandPixels[y,x]:= (cExplosionBorderColor and not AMask) or (64 shl AShift)
+            if ((LandPixels[y,x] and AMask) shr AShift) < 10 then LandPixels[y,x]:= (cExplosionBorderColor and (not AMask)) or (64 shl AShift)
             else
                 LandPixels[y,x]:=
                                 (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((cExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or
@@ -962,4 +963,56 @@
 end;
 
 
+procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword);
+var
+  eX, eY, dX, dY: LongInt;
+  i, sX, sY, x, y, d: LongInt;
+begin
+eX:= 0;
+eY:= 0;
+dX:= X2 - X1;
+dY:= Y2 - Y1;
+
+if (dX > 0) then sX:= 1
+else
+  if (dX < 0) then
+     begin
+     sX:= -1;
+     dX:= -dX
+     end else sX:= dX;
+
+if (dY > 0) then sY:= 1
+  else
+  if (dY < 0) then
+     begin
+     sY:= -1;
+     dY:= -dY
+     end else sY:= dY;
+
+if (dX > dY) then d:= dX
+             else d:= dY;
+
+x:= X1;
+y:= Y1;
+
+for i:= 0 to d do
+    begin
+    inc(eX, dX);
+    inc(eY, dY);
+    if (eX > d) then
+       begin
+       dec(eX, d);
+       inc(x, sX);
+       end;
+    if (eY > d) then
+       begin
+       dec(eY, d);
+       inc(y, sY);
+       end;
+
+    if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then
+       Land[y, x]:= Color;
+    end
+end;
+
 end.
--- a/hedgewars/uLandObjects.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uLandObjects.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -151,22 +151,22 @@
 CheckIntersect:= res;
 end;
 
+
+function CountNonZeroz(x, y: LongInt): Longword;
+var i: LongInt;
+    lRes: Longword;
+begin
+    lRes:= 0;
+    for i:= y to y + 15 do
+        if Land[i, x] <> 0 then inc(lRes);
+    CountNonZeroz:= lRes;
+end;
+
 function AddGirder(gX: LongInt): boolean;
 var tmpsurf: PSDL_Surface;
     x1, x2, y, k, i: LongInt;
     rr: TSDL_Rect;
     bRes: boolean;
-
-    function CountNonZeroz(x, y: LongInt): Longword;
-    var i: LongInt;
-        lRes: Longword;
-    begin
-    lRes:= 0;
-    for i:= y to y + 15 do
-        if Land[i, x] <> 0 then inc(lRes);
-    CountNonZeroz:= lRes;
-    end;
-
 begin
 y:= topY+150;
 repeat
@@ -192,7 +192,7 @@
         k:= CountNonZeroz(x2, y)
         until (x2 >= (rightX-150)) or (k = 0) or (k = 16) or (x2 > i) or (x2 - x1 >= 768);
         if (x2 < (rightX - 150)) and (k = 16) and (x2 - x1 > 250) and (x2 - x1 < 768)
-            and not CheckIntersect(x1 - 32, y - 64, x2 - x1 + 64, 144) then break;
+            and (not CheckIntersect(x1 - 32, y - 64, x2 - x1 + 64, 144)) then break;
         end;
 x1:= 0;
 until y > (LAND_HEIGHT-125);
@@ -345,7 +345,7 @@
         y:= 8;
         repeat
             if CheckLand(r, x, y - 8, lfBasic)
-            and not CheckIntersect(x, y, Width, Height) then
+            and (not CheckIntersect(x, y, Width, Height)) then
             begin
             ar[cnt].x:= x;
             ar[cnt].y:= y;
@@ -376,19 +376,21 @@
 TryPut:= bRes;
 end;
 
+
+procedure CheckRect(Width, Height, x, y, w, h: LongWord);
+begin
+    if (x + w > Width) then 
+        OutError('Object''s rectangle exceeds image: x + w (' + inttostr(x) + ' + ' + inttostr(w) + ') > Width (' + inttostr(Width) + ')', true);
+    if (y + h > Height) then 
+        OutError('Object''s rectangle exceeds image: y + h (' + inttostr(y) + ' + ' + inttostr(h) + ') > Height (' + inttostr(Height) + ')', true);
+end;
+
 procedure ReadThemeInfo(var ThemeObjects: TThemeObjects; var SprayObjects: TSprayObjects);
 var s, key: shortstring;
     f: textfile;
     i: LongInt;
     ii, t: Longword;
     c2: TSDL_Color;
-
-    procedure CheckRect(Width, Height, x, y, w, h: LongWord);
-    begin
-    if (x + w > Width) then OutError('Object''s rectangle exceeds image: x + w (' + inttostr(x) + ' + ' + inttostr(w) + ') > Width (' + inttostr(Width) + ')', true);
-    if (y + h > Height) then OutError('Object''s rectangle exceeds image: y + h (' + inttostr(y) + ' + ' + inttostr(h) + ') > Height (' + inttostr(Height) + ')', true);
-    end;
-
 begin
 
 AddProgress;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uLandOutline.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,292 @@
+unit uLandOutline;
+
+interface
+
+uses uConsts, SDLh, uFloat;
+
+type TPixAr = record
+              Count: Longword;
+              ar: array[0..Pred(cMaxEdgePoints)] of TPoint;
+              end;
+
+procedure DrawEdge(var pa: TPixAr; Color: Longword);
+procedure FillLand(x, y: LongInt);
+procedure BezierizeEdge(var pa: TPixAr; Delta: hwFloat);
+procedure RandomizePoints(var pa: TPixAr);
+
+implementation
+
+uses uLandGraphics, uDebug, uVariables, uLandTemplates, uRandom, uUtils;
+
+
+
+var Stack: record
+           Count: Longword;
+           points: array[0..8192] of record
+                                     xl, xr, y, dir: LongInt;
+                                     end
+           end;
+
+procedure Push(_xl, _xr, _y, _dir: LongInt);
+begin
+    TryDo(Stack.Count <= 8192, 'FillLand: stack overflow', true);
+    _y:= _y + _dir;
+    if (_y < 0) or (_y >= LAND_HEIGHT) then exit;
+    with Stack.points[Stack.Count] do
+            begin
+            xl:= _xl;
+            xr:= _xr;
+            y:= _y;
+            dir:= _dir
+            end;
+    inc(Stack.Count)
+end;
+
+procedure Pop(var _xl, _xr, _y, _dir: LongInt);
+begin
+    dec(Stack.Count);
+    with Stack.points[Stack.Count] do
+        begin
+        _xl:= xl;
+        _xr:= xr;
+        _y:= y;
+        _dir:= dir
+        end
+end;
+
+procedure FillLand(x, y: LongInt);
+var xl, xr, dir: LongInt;
+begin
+    Stack.Count:= 0;
+    xl:= x - 1;
+    xr:= x;
+    Push(xl, xr, y, -1);
+    Push(xl, xr, y,  1);
+    dir:= 0;
+    while Stack.Count > 0 do
+        begin
+        Pop(xl, xr, y, dir);
+        while (xl > 0) and (Land[y, xl] <> 0) do dec(xl);
+        while (xr < LAND_WIDTH - 1) and (Land[y, xr] <> 0) do inc(xr);
+        while (xl < xr) do
+            begin
+            while (xl <= xr) and (Land[y, xl] = 0) do inc(xl);
+            x:= xl;
+            while (xl <= xr) and (Land[y, xl] <> 0) do
+                begin
+                Land[y, xl]:= 0;
+                inc(xl)
+                end;
+            if x < xl then
+                begin
+                Push(x, Pred(xl), y, dir);
+                Push(x, Pred(xl), y,-dir);
+                end;
+            end;
+        end;
+end;
+
+procedure DrawEdge(var pa: TPixAr; Color: Longword);
+var i: LongInt;
+begin
+    i:= 0;
+    with pa do
+        while i < LongInt(Count) - 1 do
+            if (ar[i + 1].X = NTPX) then 
+                inc(i, 2)
+            else 
+                begin
+                DrawLine(ar[i].x, ar[i].y, ar[i + 1].x, ar[i + 1].y, Color);
+                inc(i)
+                end
+end;
+
+
+procedure Vector(p1, p2, p3: TPoint; var Vx, Vy: hwFloat);
+var d1, d2, d: hwFloat;
+begin
+    Vx:= int2hwFloat(p1.X - p3.X);
+    Vy:= int2hwFloat(p1.Y - p3.Y);
+
+    d:= DistanceI(p2.X - p1.X, p2.Y - p1.Y);
+    d1:= DistanceI(p2.X - p3.X, p2.Y - p3.Y);
+    d2:= Distance(Vx, Vy);
+
+    if d1 < d then d:= d1;
+    if d2 < d then d:= d2;
+
+    d:= d * _1div3;
+
+    if d2.QWordValue = 0 then
+        begin
+        Vx:= _0;
+        Vy:= _0
+        end 
+    else
+        begin
+        d2:= _1 / d2;
+        Vx:= Vx * d2;
+        Vy:= Vy * d2;
+
+        Vx:= Vx * d;
+        Vy:= Vy * d
+        end
+end;
+
+procedure AddLoopPoints(var pa, opa: TPixAr; StartI, EndI: LongInt; Delta: hwFloat);
+var i, pi, ni: LongInt;
+    NVx, NVy, PVx, PVy: hwFloat;
+    x1, x2, y1, y2: LongInt;
+    tsq, tcb, t, r1, r2, r3, cx1, cx2, cy1, cy2: hwFloat;
+    X, Y: LongInt;
+begin
+pi:= EndI;
+i:= StartI;
+ni:= Succ(StartI);
+{$HINTS OFF}
+Vector(opa.ar[pi], opa.ar[i], opa.ar[ni], NVx, NVy);
+{$HINTS ON}
+repeat
+    inc(pi);
+    if pi > EndI then pi:= StartI;
+    inc(i);
+    if i > EndI then i:= StartI;
+    inc(ni);
+    if ni > EndI then ni:= StartI;
+    PVx:= NVx;
+    PVy:= NVy;
+    Vector(opa.ar[pi], opa.ar[i], opa.ar[ni], NVx, NVy);
+
+    x1:= opa.ar[pi].x;
+    y1:= opa.ar[pi].y;
+    x2:= opa.ar[i].x;
+    y2:= opa.ar[i].y;
+    cx1:= int2hwFloat(x1) - PVx;
+    cy1:= int2hwFloat(y1) - PVy;
+    cx2:= int2hwFloat(x2) + NVx;
+    cy2:= int2hwFloat(y2) + NVy;
+    t:= _0;
+    while t.Round = 0 do
+          begin
+          tsq:= t * t;
+          tcb:= tsq * t;
+          r1:= (_1 - t*3 + tsq*3 - tcb);
+          r2:= (     t*3 - tsq*6 + tcb*3);
+          r3:= (           tsq*3 - tcb*3);
+          X:= hwRound(r1 * x1 + r2 * cx1 + r3 * cx2 + tcb * x2);
+          Y:= hwRound(r1 * y1 + r2 * cy1 + r3 * cy2 + tcb * y2);
+          t:= t + Delta;
+          pa.ar[pa.Count].x:= X;
+          pa.ar[pa.Count].y:= Y;
+          inc(pa.Count);
+          TryDo(pa.Count <= cMaxEdgePoints, 'Edge points overflow', true)
+          end;
+until i = StartI;
+pa.ar[pa.Count].x:= opa.ar[StartI].X;
+pa.ar[pa.Count].y:= opa.ar[StartI].Y;
+inc(pa.Count)
+end;
+
+procedure BezierizeEdge(var pa: TPixAr; Delta: hwFloat);
+var i, StartLoop: LongInt;
+    opa: TPixAr;
+begin
+opa:= pa;
+pa.Count:= 0;
+i:= 0;
+StartLoop:= 0;
+while i < LongInt(opa.Count) do
+    if (opa.ar[i + 1].X = NTPX) then
+       begin
+       AddLoopPoints(pa, opa, StartLoop, i, Delta);
+       inc(i, 2);
+       StartLoop:= i;
+       pa.ar[pa.Count].X:= NTPX;
+       pa.ar[pa.Count].Y:= 0;
+       inc(pa.Count);
+       end else inc(i)
+end;
+
+
+function CheckIntersect(V1, V2, V3, V4: TPoint): boolean;
+var c1, c2, dm: LongInt;
+begin
+    dm:= (V4.y - V3.y) * (V2.x - V1.x) - (V4.x - V3.x) * (V2.y - V1.y);
+    c1:= (V4.x - V3.x) * (V1.y - V3.y) - (V4.y - V3.y) * (V1.x - V3.x);
+    if dm = 0 then exit(false);
+
+    c2:= (V2.x - V3.x) * (V1.y - V3.y) - (V2.y - V3.y) * (V1.x - V3.x);
+    if dm > 0 then
+        begin
+        if (c1 < 0) or (c1 > dm) then exit(false);
+        if (c2 < 0) or (c2 > dm) then exit(false)
+        end 
+    else
+        begin
+        if (c1 > 0) or (c1 < dm) then exit(false);
+        if (c2 > 0) or (c2 < dm) then exit(false)
+        end;
+
+    //AddFileLog('1  (' + inttostr(V1.x) + ',' + inttostr(V1.y) + ')x(' + inttostr(V2.x) + ',' + inttostr(V2.y) + ')');
+    //AddFileLog('2  (' + inttostr(V3.x) + ',' + inttostr(V3.y) + ')x(' + inttostr(V4.x) + ',' + inttostr(V4.y) + ')');
+    CheckIntersect:= true
+end;
+
+
+function CheckSelfIntersect(var pa: TPixAr; ind: Longword): boolean;
+var i: Longword;
+begin
+    if (ind <= 0) or (ind >= Pred(pa.Count)) then exit(false);
+    for i:= 1 to pa.Count - 3 do
+        if (i <= ind - 1) or (i >= ind + 2) then
+        begin
+        if (i <> ind - 1) and
+            CheckIntersect(pa.ar[ind], pa.ar[ind - 1], pa.ar[i], pa.ar[i - 1]) then exit(true);
+        if (i <> ind + 2) and
+            CheckIntersect(pa.ar[ind], pa.ar[ind + 1], pa.ar[i], pa.ar[i - 1]) then exit(true);
+        end;
+    CheckSelfIntersect:= false
+end;
+
+procedure RandomizePoints(var pa: TPixAr);
+const cEdge = 55;
+      cMinDist = 8;
+var radz: array[0..Pred(cMaxEdgePoints)] of LongInt;
+    i, k, dist, px, py: LongInt;
+begin
+    for i:= 0 to Pred(pa.Count) do
+    begin
+    radz[i]:= 0;
+        with pa.ar[i] do
+            if x <> NTPX then
+            begin
+            radz[i]:= Min(Max(x - cEdge, 0), Max(LAND_WIDTH - cEdge - x, 0));
+            radz[i]:= Min(radz[i], Min(Max(y - cEdge, 0), Max(LAND_HEIGHT - cEdge - y, 0)));
+            if radz[i] > 0 then
+                for k:= 0 to Pred(i) do
+                begin
+                dist:= Max(abs(x - pa.ar[k].x), abs(y - pa.ar[k].y));
+                radz[k]:= Max(0, Min((dist - cMinDist) div 2, radz[k]));
+                radz[i]:= Max(0, Min(dist - radz[k] - cMinDist, radz[i]))
+                end
+            end;
+    end;
+
+    for i:= 0 to Pred(pa.Count) do
+        with pa.ar[i] do
+            if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then
+            begin
+            px:= x;
+            py:= y;
+            x:= x + LongInt(GetRandom(7) - 3) * (radz[i] * 5 div 7) div 3;
+            y:= y + LongInt(GetRandom(7) - 3) * (radz[i] * 5 div 7) div 3;
+            if CheckSelfIntersect(pa, i) then
+                begin
+                x:= px;
+                y:= py
+                end;
+            end
+end;
+
+
+end.
\ No newline at end of file
--- a/hedgewars/uLocale.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uLocale.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -58,7 +58,7 @@
        begin
        readln(f, s);
        if Length(s) = 0 then continue;
-       if not (s[1] in ['0'..'9']) then continue;
+       if (s[1] < '0') or (s[1] > '9') then continue;
        TryDo(Length(s) > 6, 'Load locale: empty string', true);
        val(s[1]+s[2], a, c);
        TryDo(c = 0, 'Load locale: numbers should be two-digit: ' + s, true);
--- a/hedgewars/uScript.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uScript.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -53,11 +53,11 @@
 
 implementation
 {$IFNDEF LUA_DISABLED}
-uses LuaPas in 'LuaPas.pas',
+uses LuaPas,
     uConsole,
     uConsts,
     uVisualGears,
-    uGears,
+    uGearsList,
     uFloat,
     uWorld,
     uAmmos,
@@ -1715,7 +1715,7 @@
 
 procedure ScriptCall(fname : shortstring);
 begin
-if not ScriptLoaded or not ScriptExists(fname) then
+if not ScriptLoaded or (not ScriptExists(fname)) then
     exit;
 SetGlobals;
 lua_getglobal(luaState, Str2PChar(fname));
@@ -1763,7 +1763,7 @@
 
 function ScriptCall(fname : shortstring; par1, par2, par3, par4 : LongInt) : LongInt;
 begin
-if not ScriptLoaded or not ScriptExists(fname) then
+if not ScriptLoaded or (not ScriptExists(fname)) then
     exit;
 SetGlobals;
 lua_getglobal(luaState, Str2PChar(fname));
--- a/hedgewars/uSound.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uSound.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -52,6 +52,7 @@
 procedure PauseMusic;
 procedure ResumeMusic;
 procedure ChangeMusic; // Replaces music track with current MusicFN and plays it.
+procedure StopMusic; // Stops and releases the current track
 
 
 // SOUNDS
@@ -458,7 +459,8 @@
     if (MusicFN = '') or (not isMusicEnabled) then
         exit;
 
-    Mix_PauseMusic(Mus);
+    if Mus <> nil then
+    	Mix_PauseMusic(Mus);
 end;
 
 procedure ResumeMusic;
@@ -466,7 +468,8 @@
     if (MusicFN = '') or (not isMusicEnabled) then
         exit;
 
-    Mix_ResumeMusic(Mus);
+    if Mus <> nil then
+    	Mix_ResumeMusic(Mus);
 end;
 
 procedure ChangeMusic;
@@ -474,11 +477,17 @@
     if (MusicFN = '') or (not isMusicEnabled) then
         exit;
 
-    // get rid of current music
+    StopMusic;
+    PlayMusic;
+end;
+
+procedure StopMusic;
+begin
+    if (MusicFN = '') or (not isMusicEnabled) then
+        exit;
+
     if Mus <> nil then
         Mix_FreeMusic(Mus);
-
-    PlayMusic;
 end;
 
 procedure chVoicepack(var s: shortstring);
--- a/hedgewars/uStats.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uStats.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -130,7 +130,7 @@
     else if AmmoDamagingUsed then
         AddVoice(sndMissed, PreviousTeam^.voicepack)
     else if (AmmoUsedCount > 0) and (not isTurnSkipped) then
-        // nothing ?
+        begin end// nothing ?
     else if isTurnSkipped then
         begin
         AddVoice(sndBoring, PreviousTeam^.voicepack);
--- a/hedgewars/uStore.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uStore.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -118,16 +118,15 @@
 SDL_FreeSurface(tmpsurf)
 end;
 
-procedure StoreLoad(reload: boolean);
-var s: shortstring;
 
-    procedure WriteNames(Font: THWFont);
-    var t: LongInt;
-        i: LongInt;
-        r, rr: TSDL_Rect;
-        drY: LongInt;
-        texsurf, flagsurf, iconsurf: PSDL_Surface;
-    begin
+procedure WriteNames(Font: THWFont);
+var t: LongInt;
+    i: LongInt;
+    r, rr: TSDL_Rect;
+    drY: LongInt;
+    texsurf, flagsurf, iconsurf: PSDL_Surface;
+    s: shortstring;
+begin
     r.x:= 0;
     r.y:= 0;
     drY:= - 4;
@@ -220,11 +219,11 @@
         SDL_FreeSurface(iconsurf);
         iconsurf:= nil;
         end;
-    end;
+end;
 
-    procedure InitHealth;
-    var i, t: LongInt;
-    begin
+procedure InitHealth;
+var i, t: LongInt;
+begin
     for t:= 0 to Pred(TeamsCount) do
         if TeamsArray[t] <> nil then
             with TeamsArray[t]^ do
@@ -233,12 +232,12 @@
                     if Hedgehogs[i].Gear <> nil then
                         RenderHealth(Hedgehogs[i]);
                 end
-    end;
+end;
 
-    procedure LoadGraves;
-    var t: LongInt;
-        texsurf: PSDL_Surface;
-    begin
+procedure LoadGraves;
+var t: LongInt;
+    texsurf: PSDL_Surface;
+begin
     for t:= 0 to Pred(TeamsCount) do
     if TeamsArray[t] <> nil then
         with TeamsArray[t]^ do
@@ -251,9 +250,11 @@
             GraveTex:= Surface2Tex(texsurf, false);
             SDL_FreeSurface(texsurf)
             end
-    end;
+end;
 
-var ii: TSprite;
+procedure StoreLoad(reload: boolean);
+var s: shortstring;
+    ii: TSprite;
     fi: THWFont;
     ai: TAmmoType;
     tmpsurf: PSDL_Surface;
@@ -413,7 +414,7 @@
         begin
         FreeTexture(SpritesData[ii].Texture);
         SpritesData[ii].Texture:= nil;
-        if (SpritesData[ii].Surface <> nil) and not reload then
+        if (SpritesData[ii].Surface <> nil) and (not reload) then
             begin
             SDL_FreeSurface(SpritesData[ii].Surface);
             SpritesData[ii].Surface:= nil
@@ -955,7 +956,7 @@
     {$IFNDEF DARWIN}ico: PSDL_Surface;{$ENDIF}
     {$IFDEF SDL13}x, y: LongInt;{$ENDIF}
 begin
-    if Length(s) = 0 then cFullScreen:= not cFullScreen
+    if Length(s) = 0 then cFullScreen:= (not cFullScreen)
     else cFullScreen:= s = '1';
 
     AddFileLog('Preparing to change video parameters...');
--- a/hedgewars/uTeams.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uTeams.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -142,7 +142,7 @@
 c:= CurrentTeam^.Clan^.ClanIndex;
 repeat
     with ClansArray[c]^ do
-        if (CurrTeam = TagTeamIndex) and ((GameFlags And gfTagTeam) <> 0) then
+        if (CurrTeam = TagTeamIndex) and ((GameFlags and gfTagTeam) <> 0) then
             begin
             TagTeamIndex:= Pred(TagTeamIndex) mod TeamsNumber;
             CurrTeam:= Pred(CurrTeam) mod TeamsNumber;
@@ -150,7 +150,7 @@
             NextClan:= true;
             end;
 
-    if (GameFlags And gfTagTeam) = 0 then inc(c);
+    if (GameFlags and gfTagTeam) = 0 then inc(c);
 
     if c = ClansCount then
         begin
@@ -171,7 +171,7 @@
                     CurrHedgehog:= Succ(CurrHedgehog) mod HedgehogsNumber;
                 until (Hedgehogs[CurrHedgehog].Gear <> nil) or (CurrHedgehog = PrevHH)
                 end
-        until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (PrevTeam = CurrTeam) or ((CurrTeam = TagTeamIndex) and ((GameFlags And gfTagTeam) <> 0));
+        until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (PrevTeam = CurrTeam) or ((CurrTeam = TagTeamIndex) and ((GameFlags and gfTagTeam) <> 0));
         end
 until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil);
 
@@ -243,7 +243,7 @@
     if CurrentHedgehog^.Unplaced then TurnTimeLeft:= 15000
     else TurnTimeLeft:= 0
     end
-else if ((GameFlags And gfTagTeam) <> 0) and not NextClan then
+else if ((GameFlags and gfTagTeam) <> 0) and (not NextClan) then
     begin
     if TagTurnTimeLeft <> 0 then TurnTimeLeft:= TagTurnTimeLeft;
     TagTurnTimeLeft:= 0;
--- a/hedgewars/uTextures.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uTextures.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -119,6 +119,8 @@
     fromP4:= @(fromP4^[Surf^.pitch div 4])
     end;
 end;
+
+
 function Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture;
 var tw, th, x, y: Longword;
     tmpp: pointer;
--- a/hedgewars/uVariables.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uVariables.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -624,7 +624,7 @@
             Width:  80; Height: 50; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprSDSplash
             (FileName:  'SDDroplet'; Path: ptCurrTheme; AltPath: ptSuddenDeath; Texture: nil; Surface: nil;
             Width:  16; Height: 16; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHighest; getDimensions: false; getImageDimensions: true),// sprSDDroplet
-            (FileName:  'Egg'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;//TODO change back 'Egg' to 'Tardis'
+            (FileName:  'TARDIS'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
             Width:  0; Height: 0; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: true; getImageDimensions: true),// sprTardis
             (FileName: 'firebutton'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
             Width: 450; Height: 150; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true) // sprFireButton
@@ -764,8 +764,8 @@
             (FileName:            'parachute.ogg'; Path: ptSounds),// sndParachute
             (FileName:                 'bump.ogg'; Path: ptSounds),// sndBump
             (FileName:            'hogchant3.ogg'; Path: ptSounds),// sndResurrector
-            (FileName:                'plane.ogg'; Path: ptSounds), // sndPlane
-            (FileName:                'plane.ogg'; Path: ptSounds) // sndTardis TODO change when using a new data set
+            (FileName:                'plane.ogg'; Path: ptSounds),// sndPlane
+            (FileName:               'TARDIS.ogg'; Path: ptSounds) // sndTardis
             );
 
     Ammoz: array [TAmmoType] of record
--- a/hedgewars/uVisualGears.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uVisualGears.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -120,11 +120,11 @@
 begin
 AddVisualGear:= nil;
 if ((GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet))) and // we are scrolling now
-   ((Kind <> vgtCloud) and not Critical) then exit;
+   ((Kind <> vgtCloud) and (not Critical)) then exit;
 
 if ((cReducedQuality and rqAntiBoom) <> 0) and
-   not Critical and
-   not (Kind in
+   (not Critical) and
+   (not (Kind in
    [vgtTeamHealthSorter,
     vgtSmallDamageTag,
     vgtSpeechBubble,
@@ -133,7 +133,7 @@
     vgtSmokeTrace,
     vgtEvilTrace,
     vgtNote,
-    vgtSmoothWindBar]) then exit;
+    vgtSmoothWindBar])) then exit;
 
 inc(VGCounter);
 New(gear);
--- a/hedgewars/uWorld.pas	Mon Nov 28 06:55:55 2011 +0100
+++ b/hedgewars/uWorld.pas	Mon Dec 05 18:38:25 2011 -0500
@@ -82,29 +82,30 @@
       cStereo_Water_near    = 0.0025;
       cStereo_Outside       = -0.0400;
 
+
+// helper functions to create the goal/game mode string
+function AddGoal(s: ansistring; gf: longword; si: TGoalStrId; i: LongInt): ansistring;
+var t: ansistring;
+begin
+    if (GameFlags and gf) <> 0 then
+        begin
+        t:= inttostr(i);
+        s:= s + format(trgoal[si], t) + '|'
+        end;
+    AddGoal:= s;
+end;
+
+function AddGoal(s: ansistring; gf: longword; si: TGoalStrId): ansistring;
+begin
+    if (GameFlags and gf) <> 0 then
+        s:= s + trgoal[si] + '|';
+    AddGoal:= s;
+end;
+
 procedure InitWorld;
 var i, t: LongInt;
     cp: PClan;
     g: ansistring;
-
-    // helper functions to create the goal/game mode string
-    function AddGoal(s: ansistring; gf: longword; si: TGoalStrId; i: LongInt): ansistring;
-    var t: ansistring;
-    begin
-        if (GameFlags and gf) <> 0 then
-            begin
-            t:= inttostr(i);
-            s:= s + format(trgoal[si], t) + '|'
-            end;
-        AddGoal:= s;
-    end;
-
-    function AddGoal(s: ansistring; gf: longword; si: TGoalStrId): ansistring;
-    begin
-        if (GameFlags and gf) <> 0 then
-            s:= s + trgoal[si] + '|';
-        AddGoal:= s;
-    end;
 begin
 missionTimer:= 0;
 
@@ -1220,11 +1221,11 @@
     PrevSentPointTime: LongWord = 0;
 begin
 {$IFNDEF MOBILE}
-if (not (CurrentTeam^.ExtDriven and isCursorVisible and not bShowAmmoMenu)) and cHasFocus and (GameState <> gsConfirm) then
+if (not (CurrentTeam^.ExtDriven and isCursorVisible and (not bShowAmmoMenu))) and cHasFocus and (GameState <> gsConfirm) then
     uCursor.updatePosition();
 {$ENDIF}
 z:= round(200/zoom);
-if not PlacingHogs and (FollowGear <> nil) and not isCursorVisible and not bShowAmmoMenu and not fastUntilLag then
+if not PlacingHogs and (FollowGear <> nil) and (not isCursorVisible) and (not bShowAmmoMenu) and (not fastUntilLag) then
     if (not autoCameraOn) or ((abs(CursorPoint.X - prevPoint.X) + abs(CursorPoint.Y - prevpoint.Y)) > 4) then
         begin
         FollowGear:= nil;
--- a/misc/libtremor/Xcode/Tremor.xcodeproj/project.pbxproj	Mon Nov 28 06:55:55 2011 +0100
+++ b/misc/libtremor/Xcode/Tremor.xcodeproj/project.pbxproj	Mon Dec 05 18:38:25 2011 -0500
@@ -7,77 +7,77 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
-		61958DC31364B72000B429B6 /* asm_arm.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DA61364B72000B429B6 /* asm_arm.h */; };
-		61958DC41364B72000B429B6 /* backends.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DA71364B72000B429B6 /* backends.h */; };
-		61958DC51364B72000B429B6 /* block.c in Sources */ = {isa = PBXBuildFile; fileRef = 61958DA81364B72000B429B6 /* block.c */; };
-		61958DC61364B72000B429B6 /* block.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DA91364B72000B429B6 /* block.h */; };
-		61958DC71364B72000B429B6 /* codebook.c in Sources */ = {isa = PBXBuildFile; fileRef = 61958DAA1364B72000B429B6 /* codebook.c */; };
-		61958DC81364B72000B429B6 /* codebook.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DAB1364B72000B429B6 /* codebook.h */; };
-		61958DC91364B72000B429B6 /* codec_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DAC1364B72000B429B6 /* codec_internal.h */; };
-		61958DCA1364B72000B429B6 /* config_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DAD1364B72000B429B6 /* config_types.h */; };
-		61958DCB1364B72000B429B6 /* floor0.c in Sources */ = {isa = PBXBuildFile; fileRef = 61958DAE1364B72000B429B6 /* floor0.c */; };
-		61958DCC1364B72000B429B6 /* floor1.c in Sources */ = {isa = PBXBuildFile; fileRef = 61958DAF1364B72000B429B6 /* floor1.c */; };
-		61958DCD1364B72000B429B6 /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = 61958DB01364B72000B429B6 /* info.c */; };
-		61958DCE1364B72000B429B6 /* ivorbiscodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DB11364B72000B429B6 /* ivorbiscodec.h */; };
-		61958DCF1364B72000B429B6 /* ivorbisfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DB21364B72000B429B6 /* ivorbisfile.h */; };
-		61958DD01364B72000B429B6 /* lsp_lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DB31364B72000B429B6 /* lsp_lookup.h */; };
-		61958DD11364B72000B429B6 /* mapping0.c in Sources */ = {isa = PBXBuildFile; fileRef = 61958DB41364B72000B429B6 /* mapping0.c */; };
-		61958DD21364B72000B429B6 /* mdct_lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DB51364B72000B429B6 /* mdct_lookup.h */; };
-		61958DD31364B72000B429B6 /* mdct.c in Sources */ = {isa = PBXBuildFile; fileRef = 61958DB61364B72000B429B6 /* mdct.c */; };
-		61958DD41364B72000B429B6 /* mdct.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DB71364B72000B429B6 /* mdct.h */; };
-		61958DD51364B72000B429B6 /* misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DB81364B72000B429B6 /* misc.h */; };
-		61958DD61364B72000B429B6 /* os.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DB91364B72000B429B6 /* os.h */; };
-		61958DD71364B72000B429B6 /* registry.c in Sources */ = {isa = PBXBuildFile; fileRef = 61958DBA1364B72000B429B6 /* registry.c */; };
-		61958DD81364B72000B429B6 /* registry.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DBB1364B72000B429B6 /* registry.h */; };
-		61958DD91364B72000B429B6 /* res012.c in Sources */ = {isa = PBXBuildFile; fileRef = 61958DBC1364B72000B429B6 /* res012.c */; };
-		61958DDA1364B72000B429B6 /* sharedbook.c in Sources */ = {isa = PBXBuildFile; fileRef = 61958DBD1364B72000B429B6 /* sharedbook.c */; };
-		61958DDB1364B72000B429B6 /* synthesis.c in Sources */ = {isa = PBXBuildFile; fileRef = 61958DBE1364B72000B429B6 /* synthesis.c */; };
-		61958DDC1364B72000B429B6 /* vorbisfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 61958DBF1364B72000B429B6 /* vorbisfile.c */; };
-		61958DDD1364B72000B429B6 /* window_lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DC01364B72000B429B6 /* window_lookup.h */; };
-		61958DDE1364B72000B429B6 /* window.c in Sources */ = {isa = PBXBuildFile; fileRef = 61958DC11364B72000B429B6 /* window.c */; };
-		61958DDF1364B72000B429B6 /* window.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DC21364B72000B429B6 /* window.h */; };
-		61958DFC1364B84300B429B6 /* os_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958DFB1364B84300B429B6 /* os_types.h */; };
-		61958E0E1364B89700B429B6 /* ogg.h in Headers */ = {isa = PBXBuildFile; fileRef = 61958E0D1364B89700B429B6 /* ogg.h */; };
-		619598391364BDCC00B429B6 /* framing.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598381364BDCC00B429B6 /* framing.c */; };
-		619598411364BE7F00B429B6 /* bitwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598401364BE7F00B429B6 /* bitwise.c */; };
+		61DB1809148BA9A9004A67B8 /* asm_arm.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17E7148BA9A9004A67B8 /* asm_arm.h */; };
+		61DB180A148BA9A9004A67B8 /* backends.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17E8148BA9A9004A67B8 /* backends.h */; };
+		61DB180B148BA9A9004A67B8 /* bitwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB17E9148BA9A9004A67B8 /* bitwise.c */; };
+		61DB180C148BA9A9004A67B8 /* block.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB17EA148BA9A9004A67B8 /* block.c */; };
+		61DB180D148BA9A9004A67B8 /* block.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17EB148BA9A9004A67B8 /* block.h */; };
+		61DB180E148BA9A9004A67B8 /* codebook.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB17EC148BA9A9004A67B8 /* codebook.c */; };
+		61DB180F148BA9A9004A67B8 /* codebook.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17ED148BA9A9004A67B8 /* codebook.h */; };
+		61DB1810148BA9A9004A67B8 /* codec_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17EE148BA9A9004A67B8 /* codec_internal.h */; };
+		61DB1811148BA9A9004A67B8 /* config_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17EF148BA9A9004A67B8 /* config_types.h */; };
+		61DB1812148BA9A9004A67B8 /* floor0.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB17F0148BA9A9004A67B8 /* floor0.c */; };
+		61DB1813148BA9A9004A67B8 /* floor1.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB17F1148BA9A9004A67B8 /* floor1.c */; };
+		61DB1814148BA9A9004A67B8 /* framing.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB17F2148BA9A9004A67B8 /* framing.c */; };
+		61DB1815148BA9A9004A67B8 /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB17F3148BA9A9004A67B8 /* info.c */; };
+		61DB1816148BA9A9004A67B8 /* ivorbiscodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17F4148BA9A9004A67B8 /* ivorbiscodec.h */; };
+		61DB1818148BA9A9004A67B8 /* ivorbisfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17F6148BA9A9004A67B8 /* ivorbisfile.h */; };
+		61DB1819148BA9A9004A67B8 /* lsp_lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17F7148BA9A9004A67B8 /* lsp_lookup.h */; };
+		61DB181A148BA9A9004A67B8 /* mapping0.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB17F8148BA9A9004A67B8 /* mapping0.c */; };
+		61DB181B148BA9A9004A67B8 /* mdct_lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17F9148BA9A9004A67B8 /* mdct_lookup.h */; };
+		61DB181C148BA9A9004A67B8 /* mdct.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB17FA148BA9A9004A67B8 /* mdct.c */; };
+		61DB181D148BA9A9004A67B8 /* mdct.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17FB148BA9A9004A67B8 /* mdct.h */; };
+		61DB181E148BA9A9004A67B8 /* misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17FC148BA9A9004A67B8 /* misc.h */; };
+		61DB181F148BA9A9004A67B8 /* ogg.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17FD148BA9A9004A67B8 /* ogg.h */; };
+		61DB1820148BA9A9004A67B8 /* os_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17FE148BA9A9004A67B8 /* os_types.h */; };
+		61DB1821148BA9A9004A67B8 /* os.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17FF148BA9A9004A67B8 /* os.h */; };
+		61DB1822148BA9A9004A67B8 /* registry.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB1800148BA9A9004A67B8 /* registry.c */; };
+		61DB1823148BA9A9004A67B8 /* registry.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB1801148BA9A9004A67B8 /* registry.h */; };
+		61DB1824148BA9A9004A67B8 /* res012.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB1802148BA9A9004A67B8 /* res012.c */; };
+		61DB1825148BA9A9004A67B8 /* sharedbook.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB1803148BA9A9004A67B8 /* sharedbook.c */; };
+		61DB1826148BA9A9004A67B8 /* synthesis.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB1804148BA9A9004A67B8 /* synthesis.c */; };
+		61DB1827148BA9A9004A67B8 /* vorbisfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB1805148BA9A9004A67B8 /* vorbisfile.c */; };
+		61DB1828148BA9A9004A67B8 /* window_lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB1806148BA9A9004A67B8 /* window_lookup.h */; };
+		61DB1829148BA9A9004A67B8 /* window.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB1807148BA9A9004A67B8 /* window.c */; };
+		61DB182A148BA9A9004A67B8 /* window.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB1808148BA9A9004A67B8 /* window.h */; };
 		AA747D9F0F9514B9006C5449 /* Tremor_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* Tremor_Prefix.pch */; };
 		AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
-		61958DA61364B72000B429B6 /* asm_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asm_arm.h; path = ../asm_arm.h; sourceTree = SOURCE_ROOT; };
-		61958DA71364B72000B429B6 /* backends.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = backends.h; path = ../backends.h; sourceTree = SOURCE_ROOT; };
-		61958DA81364B72000B429B6 /* block.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = block.c; path = ../block.c; sourceTree = SOURCE_ROOT; };
-		61958DA91364B72000B429B6 /* block.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = block.h; path = ../block.h; sourceTree = SOURCE_ROOT; };
-		61958DAA1364B72000B429B6 /* codebook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = codebook.c; path = ../codebook.c; sourceTree = SOURCE_ROOT; };
-		61958DAB1364B72000B429B6 /* codebook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = codebook.h; path = ../codebook.h; sourceTree = SOURCE_ROOT; };
-		61958DAC1364B72000B429B6 /* codec_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = codec_internal.h; path = ../codec_internal.h; sourceTree = SOURCE_ROOT; };
-		61958DAD1364B72000B429B6 /* config_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config_types.h; path = ../config_types.h; sourceTree = SOURCE_ROOT; };
-		61958DAE1364B72000B429B6 /* floor0.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = floor0.c; path = ../floor0.c; sourceTree = SOURCE_ROOT; };
-		61958DAF1364B72000B429B6 /* floor1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = floor1.c; path = ../floor1.c; sourceTree = SOURCE_ROOT; };
-		61958DB01364B72000B429B6 /* info.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = info.c; path = ../info.c; sourceTree = SOURCE_ROOT; };
-		61958DB11364B72000B429B6 /* ivorbiscodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ivorbiscodec.h; path = ../ivorbiscodec.h; sourceTree = SOURCE_ROOT; };
-		61958DB21364B72000B429B6 /* ivorbisfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ivorbisfile.h; path = ../ivorbisfile.h; sourceTree = SOURCE_ROOT; };
-		61958DB31364B72000B429B6 /* lsp_lookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lsp_lookup.h; path = ../lsp_lookup.h; sourceTree = SOURCE_ROOT; };
-		61958DB41364B72000B429B6 /* mapping0.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mapping0.c; path = ../mapping0.c; sourceTree = SOURCE_ROOT; };
-		61958DB51364B72000B429B6 /* mdct_lookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mdct_lookup.h; path = ../mdct_lookup.h; sourceTree = SOURCE_ROOT; };
-		61958DB61364B72000B429B6 /* mdct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mdct.c; path = ../mdct.c; sourceTree = SOURCE_ROOT; };
-		61958DB71364B72000B429B6 /* mdct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mdct.h; path = ../mdct.h; sourceTree = SOURCE_ROOT; };
-		61958DB81364B72000B429B6 /* misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = misc.h; path = ../misc.h; sourceTree = SOURCE_ROOT; };
-		61958DB91364B72000B429B6 /* os.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = os.h; path = ../os.h; sourceTree = SOURCE_ROOT; };
-		61958DBA1364B72000B429B6 /* registry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = registry.c; path = ../registry.c; sourceTree = SOURCE_ROOT; };
-		61958DBB1364B72000B429B6 /* registry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = registry.h; path = ../registry.h; sourceTree = SOURCE_ROOT; };
-		61958DBC1364B72000B429B6 /* res012.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = res012.c; path = ../res012.c; sourceTree = SOURCE_ROOT; };
-		61958DBD1364B72000B429B6 /* sharedbook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sharedbook.c; path = ../sharedbook.c; sourceTree = SOURCE_ROOT; };
-		61958DBE1364B72000B429B6 /* synthesis.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = synthesis.c; path = ../synthesis.c; sourceTree = SOURCE_ROOT; };
-		61958DBF1364B72000B429B6 /* vorbisfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vorbisfile.c; path = ../vorbisfile.c; sourceTree = SOURCE_ROOT; };
-		61958DC01364B72000B429B6 /* window_lookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = window_lookup.h; path = ../window_lookup.h; sourceTree = SOURCE_ROOT; };
-		61958DC11364B72000B429B6 /* window.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = window.c; path = ../window.c; sourceTree = SOURCE_ROOT; };
-		61958DC21364B72000B429B6 /* window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = window.h; path = ../window.h; sourceTree = SOURCE_ROOT; };
-		61958DFB1364B84300B429B6 /* os_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = os_types.h; path = ../../../../Library/cocos2d/external/Tremor/os_types.h; sourceTree = SOURCE_ROOT; };
-		61958E0D1364B89700B429B6 /* ogg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ogg.h; path = ../ogg.h; sourceTree = SOURCE_ROOT; };
-		619598381364BDCC00B429B6 /* framing.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = framing.c; path = ../framing.c; sourceTree = "<group>"; };
-		619598401364BE7F00B429B6 /* bitwise.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bitwise.c; path = ../bitwise.c; sourceTree = "<group>"; };
+		61DB17E7148BA9A9004A67B8 /* asm_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asm_arm.h; path = ../tremor/asm_arm.h; sourceTree = SOURCE_ROOT; };
+		61DB17E8148BA9A9004A67B8 /* backends.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = backends.h; path = ../tremor/backends.h; sourceTree = SOURCE_ROOT; };
+		61DB17E9148BA9A9004A67B8 /* bitwise.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bitwise.c; path = ../tremor/bitwise.c; sourceTree = SOURCE_ROOT; };
+		61DB17EA148BA9A9004A67B8 /* block.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = block.c; path = ../tremor/block.c; sourceTree = SOURCE_ROOT; };
+		61DB17EB148BA9A9004A67B8 /* block.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = block.h; path = ../tremor/block.h; sourceTree = SOURCE_ROOT; };
+		61DB17EC148BA9A9004A67B8 /* codebook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = codebook.c; path = ../tremor/codebook.c; sourceTree = SOURCE_ROOT; };
+		61DB17ED148BA9A9004A67B8 /* codebook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = codebook.h; path = ../tremor/codebook.h; sourceTree = SOURCE_ROOT; };
+		61DB17EE148BA9A9004A67B8 /* codec_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = codec_internal.h; path = ../tremor/codec_internal.h; sourceTree = SOURCE_ROOT; };
+		61DB17EF148BA9A9004A67B8 /* config_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config_types.h; path = ../tremor/config_types.h; sourceTree = SOURCE_ROOT; };
+		61DB17F0148BA9A9004A67B8 /* floor0.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = floor0.c; path = ../tremor/floor0.c; sourceTree = SOURCE_ROOT; };
+		61DB17F1148BA9A9004A67B8 /* floor1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = floor1.c; path = ../tremor/floor1.c; sourceTree = SOURCE_ROOT; };
+		61DB17F2148BA9A9004A67B8 /* framing.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = framing.c; path = ../tremor/framing.c; sourceTree = SOURCE_ROOT; };
+		61DB17F3148BA9A9004A67B8 /* info.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = info.c; path = ../tremor/info.c; sourceTree = SOURCE_ROOT; };
+		61DB17F4148BA9A9004A67B8 /* ivorbiscodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ivorbiscodec.h; path = ../tremor/ivorbiscodec.h; sourceTree = SOURCE_ROOT; };
+		61DB17F6148BA9A9004A67B8 /* ivorbisfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ivorbisfile.h; path = ../tremor/ivorbisfile.h; sourceTree = SOURCE_ROOT; };
+		61DB17F7148BA9A9004A67B8 /* lsp_lookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lsp_lookup.h; path = ../tremor/lsp_lookup.h; sourceTree = SOURCE_ROOT; };
+		61DB17F8148BA9A9004A67B8 /* mapping0.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mapping0.c; path = ../tremor/mapping0.c; sourceTree = SOURCE_ROOT; };
+		61DB17F9148BA9A9004A67B8 /* mdct_lookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mdct_lookup.h; path = ../tremor/mdct_lookup.h; sourceTree = SOURCE_ROOT; };
+		61DB17FA148BA9A9004A67B8 /* mdct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mdct.c; path = ../tremor/mdct.c; sourceTree = SOURCE_ROOT; };
+		61DB17FB148BA9A9004A67B8 /* mdct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mdct.h; path = ../tremor/mdct.h; sourceTree = SOURCE_ROOT; };
+		61DB17FC148BA9A9004A67B8 /* misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = misc.h; path = ../tremor/misc.h; sourceTree = SOURCE_ROOT; };
+		61DB17FD148BA9A9004A67B8 /* ogg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ogg.h; path = ../tremor/ogg.h; sourceTree = SOURCE_ROOT; };
+		61DB17FE148BA9A9004A67B8 /* os_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = os_types.h; path = ../tremor/os_types.h; sourceTree = SOURCE_ROOT; };
+		61DB17FF148BA9A9004A67B8 /* os.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = os.h; path = ../tremor/os.h; sourceTree = SOURCE_ROOT; };
+		61DB1800148BA9A9004A67B8 /* registry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = registry.c; path = ../tremor/registry.c; sourceTree = SOURCE_ROOT; };
+		61DB1801148BA9A9004A67B8 /* registry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = registry.h; path = ../tremor/registry.h; sourceTree = SOURCE_ROOT; };
+		61DB1802148BA9A9004A67B8 /* res012.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = res012.c; path = ../tremor/res012.c; sourceTree = SOURCE_ROOT; };
+		61DB1803148BA9A9004A67B8 /* sharedbook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sharedbook.c; path = ../tremor/sharedbook.c; sourceTree = SOURCE_ROOT; };
+		61DB1804148BA9A9004A67B8 /* synthesis.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = synthesis.c; path = ../tremor/synthesis.c; sourceTree = SOURCE_ROOT; };
+		61DB1805148BA9A9004A67B8 /* vorbisfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vorbisfile.c; path = ../tremor/vorbisfile.c; sourceTree = SOURCE_ROOT; };
+		61DB1806148BA9A9004A67B8 /* window_lookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = window_lookup.h; path = ../tremor/window_lookup.h; sourceTree = SOURCE_ROOT; };
+		61DB1807148BA9A9004A67B8 /* window.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = window.c; path = ../tremor/window.c; sourceTree = SOURCE_ROOT; };
+		61DB1808148BA9A9004A67B8 /* window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = window.h; path = ../tremor/window.h; sourceTree = SOURCE_ROOT; };
 		AA747D9E0F9514B9006C5449 /* Tremor_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tremor_Prefix.pch; sourceTree = SOURCE_ROOT; };
 		AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
 		D2AAC07E0554694100DB518D /* libTremor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTremor.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -125,39 +125,39 @@
 		08FB77AEFE84172EC02AAC07 /* Sources */ = {
 			isa = PBXGroup;
 			children = (
-				619598401364BE7F00B429B6 /* bitwise.c */,
-				619598381364BDCC00B429B6 /* framing.c */,
-				61958DA61364B72000B429B6 /* asm_arm.h */,
-				61958DA71364B72000B429B6 /* backends.h */,
-				61958DA81364B72000B429B6 /* block.c */,
-				61958DA91364B72000B429B6 /* block.h */,
-				61958DAA1364B72000B429B6 /* codebook.c */,
-				61958DAB1364B72000B429B6 /* codebook.h */,
-				61958DAC1364B72000B429B6 /* codec_internal.h */,
-				61958DAD1364B72000B429B6 /* config_types.h */,
-				61958DAE1364B72000B429B6 /* floor0.c */,
-				61958DAF1364B72000B429B6 /* floor1.c */,
-				61958DB01364B72000B429B6 /* info.c */,
-				61958DB11364B72000B429B6 /* ivorbiscodec.h */,
-				61958DB21364B72000B429B6 /* ivorbisfile.h */,
-				61958DB31364B72000B429B6 /* lsp_lookup.h */,
-				61958DB41364B72000B429B6 /* mapping0.c */,
-				61958DB51364B72000B429B6 /* mdct_lookup.h */,
-				61958DB61364B72000B429B6 /* mdct.c */,
-				61958DB71364B72000B429B6 /* mdct.h */,
-				61958DB81364B72000B429B6 /* misc.h */,
-				61958E0D1364B89700B429B6 /* ogg.h */,
-				61958DB91364B72000B429B6 /* os.h */,
-				61958DFB1364B84300B429B6 /* os_types.h */,
-				61958DBA1364B72000B429B6 /* registry.c */,
-				61958DBB1364B72000B429B6 /* registry.h */,
-				61958DBC1364B72000B429B6 /* res012.c */,
-				61958DBD1364B72000B429B6 /* sharedbook.c */,
-				61958DBE1364B72000B429B6 /* synthesis.c */,
-				61958DBF1364B72000B429B6 /* vorbisfile.c */,
-				61958DC01364B72000B429B6 /* window_lookup.h */,
-				61958DC11364B72000B429B6 /* window.c */,
-				61958DC21364B72000B429B6 /* window.h */,
+				61DB17E7148BA9A9004A67B8 /* asm_arm.h */,
+				61DB17E8148BA9A9004A67B8 /* backends.h */,
+				61DB17E9148BA9A9004A67B8 /* bitwise.c */,
+				61DB17EA148BA9A9004A67B8 /* block.c */,
+				61DB17EB148BA9A9004A67B8 /* block.h */,
+				61DB17EC148BA9A9004A67B8 /* codebook.c */,
+				61DB17ED148BA9A9004A67B8 /* codebook.h */,
+				61DB17EE148BA9A9004A67B8 /* codec_internal.h */,
+				61DB17EF148BA9A9004A67B8 /* config_types.h */,
+				61DB17F0148BA9A9004A67B8 /* floor0.c */,
+				61DB17F1148BA9A9004A67B8 /* floor1.c */,
+				61DB17F2148BA9A9004A67B8 /* framing.c */,
+				61DB17F3148BA9A9004A67B8 /* info.c */,
+				61DB17F4148BA9A9004A67B8 /* ivorbiscodec.h */,
+				61DB17F6148BA9A9004A67B8 /* ivorbisfile.h */,
+				61DB17F7148BA9A9004A67B8 /* lsp_lookup.h */,
+				61DB17F8148BA9A9004A67B8 /* mapping0.c */,
+				61DB17F9148BA9A9004A67B8 /* mdct_lookup.h */,
+				61DB17FA148BA9A9004A67B8 /* mdct.c */,
+				61DB17FB148BA9A9004A67B8 /* mdct.h */,
+				61DB17FC148BA9A9004A67B8 /* misc.h */,
+				61DB17FD148BA9A9004A67B8 /* ogg.h */,
+				61DB17FE148BA9A9004A67B8 /* os_types.h */,
+				61DB17FF148BA9A9004A67B8 /* os.h */,
+				61DB1800148BA9A9004A67B8 /* registry.c */,
+				61DB1801148BA9A9004A67B8 /* registry.h */,
+				61DB1802148BA9A9004A67B8 /* res012.c */,
+				61DB1803148BA9A9004A67B8 /* sharedbook.c */,
+				61DB1804148BA9A9004A67B8 /* synthesis.c */,
+				61DB1805148BA9A9004A67B8 /* vorbisfile.c */,
+				61DB1806148BA9A9004A67B8 /* window_lookup.h */,
+				61DB1807148BA9A9004A67B8 /* window.c */,
+				61DB1808148BA9A9004A67B8 /* window.h */,
 			);
 			name = Sources;
 			sourceTree = "<group>";
@@ -178,24 +178,24 @@
 			buildActionMask = 2147483647;
 			files = (
 				AA747D9F0F9514B9006C5449 /* Tremor_Prefix.pch in Headers */,
-				61958DC31364B72000B429B6 /* asm_arm.h in Headers */,
-				61958DC41364B72000B429B6 /* backends.h in Headers */,
-				61958DC61364B72000B429B6 /* block.h in Headers */,
-				61958DC81364B72000B429B6 /* codebook.h in Headers */,
-				61958DC91364B72000B429B6 /* codec_internal.h in Headers */,
-				61958DCA1364B72000B429B6 /* config_types.h in Headers */,
-				61958DCE1364B72000B429B6 /* ivorbiscodec.h in Headers */,
-				61958DCF1364B72000B429B6 /* ivorbisfile.h in Headers */,
-				61958DD01364B72000B429B6 /* lsp_lookup.h in Headers */,
-				61958DD21364B72000B429B6 /* mdct_lookup.h in Headers */,
-				61958DD41364B72000B429B6 /* mdct.h in Headers */,
-				61958DD51364B72000B429B6 /* misc.h in Headers */,
-				61958DD61364B72000B429B6 /* os.h in Headers */,
-				61958DD81364B72000B429B6 /* registry.h in Headers */,
-				61958DDD1364B72000B429B6 /* window_lookup.h in Headers */,
-				61958DDF1364B72000B429B6 /* window.h in Headers */,
-				61958DFC1364B84300B429B6 /* os_types.h in Headers */,
-				61958E0E1364B89700B429B6 /* ogg.h in Headers */,
+				61DB1809148BA9A9004A67B8 /* asm_arm.h in Headers */,
+				61DB180A148BA9A9004A67B8 /* backends.h in Headers */,
+				61DB180D148BA9A9004A67B8 /* block.h in Headers */,
+				61DB180F148BA9A9004A67B8 /* codebook.h in Headers */,
+				61DB1810148BA9A9004A67B8 /* codec_internal.h in Headers */,
+				61DB1811148BA9A9004A67B8 /* config_types.h in Headers */,
+				61DB1816148BA9A9004A67B8 /* ivorbiscodec.h in Headers */,
+				61DB1818148BA9A9004A67B8 /* ivorbisfile.h in Headers */,
+				61DB1819148BA9A9004A67B8 /* lsp_lookup.h in Headers */,
+				61DB181B148BA9A9004A67B8 /* mdct_lookup.h in Headers */,
+				61DB181D148BA9A9004A67B8 /* mdct.h in Headers */,
+				61DB181E148BA9A9004A67B8 /* misc.h in Headers */,
+				61DB181F148BA9A9004A67B8 /* ogg.h in Headers */,
+				61DB1820148BA9A9004A67B8 /* os_types.h in Headers */,
+				61DB1821148BA9A9004A67B8 /* os.h in Headers */,
+				61DB1823148BA9A9004A67B8 /* registry.h in Headers */,
+				61DB1828148BA9A9004A67B8 /* window_lookup.h in Headers */,
+				61DB182A148BA9A9004A67B8 /* window.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -249,21 +249,21 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				619598411364BE7F00B429B6 /* bitwise.c in Sources */,
-				61958DC51364B72000B429B6 /* block.c in Sources */,
-				61958DC71364B72000B429B6 /* codebook.c in Sources */,
-				619598391364BDCC00B429B6 /* framing.c in Sources */,
-				61958DCB1364B72000B429B6 /* floor0.c in Sources */,
-				61958DCC1364B72000B429B6 /* floor1.c in Sources */,
-				61958DCD1364B72000B429B6 /* info.c in Sources */,
-				61958DD11364B72000B429B6 /* mapping0.c in Sources */,
-				61958DD31364B72000B429B6 /* mdct.c in Sources */,
-				61958DD71364B72000B429B6 /* registry.c in Sources */,
-				61958DD91364B72000B429B6 /* res012.c in Sources */,
-				61958DDA1364B72000B429B6 /* sharedbook.c in Sources */,
-				61958DDB1364B72000B429B6 /* synthesis.c in Sources */,
-				61958DDC1364B72000B429B6 /* vorbisfile.c in Sources */,
-				61958DDE1364B72000B429B6 /* window.c in Sources */,
+				61DB180B148BA9A9004A67B8 /* bitwise.c in Sources */,
+				61DB180C148BA9A9004A67B8 /* block.c in Sources */,
+				61DB180E148BA9A9004A67B8 /* codebook.c in Sources */,
+				61DB1812148BA9A9004A67B8 /* floor0.c in Sources */,
+				61DB1813148BA9A9004A67B8 /* floor1.c in Sources */,
+				61DB1814148BA9A9004A67B8 /* framing.c in Sources */,
+				61DB1815148BA9A9004A67B8 /* info.c in Sources */,
+				61DB181A148BA9A9004A67B8 /* mapping0.c in Sources */,
+				61DB181C148BA9A9004A67B8 /* mdct.c in Sources */,
+				61DB1822148BA9A9004A67B8 /* registry.c in Sources */,
+				61DB1824148BA9A9004A67B8 /* res012.c in Sources */,
+				61DB1825148BA9A9004A67B8 /* sharedbook.c in Sources */,
+				61DB1826148BA9A9004A67B8 /* synthesis.c in Sources */,
+				61DB1827148BA9A9004A67B8 /* vorbisfile.c in Sources */,
+				61DB1829148BA9A9004A67B8 /* window.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
--- a/project_files/Android-build/SDL-android-project/AndroidManifest.xml	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/AndroidManifest.xml	Mon Dec 05 18:38:25 2011 -0500
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="org.hedgewars.hedgeroid"
-      android:versionCode="5"
-      android:installLocation="preferExternal" android:versionName="0.1.2">
-    <uses-sdk android:targetSdkVersion="8" android:minSdkVersion="7"></uses-sdk>
+      android:versionCode="7"
+      android:installLocation="preferExternal" android:versionName="0.1.2.2">
+    <uses-sdk android:targetSdkVersion="14" android:minSdkVersion="7"></uses-sdk>
     <uses-permission android:name="android.permission.INTERNET"></uses-permission>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
     <application android:label="@string/app_name" android:icon="@drawable/icon">
--- a/project_files/Android-build/SDL-android-project/res/values/strings.xml	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/res/values/strings.xml	Mon Dec 05 18:38:25 2011 -0500
@@ -8,7 +8,8 @@
     <string name="saved">Saved succesfully</string>
     
     <!-- SDCARD -->
-    <string name="sdcard_not_mounted">There\'s been an error when accessing the sdcard, is it connected to another computer?</string>
+    <string name="sdcard_not_mounted_title">Sorry! Could not find the SDCard</string>
+    <string name="sdcard_not_mounted">There\'s been an error when accessing the SDcard. Please check if there is an SDcard present in the device (internal or external) and if the SDcard is not mounted (via usb to your computer for example). Hedgewars for Android will now quit</string>
         
     <!-- Notification -->
     <string name="notification_title">Downloading hedgewars files...</string>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/FrontendDataUtils.java	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,216 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.Utils;
+import org.hedgewars.hedgeroid.Datastructures.Map.MapType;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+public class FrontendDataUtils {
+
+
+	public static ArrayList<Map> getMaps(Context c){
+		File[] files = Utils.getFilesFromRelativeDir(c,"Maps");
+		ArrayList<Map> ret = new ArrayList<Map>();
+
+		for(File f : files){
+			if(Utils.hasFileWithSuffix(f, ".lua")){
+				ret.add(new Map(f,MapType.TYPE_MISSION, c));
+			}else{
+				ret.add(new Map(f, MapType.TYPE_DEFAULT,c));
+			}
+		}
+		Collections.sort(ret);
+
+		return ret;
+	}
+
+	public static List<String> getGameplay(Context c){
+		String[] files = Utils.getFileNamesFromRelativeDir(c, "Scripts/Multiplayer");
+		ArrayList<String> ret = new ArrayList<String>();
+		
+		for(int i = 0; i < files.length; i++){
+			if(files[i].endsWith(".lua")){
+				ret.add(files[i].replace('_', ' ').substring(0, files[i].length()-4)); //replace _ by a space and removed the last four characters (.lua)
+			}
+		}
+		ret.add(0,"None");
+		Collections.sort(ret);
+		return ret;	
+	}
+
+	public static List<String> getThemes(Context c){
+		List<String> list = Utils.getDirsWithFileSuffix(c, "Themes", "icon.png");
+		Collections.sort(list);
+		return list;
+	}
+
+	public static List<Scheme> getSchemes(Context c){
+		List<Scheme> list = Scheme.getSchemes(c);
+		Collections.sort(list);
+		return list;
+	}
+
+	public static List<Weapon> getWeapons(Context c){
+		List<Weapon> list = Weapon.getWeapons(c);
+		Collections.sort(list);
+		return list;
+	}
+
+	public static ArrayList<HashMap<String, ?>> getGraves(Context c){
+		String pathPrefix = Utils.getDataPath(c) + "Graphics/Graves/";
+		ArrayList<String> names = Utils.getFilesFromDirWithSuffix(c,"Graphics/Graves", ".png", true);
+		ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(names.size());
+
+		for(String s : names){
+			HashMap<String, Object> map = new HashMap<String, Object>();
+			map.put("txt", s);
+			Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap
+			int width = b.getWidth();
+			if(b.getHeight() > width){//some pictures contain more 'frames' underneath each other, if so we only use the first frame
+				Bitmap tmp = Bitmap.createBitmap(b, 0, 0, width, width);
+				b.recycle();
+				b = tmp;
+			}
+			map.put("img", b);
+			data.add(map);
+		}
+		return data;
+	}
+
+	public static ArrayList<HashMap<String, ?>> getFlags(Context c){
+		String pathPrefix = Utils.getDataPath(c) + "Graphics/Flags/";
+		ArrayList<String> names = Utils.getFilesFromDirWithSuffix(c, "Graphics/Flags", ".png", true);
+		ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(names.size());
+
+		for(String s : names){
+			HashMap<String, Object> map = new HashMap<String, Object>();
+			map.put("txt", s);
+			Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap
+			map.put("img", b);
+			data.add(map);
+		}
+		return data;
+	}
+
+	public static ArrayList<String> getVoices(Context c){
+		File[] files = Utils.getFilesFromRelativeDir(c, "Sounds/voices");
+		ArrayList<String> ret = new ArrayList<String>();
+
+		for(File f : files){
+			if(f.isDirectory()) ret.add(f.getName());
+		}
+		return ret;
+	}
+
+	public static ArrayList<String> getForts(Context c){
+		return Utils.getFilesFromDirWithSuffix(c,"Forts", "L.png", true);
+	}
+	public static ArrayList<HashMap<String, ?>> getTypes(Context c){
+		ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(6);
+		String[] levels = {c.getString(R.string.human), c.getString(R.string.bot5), c.getString(R.string.bot4), c.getString(R.string.bot3), c.getString(R.string.bot2), c.getString(R.string.bot1)};
+		int[] images = {R.drawable.human, R.drawable.bot5, R.drawable.bot4, R.drawable.bot3, R.drawable.bot2, R.drawable.bot1};
+
+		for(int i = 0; i < levels.length; i++){
+			HashMap<String, Object> map = new HashMap<String, Object>();
+			map.put("txt", levels[i]);
+			map.put("img", images[i]);
+			data.add(map);
+		}
+
+		return data;
+	}
+
+	public static ArrayList<HashMap<String, ?>> getHats(Context c){
+		ArrayList<String> files = Utils.getFilesFromDirWithSuffix(c,"Graphics/Hats", ".png", true);
+		String pathPrefix = Utils.getDataPath(c) + "Graphics/Hats/";
+		int size = files.size();
+		ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(size);
+
+		HashMap<String, Object> hashmap; 
+		for(String s : files){
+			hashmap = new HashMap<String, Object>();
+			hashmap.put("txt", s);
+			Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap
+			b = Bitmap.createBitmap(b, 0,0,b.getWidth()/2, b.getWidth()/2);
+			hashmap.put("img", b);
+			data.add(hashmap);
+		}
+
+		return data;
+	}
+
+	public static List<HashMap<String, Object>> getTeams(Context c){
+		List<HashMap<String, Object>> ret = new ArrayList<HashMap<String, Object>>();
+
+		File teamsDir = new File(c.getFilesDir().getAbsolutePath() + '/' + Team.DIRECTORY_TEAMS);
+		File[] teamFileNames = teamsDir.listFiles();
+		if(teamFileNames != null){
+			for(File s : teamFileNames){
+				Team t = Team.getTeamFromXml(s.getAbsolutePath());
+				if(t != null){
+					t.file = s.getName();
+					ret.add(teamToMap(t));
+				}
+			}
+		}
+		return ret;
+	}
+
+	public static HashMap<String, Object> teamToMap(Team t){
+		HashMap<String, Object> hashmap = new HashMap<String, Object>();
+		hashmap.put("team", t);
+		hashmap.put("txt", t.name);
+		hashmap.put("color", t.color);
+		hashmap.put("count", t.hogCount);
+		switch(t.levels[0]){
+		case 0:
+			hashmap.put("img", R.drawable.human);
+			break;
+		case 1:
+			hashmap.put("img", R.drawable.bot5);
+			break;
+		case 2:
+			hashmap.put("img", R.drawable.bot4);
+			break;
+		case 3:
+			hashmap.put("img", R.drawable.bot3);
+			break;
+		case 4:
+			hashmap.put("img", R.drawable.bot2);
+			break;
+		default:
+		case 5:
+			hashmap.put("img", R.drawable.bot1);
+			break;
+		}
+		return hashmap;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/GameMode.java	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,24 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+public enum GameMode {
+		MODE_LOCAL, MODE_DEMO, MODE_NET, MODE_SAVE
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Grave.java	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,36 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+public class Grave{
+
+	public final String name;
+	public final String path;
+	
+	public Grave(String _name, String _path) {
+		name = _name;
+		path = _path;
+	}
+
+	public String toString(){
+		return name;
+	}
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Map.java	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,163 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork;
+
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class Map implements Comparable<Map>, Parcelable{
+
+	private static final String MISSION_PREFIX = "Mission: ";
+
+	private String name;
+	private String path;
+	private String previewPath;
+	private MapType type;
+
+	public Map(File mapDir, MapType _type, Context c){
+		type = _type;
+
+		name = mapDir.getName();
+		path = mapDir.getAbsolutePath();
+		previewPath = path + "/preview.png";
+		
+		/*switch(type){
+		case TYPE_DEFAULT:
+			
+			break;
+		case TYPE_GENERATED:
+			//TODO
+			break;
+		case TYPE_MISSION:
+			name = MISSION_PREFIX + mapDir.getName();
+			path = mapDir.getAbsolutePath();
+			break;
+		}*/
+
+		
+	}
+	
+	public Map(Parcel in){
+		readFromParcel(in);
+	}
+
+	public String toString(){
+		switch(type){
+		default:
+		case TYPE_DEFAULT:
+			return name;
+		case TYPE_GENERATED:
+			return "bla";
+		case TYPE_MISSION:
+			return MISSION_PREFIX + name;
+		}
+	}
+	
+	public void sendToEngine(EngineProtocolNetwork epn) throws IOException{
+		epn.sendToEngine(String.format("emap %s",name));
+	}
+	
+	public MapType getType(){
+		return type;
+	}
+
+	public Drawable getDrawable(){
+		switch(type){
+		case TYPE_MISSION:
+		case TYPE_DEFAULT:
+			return Drawable.createFromPath(previewPath);
+		case TYPE_GENERATED:
+
+		default:
+			return null;
+		}
+	}
+
+	public int compareTo(Map another) {
+		switch(type){
+		case TYPE_GENERATED:
+			switch(another.getType()){
+			case TYPE_GENERATED:
+				return name.compareTo(another.name);
+			case TYPE_MISSION:
+				return -1;
+			case TYPE_DEFAULT:
+				return -1;
+			}
+		case TYPE_MISSION:
+			switch(another.getType()){
+			case TYPE_GENERATED:
+				return 1;
+			case TYPE_MISSION:
+				return name.compareTo(another.name);
+			case TYPE_DEFAULT:
+				return -1;
+			}
+		case TYPE_DEFAULT:
+			switch(another.getType()){
+			case TYPE_GENERATED:
+				return 1;
+			case TYPE_MISSION:
+				return 1;
+			case TYPE_DEFAULT:
+				return name.compareTo(another.name);
+			}
+		}
+		return 0;//default case this should never happen
+	}
+
+	public enum MapType{
+		TYPE_DEFAULT, TYPE_MISSION, TYPE_GENERATED
+	}
+
+	public int describeContents() {
+		return 0;
+	}
+	
+	public void writeToParcel(Parcel dest, int flags) {
+		dest.writeString(name);
+		dest.writeString(path);
+		dest.writeString(previewPath);
+		dest.writeString(type.name());
+	}
+	
+	private void readFromParcel(Parcel src){
+		name = src.readString();
+		path = src.readString();
+		previewPath = src.readString();
+		type = MapType.valueOf(src.readString());
+	}
+	public static final Parcelable.Creator<Map> CREATOR = new Parcelable.Creator<Map>() {
+		public Map createFromParcel(Parcel source) {
+			return new Map(source);
+		}
+		public Map[] newArray(int size) {
+			return new Map[size];
+		}
+		
+	};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Scheme.java	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,360 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+
+import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class Scheme implements Parcelable, Comparable<Scheme>{
+
+	public static final String DIRECTORY_SCHEME = "schemes";
+
+	private String name;
+	//private ArrayList<Integer> basic;
+	private Integer gamemod;
+	private ArrayList<Integer> basic;;
+	private static ArrayList<LinkedHashMap<String, ?>> basicflags = new ArrayList<LinkedHashMap<String, ?>>();//TODO why is it static?
+	
+	public Scheme(String _name, ArrayList<Integer> _basic, int _gamemod){
+		name = _name;
+		gamemod = _gamemod;
+		basic = _basic;
+	}
+	
+	public Scheme(Parcel in){
+		readFromParcel(in);
+	}
+
+	public void sendToEngine(EngineProtocolNetwork epn)throws IOException{ 
+		epn.sendToEngine(String.format("e$gmflags %d", gamemod));
+
+		for(int pos = 0; pos < basic.size(); pos++){
+			LinkedHashMap<String, ?> basicflag = basicflags.get(pos);
+			
+			String command = (String)basicflag.get("command");
+			Integer value = basic.get(pos);
+			Boolean checkOverMax = (Boolean) basicflag.get("checkOverMax");
+			Boolean times1000 = (Boolean) basicflag.get("times1000");
+			Integer max = (Integer) basicflag.get("max");
+			
+			if(checkOverMax && value >= max) value = max;
+			if(times1000) value *= 1000;
+			
+			epn.sendToEngine(String.format("%s %d", command, value));
+		}
+	}
+	public String toString(){
+		return name;
+	}
+
+
+	public static final int STATE_START = 0;
+	public static final int STATE_ROOT = 1;
+	public static final int STATE_NAME = 2;
+	public static final int STATE_BASICFLAGS = 3;
+	public static final int STATE_GAMEMOD = 4;
+	public static final int STATE_BASICFLAG_INTEGER = 5;
+	public static final int STATE_GAMEMOD_TRUE = 6;
+	public static final int STATE_GAMEMOD_FALSE = 7;
+
+	public static ArrayList<Scheme> getSchemes(Context c) throws IllegalArgumentException{
+		String dir = c.getFilesDir().getAbsolutePath() + '/' + DIRECTORY_SCHEME + '/';
+		String[] files = new File(dir).list(fnf);
+		if(files == null) files = new String[]{};
+		Arrays.sort(files);
+		ArrayList<Scheme> schemes = new ArrayList<Scheme>();
+
+		try {
+			XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance();
+			XmlPullParser xmlPuller = xmlPullFactory.newPullParser();
+
+			for(String file : files){
+				BufferedReader br = new BufferedReader(new FileReader(dir + file), 1024);
+				xmlPuller.setInput(br);
+				String name = null;
+				ArrayList<Integer> basic = new ArrayList<Integer>();
+				Integer gamemod = 0;
+				int mask = 0x000000004;
+
+				int eventType = xmlPuller.getEventType();
+				int state = STATE_START;
+				while(eventType != XmlPullParser.END_DOCUMENT){
+					switch(state){
+					case STATE_START:
+						if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("scheme")) state = STATE_ROOT;
+						else if(eventType != XmlPullParser.START_DOCUMENT) throwException(file, eventType);
+						break;
+					case STATE_ROOT:
+						if(eventType == XmlPullParser.START_TAG){
+							if(xmlPuller.getName().equals("basicflags")) state = STATE_BASICFLAGS;
+							else if(xmlPuller.getName().toLowerCase().equals("gamemod")) state = STATE_GAMEMOD;
+							else if(xmlPuller.getName().toLowerCase().equals("name")) state = STATE_NAME;
+							else throwException(file, eventType);
+						}else if(eventType == XmlPullParser.END_TAG) state = STATE_START;
+						else throwException(xmlPuller.getText(), eventType);
+						break;
+					case STATE_BASICFLAGS:
+						if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().toLowerCase().equals("integer")) state = STATE_BASICFLAG_INTEGER;
+						else if(eventType == XmlPullParser.END_TAG)	state = STATE_ROOT;
+						else throwException(file, eventType);
+						break;
+					case STATE_GAMEMOD:
+						if(eventType == XmlPullParser.START_TAG){
+							if(xmlPuller.getName().toLowerCase().equals("true")) state = STATE_GAMEMOD_TRUE;
+							else if(xmlPuller.getName().toLowerCase().equals("false")) state = STATE_GAMEMOD_FALSE;
+							else throwException(file, eventType);
+						}else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
+						else throwException(file, eventType);
+						break;
+					case STATE_NAME:
+						if(eventType == XmlPullParser.TEXT) name = xmlPuller.getText().trim();
+						else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
+						else throwException(file, eventType);
+						break;
+					case STATE_BASICFLAG_INTEGER:
+						if(eventType == XmlPullParser.TEXT) basic.add(Integer.parseInt(xmlPuller.getText().trim()));
+						else if(eventType == XmlPullParser.END_TAG) state = STATE_BASICFLAGS;
+						else throwException(file, eventType);
+						break;
+					case STATE_GAMEMOD_FALSE:
+						if(eventType == XmlPullParser.TEXT) gamemod <<= 1;
+						else if(eventType == XmlPullParser.END_TAG) state = STATE_GAMEMOD;
+						else throwException(file, eventType);
+						break;
+					case STATE_GAMEMOD_TRUE:
+						if(eventType == XmlPullParser.TEXT){
+							gamemod |= mask;
+							gamemod <<= 1;
+						}else if(eventType == XmlPullParser.END_TAG) state = STATE_GAMEMOD;
+						else throwException(file, eventType);
+						break;
+					}
+					eventType = getEventType(xmlPuller);
+				}//end while(eventtype != END_DOCUMENT
+				schemes.add(new Scheme(name, basic, gamemod));
+			}//end for(string file : files
+			return schemes;
+		} catch (XmlPullParserException e) {
+			e.printStackTrace();
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return new ArrayList<Scheme>();//TODO handle correctly
+	}
+	
+	private static FilenameFilter fnf = new FilenameFilter(){
+		public boolean accept(File dir, String filename) {
+			return filename.toLowerCase().startsWith("scheme_");
+		}
+	};
+
+	/**
+	 * This method will parse the basic flags from a prespecified xml file.
+	 * I use a raw xml file rather than one parsed by aatp at compile time
+	 * to keep it generic with other frontends, ie in the future we could 
+	 * use one provided by the Data folder.
+	 */
+	public static void parseBasicFlags(Context c){
+		String filename = String.format("%s/%s/basicflags", c.getFilesDir().getAbsolutePath(), DIRECTORY_SCHEME);
+
+		XmlPullParser xmlPuller = null;
+		BufferedReader br = null;
+		try {
+			XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance();
+			xmlPuller = xmlPullFactory.newPullParser();
+			br = new BufferedReader(new FileReader(filename), 1024);
+			xmlPuller.setInput(br);
+
+			int eventType = getEventType(xmlPuller);
+			boolean continueParsing = true;
+			do{
+				switch(eventType){
+				
+				case XmlPullParser.START_TAG:
+					if(xmlPuller.getName().toLowerCase().equals("flag")){
+						basicflags.add(parseFlag(xmlPuller));
+					}else if(xmlPuller.getName().toLowerCase().equals("basicflags")){
+						eventType = getEventType(xmlPuller);
+					}else{
+						skipCurrentTag(xmlPuller);
+						eventType = getEventType(xmlPuller);
+					}
+					break;
+				case XmlPullParser.START_DOCUMENT://ignore all tags not being "flag"
+				case XmlPullParser.END_TAG:
+				case XmlPullParser.TEXT:
+				default:
+					continueParsing = true;
+				case XmlPullParser.END_DOCUMENT:
+					continueParsing = false;
+				}
+			}while(continueParsing);
+
+		}catch(IOException e){
+			e.printStackTrace();
+		}catch (XmlPullParserException e) {
+			e.printStackTrace();
+		}finally{
+			if(br != null)
+				try {
+					br.close();
+				} catch (IOException e) {}
+		}
+
+	}
+
+	/*
+	 * * Parses a Tag structure from xml as example we use
+	 *<flag>
+	 *   <checkOverMax>
+	 *       <boolean>false</boolean>
+	 *   </checkOverMax>
+	 *</flag>
+	 *
+	 * It returns a LinkedHashMap with key/value pairs
+	 */
+	private static LinkedHashMap<String, Object> parseFlag(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{
+		LinkedHashMap<String, Object> hash = new LinkedHashMap<String, Object>();
+
+		int eventType = xmlPuller.getEventType();//Get the event type which triggered this method
+		if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().toLowerCase().equals("flag")){//valid start of flag tag
+			String lcKey = null;
+			String lcType = null;
+			String value = null;
+
+			eventType = getEventType(xmlPuller);//<checkOverMax>
+			while(eventType == XmlPullParser.START_TAG){
+				lcKey = xmlPuller.getName();//checkOverMax
+				if(getEventType(xmlPuller) == XmlPullParser.START_TAG){//<boolean>
+					lcType = xmlPuller.getName().toLowerCase();
+					if(getEventType(xmlPuller) == XmlPullParser.TEXT){
+						value = xmlPuller.getText();
+						if(getEventType(xmlPuller) == XmlPullParser.END_TAG && //</boolean> 
+								getEventType(xmlPuller) == XmlPullParser.END_TAG){//</checkOverMax>
+							if(lcType.equals("boolean")) hash.put(lcKey, new Boolean(value));
+							else if(lcType.equals("string"))hash.put(lcKey, value);							
+							else if(lcType.equals("integer")){
+								try{
+									hash.put(lcKey, new Integer(value));
+								}catch (NumberFormatException e){
+									throw new XmlPullParserException("Wrong integer value in xml file");
+								}
+							}else{
+								throwException("basicflags", eventType);
+							}
+						}//</boolean> / </checkOverMax>
+					}//if TEXT
+				}//if boolean
+				eventType = getEventType(xmlPuller);//start new loop
+			}
+			eventType = getEventType(xmlPuller);//</flag>
+		}
+
+		return hash;
+	}
+
+	private static void skipCurrentTag(XmlPullParser xmlPuller) throws XmlPullParserException, IOException{
+		int eventType = xmlPuller.getEventType();
+		if(eventType != XmlPullParser.START_TAG)return;
+		String tag = xmlPuller.getName().toLowerCase();
+
+		while(true){
+			eventType = getEventType(xmlPuller);//getNext()
+			switch(eventType){
+			case XmlPullParser.START_DOCUMENT://we're inside of a start tag so START_ or END_DOCUMENT is just wrong
+			case XmlPullParser.END_DOCUMENT:
+				throw new XmlPullParserException("invalid xml file");
+			case XmlPullParser.START_TAG://if we get a new tag recursively handle it
+				skipCurrentTag(xmlPuller);
+				break;
+			case XmlPullParser.TEXT:
+				break;
+			case XmlPullParser.END_TAG:
+				if(!xmlPuller.getName().toLowerCase().equals(tag)){//if the end tag doesn't match the start tag
+					throw new XmlPullParserException("invalid xml file");
+				}else{
+					return;//skip completed	
+				}
+
+			}
+		}
+	}
+
+	/**
+	 * Skips whitespaces..
+	 */
+	private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{
+		int eventType = xmlPuller.next();
+		while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){
+			eventType = xmlPuller.next();
+		}
+		return eventType;
+	}
+	private static void throwException(String file, int eventType){
+		throw new IllegalArgumentException(String.format("Xml file: %s malformed with error: %d.", file, eventType));
+	}
+
+	public int describeContents() {
+		return 0;
+	}
+
+	public void writeToParcel(Parcel dest, int flags) {
+		dest.writeString(name);
+		dest.writeInt(gamemod);
+		dest.writeList(basic);
+	}
+	
+	public void readFromParcel(Parcel src){
+		name = src.readString();
+		gamemod = src.readInt();
+		basic = src.readArrayList(ArrayList.class.getClassLoader());
+	}
+
+	public static final Parcelable.Creator<Scheme> CREATOR = new Parcelable.Creator<Scheme>() {
+		public Scheme createFromParcel(Parcel source) {
+			return new Scheme(source);
+		}
+		public Scheme[] newArray(int size) {
+			return new Scheme[size];
+		}
+		
+	};
+
+	public int compareTo(Scheme another) {
+		return name.compareTo(another.name);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Team.java	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,368 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork;
+import org.hedgewars.hedgeroid.EngineProtocol.PascalExports;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+import org.xmlpull.v1.XmlSerializer;
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Xml;
+
+public class Team implements Parcelable{
+
+	public static final String DIRECTORY_TEAMS = "teams";
+	private static final Integer[] TEAM_COLORS = {
+		0xd12b42, /* red    */ 
+		0x4980c1, /* blue   */ 
+		0x6ab530, /* green  */ 
+		0xbc64c4, /* purple */ 
+		0xe76d14, /* orange */ 
+		0x3fb6e6, /* cyan   */ 
+		0xe3e90c, /* yellow */ 
+		0x61d4ac, /* mint   */ 
+		0xf1c3e1, /* pink   */ 
+		/* add new colors here */
+	};
+
+//	private static final Integer[] TEAM_COLORS = {
+//		0xff0000, /* red    */ 
+//		0x00ff00, /* blue   */ 
+//		0x0000ff, /* green  */ 
+//	};
+
+	private static final int STATE_START = 0;
+	private static final int STATE_ROOT = 1;
+	private static final int STATE_HOG_ROOT = 2;
+
+	public String name, grave, flag, voice, fort, hash;
+	public String file = null;
+
+	public static int maxNumberOfHogs = 0;
+	public static int maxNumberOfTeams = 0;
+
+	static{
+		maxNumberOfHogs = PascalExports.HWgetMaxNumberOfHogs();
+		maxNumberOfTeams = PascalExports.HWgetMaxNumberOfTeams();
+	}
+	public String[] hats = new String[maxNumberOfHogs];
+	public String[] hogNames = new String[maxNumberOfHogs];
+	public int[] levels = new int[maxNumberOfHogs];
+
+	public int hogCount = 4;
+	public int color = TEAM_COLORS[0];
+
+	public Team(){
+	}
+
+	public Team(Parcel in){
+		readFromParcel(in);
+	}
+
+	public boolean equals(Object o){
+		if(super.equals(o)) return true;
+		else if(o instanceof Team){
+			Team t = (Team)o;
+			boolean ret = name.equals(t.name);
+			ret &= grave.equals(t.grave);
+			ret &= flag.equals(t.flag);
+			ret &= voice.equals(t.voice);
+			ret &= fort.equals(t.fort);
+			ret &= hash.equals(t.hash);
+			return ret;
+		}else{
+			return false;
+		}
+	}
+
+	public void setRandomColor(int[] illegalcolors){
+		Integer[] colorsToPickFrom = TEAM_COLORS;
+		if(illegalcolors != null){
+			ArrayList<Integer> colors = new ArrayList<Integer>();
+			for(int color : TEAM_COLORS){
+				boolean validColor = true;
+				for(int illegal : illegalcolors){
+					if(color == illegal) validColor = false;
+				}
+				if(validColor) colors.add(color);
+			}
+			if(colors.size() != 0) colorsToPickFrom = colors.toArray(new Integer[1]);
+		}
+		int index = (int)Math.round(Math.random()*(colorsToPickFrom.length-1));
+		color = colorsToPickFrom[index];
+	}
+
+
+	public void sendToEngine(EngineProtocolNetwork epn, int hogCount, int health) throws IOException{
+		epn.sendToEngine(String.format("eaddteam %s %d %s", hash, color, name));
+		epn.sendToEngine(String.format("egrave %s", grave));
+		epn.sendToEngine(String.format("efort %s", fort));
+		epn.sendToEngine(String.format("evoicepack %s", voice));
+		epn.sendToEngine(String.format("eflag %s", flag));
+
+		for(int i = 0; i < hogCount; i++){
+			epn.sendToEngine(String.format("eaddhh %d %d %s", levels[i], health, hogNames[i]));
+			epn.sendToEngine(String.format("ehat %s", hats[i]));
+		}
+	}
+
+	public void setFileName(Context c){
+		if(file == null){
+		  	file = validFileName(c, name);
+		}
+	}
+	private String validFileName(Context c, String fileName){
+		String absolutePath = String.format("%s/%s", c.getFilesDir(), fileName);
+		File f = new File(absolutePath);
+		if(f.exists()){
+			String newFileName = fileName + (int)(Math.random()*10);
+			return validFileName(c, newFileName);
+		}else{
+			return fileName;
+		}
+	}
+	
+	/*
+	 * XML METHODS
+	 */
+
+	/**
+	 * Read the xml file path and convert it to a Team object
+	 * @param path absolute path to the xml file
+	 * @return
+	 */
+	public static Team getTeamFromXml(String path){
+		try {
+			XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance();
+			XmlPullParser xmlPuller = xmlPullFactory.newPullParser();
+
+			BufferedReader br = new BufferedReader(new FileReader(path), 1024);
+			xmlPuller.setInput(br);
+			Team team = new Team();
+			int hogCounter = 0;
+
+			int eventType = xmlPuller.getEventType();
+			int state = STATE_START;
+			while(eventType != XmlPullParser.END_DOCUMENT){
+				switch(state){
+				case STATE_START:
+					if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("team")) state = STATE_ROOT;
+					else if(eventType != XmlPullParser.START_DOCUMENT) throwException(path, eventType);
+					break;
+				case STATE_ROOT:
+					if(eventType == XmlPullParser.START_TAG){
+						if(xmlPuller.getName().toLowerCase().equals("name")){
+							team.name = getXmlText(xmlPuller, "name");
+						}else if(xmlPuller.getName().toLowerCase().equals("flag")){
+							team.flag= getXmlText(xmlPuller, "flag");
+						}else if(xmlPuller.getName().toLowerCase().equals("voice")){
+							team.voice = getXmlText(xmlPuller, "voice");
+						}else if(xmlPuller.getName().toLowerCase().equals("grave")){
+							team.grave = getXmlText(xmlPuller, "grave");
+						}else if(xmlPuller.getName().toLowerCase().equals("fort")){
+							team.fort = getXmlText(xmlPuller, "fort");
+						}else if(xmlPuller.getName().toLowerCase().equals("hash")){
+							team.hash = getXmlText(xmlPuller, "hash");
+						}else if(xmlPuller.getName().toLowerCase().equals("hog")){
+							state = STATE_HOG_ROOT;
+						}else throwException(xmlPuller.getName(), eventType);
+					}else if(eventType == XmlPullParser.END_TAG) state = STATE_START;
+					else throwException(xmlPuller.getText(), eventType);
+					break;
+				case STATE_HOG_ROOT:
+					if(eventType == XmlPullParser.START_TAG){
+						if(xmlPuller.getName().toLowerCase().equals("name")){
+							team.hogNames[hogCounter] = getXmlText(xmlPuller, "name");
+						}else if(xmlPuller.getName().toLowerCase().equals("hat")){
+							team.hats[hogCounter] = getXmlText(xmlPuller, "hat");
+						}else if(xmlPuller.getName().toLowerCase().equals("level")){
+							team.levels[hogCounter] = Integer.parseInt(getXmlText(xmlPuller, "level"));
+						}else throwException(xmlPuller.getText(), eventType);
+					}else if(eventType == XmlPullParser.END_TAG){
+						hogCounter++;
+						state = STATE_ROOT;
+					}else throwException(xmlPuller.getText(), eventType);
+					break;
+				}
+				eventType = getEventType(xmlPuller);
+			}//end while(eventtype != END_DOCUMENT
+			return team;
+		} catch (NumberFormatException e){
+			e.printStackTrace();
+		} catch (XmlPullParserException e) {
+			e.printStackTrace();
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	private static String getXmlText(XmlPullParser xmlPuller, String parentTag)throws XmlPullParserException, IOException{
+		if(getEventType(xmlPuller) == XmlPullParser.TEXT){
+			String txt = xmlPuller.getText();
+			if(getEventType(xmlPuller) == XmlPullParser.END_TAG && xmlPuller.getName().toLowerCase().equals(parentTag)){
+				return txt;
+			}
+		}
+		throw new XmlPullParserException("malformed xml file on string read from tag: " + parentTag);
+	}
+
+	/**
+	 * Skips whitespaces..
+	 */
+	private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{
+		int eventType = xmlPuller.next();
+		while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){
+			eventType = xmlPuller.next();
+		}
+		return eventType;
+	}
+
+	private static void throwException(String file, int eventType){
+		throw new IllegalArgumentException(String.format("Xml file: %s malformed with error: %d.", file, eventType));
+	}
+
+	public void writeToXml(OutputStream os){
+		XmlSerializer serializer = Xml.newSerializer();
+		try{
+			serializer.setOutput(os, "UTF-8");	
+			serializer.startDocument("UTF-8", true);
+			serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+
+			serializer.startTag(null, "team");
+			serializer.startTag(null, "name");
+			serializer.text(name);
+			serializer.endTag(null, "name");
+			serializer.startTag(null, "flag");
+			serializer.text(flag);
+			serializer.endTag(null, "flag");
+			serializer.startTag(null, "fort");
+			serializer.text(fort);
+			serializer.endTag(null, "fort");
+			serializer.startTag(null, "grave");
+			serializer.text(grave);
+			serializer.endTag(null, "grave");
+			serializer.startTag(null, "voice");
+			serializer.text(voice);
+			serializer.endTag(null, "voice");
+			serializer.startTag(null, "hash");
+			serializer.text(hash);
+			serializer.endTag(null, "hash");
+
+			for(int i = 0; i < maxNumberOfHogs; i++){
+				serializer.startTag(null, "hog");
+				serializer.startTag(null, "name");
+				serializer.text(hogNames[i]);
+				serializer.endTag(null, "name");
+				serializer.startTag(null, "hat");
+				serializer.text(hats[i]);
+				serializer.endTag(null, "hat");
+				serializer.startTag(null, "level");
+				serializer.text(String.valueOf(levels[i]));
+				serializer.endTag(null, "level");
+
+				serializer.endTag(null, "hog");
+			}
+			serializer.endTag(null, "team");
+			serializer.endDocument();
+			serializer.flush();
+
+		} catch (IOException e) {
+			e.printStackTrace();
+		}finally{
+			try {
+				os.close();
+			} catch (IOException e) {}
+		}
+	}
+	/*
+	 * END XML METHODS
+	 */
+
+
+
+	/*
+	 * PARCABLE METHODS
+	 */
+
+	public int describeContents() {
+		return 0;
+	}
+
+	public void writeToParcel(Parcel dest, int flags) {
+		dest.writeString(name);
+		dest.writeString(grave);
+		dest.writeString(flag);
+		dest.writeString(voice);
+		dest.writeString(fort);
+		dest.writeString(hash);
+		dest.writeStringArray(hats);
+		dest.writeStringArray(hogNames);
+		dest.writeIntArray(levels);
+		dest.writeInt(color);
+		dest.writeInt(hogCount);
+		dest.writeString(file);
+	}
+
+
+	public void readFromParcel(Parcel src){
+		name = src.readString();
+		grave = src.readString();
+		flag = src.readString();
+		voice = src.readString();
+		fort = src.readString();
+		hash = src.readString();
+		src.readStringArray(hats);
+		src.readStringArray(hogNames);
+		src.readIntArray(levels);
+		color = src.readInt();
+		hogCount = src.readInt();
+		file = src.readString();
+	}
+
+	public static final Parcelable.Creator<Team> CREATOR = new Parcelable.Creator<Team>() {
+		public Team createFromParcel(Parcel source) {
+			return new Team(source);
+		}
+		public Team[] newArray(int size) {
+			return new Team[size];
+		}
+
+	};
+
+	/*
+	 * END PARCABLE METHODS
+	 */
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Weapon.java	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,217 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class Weapon implements Parcelable, Comparable<Weapon>{
+
+	public static final String DIRECTORY_WEAPON = "weapons";
+	
+	private String name;
+	private String QT;
+	private String prob;
+	private String delay;
+	private String crate;
+	private static int maxWeapons;
+	
+	static{
+		//maxWeapons = PascalExports.HWgetNumberOfWeapons();
+	}
+	
+	public Weapon(String _name, String _QT, String _prob, String _delay, String _crate){
+		name = _name;
+		
+		//Incase there's a newer ammoStore which is bigger we append with zeros
+		StringBuffer sb = new StringBuffer();
+		while(_QT.length() + sb.length() < maxWeapons){
+			sb.append('0');
+		}
+		
+		QT = String.format("e%s %s%s", "ammloadt", _QT, sb);
+		prob = String.format("e%s %s%s", "ammprob", _prob, sb);
+		delay = String.format("e%s %s%s", "ammdelay", _delay, sb);
+		crate = String.format("e%s %s%s", "ammreinf", _crate, sb);
+	}
+	
+	public Weapon(Parcel in){
+		readFromParcel(in);
+	}
+	
+	public String toString(){
+		return name;
+	}
+	
+	public void sendToEngine(EngineProtocolNetwork epn, int teamsCount) throws IOException{
+		epn.sendToEngine(QT);//command prefix is already in string 
+		epn.sendToEngine(prob);
+		epn.sendToEngine(delay);
+		epn.sendToEngine(crate);
+		
+		for(int i = 0; i < teamsCount; i++){
+			epn.sendToEngine("eammstore");
+		}
+	}
+	
+	public static final int STATE_START = 0;
+	public static final int STATE_ROOT = 1;
+	public static final int STATE_NAME = 2;
+	public static final int STATE_QT = 3;
+	public static final int STATE_PROBABILITY = 4;
+	public static final int STATE_DELAY = 5;
+	public static final int STATE_CRATE = 6;
+	
+	public static ArrayList<Weapon> getWeapons(Context c) throws IllegalArgumentException{
+		String dir = c.getFilesDir().getAbsolutePath() + '/' + DIRECTORY_WEAPON + '/';
+		String[] files = new File(dir).list();
+		if(files == null) files = new String[]{};
+		
+		ArrayList<Weapon> weapons = new ArrayList<Weapon>();
+
+		try {
+			XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance();
+			XmlPullParser xmlPuller = xmlPullFactory.newPullParser();
+			
+			for(String file : files){
+				BufferedReader br = new BufferedReader(new FileReader(dir + file), 1024);
+				xmlPuller.setInput(br);
+				String name = null;
+				String qt = null;
+				String prob = null;
+				String delay = null;
+				String crate = null;
+				
+				int eventType = xmlPuller.getEventType();
+				int state = STATE_START;
+				while(eventType != XmlPullParser.END_DOCUMENT){
+					switch(state){
+					case STATE_START:
+						if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("weapon")) state = STATE_ROOT;
+						else if(eventType != XmlPullParser.START_DOCUMENT) throwException(file, eventType);
+						break;
+					case STATE_ROOT:
+						if(eventType == XmlPullParser.START_TAG){
+							if(xmlPuller.getName().toLowerCase().equals("qt")) state = STATE_QT;
+							else if(xmlPuller.getName().toLowerCase().equals("name")) state = STATE_NAME;
+							else if(xmlPuller.getName().toLowerCase().equals("probability")) state = STATE_PROBABILITY;
+							else if(xmlPuller.getName().toLowerCase().equals("delay")) state = STATE_DELAY;
+							else if(xmlPuller.getName().toLowerCase().equals("crate")) state = STATE_CRATE;
+							else throwException(file, eventType);
+						}else if(eventType == XmlPullParser.END_TAG) state = STATE_START;
+						else throwException(xmlPuller.getText(), eventType);
+						break;
+					case STATE_NAME:
+						if(eventType == XmlPullParser.TEXT) name = xmlPuller.getText().trim();
+						else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
+						else throwException(file, eventType);
+						break;
+					case STATE_QT:
+						if(eventType == XmlPullParser.TEXT) qt = xmlPuller.getText().trim();
+						else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
+						else throwException(file, eventType);
+						break;
+					case STATE_PROBABILITY:
+						if(eventType == XmlPullParser.TEXT) prob = xmlPuller.getText().trim();
+						else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
+						else throwException(file, eventType);
+						break;
+					case STATE_DELAY:
+						if(eventType == XmlPullParser.TEXT) delay = xmlPuller.getText().trim();
+						else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
+						else throwException(file, eventType);
+						break;
+					case STATE_CRATE:
+						if(eventType == XmlPullParser.TEXT) crate = xmlPuller.getText().trim();
+						else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
+						else throwException(file, eventType);
+						break;
+					}
+					eventType = xmlPuller.next();
+					while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){//Skip whitespaces
+						eventType = xmlPuller.next();
+					}
+				}//end while(eventtype != END_DOCUMENT
+				weapons.add(new Weapon(name, qt, prob, delay, crate));
+			}//end for(string file : files
+			return weapons;
+			
+		} catch (XmlPullParserException e) {
+			e.printStackTrace();
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return new ArrayList<Weapon>();//TODO handle correctly
+	}
+	
+	private static void throwException(String file, int eventType){
+		throw new IllegalArgumentException(String.format("Xml file: %s malformed with eventType: %d.", file, eventType));
+	}
+
+	public int describeContents() {
+		return 0;
+	}
+
+	public void writeToParcel(Parcel dest, int flags) {
+		dest.writeString(name);
+		dest.writeString(QT);
+		dest.writeString(prob);
+		dest.writeString(delay);
+		dest.writeString(crate);
+	}
+	
+	private void readFromParcel(Parcel src){
+		name = src.readString();
+		QT = src.readString();
+		prob = src.readString();
+		delay = src.readString();
+		crate = src.readString();
+	}
+	
+	public static final Parcelable.Creator<Weapon> CREATOR = new Parcelable.Creator<Weapon>() {
+		public Weapon createFromParcel(Parcel source) {
+			return new Weapon(source);
+		}
+		public Weapon[] newArray(int size) {
+			return new Weapon[size];
+		}
+		
+	};
+
+	public int compareTo(Weapon another) {
+		return name.compareTo(another.name);
+	}
+	
+	
+}
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java	Mon Dec 05 18:38:25 2011 -0500
@@ -25,8 +25,6 @@
 		act = _act;
 	}
 	
-	
-	
 	public static Long copyFileOrDir(Context c, String path) {
 	    AssetManager assetManager = c.getAssets();
 	    String assets[] = null;
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java	Mon Dec 05 18:38:25 2011 -0500
@@ -37,11 +37,6 @@
 		layout = (FrameLayout)findViewById(R.id.downloadFrameLayout);
 		downloadQueueContainer = (LinearLayout) findViewById(R.id.downloadQueueContainer);
 	}
-
-	public void onDestroy(){
-		super.onDestroy();
-		Log.d("tag", "on destroy");
-	}
 	
 	public void onNewItemSelected(DownloadPackage _task, int x, int minX, int maxX, int size) {
 		if(layout != null){
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListFragment.java	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListFragment.java	Mon Dec 05 18:38:25 2011 -0500
@@ -13,9 +13,6 @@
 
 import android.graphics.Color;
 import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
 import android.support.v4.app.ListFragment;
 import android.util.Log;
 import android.view.View;
@@ -103,6 +100,8 @@
 	}
 
 	public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
+		DownloadPackage task = (DownloadPackage)arg0.getAdapter().getItem(position);
+		/*
 		FragmentTransaction ft = getFragmentManager().beginTransaction();
 		Fragment prev = getFragmentManager().findFragmentByTag("dialog");
 
@@ -111,12 +110,12 @@
 		ft.addToBackStack(null);
 
 		//create a new dialog based on this task
-		DownloadPackage task = (DownloadPackage)arg0.getAdapter().getItem(position);
+		
 		DialogFragment newFragment = DownloadDialogFragment.newInstance(task);
 
 		//show it
-		//newFragment.show(ft, "dialog");
-
+		newFragment.show(ft, "dialog");
+		 */
 		targetView = arg1;
 
 		//determine state
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java	Mon Dec 05 18:38:25 2011 -0500
@@ -19,7 +19,6 @@
 
 package org.hedgewars.hedgeroid.Downloader;
 
-import java.util.Deque;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -57,7 +56,7 @@
 	private NotificationManager nM;
 	private RemoteViews contentView;
 
-	private Deque<DownloadTask> downloadTasks = new LinkedList<DownloadTask>();
+	private LinkedList<DownloadTask> downloadTasks = new LinkedList<DownloadTask>();
 	private DownloadTask currentTask = null;
 
 	public class DownloadHandler extends Handler{
@@ -112,7 +111,7 @@
 
 	private void runNextTask(){
 		if(asyncExecutor == null){//if (task isnt running right now) ...
-			currentTask = downloadTasks.pollFirst();
+			currentTask = downloadTasks.poll();
 			if(currentTask != null){
 				asyncExecutor = new DownloadAsyncTask(currentTask);
 				asyncExecutor.execute(currentTask.getPackage());
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/FrontendDataUtils.java	Mon Nov 28 06:55:55 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,215 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-
-package org.hedgewars.hedgeroid.EngineProtocol;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-
-import org.hedgewars.hedgeroid.R;
-import org.hedgewars.hedgeroid.Utils;
-import org.hedgewars.hedgeroid.EngineProtocol.Map.MapType;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-
-public class FrontendDataUtils {
-
-
-	public static ArrayList<Map> getMaps(Context c){
-		File[] files = Utils.getFilesFromRelativeDir(c,"Maps");
-		ArrayList<Map> ret = new ArrayList<Map>();
-
-		for(File f : files){
-			if(Utils.hasFileWithSuffix(f, ".lua")){
-				ret.add(new Map(f,MapType.TYPE_MISSION, c));
-			}else{
-				ret.add(new Map(f, MapType.TYPE_DEFAULT,c));
-			}
-		}
-		Collections.sort(ret);
-
-		return ret;
-	}
-
-	public static List<String> getGameplay(Context c){
-		String[] files = Utils.getFileNamesFromRelativeDir(c, "Scripts/Multiplayer");
-		ArrayList<String> ret = new ArrayList<String>();
-		
-		for(int i = 0; i < files.length; i++){
-			if(files[i].endsWith(".lua")){
-				ret.add(files[i].replace('_', ' ').substring(0, files[i].length()-4)); //replace _ by a space and removed the last four characters (.lua)
-			}
-		}
-		Collections.sort(ret);
-
-		ret.add(0,"None");
-		return ret;	
-	}
-
-	public static String[] getThemes(Context c){
-		return Utils.getDirsWithFileSuffix(c, "Themes", "icon.png");
-	}
-
-	public static List<Scheme> getSchemes(Context c){
-		List<Scheme> list = Scheme.getSchemes(c);
-		Collections.sort(list);
-		return list;
-	}
-
-	public static List<Weapon> getWeapons(Context c){
-		List<Weapon> list = Weapon.getWeapons(c);
-		Collections.sort(list);
-		return list;
-	}
-
-	public static ArrayList<HashMap<String, ?>> getGraves(Context c){
-		String pathPrefix = Utils.getDataPath(c) + "Graphics/Graves/";
-		ArrayList<String> names = Utils.getFilesFromDirWithSuffix(c,"Graphics/Graves", ".png", true);
-		ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(names.size());
-
-		for(String s : names){
-			HashMap<String, Object> map = new HashMap<String, Object>();
-			map.put("txt", s);
-			Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap
-			int width = b.getWidth();
-			if(b.getHeight() > width){//some pictures contain more 'frames' underneath each other, if so we only use the first frame
-				Bitmap tmp = Bitmap.createBitmap(b, 0, 0, width, width);
-				b.recycle();
-				b = tmp;
-			}
-			map.put("img", b);
-			data.add(map);
-		}
-		return data;
-	}
-
-	public static ArrayList<HashMap<String, ?>> getFlags(Context c){
-		String pathPrefix = Utils.getDataPath(c) + "Graphics/Flags/";
-		ArrayList<String> names = Utils.getFilesFromDirWithSuffix(c, "Graphics/Flags", ".png", true);
-		ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(names.size());
-
-		for(String s : names){
-			HashMap<String, Object> map = new HashMap<String, Object>();
-			map.put("txt", s);
-			Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap
-			map.put("img", b);
-			data.add(map);
-		}
-		return data;
-	}
-
-	public static ArrayList<String> getVoices(Context c){
-		File[] files = Utils.getFilesFromRelativeDir(c, "Sounds/voices");
-		ArrayList<String> ret = new ArrayList<String>();
-
-		for(File f : files){
-			if(f.isDirectory()) ret.add(f.getName());
-		}
-		return ret;
-	}
-
-	public static ArrayList<String> getForts(Context c){
-		return Utils.getFilesFromDirWithSuffix(c,"Forts", "L.png", true);
-	}
-	public static ArrayList<HashMap<String, ?>> getTypes(Context c){
-		ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(6);
-		String[] levels = {c.getString(R.string.human), c.getString(R.string.bot5), c.getString(R.string.bot4), c.getString(R.string.bot3), c.getString(R.string.bot2), c.getString(R.string.bot1)};
-		int[] images = {R.drawable.human, R.drawable.bot5, R.drawable.bot4, R.drawable.bot3, R.drawable.bot2, R.drawable.bot1};
-
-		for(int i = 0; i < levels.length; i++){
-			HashMap<String, Object> map = new HashMap<String, Object>();
-			map.put("txt", levels[i]);
-			map.put("img", images[i]);
-			data.add(map);
-		}
-
-		return data;
-	}
-
-	public static ArrayList<HashMap<String, ?>> getHats(Context c){
-		ArrayList<String> files = Utils.getFilesFromDirWithSuffix(c,"Graphics/Hats", ".png", true);
-		String pathPrefix = Utils.getDataPath(c) + "Graphics/Hats/";
-		int size = files.size();
-		ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(size);
-
-		HashMap<String, Object> hashmap; 
-		for(String s : files){
-			hashmap = new HashMap<String, Object>();
-			hashmap.put("txt", s);
-			Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap
-			b = Bitmap.createBitmap(b, 0,0,b.getWidth()/2, b.getWidth()/2);
-			hashmap.put("img", b);
-			data.add(hashmap);
-		}
-
-		return data;
-	}
-
-	public static List<HashMap<String, Object>> getTeams(Context c){
-		List<HashMap<String, Object>> ret = new ArrayList<HashMap<String, Object>>();
-
-		File teamsDir = new File(c.getFilesDir().getAbsolutePath() + '/' + Team.DIRECTORY_TEAMS);
-		File[] teamFileNames = teamsDir.listFiles();
-		if(teamFileNames != null){
-			for(File s : teamFileNames){
-				Team t = Team.getTeamFromXml(s.getAbsolutePath());
-				if(t != null){
-					t.file = s.getName();
-					ret.add(teamToMap(t));
-				}
-			}
-		}
-		return ret;
-	}
-
-	public static HashMap<String, Object> teamToMap(Team t){
-		HashMap<String, Object> hashmap = new HashMap<String, Object>();
-		hashmap.put("team", t);
-		hashmap.put("txt", t.name);
-		hashmap.put("color", t.color);
-		hashmap.put("count", t.hogCount);
-		switch(t.levels[0]){
-		case 0:
-			hashmap.put("img", R.drawable.human);
-			break;
-		case 1:
-			hashmap.put("img", R.drawable.bot5);
-			break;
-		case 2:
-			hashmap.put("img", R.drawable.bot4);
-			break;
-		case 3:
-			hashmap.put("img", R.drawable.bot3);
-			break;
-		case 4:
-			hashmap.put("img", R.drawable.bot2);
-			break;
-		default:
-		case 5:
-			hashmap.put("img", R.drawable.bot1);
-			break;
-		}
-		return hashmap;
-	}
-}
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/GameConfig.java	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/GameConfig.java	Mon Dec 05 18:38:25 2011 -0500
@@ -22,6 +22,12 @@
 import java.util.ArrayList;
 import java.util.UUID;
 
+import org.hedgewars.hedgeroid.Datastructures.GameMode;
+import org.hedgewars.hedgeroid.Datastructures.Map;
+import org.hedgewars.hedgeroid.Datastructures.Scheme;
+import org.hedgewars.hedgeroid.Datastructures.Team;
+import org.hedgewars.hedgeroid.Datastructures.Weapon;
+
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/GameMode.java	Mon Nov 28 06:55:55 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-
-package org.hedgewars.hedgeroid.EngineProtocol;
-
-public enum GameMode {
-		MODE_LOCAL, MODE_DEMO, MODE_NET, MODE_SAVE
-}
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Grave.java	Mon Nov 28 06:55:55 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-
-package org.hedgewars.hedgeroid.EngineProtocol;
-
-public class Grave{
-
-	public final String name;
-	public final String path;
-	
-	public Grave(String _name, String _path) {
-		name = _name;
-		path = _path;
-	}
-
-	public String toString(){
-		return name;
-	}
-	
-}
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Map.java	Mon Nov 28 06:55:55 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-package org.hedgewars.hedgeroid.EngineProtocol;
-
-import java.io.File;
-import java.io.IOException;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class Map implements Comparable<Map>, Parcelable{
-
-	private static final String MISSION_PREFIX = "Mission: ";
-
-	private String name;
-	private String path;
-	private String previewPath;
-	private MapType type;
-
-	public Map(File mapDir, MapType _type, Context c){
-		type = _type;
-
-		name = mapDir.getName();
-		path = mapDir.getAbsolutePath();
-		previewPath = path + "/preview.png";
-		
-		/*switch(type){
-		case TYPE_DEFAULT:
-			
-			break;
-		case TYPE_GENERATED:
-			//TODO
-			break;
-		case TYPE_MISSION:
-			name = MISSION_PREFIX + mapDir.getName();
-			path = mapDir.getAbsolutePath();
-			break;
-		}*/
-
-		
-	}
-	
-	public Map(Parcel in){
-		readFromParcel(in);
-	}
-
-	public String toString(){
-		switch(type){
-		default:
-		case TYPE_DEFAULT:
-			return name;
-		case TYPE_GENERATED:
-			return "bla";
-		case TYPE_MISSION:
-			return MISSION_PREFIX + name;
-		}
-	}
-	
-	public void sendToEngine(EngineProtocolNetwork epn) throws IOException{
-		epn.sendToEngine(String.format("emap %s",name));
-	}
-	
-	public MapType getType(){
-		return type;
-	}
-
-	public Drawable getDrawable(){
-		switch(type){
-		case TYPE_MISSION:
-		case TYPE_DEFAULT:
-			return Drawable.createFromPath(previewPath);
-		case TYPE_GENERATED:
-
-		default:
-			return null;
-		}
-	}
-
-	public int compareTo(Map another) {
-		switch(type){
-		case TYPE_GENERATED:
-			switch(another.getType()){
-			case TYPE_GENERATED:
-				return name.compareTo(another.name);
-			case TYPE_MISSION:
-				return -1;
-			case TYPE_DEFAULT:
-				return -1;
-			}
-		case TYPE_MISSION:
-			switch(another.getType()){
-			case TYPE_GENERATED:
-				return 1;
-			case TYPE_MISSION:
-				return name.compareTo(another.name);
-			case TYPE_DEFAULT:
-				return -1;
-			}
-		case TYPE_DEFAULT:
-			switch(another.getType()){
-			case TYPE_GENERATED:
-				return 1;
-			case TYPE_MISSION:
-				return 1;
-			case TYPE_DEFAULT:
-				return name.compareTo(another.name);
-			}
-		}
-		return 0;//default case this should never happen
-	}
-
-	public enum MapType{
-		TYPE_DEFAULT, TYPE_MISSION, TYPE_GENERATED
-	}
-
-	public int describeContents() {
-		return 0;
-	}
-	
-	public void writeToParcel(Parcel dest, int flags) {
-		dest.writeString(name);
-		dest.writeString(path);
-		dest.writeString(previewPath);
-		dest.writeString(type.name());
-	}
-	
-	private void readFromParcel(Parcel src){
-		name = src.readString();
-		path = src.readString();
-		previewPath = src.readString();
-		type = MapType.valueOf(src.readString());
-	}
-	public static final Parcelable.Creator<Map> CREATOR = new Parcelable.Creator<Map>() {
-		public Map createFromParcel(Parcel source) {
-			return new Map(source);
-		}
-		public Map[] newArray(int size) {
-			return new Map[size];
-		}
-		
-	};
-}
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Scheme.java	Mon Nov 28 06:55:55 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,367 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-package org.hedgewars.hedgeroid.EngineProtocol;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import android.content.Context;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class Scheme implements Parcelable, Comparable<Scheme>{
-
-	public static final String DIRECTORY_SCHEME = "schemes";
-
-	private String name;
-	//private ArrayList<Integer> basic;
-	private Integer gamemod;
-	private ArrayList<Integer> basic;;
-	private static ArrayList<LinkedHashMap<String, ?>> basicflags = new ArrayList<LinkedHashMap<String, ?>>();
-	
-	public Scheme(String _name, ArrayList<Integer> _basic, int _gamemod){
-		name = _name;
-		gamemod = _gamemod;
-		basic = _basic;
-
-	}
-	
-	public Scheme(Parcel in){
-		readFromParcel(in);
-	}
-
-	public void sendToEngine(EngineProtocolNetwork epn)throws IOException{ 
-		epn.sendToEngine(String.format("e$gmflags %d", gamemod));
-
-		for(int pos = 0; pos < basic.size(); pos++){
-			LinkedHashMap<String, ?> basicflag = basicflags.get(pos);
-			
-			String command = (String)basicflag.get("command");
-			Integer value = basic.get(pos);
-			Boolean checkOverMax = (Boolean) basicflag.get("checkOverMax");
-			Boolean times1000 = (Boolean) basicflag.get("times1000");
-			Integer max = (Integer) basicflag.get("max");
-			
-			if(checkOverMax && value >= max) value = max;
-			if(times1000) value *= 1000;
-			
-			epn.sendToEngine(String.format("%s %d", command, value));
-		}
-	}
-	public String toString(){
-		return name;
-	}
-
-
-	public static final int STATE_START = 0;
-	public static final int STATE_ROOT = 1;
-	public static final int STATE_NAME = 2;
-	public static final int STATE_BASICFLAGS = 3;
-	public static final int STATE_GAMEMOD = 4;
-	public static final int STATE_BASICFLAG_INTEGER = 5;
-	public static final int STATE_GAMEMOD_TRUE = 6;
-	public static final int STATE_GAMEMOD_FALSE = 7;
-
-	public static ArrayList<Scheme> getSchemes(Context c) throws IllegalArgumentException{
-		String dir = c.getFilesDir().getAbsolutePath() + '/' + DIRECTORY_SCHEME + '/';
-		String[] files = new File(dir).list(fnf);
-		if(files == null) files = new String[]{};
-		Arrays.sort(files);
-		ArrayList<Scheme> schemes = new ArrayList<Scheme>();
-
-		try {
-			XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance();
-			XmlPullParser xmlPuller = xmlPullFactory.newPullParser();
-
-			for(String file : files){
-				BufferedReader br = new BufferedReader(new FileReader(dir + file), 1024);
-				xmlPuller.setInput(br);
-				String name = null;
-				ArrayList<Integer> basic = new ArrayList<Integer>();
-				Integer gamemod = 0;
-				int mask = 0x000000004;
-
-				int eventType = xmlPuller.getEventType();
-				int state = STATE_START;
-				while(eventType != XmlPullParser.END_DOCUMENT){
-					switch(state){
-					case STATE_START:
-						if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("scheme")) state = STATE_ROOT;
-						else if(eventType != XmlPullParser.START_DOCUMENT) throwException(file, eventType);
-						break;
-					case STATE_ROOT:
-						if(eventType == XmlPullParser.START_TAG){
-							if(xmlPuller.getName().equals("basicflags")) state = STATE_BASICFLAGS;
-							else if(xmlPuller.getName().toLowerCase().equals("gamemod")) state = STATE_GAMEMOD;
-							else if(xmlPuller.getName().toLowerCase().equals("name")) state = STATE_NAME;
-							else throwException(file, eventType);
-						}else if(eventType == XmlPullParser.END_TAG) state = STATE_START;
-						else throwException(xmlPuller.getText(), eventType);
-						break;
-					case STATE_BASICFLAGS:
-						if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().toLowerCase().equals("integer")) state = STATE_BASICFLAG_INTEGER;
-						else if(eventType == XmlPullParser.END_TAG)	state = STATE_ROOT;
-						else throwException(file, eventType);
-						break;
-					case STATE_GAMEMOD:
-						if(eventType == XmlPullParser.START_TAG){
-							if(xmlPuller.getName().toLowerCase().equals("true")) state = STATE_GAMEMOD_TRUE;
-							else if(xmlPuller.getName().toLowerCase().equals("false")) state = STATE_GAMEMOD_FALSE;
-							else throwException(file, eventType);
-						}else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
-						else throwException(file, eventType);
-						break;
-					case STATE_NAME:
-						if(eventType == XmlPullParser.TEXT) name = xmlPuller.getText().trim();
-						else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
-						else throwException(file, eventType);
-						break;
-					case STATE_BASICFLAG_INTEGER:
-						if(eventType == XmlPullParser.TEXT) basic.add(Integer.parseInt(xmlPuller.getText().trim()));
-						else if(eventType == XmlPullParser.END_TAG) state = STATE_BASICFLAGS;
-						else throwException(file, eventType);
-						break;
-					case STATE_GAMEMOD_FALSE:
-						if(eventType == XmlPullParser.TEXT) gamemod <<= 1;
-						else if(eventType == XmlPullParser.END_TAG) state = STATE_GAMEMOD;
-						else throwException(file, eventType);
-						break;
-					case STATE_GAMEMOD_TRUE:
-						if(eventType == XmlPullParser.TEXT){
-							gamemod |= mask;
-							gamemod <<= 1;
-						}else if(eventType == XmlPullParser.END_TAG) state = STATE_GAMEMOD;
-						else throwException(file, eventType);
-						break;
-					}
-					eventType = getEventType(xmlPuller);
-				}//end while(eventtype != END_DOCUMENT
-				schemes.add(new Scheme(name, basic, gamemod));
-			}//end for(string file : files
-			return schemes;
-		} catch (XmlPullParserException e) {
-			e.printStackTrace();
-		} catch (FileNotFoundException e) {
-			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		return new ArrayList<Scheme>();//TODO handle correctly
-	}
-	
-	private static FilenameFilter fnf = new FilenameFilter(){
-		public boolean accept(File dir, String filename) {
-			return filename.toLowerCase().startsWith("scheme_");
-		}
-	};
-
-	/**
-	 * This method will parse the basic flags from a prespecified xml file.
-	 * I use a raw xml file rather than one parsed by aatp at compile time
-	 * to keep it generic with other frontends, ie in the future we could 
-	 * use one provided by the Data folder.
-	 */
-	public static void parseBasicFlags(Context c){
-		String filename = String.format("%s/%s/basicflags", c.getFilesDir().getAbsolutePath(), DIRECTORY_SCHEME);
-
-		XmlPullParser xmlPuller = null;
-		BufferedReader br = null;
-		try {
-			XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance();
-			xmlPuller = xmlPullFactory.newPullParser();
-			br = new BufferedReader(new FileReader(filename), 1024);
-			xmlPuller.setInput(br);
-
-			int eventType = getEventType(xmlPuller);
-			boolean continueParsing = true;
-			do{
-				switch(eventType){
-				
-				case XmlPullParser.START_TAG:
-					if(xmlPuller.getName().toLowerCase().equals("flag")){
-						basicflags.add(parseFlag(xmlPuller));
-					}else if(xmlPuller.getName().toLowerCase().equals("basicflags")){
-						eventType = getEventType(xmlPuller);
-					}else{
-						skipCurrentTag(xmlPuller);
-						eventType = getEventType(xmlPuller);
-					}
-					break;
-				case XmlPullParser.START_DOCUMENT://ignore all tags not being "flag"
-				case XmlPullParser.END_TAG:
-				case XmlPullParser.TEXT:
-				default:
-					continueParsing = true;
-				case XmlPullParser.END_DOCUMENT:
-					continueParsing = false;
-				}
-			}while(continueParsing);
-
-		}catch(IOException e){
-			e.printStackTrace();
-		}catch (XmlPullParserException e) {
-			e.printStackTrace();
-		}finally{
-			if(br != null)
-				try {
-					br.close();
-				} catch (IOException e) {}
-		}
-
-	}
-
-	/*
-	 * * Parses a Tag structure from xml as example we use
-	 *<flag>
-	 *   <checkOverMax>
-	 *       <boolean>false</boolean>
-	 *   </checkOverMax>
-	 *</flag>
-	 *
-	 * It returns a LinkedHashMap with key/value pairs
-	 */
-	private static LinkedHashMap<String, Object> parseFlag(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{
-		LinkedHashMap<String, Object> hash = new LinkedHashMap<String, Object>();
-
-		int eventType = xmlPuller.getEventType();//Get the event type which triggered this method
-		if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().toLowerCase().equals("flag")){//valid start of flag tag
-			String lcKey = null;
-			String lcType = null;
-			String value = null;
-
-			eventType = getEventType(xmlPuller);//<checkOverMax>
-			while(eventType == XmlPullParser.START_TAG){
-				lcKey = xmlPuller.getName();//checkOverMax
-				if(getEventType(xmlPuller) == XmlPullParser.START_TAG){//<boolean>
-					lcType = xmlPuller.getName().toLowerCase();
-					if(getEventType(xmlPuller) == XmlPullParser.TEXT){
-						value = xmlPuller.getText();
-						if(getEventType(xmlPuller) == XmlPullParser.END_TAG && //</boolean> 
-								getEventType(xmlPuller) == XmlPullParser.END_TAG){//</checkOverMax>
-							if(lcType.equals("boolean")) hash.put(lcKey, new Boolean(value));
-							else if(lcType.equals("string"))hash.put(lcKey, value);							
-							else if(lcType.equals("integer")){
-								try{
-									hash.put(lcKey, new Integer(value));
-								}catch (NumberFormatException e){
-									throw new XmlPullParserException("Wrong integer value in xml file");
-								}
-							}else{
-								throwException("basicflags", eventType);
-							}
-						}//</boolean> / </checkOverMax>
-					}//if TEXT
-				}//if boolean
-				eventType = getEventType(xmlPuller);//start new loop
-			}
-			eventType = getEventType(xmlPuller);//</flag>
-		}
-
-		return hash;
-	}
-
-	private static void skipCurrentTag(XmlPullParser xmlPuller) throws XmlPullParserException, IOException{
-		int eventType = xmlPuller.getEventType();
-		if(eventType != XmlPullParser.START_TAG)return;
-		String tag = xmlPuller.getName().toLowerCase();
-
-		while(true){
-			eventType = getEventType(xmlPuller);//getNext()
-			switch(eventType){
-			case XmlPullParser.START_DOCUMENT://we're inside of a start tag so START_ or END_DOCUMENT is just wrong
-			case XmlPullParser.END_DOCUMENT:
-				throw new XmlPullParserException("invalid xml file");
-			case XmlPullParser.START_TAG://if we get a new tag recursively handle it
-				skipCurrentTag(xmlPuller);
-				break;
-			case XmlPullParser.TEXT:
-				break;
-			case XmlPullParser.END_TAG:
-				if(!xmlPuller.getName().toLowerCase().equals(tag)){//if the end tag doesn't match the start tag
-					throw new XmlPullParserException("invalid xml file");
-				}else{
-					return;//skip completed	
-				}
-
-			}
-		}
-	}
-
-	/**
-	 * Skips whitespaces..
-	 */
-	private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{
-		int eventType = xmlPuller.next();
-		while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){
-			eventType = xmlPuller.next();
-		}
-		return eventType;
-	}
-	private static void throwException(String file, int eventType){
-		throw new IllegalArgumentException(String.format("Xml file: %s malformed with error: %d.", file, eventType));
-	}
-
-	public int describeContents() {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	public void writeToParcel(Parcel dest, int flags) {
-		dest.writeString(name);
-		dest.writeInt(gamemod);
-		dest.writeList(basic);
-		
-	}
-	
-	public void readFromParcel(Parcel src){
-		name = src.readString();
-		gamemod = src.readInt();
-		basic = src.readArrayList(ArrayList.class.getClassLoader());
-	}
-
-	public static final Parcelable.Creator<Scheme> CREATOR = new Parcelable.Creator<Scheme>() {
-		public Scheme createFromParcel(Parcel source) {
-			return new Scheme(source);
-		}
-		public Scheme[] newArray(int size) {
-			return new Scheme[size];
-		}
-		
-	};
-
-	public int compareTo(Scheme another) {
-		boolean equalsDefault = name.toLowerCase().equals("default");
-		boolean otherEqualsDefault = another.name.toLowerCase().equals("default");
-		if(equalsDefault && otherEqualsDefault)	return 0;
-		else if(equalsDefault && !otherEqualsDefault) return -1;
-		else if((!equalsDefault) && otherEqualsDefault)	return 1;
-		else return name.compareTo(another.name);
-	}
-}
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Team.java	Mon Nov 28 06:55:55 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,366 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-package org.hedgewars.hedgeroid.EngineProtocol;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-import org.xmlpull.v1.XmlSerializer;
-
-import android.content.Context;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Xml;
-
-public class Team implements Parcelable{
-
-	public static final String DIRECTORY_TEAMS = "teams";
-	private static final Integer[] TEAM_COLORS = {
-		0xd12b42, /* red    */ 
-		0x4980c1, /* blue   */ 
-		0x6ab530, /* green  */ 
-		0xbc64c4, /* purple */ 
-		0xe76d14, /* orange */ 
-		0x3fb6e6, /* cyan   */ 
-		0xe3e90c, /* yellow */ 
-		0x61d4ac, /* mint   */ 
-		0xf1c3e1, /* pink   */ 
-		/* add new colors here */
-	};
-
-//	private static final Integer[] TEAM_COLORS = {
-//		0xff0000, /* red    */ 
-//		0x00ff00, /* blue   */ 
-//		0x0000ff, /* green  */ 
-//	};
-
-	private static final int STATE_START = 0;
-	private static final int STATE_ROOT = 1;
-	private static final int STATE_HOG_ROOT = 2;
-
-	public String name, grave, flag, voice, fort, hash;
-	public String file = null;
-
-	public static int maxNumberOfHogs = 0;
-	public static int maxNumberOfTeams = 0;
-
-	static{
-		maxNumberOfHogs = PascalExports.HWgetMaxNumberOfHogs();
-		maxNumberOfTeams = PascalExports.HWgetMaxNumberOfTeams();
-	}
-	public String[] hats = new String[maxNumberOfHogs];
-	public String[] hogNames = new String[maxNumberOfHogs];
-	public int[] levels = new int[maxNumberOfHogs];
-
-	public int hogCount = 4;
-	public int color = TEAM_COLORS[0];
-
-	public Team(){
-	}
-
-	public Team(Parcel in){
-		readFromParcel(in);
-	}
-
-	public boolean equals(Object o){
-		if(super.equals(o)) return true;
-		else if(o instanceof Team){
-			Team t = (Team)o;
-			boolean ret = name.equals(t.name);
-			ret &= grave.equals(t.grave);
-			ret &= flag.equals(t.flag);
-			ret &= voice.equals(t.voice);
-			ret &= fort.equals(t.fort);
-			ret &= hash.equals(t.hash);
-			return ret;
-		}else{
-			return false;
-		}
-	}
-
-	public void setRandomColor(int[] illegalcolors){
-		Integer[] colorsToPickFrom = TEAM_COLORS;
-		if(illegalcolors != null){
-			ArrayList<Integer> colors = new ArrayList<Integer>();
-			for(int color : TEAM_COLORS){
-				boolean validColor = true;
-				for(int illegal : illegalcolors){
-					if(color == illegal) validColor = false;
-				}
-				if(validColor) colors.add(color);
-			}
-			if(colors.size() != 0) colorsToPickFrom = colors.toArray(new Integer[1]);
-		}
-		int index = (int)Math.round(Math.random()*(colorsToPickFrom.length-1));
-		color = colorsToPickFrom[index];
-	}
-
-
-	public void sendToEngine(EngineProtocolNetwork epn, int hogCount, int health) throws IOException{
-		epn.sendToEngine(String.format("eaddteam %s %d %s", hash, color, name));
-		epn.sendToEngine(String.format("egrave %s", grave));
-		epn.sendToEngine(String.format("efort %s", fort));
-		epn.sendToEngine(String.format("evoicepack %s", voice));
-		epn.sendToEngine(String.format("eflag %s", flag));
-
-		for(int i = 0; i < hogCount; i++){
-			epn.sendToEngine(String.format("eaddhh %d %d %s", levels[i], health, hogNames[i]));
-			epn.sendToEngine(String.format("ehat %s", hats[i]));
-		}
-	}
-
-	public void setFileName(Context c){
-		if(file == null){
-		  	file = validFileName(c, name);
-		}
-	}
-	private String validFileName(Context c, String fileName){
-		String absolutePath = String.format("%s/%s", c.getFilesDir(), fileName);
-		File f = new File(absolutePath);
-		if(f.exists()){
-			String newFileName = fileName + (int)(Math.random()*10);
-			return validFileName(c, newFileName);
-		}else{
-			return fileName;
-		}
-	}
-	
-	/*
-	 * XML METHODS
-	 */
-
-	/**
-	 * Read the xml file path and convert it to a Team object
-	 * @param path absolute path to the xml file
-	 * @return
-	 */
-	public static Team getTeamFromXml(String path){
-		try {
-			XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance();
-			XmlPullParser xmlPuller = xmlPullFactory.newPullParser();
-
-			BufferedReader br = new BufferedReader(new FileReader(path), 1024);
-			xmlPuller.setInput(br);
-			Team team = new Team();
-			int hogCounter = 0;
-
-			int eventType = xmlPuller.getEventType();
-			int state = STATE_START;
-			while(eventType != XmlPullParser.END_DOCUMENT){
-				switch(state){
-				case STATE_START:
-					if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("team")) state = STATE_ROOT;
-					else if(eventType != XmlPullParser.START_DOCUMENT) throwException(path, eventType);
-					break;
-				case STATE_ROOT:
-					if(eventType == XmlPullParser.START_TAG){
-						if(xmlPuller.getName().toLowerCase().equals("name")){
-							team.name = getXmlText(xmlPuller, "name");
-						}else if(xmlPuller.getName().toLowerCase().equals("flag")){
-							team.flag= getXmlText(xmlPuller, "flag");
-						}else if(xmlPuller.getName().toLowerCase().equals("voice")){
-							team.voice = getXmlText(xmlPuller, "voice");
-						}else if(xmlPuller.getName().toLowerCase().equals("grave")){
-							team.grave = getXmlText(xmlPuller, "grave");
-						}else if(xmlPuller.getName().toLowerCase().equals("fort")){
-							team.fort = getXmlText(xmlPuller, "fort");
-						}else if(xmlPuller.getName().toLowerCase().equals("hash")){
-							team.hash = getXmlText(xmlPuller, "hash");
-						}else if(xmlPuller.getName().toLowerCase().equals("hog")){
-							state = STATE_HOG_ROOT;
-						}else throwException(xmlPuller.getName(), eventType);
-					}else if(eventType == XmlPullParser.END_TAG) state = STATE_START;
-					else throwException(xmlPuller.getText(), eventType);
-					break;
-				case STATE_HOG_ROOT:
-					if(eventType == XmlPullParser.START_TAG){
-						if(xmlPuller.getName().toLowerCase().equals("name")){
-							team.hogNames[hogCounter] = getXmlText(xmlPuller, "name");
-						}else if(xmlPuller.getName().toLowerCase().equals("hat")){
-							team.hats[hogCounter] = getXmlText(xmlPuller, "hat");
-						}else if(xmlPuller.getName().toLowerCase().equals("level")){
-							team.levels[hogCounter] = Integer.parseInt(getXmlText(xmlPuller, "level"));
-						}else throwException(xmlPuller.getText(), eventType);
-					}else if(eventType == XmlPullParser.END_TAG){
-						hogCounter++;
-						state = STATE_ROOT;
-					}else throwException(xmlPuller.getText(), eventType);
-					break;
-				}
-				eventType = getEventType(xmlPuller);
-			}//end while(eventtype != END_DOCUMENT
-			return team;
-		} catch (NumberFormatException e){
-			e.printStackTrace();
-		} catch (XmlPullParserException e) {
-			e.printStackTrace();
-		} catch (FileNotFoundException e) {
-			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		return null;
-	}
-
-	private static String getXmlText(XmlPullParser xmlPuller, String parentTag)throws XmlPullParserException, IOException{
-		if(getEventType(xmlPuller) == XmlPullParser.TEXT){
-			String txt = xmlPuller.getText();
-			if(getEventType(xmlPuller) == XmlPullParser.END_TAG && xmlPuller.getName().toLowerCase().equals(parentTag)){
-				return txt;
-			}
-		}
-		throw new XmlPullParserException("malformed xml file on string read from tag: " + parentTag);
-	}
-
-	/**
-	 * Skips whitespaces..
-	 */
-	private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{
-		int eventType = xmlPuller.next();
-		while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){
-			eventType = xmlPuller.next();
-		}
-		return eventType;
-	}
-
-	private static void throwException(String file, int eventType){
-		throw new IllegalArgumentException(String.format("Xml file: %s malformed with error: %d.", file, eventType));
-	}
-
-	public void writeToXml(OutputStream os){
-		XmlSerializer serializer = Xml.newSerializer();
-		try{
-			serializer.setOutput(os, "UTF-8");	
-			serializer.startDocument("UTF-8", true);
-			serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
-
-			serializer.startTag(null, "team");
-			serializer.startTag(null, "name");
-			serializer.text(name);
-			serializer.endTag(null, "name");
-			serializer.startTag(null, "flag");
-			serializer.text(flag);
-			serializer.endTag(null, "flag");
-			serializer.startTag(null, "fort");
-			serializer.text(fort);
-			serializer.endTag(null, "fort");
-			serializer.startTag(null, "grave");
-			serializer.text(grave);
-			serializer.endTag(null, "grave");
-			serializer.startTag(null, "voice");
-			serializer.text(voice);
-			serializer.endTag(null, "voice");
-			serializer.startTag(null, "hash");
-			serializer.text(hash);
-			serializer.endTag(null, "hash");
-
-			for(int i = 0; i < maxNumberOfHogs; i++){
-				serializer.startTag(null, "hog");
-				serializer.startTag(null, "name");
-				serializer.text(hogNames[i]);
-				serializer.endTag(null, "name");
-				serializer.startTag(null, "hat");
-				serializer.text(hats[i]);
-				serializer.endTag(null, "hat");
-				serializer.startTag(null, "level");
-				serializer.text(String.valueOf(levels[i]));
-				serializer.endTag(null, "level");
-
-				serializer.endTag(null, "hog");
-			}
-			serializer.endTag(null, "team");
-			serializer.endDocument();
-			serializer.flush();
-
-		} catch (IOException e) {
-			e.printStackTrace();
-		}finally{
-			try {
-				os.close();
-			} catch (IOException e) {}
-		}
-	}
-	/*
-	 * END XML METHODS
-	 */
-
-
-
-	/*
-	 * PARCABLE METHODS
-	 */
-
-	public int describeContents() {
-		return 0;
-	}
-
-	public void writeToParcel(Parcel dest, int flags) {
-		dest.writeString(name);
-		dest.writeString(grave);
-		dest.writeString(flag);
-		dest.writeString(voice);
-		dest.writeString(fort);
-		dest.writeString(hash);
-		dest.writeStringArray(hats);
-		dest.writeStringArray(hogNames);
-		dest.writeIntArray(levels);
-		dest.writeInt(color);
-		dest.writeInt(hogCount);
-		dest.writeString(file);
-	}
-
-
-	public void readFromParcel(Parcel src){
-		name = src.readString();
-		grave = src.readString();
-		flag = src.readString();
-		voice = src.readString();
-		fort = src.readString();
-		hash = src.readString();
-		src.readStringArray(hats);
-		src.readStringArray(hogNames);
-		src.readIntArray(levels);
-		color = src.readInt();
-		hogCount = src.readInt();
-		file = src.readString();
-	}
-
-	public static final Parcelable.Creator<Team> CREATOR = new Parcelable.Creator<Team>() {
-		public Team createFromParcel(Parcel source) {
-			return new Team(source);
-		}
-		public Team[] newArray(int size) {
-			return new Team[size];
-		}
-
-	};
-
-	/*
-	 * END PARCABLE METHODS
-	 */
-
-}
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Weapon.java	Mon Nov 28 06:55:55 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-package org.hedgewars.hedgeroid.EngineProtocol;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import android.content.Context;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-public class Weapon implements Parcelable, Comparable<Weapon>{
-
-	public static final String DIRECTORY_WEAPON = "weapons";
-	
-	private String name;
-	private String QT;
-	private String prob;
-	private String delay;
-	private String crate;
-	private static int maxWeapons;
-	
-	static{
-		//maxWeapons = PascalExports.HWgetNumberOfWeapons();
-	}
-	
-	public Weapon(String _name, String _QT, String _prob, String _delay, String _crate){
-		name = _name;
-		
-		//Incase there's a newer ammoStore which is bigger we append with zeros
-		StringBuffer sb = new StringBuffer();
-		while(_QT.length() + sb.length() < maxWeapons){
-			sb.append('0');
-		}
-		
-		QT = String.format("e%s %s%s", "ammloadt", _QT, sb);
-		prob = String.format("e%s %s%s", "ammprob", _prob, sb);
-		delay = String.format("e%s %s%s", "ammdelay", _delay, sb);
-		crate = String.format("e%s %s%s", "ammreinf", _crate, sb);
-	}
-	
-	public Weapon(Parcel in){
-		readFromParcel(in);
-	}
-	
-	public String toString(){
-		return name;
-	}
-	
-	public void sendToEngine(EngineProtocolNetwork epn, int teamsCount) throws IOException{
-		epn.sendToEngine(QT);//command prefix is already in string 
-		epn.sendToEngine(prob);
-		epn.sendToEngine(delay);
-		epn.sendToEngine(crate);
-		
-		for(int i = 0; i < teamsCount; i++){
-			epn.sendToEngine("eammstore");
-		}
-	}
-	
-	public static final int STATE_START = 0;
-	public static final int STATE_ROOT = 1;
-	public static final int STATE_NAME = 2;
-	public static final int STATE_QT = 3;
-	public static final int STATE_PROBABILITY = 4;
-	public static final int STATE_DELAY = 5;
-	public static final int STATE_CRATE = 6;
-	
-	public static ArrayList<Weapon> getWeapons(Context c) throws IllegalArgumentException{
-		String dir = c.getFilesDir().getAbsolutePath() + '/' + DIRECTORY_WEAPON + '/';
-		String[] files = new File(dir).list();
-		if(files == null) files = new String[]{};
-		
-		ArrayList<Weapon> weapons = new ArrayList<Weapon>();
-
-		try {
-			XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance();
-			XmlPullParser xmlPuller = xmlPullFactory.newPullParser();
-			
-			for(String file : files){
-				BufferedReader br = new BufferedReader(new FileReader(dir + file), 1024);
-				xmlPuller.setInput(br);
-				String name = null;
-				String qt = null;
-				String prob = null;
-				String delay = null;
-				String crate = null;
-				
-				int eventType = xmlPuller.getEventType();
-				int state = STATE_START;
-				while(eventType != XmlPullParser.END_DOCUMENT){
-					switch(state){
-					case STATE_START:
-						if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("weapon")) state = STATE_ROOT;
-						else if(eventType != XmlPullParser.START_DOCUMENT) throwException(file, eventType);
-						break;
-					case STATE_ROOT:
-						if(eventType == XmlPullParser.START_TAG){
-							if(xmlPuller.getName().toLowerCase().equals("qt")) state = STATE_QT;
-							else if(xmlPuller.getName().toLowerCase().equals("name")) state = STATE_NAME;
-							else if(xmlPuller.getName().toLowerCase().equals("probability")) state = STATE_PROBABILITY;
-							else if(xmlPuller.getName().toLowerCase().equals("delay")) state = STATE_DELAY;
-							else if(xmlPuller.getName().toLowerCase().equals("crate")) state = STATE_CRATE;
-							else throwException(file, eventType);
-						}else if(eventType == XmlPullParser.END_TAG) state = STATE_START;
-						else throwException(xmlPuller.getText(), eventType);
-						break;
-					case STATE_NAME:
-						if(eventType == XmlPullParser.TEXT) name = xmlPuller.getText().trim();
-						else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
-						else throwException(file, eventType);
-						break;
-					case STATE_QT:
-						if(eventType == XmlPullParser.TEXT) qt = xmlPuller.getText().trim();
-						else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
-						else throwException(file, eventType);
-						break;
-					case STATE_PROBABILITY:
-						if(eventType == XmlPullParser.TEXT) prob = xmlPuller.getText().trim();
-						else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
-						else throwException(file, eventType);
-						break;
-					case STATE_DELAY:
-						if(eventType == XmlPullParser.TEXT) delay = xmlPuller.getText().trim();
-						else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
-						else throwException(file, eventType);
-						break;
-					case STATE_CRATE:
-						if(eventType == XmlPullParser.TEXT) crate = xmlPuller.getText().trim();
-						else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
-						else throwException(file, eventType);
-						break;
-					}
-					eventType = xmlPuller.next();
-					while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){//Skip whitespaces
-						eventType = xmlPuller.next();
-					}
-				}//end while(eventtype != END_DOCUMENT
-				weapons.add(new Weapon(name, qt, prob, delay, crate));
-			}//end for(string file : files
-			return weapons;
-			
-		} catch (XmlPullParserException e) {
-			e.printStackTrace();
-		} catch (FileNotFoundException e) {
-			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		return new ArrayList<Weapon>();//TODO handle correctly
-	}
-	
-	private static void throwException(String file, int eventType){
-		throw new IllegalArgumentException(String.format("Xml file: %s malformed with eventType: %d.", file, eventType));
-	}
-
-	public int describeContents() {
-		return 0;
-	}
-
-	public void writeToParcel(Parcel dest, int flags) {
-		dest.writeString(name);
-		dest.writeString(QT);
-		dest.writeString(prob);
-		dest.writeString(delay);
-		dest.writeString(crate);
-	}
-	
-	private void readFromParcel(Parcel src){
-		name = src.readString();
-		QT = src.readString();
-		prob = src.readString();
-		delay = src.readString();
-		crate = src.readString();
-	}
-	
-	public static final Parcelable.Creator<Weapon> CREATOR = new Parcelable.Creator<Weapon>() {
-		public Weapon createFromParcel(Parcel source) {
-			return new Weapon(source);
-		}
-		public Weapon[] newArray(int size) {
-			return new Weapon[size];
-		}
-		
-	};
-
-	public int compareTo(Weapon another) {
-		boolean equalsDefault = name.toLowerCase().equals("crazy");
-		boolean otherEqualsDefault = another.name.toLowerCase().equals("crazy");
-		if(equalsDefault && otherEqualsDefault)	return 0;
-		else if(equalsDefault && !otherEqualsDefault) return -1;
-		else if((!equalsDefault) && otherEqualsDefault)	return 1;
-		else return name.compareTo(another.name);
-	}
-	
-	
-}
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java	Mon Dec 05 18:38:25 2011 -0500
@@ -19,11 +19,12 @@
 package org.hedgewars.hedgeroid;
 
 import org.hedgewars.hedgeroid.Downloader.DownloadAssets;
-import org.hedgewars.hedgeroid.Downloader.DownloadFragment;
 import org.hedgewars.hedgeroid.Downloader.DownloadListActivity;
-import org.hedgewars.hedgeroid.Downloader.DownloadService;
 
+import android.app.AlertDialog;
+import android.app.Dialog;
 import android.app.ProgressDialog;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
@@ -48,15 +49,34 @@
 		downloader.setOnClickListener(downloadClicker);
 		startGame.setOnClickListener(startGameClicker);
 
-		boolean assetsCopied = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("assetscopied", false);
+
+		String cacheDir = Utils.getCachePath(this);
+		if(cacheDir == null){
+			showDialog(0);
+		}else{
+			boolean assetsCopied = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("assetscopied", false);
 
-		if(!assetsCopied){
-			DownloadAssets assetsAsyncTask = new DownloadAssets(this);
-			assetsDialog = ProgressDialog.show(this, "Please wait a moment", "Moving assets...");
-			assetsAsyncTask.execute((Object[])null);
+			if(!assetsCopied){
+				DownloadAssets assetsAsyncTask = new DownloadAssets(this);
+				assetsDialog = ProgressDialog.show(this, "Please wait a moment", "Moving assets...");
+				assetsAsyncTask.execute((Object[])null);
+			}
 		}
 	}
 
+	public Dialog onCreateDialog(int id, Bundle args){
+		AlertDialog.Builder builder = new AlertDialog.Builder(this);
+		builder.setTitle(R.string.sdcard_not_mounted_title);
+		builder.setMessage(R.string.sdcard_not_mounted);
+		builder.setNegativeButton(android.R.string.ok, new DialogInterface.OnClickListener(){
+			public void onClick(DialogInterface dialog, int which) {
+				finish();				
+			}
+		});
+
+		return builder.create();
+	}
+
 	public void onAssetsDownloaded(boolean result){
 		if(result){
 			PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean("assetscopied", true).commit();
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java	Mon Dec 05 18:38:25 2011 -0500
@@ -9,7 +9,7 @@
 import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork;
 import org.hedgewars.hedgeroid.EngineProtocol.GameConfig;
 import org.hedgewars.hedgeroid.EngineProtocol.PascalExports;
-import org.hedgewars.hedgeroid.TouchInterface.TouchInterface;
+import org.hedgewars.hedgeroid.UserInput.TouchInterface;
 
 import android.app.Activity;
 import android.content.Context;
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartGameActivity.java	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartGameActivity.java	Mon Dec 05 18:38:25 2011 -0500
@@ -19,12 +19,13 @@
 
 package org.hedgewars.hedgeroid;
 
-import org.hedgewars.hedgeroid.EngineProtocol.FrontendDataUtils;
+import org.hedgewars.hedgeroid.Datastructures.FrontendDataUtils;
+import org.hedgewars.hedgeroid.Datastructures.Map;
+import org.hedgewars.hedgeroid.Datastructures.Map.MapType;
+import org.hedgewars.hedgeroid.Datastructures.Scheme;
+import org.hedgewars.hedgeroid.Datastructures.Team;
+import org.hedgewars.hedgeroid.Datastructures.Weapon;
 import org.hedgewars.hedgeroid.EngineProtocol.GameConfig;
-import org.hedgewars.hedgeroid.EngineProtocol.Map;
-import org.hedgewars.hedgeroid.EngineProtocol.Scheme;
-import org.hedgewars.hedgeroid.EngineProtocol.Team;
-import org.hedgewars.hedgeroid.EngineProtocol.Weapon;
 
 import android.app.Activity;
 import android.content.Intent;
@@ -93,27 +94,53 @@
 		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 		maps.setAdapter(adapter);
 		maps.setOnItemSelectedListener(mapsClicker);
+		//set to first nonmap
+		for(int i = 0; i < adapter.getCount(); i++){
+			if(((Map)adapter.getItem(i)).getType() == MapType.TYPE_DEFAULT){
+				maps.setSelection(i, false);
+				break;
+			}
+		}
 
 		adapter = new ArrayAdapter<String>(this, R.layout.listview_item, FrontendDataUtils.getGameplay(this));
 		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 		gameplay.setAdapter(adapter);
 		gameplay.setOnItemSelectedListener(gameplayClicker);
+		//set to first nonmap
+		for(int i = 0; i < adapter.getCount(); i++){
+			if(((String)adapter.getItem(i)).equals("None")){
+				gameplay.setSelection(i, false);
+				break;
+			}
+		}
 
 		adapter = new ArrayAdapter<Scheme>(this, R.layout.listview_item, FrontendDataUtils.getSchemes(this));
 		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 		gamescheme.setAdapter(adapter);
 		gamescheme.setOnItemSelectedListener(schemeClicker);
-
+		//set to first nonmap
+		for(int i = 0; i < adapter.getCount(); i++){
+			if(((Scheme)adapter.getItem(i)).toString().equals("Default")){
+				gamescheme.setSelection(i, false);
+				break;
+			}
+		}
+		
+		
 		adapter = new ArrayAdapter<Weapon>(this, R.layout.listview_item, FrontendDataUtils.getWeapons(this));
 		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 		weapons.setAdapter(adapter);
 		weapons.setOnItemSelectedListener(weaponClicker);
-
+		for(int i = 0; i < adapter.getCount(); i++){
+			if(((Weapon)adapter.getItem(i)).toString().equals("Crazy")){
+				weapons.setSelection(i, false);
+				break;
+			}
+		}
 		adapter = new ArrayAdapter<String>(this, R.layout.listview_item, FrontendDataUtils.getThemes(this));
 		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 		themes.setAdapter(adapter);
 		themes.setOnItemSelectedListener(themesClicker);
-
 	}
 
 	private void startTeamsActivity(){
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java	Mon Dec 05 18:38:25 2011 -0500
@@ -24,12 +24,11 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 
-import org.hedgewars.hedgeroid.EngineProtocol.FrontendDataUtils;
-import org.hedgewars.hedgeroid.EngineProtocol.Team;
+import org.hedgewars.hedgeroid.Datastructures.FrontendDataUtils;
+import org.hedgewars.hedgeroid.Datastructures.Team;
 
 import android.app.Activity;
 import android.graphics.Bitmap;
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamSelectionActivity.java	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamSelectionActivity.java	Mon Dec 05 18:38:25 2011 -0500
@@ -24,8 +24,8 @@
 import java.util.HashMap;
 import java.util.List;
 
-import org.hedgewars.hedgeroid.EngineProtocol.FrontendDataUtils;
-import org.hedgewars.hedgeroid.EngineProtocol.Team;
+import org.hedgewars.hedgeroid.Datastructures.FrontendDataUtils;
+import org.hedgewars.hedgeroid.Datastructures.Team;
 
 import android.app.Activity;
 import android.content.Intent;
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TouchInterface/TouchInterface.java	Mon Nov 28 06:55:55 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-package org.hedgewars.hedgeroid.TouchInterface;
-
-import org.hedgewars.hedgeroid.SDLActivity;
-
-import android.os.Build;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnTouchListener;
-
-public class TouchInterface{
-
-	public static OnTouchListener getTouchInterface(){
-		OnTouchListener toucher;
-		if(Build.VERSION.SDK_INT < 5){//8 == Build.VERSION_CODES.FROYO
-			toucher = new TouchInterfaceST();
-		}else{
-			toucher = new TouchInterfaceMT();
-		}
-
-		return toucher;
-	}
-}
-/**
- * Touch interface with multitouch
- */
-class TouchInterfaceMT implements OnTouchListener {
-	
-	private boolean firstEvent = true;
-	
-	public boolean onTouch(View v, MotionEvent event) {
-		//dumpEvent(event);
-		
-		int action = event.getAction();
-		int actionCode = action & MotionEvent.ACTION_MASK;
-		
-		for (int i = 0; i < event.getPointerCount(); i++) {
-			SDLActivity.onNativeTouch(event.getDeviceId(),  event.getPointerId(i), actionCode, (int)event.getX(i), (int)event.getY(i), event.getPressure(i));
-//			Log.d("Android", String.format("x=%f, y=%f, pntr=%d", event.getX(i), event.getY(i), event.getPointerId(i)));
-		   }
-		return true;
-	}
-
-	/** Show an event in the LogCat view, for debugging */
-	private void dumpEvent(MotionEvent event) {
-	   String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" ,
-	      "POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" };
-	   StringBuilder sb = new StringBuilder();
-	   int action = event.getAction();
-	   int actionCode = action & MotionEvent.ACTION_MASK;
-	   sb.append("event ACTION_" ).append(names[actionCode]);
-	   if (actionCode == MotionEvent.ACTION_POINTER_DOWN
-	         || actionCode == MotionEvent.ACTION_POINTER_UP) {
-	      sb.append("(pid " ).append(
-	      action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
-	      sb.append(")" );
-	   }
-	   sb.append("[" );
-	   for (int i = 0; i < event.getPointerCount(); i++) {
-	      sb.append("#" ).append(i);
-	      sb.append("(pid " ).append(event.getPointerId(i));
-	      sb.append(")=" ).append((int) event.getX(i));
-	      sb.append("," ).append((int) event.getY(i));
-	      if (i + 1 < event.getPointerCount())
-	         sb.append(";" );
-	   }
-	   sb.append("]" );
-	   Log.d("HW_APP_TOUCH", sb.toString());
-	}
-
-}
-
-/**
- * Touch interface without multitouch
- */
-class TouchInterfaceST implements OnTouchListener {
-
-	public boolean onTouch(View v, MotionEvent event) {
-		return false;
-	}
-
-
-
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/UserInput/TouchInterface.java	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,103 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+package org.hedgewars.hedgeroid.UserInput;
+
+import org.hedgewars.hedgeroid.SDLActivity;
+
+import android.os.Build;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnTouchListener;
+
+public class TouchInterface{
+
+	public static OnTouchListener getTouchInterface(){
+		OnTouchListener toucher;
+		if(Build.VERSION.SDK_INT < 5){//8 == Build.VERSION_CODES.FROYO
+			toucher = new TouchInterfaceST();
+		}else{
+			toucher = new TouchInterfaceMT();
+		}
+
+		return toucher;
+	}
+}
+/**
+ * Touch interface with multitouch
+ */
+class TouchInterfaceMT implements OnTouchListener {
+	
+	private boolean firstEvent = true;
+	
+	public boolean onTouch(View v, MotionEvent event) {
+		//dumpEvent(event);
+		
+		int action = event.getAction();
+		int actionCode = action & MotionEvent.ACTION_MASK;
+		
+		for (int i = 0; i < event.getPointerCount(); i++) {
+			SDLActivity.onNativeTouch(event.getDeviceId(),  event.getPointerId(i), actionCode, (int)event.getX(i), (int)event.getY(i), event.getPressure(i));
+//			Log.d("Android", String.format("x=%f, y=%f, pntr=%d", event.getX(i), event.getY(i), event.getPointerId(i)));
+		   }
+		return true;
+	}
+
+	/** Show an event in the LogCat view, for debugging */
+	private void dumpEvent(MotionEvent event) {
+	   String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" ,
+	      "POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" };
+	   StringBuilder sb = new StringBuilder();
+	   int action = event.getAction();
+	   int actionCode = action & MotionEvent.ACTION_MASK;
+	   sb.append("event ACTION_" ).append(names[actionCode]);
+	   if (actionCode == MotionEvent.ACTION_POINTER_DOWN
+	         || actionCode == MotionEvent.ACTION_POINTER_UP) {
+	      sb.append("(pid " ).append(
+	      action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
+	      sb.append(")" );
+	   }
+	   sb.append("[" );
+	   for (int i = 0; i < event.getPointerCount(); i++) {
+	      sb.append("#" ).append(i);
+	      sb.append("(pid " ).append(event.getPointerId(i));
+	      sb.append(")=" ).append((int) event.getX(i));
+	      sb.append("," ).append((int) event.getY(i));
+	      if (i + 1 < event.getPointerCount())
+	         sb.append(";" );
+	   }
+	   sb.append("]" );
+	   Log.d("HW_APP_TOUCH", sb.toString());
+	}
+
+}
+
+/**
+ * Touch interface without multitouch
+ */
+class TouchInterfaceST implements OnTouchListener {
+
+	public boolean onTouch(View v, MotionEvent event) {
+		return false;
+	}
+
+
+
+}
+
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Utils.java	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Utils.java	Mon Dec 05 18:38:25 2011 -0500
@@ -25,18 +25,18 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.List;
 
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.os.Build;
 import android.os.Environment;
 import android.util.Log;
-import android.widget.Toast;
 
 public class Utils {
 
 	private static final String ROOT_DIR = "Data/";
-	
+
 	/**
 	 * get the path to which we should download all the data files
 	 * @param c context 
@@ -49,34 +49,32 @@
 			return FroyoSDCardDir.getDownloadPath(c) + '/';
 		}
 	}
-	
+
 	public static String getDataPath(Context c){
 		return getCachePath(c) + ROOT_DIR;
 	}
-	
+
 	static class FroyoSDCardDir{
 		public static String getDownloadPath(Context c){
 			File f =  c.getExternalCacheDir();
 			if(f != null){
 				return f.getAbsolutePath();
 			}else{
-				Toast.makeText(c, R.string.sdcard_not_mounted, Toast.LENGTH_LONG).show();
 				return null;
 			}	
 		}
 	}
-	
+
 	static class PreFroyoSDCardDir{
 		public static String getDownloadPath(Context c){
 			if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
 				if(Environment.getExternalStorageDirectory() != null)
 					return Environment.getExternalStorageDirectory().getAbsolutePath() + "/Hedgewars/";				
 			}
-			Toast.makeText(c, R.string.sdcard_not_mounted, Toast.LENGTH_LONG).show();
 			return null;
 		}
 	}
-	
+
 	/**
 	 * Get files from dirName, dir name is relative to {@link getDownloadPath}
 	 * @param dirName
@@ -86,15 +84,15 @@
 	public static String[] getFileNamesFromRelativeDir(Context c, String dirName){
 		String prefix = getDataPath(c);
 		File f = new File(prefix + dirName);
-		
+
 		if(f.exists() && f.isDirectory()) return f.list();
 		else{
-			
+
 			Log.e("Utils::", "Couldn't find dir: " + dirName);
 			return new String[0];
 		}
 	}
-	
+
 	/**
 	 * Return a File array with all the files from dirName
 	 * @param c
@@ -104,14 +102,14 @@
 	public static File[] getFilesFromRelativeDir(Context c, String dirName){
 		String prefix = getDataPath(c);
 		File f = new File(prefix + dirName);
-		
+
 		if(f.exists() && f.isDirectory()) return f.listFiles();
 		else {
 			Log.e("Utils::", "Dir not found: " + dirName);
 			return new File[0];
 		}
 	}
-	
+
 	/**
 	 * Checks if this directory has a file with suffix suffix
 	 * @param f - directory
@@ -127,7 +125,7 @@
 			return false;
 		}
 	}
-	
+
 	/**
 	 * Gives back all dirs which contain a file with suffix fileSuffix
 	 * @param c
@@ -135,19 +133,16 @@
 	 * @param fileSuffix
 	 * @return
 	 */
-	public static String[] getDirsWithFileSuffix(Context c, String path, String fileSuffix){
+	public static List<String> getDirsWithFileSuffix(Context c, String path, String fileSuffix){
 		File[] files = getFilesFromRelativeDir(c,path);
-		String[] validFiles = new String[files.length];
-		int validCounter = 0;
-		
+		ArrayList<String> ret = new ArrayList<String>();
+
 		for(File f : files){
-			if(hasFileWithSuffix(f, fileSuffix)) validFiles[validCounter++] = f.getName();
+			if(hasFileWithSuffix(f, fileSuffix)) ret.add(f.getName());
 		}
-		String[] ret = new String[validCounter];
-		System.arraycopy(validFiles, 0, ret, 0, validCounter);
 		return ret;
 	}
-	
+
 	/**
 	 * Get all files from directory dir which have the given suffix
 	 * @param c
@@ -167,13 +162,13 @@
 		}
 		return ret;
 	}
-	
-    /**
-     * Moves resources pointed to by sourceResId (from @res/raw/) to the app's private data directory
-     * @param c
-     * @param sourceResId
-     * @param directory
-     */
+
+	/**
+	 * Moves resources pointed to by sourceResId (from @res/raw/) to the app's private data directory
+	 * @param c
+	 * @param sourceResId
+	 * @param directory
+	 */
 	public static void resRawToFilesDir(Context c, int sourceResId, String directory){
 		byte[] buffer = new byte[1024];
 		InputStream bis = null;
@@ -214,12 +209,12 @@
 					} catch (IOException e) {
 						e.printStackTrace();
 					}
-				if(bos != null)
-					try {
-						bos.close();
-					} catch (IOException e) {
-						e.printStackTrace();
-					}
+					if(bos != null)
+						try {
+							bos.close();
+						} catch (IOException e) {
+							e.printStackTrace();
+						}
 			}
 		}
 	}
Binary file project_files/AudioMono/Music/Art.ogg has changed
Binary file project_files/AudioMono/Music/Brick.ogg has changed
Binary file project_files/AudioMono/Music/Castle.ogg has changed
Binary file project_files/AudioMono/Music/City.ogg has changed
Binary file project_files/AudioMono/Music/Compost.ogg has changed
Binary file project_files/AudioMono/Music/Desert.ogg has changed
Binary file project_files/AudioMono/Music/EarthRise.ogg has changed
Binary file project_files/AudioMono/Music/Freeway.ogg has changed
Binary file project_files/AudioMono/Music/Golf.ogg has changed
Binary file project_files/AudioMono/Music/Halloween.ogg has changed
Binary file project_files/AudioMono/Music/Nature.ogg has changed
Binary file project_files/AudioMono/Music/Olympics.ogg has changed
Binary file project_files/AudioMono/Music/Rock.ogg has changed
Binary file project_files/AudioMono/Music/Sheep.ogg has changed
Binary file project_files/AudioMono/Music/bath.ogg has changed
Binary file project_files/AudioMono/Music/hell.ogg has changed
Binary file project_files/AudioMono/Music/main_theme.ogg has changed
Binary file project_files/AudioMono/Music/oriental.ogg has changed
Binary file project_files/AudioMono/Music/pirate.ogg has changed
Binary file project_files/AudioMono/Music/snow.ogg has changed
Binary file project_files/AudioMono/Music/underwater.ogg has changed
Binary file project_files/AudioMono/Sounds/1C.ogg has changed
Binary file project_files/AudioMono/Sounds/2D.ogg has changed
Binary file project_files/AudioMono/Sounds/3E.ogg has changed
Binary file project_files/AudioMono/Sounds/4F.ogg has changed
Binary file project_files/AudioMono/Sounds/5G.ogg has changed
Binary file project_files/AudioMono/Sounds/6A.ogg has changed
Binary file project_files/AudioMono/Sounds/7B.ogg has changed
Binary file project_files/AudioMono/Sounds/8C.ogg has changed
Binary file project_files/AudioMono/Sounds/9D.ogg has changed
Binary file project_files/AudioMono/Sounds/BirdyLay.ogg has changed
Binary file project_files/AudioMono/Sounds/CollectCrate.ogg has changed
Binary file project_files/AudioMono/Sounds/Droplet1.ogg has changed
Binary file project_files/AudioMono/Sounds/Droplet2.ogg has changed
Binary file project_files/AudioMono/Sounds/Droplet3.ogg has changed
Binary file project_files/AudioMono/Sounds/Hellish.ogg has changed
Binary file project_files/AudioMono/Sounds/Whistle.ogg has changed
Binary file project_files/AudioMono/Sounds/Yoohoo.ogg has changed
Binary file project_files/AudioMono/Sounds/baseballbat.ogg has changed
Binary file project_files/AudioMono/Sounds/bee.ogg has changed
Binary file project_files/AudioMono/Sounds/beewater.ogg has changed
Binary file project_files/AudioMono/Sounds/bump.ogg has changed
Binary file project_files/AudioMono/Sounds/cake2.ogg has changed
Binary file project_files/AudioMono/Sounds/denied.ogg has changed
Binary file project_files/AudioMono/Sounds/drillgun.ogg has changed
Binary file project_files/AudioMono/Sounds/egg.ogg has changed
Binary file project_files/AudioMono/Sounds/explosion.ogg has changed
Binary file project_files/AudioMono/Sounds/graveimpact.ogg has changed
Binary file project_files/AudioMono/Sounds/grenadeimpact.ogg has changed
Binary file project_files/AudioMono/Sounds/gun.ogg has changed
Binary file project_files/AudioMono/Sounds/hammer.ogg has changed
Binary file project_files/AudioMono/Sounds/hell_growl.ogg has changed
Binary file project_files/AudioMono/Sounds/hell_ooff.ogg has changed
Binary file project_files/AudioMono/Sounds/hell_ow.ogg has changed
Binary file project_files/AudioMono/Sounds/hell_ugh.ogg has changed
Binary file project_files/AudioMono/Sounds/hogchant3.ogg has changed
Binary file project_files/AudioMono/Sounds/homerun.ogg has changed
Binary file project_files/AudioMono/Sounds/lowgravity.ogg has changed
Binary file project_files/AudioMono/Sounds/melonimpact.ogg has changed
Binary file project_files/AudioMono/Sounds/mineimpact.ogg has changed
Binary file project_files/AudioMono/Sounds/minetick.ogg has changed
Binary file project_files/AudioMono/Sounds/molotov.ogg has changed
Binary file project_files/AudioMono/Sounds/mortar.ogg has changed
Binary file project_files/AudioMono/Sounds/parachute.ogg has changed
Binary file project_files/AudioMono/Sounds/pickhammer.ogg has changed
Binary file project_files/AudioMono/Sounds/placed.ogg has changed
Binary file project_files/AudioMono/Sounds/plane.ogg has changed
Binary file project_files/AudioMono/Sounds/rcplane.ogg has changed
Binary file project_files/AudioMono/Sounds/ride_of_the_valkyries.ogg has changed
Binary file project_files/AudioMono/Sounds/ropeattach.ogg has changed
Binary file project_files/AudioMono/Sounds/roperelease.ogg has changed
Binary file project_files/AudioMono/Sounds/ropeshot.ogg has changed
Binary file project_files/AudioMono/Sounds/shotgunfire.ogg has changed
Binary file project_files/AudioMono/Sounds/shotgunreload.ogg has changed
Binary file project_files/AudioMono/Sounds/shutterclick.ogg has changed
Binary file project_files/AudioMono/Sounds/sinegun.ogg has changed
Binary file project_files/AudioMono/Sounds/skip.ogg has changed
Binary file project_files/AudioMono/Sounds/sniperreload.ogg has changed
Binary file project_files/AudioMono/Sounds/splash.ogg has changed
Binary file project_files/AudioMono/Sounds/steam.ogg has changed
Binary file project_files/AudioMono/Sounds/steps.ogg has changed
Binary file project_files/AudioMono/Sounds/suddendeath.ogg has changed
Binary file project_files/AudioMono/Sounds/switchhog.ogg has changed
Binary file project_files/AudioMono/Sounds/throwpowerup.ogg has changed
Binary file project_files/AudioMono/Sounds/throwrelease.ogg has changed
Binary file project_files/AudioMono/Sounds/ufo.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Amazing.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Boring.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Brilliant.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Bugger.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Bungee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Byebye.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Comeonthen.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Coward.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Cutitout.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Drat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Enemydown.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Excellent.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Fire.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Firepunch1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Firstblood.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Flawless.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Gonnagetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Grenade.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Hello.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Hmm.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Hurry.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Illgetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Incoming.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Jump1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Jump2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Jump3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Justyouwait.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Kamikaze.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Laugh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Leavemealone.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Melon.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Missed.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Nooo.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Nutter.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Ohdear.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Ooff1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Ooff2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Ooff3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Oops.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Ouch.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Ow1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Ow2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Ow3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Ow4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Perfect.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/PoisonCough.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/PoisonMoan.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Reinforcements.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Revenge.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Runaway.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Sameteam.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Solong.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Stupid.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Takecover.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Thisoneismine.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Traitor.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Uh-oh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Victory.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Watchit.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Watchthis.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Whatthe.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Whoopsee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Yessir.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/British/Youllregretthat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Boring.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Byebye.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Comeonthen.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Coward.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Enemydown.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Firstblood.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Flawless.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Hello.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Hurry.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Illgetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Incoming.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Jump1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Jump2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Jump3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Kamikaze.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Laugh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Missed.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Nooo.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Nutter.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Ooff1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Ooff2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Ooff3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Oops.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Ow1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Ow2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Ow3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Ow4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/PoisonCough.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/PoisonMoan.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Reinforcements.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Sameteam.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Stupid.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Takecover.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Traitor.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Uh-oh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Victory.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Watchit.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Yessir.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Classic/Youllregretthat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Amazing.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Boring.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Brilliant.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Bugger.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Bungee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Byebye.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Comeonthen.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Coward.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Cutitout.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Drat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Enemydown.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Excellent.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Fire.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Firepunch1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Firepunch2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Firepunch3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Firepunch4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Firepunch5.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Firepunch6.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Firstblood.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Flawless.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Gonnagetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Grenade.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Hello.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Hmm.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Hurry.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Illgetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Incoming.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Jump1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Jump2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Jump3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Justyouwait.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Kamikaze.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Laugh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Leavemealone.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Melon.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Missed.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Nooo.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Nutter.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Ohdear.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Ooff1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Ooff2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Ooff3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Oops.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Ouch.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Ow1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Ow2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Ow3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Ow4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Perfect.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/PoisonCough.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/PoisonMoan.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Reinforcements.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Revenge.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Runaway.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Sameteam.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Solong.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Stupid.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Takecover.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Thisoneismine.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Traitor.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Uh-oh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Victory.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Watchit.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Watchthis.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Whatthe.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Whoopsee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Yessir.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Default/Youllregretthat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Amazing.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Boring.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Brilliant.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Bugger.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Bungee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Byebye.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Comeonthen.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Coward.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Cutitout.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Drat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Enemydown.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Excellent.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Fire.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Firepunch1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Firstblood.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Flawless.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Gonnagetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Grenade.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Hello.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Hmm.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Hurry.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Illgetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Incoming.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Jump1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Jump2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Jump3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Justyouwait.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Kamikaze.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Laugh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Leavemealone.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Melon.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Missed.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Nooo.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Nutter.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Ohdear.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Ooff1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Ooff2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Ooff3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Oops.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Ouch.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Ow1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Ow2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Ow3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Ow4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Perfect.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/PoisonCough.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/PoisonMoan.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Reinforcements.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Revenge.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Runaway.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Sameteam.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Solong.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Stupid.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Takecover.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Thisoneismine.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Traitor.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Uh-oh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Victory.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Watchit.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Watchthis.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Whatthe.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Whoopsee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Yessir.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Mobster/Youllregretthat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Amazing.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Boring.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Brilliant.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Bugger.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Bungee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Byebye.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Comeonthen.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Coward.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Cutitout.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Drat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Enemydown.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Excellent.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Fire.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Firepunch1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Firepunch2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Firepunch3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Firepunch4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Firepunch5.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Firepunch6.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Firstblood.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Flawless.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Gonnagetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Grenade.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Hello.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Hmm.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Hurry.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Illgetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Incoming.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Jump1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Jump2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Jump3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Justyouwait.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Kamikaze.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Laugh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Leavemealone.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Melon.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Missed.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Nooo.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Nutter.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Ohdear.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Ooff1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Ooff2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Ooff3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Oops.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Ouch.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Ow1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Ow2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Ow3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Ow4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Perfect.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/PoisonCough.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/PoisonMoan.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Reinforcements.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Revenge.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Runaway.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Sameteam.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Solong.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Stupid.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Takecover.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Thisoneismine.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Traitor.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Uh-oh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Victory.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Watchit.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Watchthis.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Whatthe.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Whoopsee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Yessir.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Pirate/Youllregretthat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Amazing.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Boring.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Brilliant.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Bugger.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Bungee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Byebye.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Comeonthen.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Coward.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Cutitout.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Drat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Enemydown.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Excellent.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Fire.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Firepunch1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Firepunch2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Firepunch3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Firepunch4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Firepunch5.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Firepunch6.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Firstblood.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Flawless.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Gonnagetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Grenade.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Hello.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Hmm.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Hurry.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Illgetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Incoming.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Jump1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Jump2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Jump3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Justyouwait.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Kamikaze.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Laugh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Leavemealone.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Melon.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Missed.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Nooo.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Nutter.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Ohdear.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Ooff1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Ooff2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Ooff3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Oops.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Ouch.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Ow1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Ow2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Ow3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Ow4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Perfect.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/PoisonCough.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/PoisonMoan.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Reinforcements.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Revenge.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Runaway.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Sameteam.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Solong.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Stupid.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Takecover.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Thisoneismine.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Traitor.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Uh-oh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Victory.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Watchit.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Watchthis.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Whatthe.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Whoopsee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Yessir.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Robot/Youllregretthat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Amazing.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Boring.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Brilliant.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Bugger.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Bungee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Byebye.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Comeonthen.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Coward.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Cutitout.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Drat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Enemydown.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Excellent.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Fire.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Firepunch1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Firstblood.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Flawless.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Gonnagetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Grenade.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Hello.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Hmm.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Hurry.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Illgetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Incoming.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Jump1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Jump2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Jump3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Justyouwait.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Kamikaze.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Laugh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Leavemealone.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Melon.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Missed.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Nooo.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Nutter.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Ohdear.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Ooff1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Ooff2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Ooff3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Oops.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Ouch.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Ow1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Ow2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Ow3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Ow4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Perfect.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/PoisonCough.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/PoisonMoan.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Reinforcements.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Revenge.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Runaway.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Sameteam.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Solong.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Stupid.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Takecover.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Thisoneismine.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Traitor.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Uh-oh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Victory.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Watchit.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Watchthis.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Whatthe.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Whoopsee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Yessir.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Russian/Youllregretthat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Amazing.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Boring.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Brilliant.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Bugger.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Bungee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Byebye.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Comeonthen.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Coward.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Cutitout.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Drat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Enemydown.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Excellent.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Fire.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Firepunch1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Firepunch2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Firepunch3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Firepunch4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Firepunch5.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Firepunch6.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Firstblood.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Flawless.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/FlawlessPossibility.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Gonnagetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Grenade.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Hello.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Hmm.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Hurry.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Illgetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Incoming.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Jump1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Jump2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Jump3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Justyouwait.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Kamikaze.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Laugh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Leavemealone.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Melon.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Missed.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Nooo.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Nutter.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Ohdear.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Ooff1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Ooff2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Ooff3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Oops.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Ouch.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Ow1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Ow2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Ow3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Ow4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Perfect.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/PoisonCough.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/PoisonMoan.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Reinforcements.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Revenge.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Runaway.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Sameteam.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Solong.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Stupid.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Takecover.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Thisoneismine.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Traitor.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Uh-oh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Victory.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/VictoryPossibility.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Watchit.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Watchthis.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Whatthe.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Whoopsee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Yessir.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Singer/Youllregretthat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Amazing.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Boring.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Brilliant.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Bugger.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Bungee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Byebye.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Comeonthen.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Coward.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Cutitout.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Drat.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Enemydown.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Excellent.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Fire.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Firepunch1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Firepunch2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Firepunch3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Firepunch4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Firepunch5.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Firepunch6.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Firstblood.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Flawless.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Gonnagetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Grenade.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Hello.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Hmm.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Hurry.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Illgetyou.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Incoming.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Jump1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Jump2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Jump3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Justyouwait.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Kamikaze.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Laugh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Leavemealone.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Melon.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Missed.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Nooo.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Nutter.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Ohdear.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Ooff1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Ooff2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Ooff3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Oops.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Ouch.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Ow1.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Ow2.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Ow3.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Ow4.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Perfect.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/PoisonCough.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/PoisonMoan.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Reinforcements.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Revenge.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Runaway.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Sameteam.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Solong.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Stupid.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Takecover.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Thisoneismine.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Traitor.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Uh-oh.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Victory.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Watchit.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Watchthis.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Whatthe.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Whoopsee.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Yessir.ogg has changed
Binary file project_files/AudioMono/Sounds/voices/Surfer/Youllregretthat.ogg has changed
Binary file project_files/AudioMono/Sounds/warp.ogg has changed
Binary file project_files/AudioMono/Sounds/whipcrack.ogg has changed
--- a/project_files/HedgewarsMobile/Classes/MissionTrainingViewController.m	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/MissionTrainingViewController.m	Mon Dec 05 18:38:25 2011 -0500
@@ -93,13 +93,13 @@
         NSString *descComplete = [[NSString alloc] initWithContentsOfFile:descLocation encoding:NSUTF8StringEncoding error:NULL];
         [descLocation release];
         NSArray *descArray = [descComplete componentsSeparatedByString:@"\n"];
-        NSMutableArray *filteredArray = [[NSMutableArray alloc] initWithCapacity:[descArray count]];
+        NSMutableArray *filteredArray = [[NSMutableArray alloc] initWithCapacity:[descArray count]/3];
         [descComplete release];
         // sanity check to avoid having missions and descriptions conflicts
         for (int i = 0; i < [self.listOfMissions count]; i++) {
             NSString *desc = [[self.listOfMissions objectAtIndex:i] stringByDeletingPathExtension];
             for (NSString *str in descArray)
-                if ([str hasPrefix:desc]) {
+                if ([str hasPrefix:desc] && [str hasSuffix:@"\""]) {
                     NSArray *descriptionText = [str componentsSeparatedByString:@"\""];
                     [filteredArray insertObject:[descriptionText objectAtIndex:1] atIndex:i];
                     break;
--- a/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj	Mon Dec 05 18:38:25 2011 -0500
@@ -36,6 +36,8 @@
 		61156521147F48B6006729A9 /* About.strings in Resources */ = {isa = PBXBuildFile; fileRef = 61156520147F48B6006729A9 /* About.strings */; };
 		61156523147F48B7006729A9 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 61156522147F48B7006729A9 /* Localizable.strings */; };
 		61156525147F48B8006729A9 /* Scheme.strings in Resources */ = {isa = PBXBuildFile; fileRef = 61156524147F48B8006729A9 /* Scheme.strings */; };
+		61177C02148B8BB100686905 /* uLandGenMaze.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61177C00148B8BB100686905 /* uLandGenMaze.pas */; };
+		61177C03148B8BB100686905 /* uLandOutline.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61177C01148B8BB100686905 /* uLandOutline.pas */; };
 		61188BF212A6FE530026C5DA /* ammoButton@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6103D399129B350700911D8D /* ammoButton@2x.png */; };
 		61188BF312A6FE540026C5DA /* arrowDown@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6103D39A129B350700911D8D /* arrowDown@2x.png */; };
 		61188BF412A6FE560026C5DA /* arrowLeft@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6103D39B129B350700911D8D /* arrowLeft@2x.png */; };
@@ -386,6 +388,17 @@
 		61156530147F4D10006729A9 /* Polish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Polish; path = Locale/Polish.lproj/About.strings; sourceTree = "<group>"; };
 		61156531147F4D17006729A9 /* Polish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Polish; path = Locale/Polish.lproj/Localizable.strings; sourceTree = "<group>"; };
 		61156532147F4D1E006729A9 /* Polish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Polish; path = Locale/Polish.lproj/Scheme.strings; sourceTree = "<group>"; };
+		61177BA7148A658900686905 /* German */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = German; path = Locale/German.lproj/Localizable.strings; sourceTree = "<group>"; };
+		61177BA9148A660C00686905 /* German */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = German; path = Locale/German.lproj/Scheme.strings; sourceTree = "<group>"; };
+		61177BAA148A661600686905 /* German */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = German; path = Locale/German.lproj/About.strings; sourceTree = "<group>"; };
+		61177BAC148A671600686905 /* Turkish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Turkish; path = Locale/Turkish.lproj/About.strings; sourceTree = "<group>"; };
+		61177BAD148A672000686905 /* Turkish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Turkish; path = Locale/Turkish.lproj/Localizable.strings; sourceTree = "<group>"; };
+		61177BAE148A672C00686905 /* Turkish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Turkish; path = Locale/Turkish.lproj/Scheme.strings; sourceTree = "<group>"; };
+		61177BE4148B881C00686905 /* Danish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Danish; path = Locale/Danish.lproj/About.strings; sourceTree = "<group>"; };
+		61177BF0148B882500686905 /* Danish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Danish; path = Locale/Danish.lproj/Localizable.strings; sourceTree = "<group>"; };
+		61177BF1148B882F00686905 /* Danish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Danish; path = Locale/Danish.lproj/Scheme.strings; sourceTree = "<group>"; };
+		61177C00148B8BB100686905 /* uLandGenMaze.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uLandGenMaze.pas; path = ../../hedgewars/uLandGenMaze.pas; sourceTree = SOURCE_ROOT; };
+		61177C01148B8BB100686905 /* uLandOutline.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uLandOutline.pas; path = ../../hedgewars/uLandOutline.pas; sourceTree = SOURCE_ROOT; };
 		611D7A4F142FDCD3006E0798 /* uTouch.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uTouch.pas; path = ../../hedgewars/uTouch.pas; sourceTree = SOURCE_ROOT; };
 		611D9BF812497E9800008271 /* SavedGamesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SavedGamesViewController.h; sourceTree = "<group>"; };
 		611D9BF912497E9800008271 /* SavedGamesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SavedGamesViewController.m; sourceTree = "<group>"; };
@@ -1177,6 +1190,8 @@
 		9283015C0F10E48900CC5A3C /* Pascal Sources */ = {
 			isa = PBXGroup;
 			children = (
+				61177C00148B8BB100686905 /* uLandGenMaze.pas */,
+				61177C01148B8BB100686905 /* uLandOutline.pas */,
 				611D7A4F142FDCD3006E0798 /* uTouch.pas */,
 				61A976B2136F668500DD9878 /* uCursor.pas */,
 				61E5D68C12AB006F00566F29 /* uLandPainted.pas */,
@@ -1290,6 +1305,8 @@
 				German,
 				Spanish,
 				Polish,
+				Turkish,
+				Danish,
 			);
 			mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
 			projectDirPath = "";
@@ -1545,7 +1562,7 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "#copy new stuff over old stuff\nrm -rf ${PROJECT_DIR}/Data\n\n#create config.inc\necho \"Updating config file...\"\nPROTO=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep HEDGEWARS_PROTO_VER | cut -d ' ' -f 2 | cut -d ')' -f 1`\nMAJN=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep CPACK_PACKAGE_VERSION_MAJOR | xargs | cut -d ' ' -f 2 |cut -d ')' -f 1`\nMINN=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep CPACK_PACKAGE_VERSION_MINOR | xargs | cut -d ' ' -f 2 |cut -d ')' -f 1`\nPATN=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep CPACK_PACKAGE_VERSION_PATCH | xargs | cut -d ' ' -f 2 |cut -d '$' -f 1`\nREVN=-`/usr/local/bin/hg id -n ${PROJECT_DIR}/../../`\necho \"const cNetProtoVersion = $PROTO; const cVersionString = '${MAJN}.${MINN}.${PATN}${REVN}'; const cLuaLibrary = '';\" > ${PROJECT_DIR}/config.inc\n\necho \"Copying Data...\"\ncp -R ${PROJECT_DIR}/../../share/hedgewars/Data ${PROJECT_DIR}/Data\n\n#copy some files from QTfrontend/res\necho \"Fetching additional graphics from QTfrontend...\"\nmkdir ${PROJECT_DIR}/Data/Graphics/Icons\ncp    ${PROJECT_DIR}/../../QTfrontend/res/{btn*,icon*,StatsMedal*,ammopic*}.png  ${PROJECT_DIR}/Data/Graphics/Icons/\n\necho \"Removing text and dummy files...\"\n#delete all CMakeLists.txt and image source files\nfind ${PROJECT_DIR}/Data -name CMakeLists.txt -delete\nfind ${PROJECT_DIR}/Data -name *.svg* -delete\nfind ${PROJECT_DIR}/Data -name *.psd -delete\nfind ${PROJECT_DIR}/Data -name *.sifz -delete\nfind ${PROJECT_DIR}/Data -name *.xcf -delete\nfind ${PROJECT_DIR}/Data -name *.orig -delete\nfind ${PROJECT_DIR}/Data -name *.ts -delete\n\n#delete dummy maps and hats, misc stuff\nrm -rf ${PROJECT_DIR}/Data/Maps/test*\nrm -rf ${PROJECT_DIR}/Data/Graphics/Hats/{TeamCap,TeamHeadband,TeamHair}\nrm -rf ${PROJECT_DIR}/Data/misc/\n\n#delete forbidden maps and WIP themes (remember to check that no Map uses them)\nrm -rf ${PROJECT_DIR}/Data/Maps/{Cheese,FlightJoust}\nrm -rf ${PROJECT_DIR}/Data/Themes/{Beach,Digital}\n\n#delete all names, reserved hats and unused fonts\nrm -rf ${PROJECT_DIR}/Data/Names/\nrm -rf ${PROJECT_DIR}/Data/Graphics/Hats/Reserved/\nrm -rf ${PROJECT_DIR}/Data/Fonts/{wqy-zenhei.ttc,DroidSansFallback.ttf}\n\necho \"Handling audio files...\"\n#delete the Classic voice\nrm -rf ${PROJECT_DIR}/Data/Sounds/voices/Classic\n#delete the main theme file\nrm -rf ${PROJECT_DIR}/Data/Music/main_theme.ogg\n#copy mono audio\ncp -R ${PROJECT_DIR}/Audio/* ${PROJECT_DIR}/Data/\n#remove unused voices\nfor i in {Amazing,Brilliant,Bugger,Bungee,Cutitout,Drat,Excellent,Fire,FlawlessPossibility,Gonnagetyou,Grenade,Hmm,Justyouwait,Leavemealone,Ohdear,Ouch,Perfect,Revenge,Runaway,Solong,Thisoneismine,VictoryPossibility,Watchthis,Whatthe,Whoopsee}; do find Data/Sounds/voices/ -name $i.ogg -delete; done\n\necho \"Tweaking Data contents...\"\n#move Lua maps in Missions\nmkdir ${PROJECT_DIR}/Data/Missions/Maps/\nfor i in `ls ${PROJECT_DIR}/Data/Maps/`; do if [[ `ls -f ${PROJECT_DIR}/Data/Maps/$i/map.lua 2> /dev/null` != '' ]]; then mv ${PROJECT_DIR}/Data/Maps/$i ${PROJECT_DIR}/Data/Missions/Maps/; fi; done;\n#workaround for missing map in CTF_Blizzard\nln -s ../../../Maps/Blizzard/map.png ${PROJECT_DIR}/Data/Missions/Maps/CTF_Blizzard/map.png\n#remove cfg files since we have plists\nfind ${PROJECT_DIR}/Data/Scripts -name *.cfg -delete\nif ((`ls ${PROJECT_DIR}/Data/Scripts/Multiplayer/*.lua|wc -l` >= `ls ${PROJECT_DIR}/Data/Scripts/plist/*.plist|wc -l` ))\nthen\necho \"${PROJECT_DIR}/Data/Scripts/Multiplayer/Normal.plist:0: warning, missing plist implementation of a Multiplayer script file\"\nfi\n\n#reduce the number of flakes for City\nsed -i -e 's/1500/50/' ${PROJECT_DIR}/Data/Themes/City/theme.cfg\n#cleanup missions/trainings info\nsed -i -e -n '/\"/p' ${PROJECT_DIR}/Data/Locale/missions_en.txt\n\necho \"Done\"";
+			shellScript = "#copy new stuff over old stuff\nrm -rf ${PROJECT_DIR}/Data\n\n#create config.inc\necho \"Updating config file...\"\nPROTO=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep HEDGEWARS_PROTO_VER | cut -d ' ' -f 2 | cut -d ')' -f 1`\nMAJN=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep CPACK_PACKAGE_VERSION_MAJOR | xargs | cut -d ' ' -f 2 |cut -d ')' -f 1`\nMINN=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep CPACK_PACKAGE_VERSION_MINOR | xargs | cut -d ' ' -f 2 |cut -d ')' -f 1`\nPATN=`cat ${PROJECT_DIR}/../../CMakeLists.txt | grep CPACK_PACKAGE_VERSION_PATCH | xargs | cut -d ' ' -f 2 |cut -d '$' -f 1`\nREVN=-`/usr/local/bin/hg id -n ${PROJECT_DIR}/../../`\necho \"const cNetProtoVersion = $PROTO; const cVersionString = '${MAJN}.${MINN}.${PATN}${REVN}'; const cLuaLibrary = '';\" > ${PROJECT_DIR}/config.inc\n\necho \"Copying Data...\"\ncp -R ${PROJECT_DIR}/../../share/hedgewars/Data ${PROJECT_DIR}/Data\n\n#copy some files from QTfrontend/res\necho \"Fetching additional graphics from QTfrontend...\"\nmkdir ${PROJECT_DIR}/Data/Graphics/Icons\ncp    ${PROJECT_DIR}/../../QTfrontend/res/{btn*,icon*,StatsMedal*,ammopic*}.png  ${PROJECT_DIR}/Data/Graphics/Icons/\n\necho \"Removing text and dummy files...\"\n#delete all CMakeLists.txt and image source files\nfind ${PROJECT_DIR}/Data -name CMakeLists.txt -delete\nfind ${PROJECT_DIR}/Data -name *.svg* -delete\nfind ${PROJECT_DIR}/Data -name *.psd -delete\nfind ${PROJECT_DIR}/Data -name *.sifz -delete\nfind ${PROJECT_DIR}/Data -name *.xcf -delete\nfind ${PROJECT_DIR}/Data -name *.orig -delete\nfind ${PROJECT_DIR}/Data -name *.ts -delete\n\n#delete dummy maps and hats, misc stuff\nrm -rf ${PROJECT_DIR}/Data/Maps/test*\nrm -rf ${PROJECT_DIR}/Data/Graphics/Hats/{TeamCap,TeamHeadband,TeamHair}\nrm -rf ${PROJECT_DIR}/Data/misc/\n\n#delete forbidden maps and WIP themes (remember to check that no Map uses them)\nrm -rf ${PROJECT_DIR}/Data/Maps/{Cheese,FlightJoust}\nrm -rf ${PROJECT_DIR}/Data/Themes/{Beach,Digital}\n\n#delete all names, reserved hats and unused fonts\nrm -rf ${PROJECT_DIR}/Data/Names/\nrm -rf ${PROJECT_DIR}/Data/Graphics/Hats/Reserved/\nrm -rf ${PROJECT_DIR}/Data/Fonts/{wqy-zenhei.ttc,DroidSansFallback.ttf}\n\necho \"Handling audio files...\"\n#copy mono audio\ncp -R ${PROJECT_DIR}/../AudioMono/* ${PROJECT_DIR}/Data/\n#delete the Classic voice\nrm -rf ${PROJECT_DIR}/Data/Sounds/voices/Classic\n#delete the main theme file\nrm -rf ${PROJECT_DIR}/Data/Music/main_theme.ogg\n\n#remove unused voices\nfor i in {Amazing,Brilliant,Bugger,Bungee,Cutitout,Drat,Excellent,Fire,FlawlessPossibility,Gonnagetyou,Grenade,Hmm,Justyouwait,Leavemealone,Ohdear,Ouch,Perfect,Revenge,Runaway,Solong,Thisoneismine,VictoryPossibility,Watchthis,Whatthe,Whoopsee}; do find Data/Sounds/voices/ -name $i.ogg -delete; done\n\necho \"Tweaking Data contents...\"\n#move Lua maps in Missions\nmkdir ${PROJECT_DIR}/Data/Missions/Maps/\nfor i in `ls ${PROJECT_DIR}/Data/Maps/`;\ndo \n    if [[ `ls -f ${PROJECT_DIR}/Data/Maps/$i/map.lua 2> /dev/null` != '' ]];\n    then\n        mv ${PROJECT_DIR}/Data/Maps/$i ${PROJECT_DIR}/Data/Missions/Maps/;\n    fi;\ndone;\n\n#workaround for missing map in CTF_Blizzard\nln -s ../../../Maps/Blizzard/map.png ${PROJECT_DIR}/Data/Missions/Maps/CTF_Blizzard/map.png\n#remove cfg files since we have plists\nfind ${PROJECT_DIR}/Data/Scripts -name *.cfg -delete\nif ((`ls ${PROJECT_DIR}/Data/Scripts/Multiplayer/*.lua|wc -l` >= `ls ${PROJECT_DIR}/Data/Scripts/plist/*.plist|wc -l` ))\nthen\necho \"${PROJECT_DIR}/Data/Scripts/Multiplayer/Normal.plist:0: warning, missing plist implementation of a Multiplayer script file\"\nfi\n\n#reduce the number of flakes for City\nsed -i -e 's/1500/50/' ${PROJECT_DIR}/Data/Themes/City/theme.cfg\n\necho \"Done\"";
 			showEnvVarsInLog = 0;
 		};
 		9283011B0F10CB2D00CC5A3C /* Build libfpc.a */ = {
@@ -1684,6 +1701,8 @@
 				611D7A50142FDCD3006E0798 /* uTouch.pas in Sources */,
 				61915D5B143A4E2C00299991 /* MissionTrainingViewController.m in Sources */,
 				61D0BDF91457508C0011A899 /* ExtraCategories.m in Sources */,
+				61177C02148B8BB100686905 /* uLandGenMaze.pas in Sources */,
+				61177C03148B8BB100686905 /* uLandOutline.pas in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -1705,6 +1724,9 @@
 				61156526147F49E1006729A9 /* Spanish */,
 				6115652D147F4C52006729A9 /* French */,
 				61156530147F4D10006729A9 /* Polish */,
+				61177BAA148A661600686905 /* German */,
+				61177BAC148A671600686905 /* Turkish */,
+				61177BE4148B881C00686905 /* Danish */,
 			);
 			name = About.strings;
 			sourceTree = "<group>";
@@ -1716,6 +1738,9 @@
 				61156527147F4A2E006729A9 /* Spanish */,
 				6115652C147F4C4C006729A9 /* French */,
 				61156531147F4D17006729A9 /* Polish */,
+				61177BA7148A658900686905 /* German */,
+				61177BAD148A672000686905 /* Turkish */,
+				61177BF0148B882500686905 /* Danish */,
 			);
 			name = Localizable.strings;
 			sourceTree = "<group>";
@@ -1727,6 +1752,9 @@
 				61156528147F4A3C006729A9 /* Spanish */,
 				6115652B147F4C45006729A9 /* French */,
 				61156532147F4D1E006729A9 /* Polish */,
+				61177BA9148A660C00686905 /* German */,
+				61177BAE148A672C00686905 /* Turkish */,
+				61177BF1148B882F00686905 /* Danish */,
 			);
 			name = Scheme.strings;
 			sourceTree = "<group>";
Binary file project_files/HedgewarsMobile/Locale/Danish.lproj/About.strings has changed
Binary file project_files/HedgewarsMobile/Locale/Danish.lproj/Localizable.strings has changed
Binary file project_files/HedgewarsMobile/Locale/Danish.lproj/Scheme.strings has changed
Binary file project_files/HedgewarsMobile/Locale/French.lproj/About.strings has changed
Binary file project_files/HedgewarsMobile/Locale/German.lproj/About.strings has changed
Binary file project_files/HedgewarsMobile/Locale/German.lproj/Localizable.strings has changed
Binary file project_files/HedgewarsMobile/Locale/German.lproj/Scheme.strings has changed
Binary file project_files/HedgewarsMobile/Locale/Polish.lproj/About.strings has changed
Binary file project_files/HedgewarsMobile/Locale/Polish.lproj/Localizable.strings has changed
Binary file project_files/HedgewarsMobile/Locale/Polish.lproj/Scheme.strings has changed
Binary file project_files/HedgewarsMobile/Locale/Turkish.lproj/About.strings has changed
Binary file project_files/HedgewarsMobile/Locale/Turkish.lproj/Localizable.strings has changed
Binary file project_files/HedgewarsMobile/Locale/Turkish.lproj/Scheme.strings has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_da.txt	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,31 @@
+Hedgewars, det' Vildt!
+
+✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭
+✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭
+Hedgewars er tilgængeligt i Mac App Store! Søg efter Hedgewars på din Mac og få din GRATIS kopi i dag!
+✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭
+✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭ 
+
+iOS versionen har flere eksklusive funktioner, så som
+* iPad VGA-udgangssignal: tilslut en ekstern skærm og spil i fuld oplysning;
+* Understøttelse af Retina-skærmen: spil hele spillet i en højere opløsning;
+* Multitasking: sæt spillet på pause når som helst;
+* Genoptagelse af Spil: du kan altid færdiggøre din kamp, lige meget hvad.
+
+Beskrivelse:
+Det her er det sjoveste og mest afhængighedsskabende spil du nogensinde kommer til at prøve - hylende morsomt og lige til at tage op af lommen hvor som helst, når som helst. Hedgewars er et turbaseret strategispil, men det fedeste er at se de utrolige ødelæggelser de forbistrede pindsvin laver med deres fantasifulde våben - luskede små fyre med en uforskammet holdning.
+
+Med andre ord er Hedgewars et turbaseret strategi-, artilleri-, action- og komediespil som byder på an narrestreger fra små lyserøde pindsvin med attitude og som viser hvordan de slås overalt, fra det dybeste helvede til den yderste afkroge af rummet.
+
+Som hærfører er det dit arbejde at sammensætte et førsteklasses hold af pindsvinesoldater og føre krig mod fjenderne helt fremme ved frontlinjen.
+
+Hver spiller styrer et hold bestående af adskillige pindsvin. I løbet af spillet tager spillerne ture med et af deres pindsvin. De bruger her et hvilket som helst tilgængeligt værktøj eller våben til at angribe og dræbe deres modstanderes pindsvin, og vinder derved spillet. Pindsvinene kan bevæge sig rundt i terrænet på mange forskellige måder, normalt ved at gå og hoppe, men også ved at bruge forskellige værktøjer som f.eks. et reb, en teleporter eller en faldskærm for at nå ellers utilgængelige steder. Hver tur er tidsbegrænset for at sikre at spillere ikke forsinker spillet med for mange tanker eller bevægelser. Et stort assortiment af våben er tilgængeligt i løbet af spillet: Granater, klyngebomber, bazookaer, UFO'er, haglgeværer, pistoler, slag med brændende næver, baseballbatter, dynamit, miner, reb, trykluftsbor, faldskærme, osv. De fleste våben laver eksplosioner som deformerer terrænet ved at fjerne cirkulære stykker. Landskabet består af en flydende ø i en vandmasse, eller en begrænset grotte med vand i bunden. Pindsvin dør hvis de falder i vandet (enten ved at falde ud over kanten af øen, eller gennem et hul i bunden), falder ud over kanten af banen eller hvis deres liv bliver reduceret (typisk ved nærkontakt med for mange eksplosioner) til nul.
+
+* Vandvittig morsom og ødelæggende turbaseret krigsførsel for op til 6 spillere
+* Multiplayer, både lokalt og over et netværk, men valgfri computerstyrede modstandere
+* Kæmp på et uendeligt antal tilfældigt genererede baner med over 20 forskellige typer omgivelser
+* Brug 48 (forøges løbende) overvældende våben! Inklusiv klaveranslaget og den eksplosive robotkage
+* Spil lige som du har lyst til! Med mere end 20 forskellige måder at justere spillet på, kan du selv bestemme over næsten alle aspekter af kampen
+* Skræddersy dit hold med over 120 kostumer, 30 gravsten, 12 forter, hundredvis af flag og mange unikke sæt stemmer
+* Enorme slag med op til 64 pindsvin
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_de.txt	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,31 @@
+Hedgewars, einfach Bombastisch!
+
+✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭
+✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭
+Hedgewars ist jetzt auch im Mac Appstore verfügbar! Suche Hedgewars von deinem Mac und bekomme deine GRATIS Kopie!
+✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭
+✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭✭ 
+
+Der iOS-Port hat einige exklusiven Features, wie z.B.:
+* iPad VGA-Ausgabe: Schließe einen externen Bildschirm an und spiele mit voller Auflösung;
+* Retina Display-Unterstützung: Spiele das gesamte Spiel mit noch höherer Auflösung;
+* Multitasking: Pausiere das Spiel wann immer du willst;
+* Spielstandwiederherstellung: Egal was passiert, du wirst immer in der Lage sein die Partie zu Ende zu spielen.
+
+Beschreibung:
+Es ist das lustigste und süchtig-machendste Spiel auf der Welt - wahnsinniger Spielspaß, wo und wann du willst. Hedgewars ist ein rundenbasiertes Strategiespiel. Aber die richtige Begeisterung verursacht erst, diesen nervigen kleinen Igeln zu zuschauen, wie sie mit ihren fantastischen Waffen alles zerstören - hinterhältige kleine Mistkerle mit bösen Absichten!
+
+Anders gesagt, Hedgewars ist ein rundenbasiertes Strategie-, Artillerie-, Action- und Comedy-Spiel. In den Hauptrollen die Grimassen der pinken Igel, mit dem Anschein als wollten sie sich aus den Tiefen der Hölle in die Tiefen des Universums vorkämpfen.
+
+Als Kommandant ist es deine Aufgabe ein Sondereinsatzkommando aus Igelsoldaten zusammenzustellen und deine Feinde mit Krieg zu überziehen.
+
+Jeder Spieler befehligt ein aus mehreren Igeln bestehendes Team. Im Spielverlauf ziehen die Spieler mit einem ihrer Igel. Sie benutzen dann alle zur Verfügung stehende Hilfsmittel und Waffen um die gegnerischen Igel zu töten. Dadurch gewinnen sie das Spiel. Igel können sich auf verschiedene Arten und Weisen auf dem Gelände bewegen, normalerweise durch laufen und springen, sie können aber auch spezielle Hilfsmittel wie zum Beispiel ein Seil oder einen Fallschirm benutzen, um zu ansonsten unerreichbaren Regionen vorzudringen. Um zu verhindern, dass Teilnehmer nicht das Spiel durch übermäßiges Nachdenken oder Bewegen aufhalten, ist jeder Zug zeitlich begrenzt. Während dem Spiel gibt es eine Vielzahl von Waffen und Hilfsmitteln: Granaten, Streubomben, Panzerfäuste, UFOs, Schrotflinten, Desert Eagles, Feuerschläge, Baseballschläger, Dynamit, Minen, Seile, Presslufthammer und Fallschirme. Die meisten Waffen verursachen Explosionen, die auch kreisförmige Stücke des Geländes heraus sprengen. Die verfügbaren Umgebungen sind eine auf einem Gewässer schwimmende Insel oder eine beschränkt zugängliche Höhle mit Wasser auf dem Boden. Ein Igel stirbt wenn er ins Wasser fällt (z.B. weil er von der Insel oder durch ein Loch in deren Boden fällt), er auf irgendeiner Seite aus dem Spielfeld fliegt oder wenn seine Gesundheit unter Null fällt, typischerweise aber durch Explosionen. (Der einem oder mehreren Igeln durch einen Spieler- oder KI-Zug zugefügte Schaden wird erst angerechnet, nachdem alle Bewegungen auf dem Schlachtfeld abgeschlossen ist).
+
+* Sensationeller, zerstörerischer, rundenbasierter Krieg für bis zu 6 Spieler
+* Lokale- und Online-Multiplayerspiele, mit zusätzlichen KI-Gegnern
+* Kämpfe auf unendlichen vielen, zufällig generierten Karten mit über 20 Umgebungen
+* Benutze 48 (und es werden laufend mehr) überwältigende Waffen! Inklusive dem Piano-Schlag und dem explosiven Roboterkuchen
+* Spiel das Spiel auf deine Weise, mit mehr als 20 verschiedenen Modifikatoren kannst du so gut wie jedes Detail anpassen
+* Passe dein Team an, mit über 120 Kostümen, 30 Gräbern, 12 Festungen, 100ten von Flaggen und einzigartigen Stimmen
+* Riesige Schlachten mit bis zu 64 Igeln
+
--- a/project_files/HedgewarsMobile/Locale/hw-desc_pl.txt	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_pl.txt	Mon Dec 05 18:38:25 2011 -0500
@@ -9,17 +9,17 @@
 Port na iOS posiada kilka unikalnych funkcji, takich jak:
 * Wtyczka iPad VGA : podłącz zewnętrzny ekran i graj w pełnej rozdzielczości;
 * Wsparcie dla Retina Display: graj całą grę w wyższej rozdzielczości;
-* Wielozoadaniowość: pauzuj grę kiedy chcesz;
+* Wielozadaniowość: pauzuj grę kiedy chcesz;
 * Wznawianie gry: zawsze możesz dokończyć swój mecz;.
 
 Opis:
 To najzabawniejsza i najbardziej uzależniająca gra w jaką kiedykolwiek grałeś - niezwykła zabawa, w którą możesz wciągnąć się zawsze i wszędzie. Hedgewars to turowa gra strategiczna, jednak najlepsze jest patrzenie, jak te małe jeże niszczą otoczenie swoim niecodziennym orężem. Nie daj się zmylić pozorom - to podstępne małe gagatki z nie do końca dobrą postawą.
 
-Inaczej mówiąc Hedgewars jestkomediową grą strategiczną, artylerii i akcji, w której do łez rozbawią cię wybryki jeżów z charakterkiem, które walczą ze sobą przy każdej okazji.
+Inaczej mówiąc Hedgewars jest komediową grą strategiczną, artylerii i akcji, w której do łez rozbawią cię wybryki jeżów z charakterkiem, które walczą ze sobą przy każdej okazji.
 
 W roli dowódcy, Twoją robotą będzie zorganizowanie ekipy jeży i sprawienie piekła przeciwnikowi.
 
-Każdy gracz kontroluje drużynę złożoną z kilku jeży. Podczas gry, uczestnicy kierują jednym jeżem na turę. Mogą wtedy używać przeróżnych narzędzi i broni, którymi rozniesie w pył jeże wroga, w ten sposób zwyciężając. Jeże przemieszczać się mogą na różnorakie sposoby, m.in. chodząc lub skacząc, ale również używając narzędzi takich jak lina, czy spadochron, aby dostać się do trudno dostępnych obszarów. Każda tura jest ograniczona czasowo, aby zapewnić brak sytuacji, w których gracz zbyt długo "zastanawia się nad ruchem". Gracze do dyspozycji mają dużą pulę broni i narzędzi: granaty, bomby kasetowe, bazooki, UFO, strzelby, pistolety Desert Eagle, kije baseball'owe, dynamity, miny, młoty pneumatyczne. Większość typów oręża powoduje eksplozje, które deformują teren zostawiając okrągłe wyrwy. Mapa jest unoszącą się na wodzie wyspą, lub ograniczoną jaskinią, z wodą na dnie. Jeż umiera, gdy znajdzie się w wodzie (na przykład przez wyrzucenie poza wyspę lub wpadnięcie do dziury), wypadnie poza mapę, lub jeśli jego poziom zdrowia wyniesie 0. Zdrowie spada po kontakcie z  (obrażenia zadane jeżom przez gracza lub CPU ukazują się gdy wszystkie ruchy są zatrzymane).
+Każdy gracz kontroluje drużynę złożoną z kilku jeży. Podczas gry, uczestnicy kierują jednym jeżem na turę. Mogą wtedy używać przeróżnych narzędzi i broni, którymi rozniesie w pył jeże wroga, w ten sposób zwyciężając. Jeże przemieszczać się mogą na różnorakie sposoby, m.in. chodząc lub skacząc, ale również używając narzędzi takich jak lina, czy spadochron, aby dostać się do trudno dostępnych obszarów. Każda tura jest ograniczona czasowo, aby zapewnić brak sytuacji, w których gracz zbyt długo "zastanawia się nad ruchem". Gracze do dyspozycji mają dużą pulę broni i narzędzi: granaty, bomby kasetowe, bazooki, UFO, strzelby, pistolety Desert Eagle, kije baseballowe, dynamity, miny, młoty pneumatyczne. Większość typów oręża powoduje eksplozje, które deformują teren zostawiając okrągłe wyrwy. Mapa jest unoszącą się na wodzie wyspą, lub ograniczoną jaskinią, z wodą na dnie. Jeż umiera, gdy znajdzie się w wodzie (na przykład przez wyrzucenie poza wyspę lub wpadnięcie do dziury), wypadnie poza mapę, lub jeśli jego poziom zdrowia wyniesie 0 (obrażenia zadane jeżom przez gracza lub CPU ukazują się gdy wszystkie ruchy są zatrzymane).
 
 * Komiczne i niszczycielskie boje podzielone na tury dla maksymalnie 6 graczy
 * Możliwa jest gra zarówno lokalna jak i sieciowa z opcjonalnymi przeciwnikami AI
Binary file project_files/HedgewarsMobile/Locale/hw-desc_tr.txt has changed
--- a/project_files/hedgewars.pro	Mon Nov 28 06:55:55 2011 +0100
+++ b/project_files/hedgewars.pro	Mon Dec 05 18:38:25 2011 -0500
@@ -95,7 +95,8 @@
     ../QTfrontend/ui_hwform.h \
 	../QTfrontend/KB.h \
     ../QTfrontend/hwconsts.h \
-    ../QTfrontend/sdlkeys.h
+    ../QTfrontend/sdlkeys.h \
+    ../QTfrontend/ui/mouseoverfilter.h
 
 SOURCES += ../QTfrontend/model/ammoSchemeModel.cpp \
     ../QTfrontend/model/themesmodel.cpp \
@@ -169,7 +170,8 @@
     ../QTfrontend/util/SDLInteraction.cpp \
     ../QTfrontend/team.cpp \
     ../QTfrontend/ui_hwform.cpp \
-    ../QTfrontend/hwconsts.cpp
+    ../QTfrontend/hwconsts.cpp \
+    ../QTfrontend/ui/mouseoverfilter.cpp
 
 win32 {
 	SOURCES += ../QTfrontend/xfire.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Locale/da.txt	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,533 @@
+; Danish locale
+
+00:00=Granat
+00:01=Klyngebombe
+00:02=Bazooka
+00:03=Målsøgende Bi
+00:04=Haglgevær
+00:05=Hakke
+00:06=Spring Over
+00:07=Reb
+00:08=Hakke
+00:09=Desert Eagle
+00:10=Dynamit
+00:11=Bat
+00:12=Shoryuken
+00:13=sek.
+00:14=Faldskærm
+00:15=Luftangreb
+00:16=Mineangreb
+00:17=Skærebrænder
+00:18=Konstruktion
+00:19=Teleportering
+00:20=Skift Pindsvin
+00:21=Granatkaster
+00:22=Pisk
+00:23=Kamikaze
+00:24=Kage
+00:25=Forførelse
+00:26=Vandmelon-bombe
+00:27=Helvedes håndgranat
+00:28=Boreraket
+00:29=Boldpistol
+00:30=Napalm
+00:31=Fjernstyret Modelfly
+00:32=Svag Tyngdekraft
+00:33=Ekstra Skade
+00:34=Udødelig
+00:35=Ekstra Tid
+00:36=Lasersigte
+00:37=Vampyr
+00:38=Sniperriffel
+00:39=Flyvende Tallerken
+00:40=Molotovcocktail
+00:41=Pipfugl
+00:42=Håndholdt Portal-Pistol
+00:43=Klaveranslag
+00:44=Gamle Ole
+00:45=Sinusgevær (beta)
+00:46=Flammekaster
+00:47=Klæbrige Miner
+00:48=Hammer
+00:49=Genopliver
+00:50=Boreangreb
+00:51=Mudderklat
+00:52=Intet våben valgt
+00:53=Tidsboks
+00:54=Struktur
+00:55=Jordspray
+
+01:00=Kæmp!
+01:01=Runde uafgjort
+01:02=%1 vinder!
+01:03=Lydstyrke %1%
+01:04=Sat på pause
+01:05=Vil du virkelig forlade spillet (Y/Esc)?
+01:06=Pludselig Død!
+01:07=%1 tilbage
+01:08=Brændstof
+01:09=Synkroniserer...
+01:10=Brug af dette værktøj afslutter ikke din tur!
+01:11=Dette våben eller værktøj er ikke tilgængeligt endnu!
+01:12=Sidste runde før Pludselig Død!
+01:13=%1 runder til Pludselig Død!
+01:14=Gør dig klar, %1!
+01:15=Spinkel
+01:16=Lav
+01:17=Normal
+01:18=Høj
+01:19=Ekstrem
+01:20=%1 Tilbagespring
+
+; Event messages
+; Hog (%1) died
+02:00=%1 har stillet træskoene!
+02:00=%1 har set lyset!
+02:00=%1 så det ikke komme!
+02:00=%1 vinker farvel!
+02:00=%1 ser den anden side af græsplænen!
+02:00=%1 møder sin skaver!
+02:00=%1 kan ikke hænge på mere!
+02:00=%1 har gjort sin pligt!
+02:00=%1 gør det ultimative offer!
+02:00=%1 smutter fra de daglige lidelser!
+02:00=%1 blev en grøntsag!
+02:00=%1 gik time-out!
+02:00=%1 fik fred!
+02:00=%1 vil blive husket!
+02:00=%1 har en aneurisme!
+02:00=%1 efterlader kone og børn
+02:00=%1 har affyret sin sidste bazooka
+02:00=%1 har kastet sin sidste grenade
+02:00=%1 har bagt sin sidste kage
+02:00=%1 har svinget sig i sit sidste reb
+02:00=%1 har indkaldt sit sidste luftangreb
+02:00=%1 har ladt sit sidste haglgevær
+02:00=%1 har kastet sin sidste melon
+02:00=%1 har trukket sin sidste Desert Eagle
+02:00=%1's bægre flød over
+02:00=%1 kunne godt have brugt en bandage
+02:00=%1 er smuttet videre til et sjovere spil
+02:00=%1 forlod rasende livet
+02:00=%1 tabte
+02:00=Stakkels, stakkels %1...
+02:00=%1 kan bedre lide Warmux
+02:00=%1 hoppede ind foran et skud
+02:00=%1 er en helt blandt mæ...ehm...pindsvin
+02:00=%1 bliver budt velkommen i Valhalla
+02:00=%1 har forladt bygningen
+02:00=%1 gik samme vej som dinosaurerne
+02:00=%1 bringer pindsvin et skidt tættere på udrydelse
+02:00=%1 bringer tårerne til mine øjne
+02:00=%1 er et ex-pindsvin
+02:00=%1 smuttede
+02:00=%1 er ikke længere
+02:00=Sig farvel til %1
+02:00=Der er intet håb for %1
+02:00=%1 forsvinder bag det sorte tæppe
+02:00=%1 ligger allerede i kisten
+02:00=%1 lider under en Komplet Spontan Eksistensfejl
+02:00=%1 er gået bort
+02:00=%1 er stendød
+02:00=%1 er ikke mere
+02:00=%1 har nået sidste salgsdato
+02:00=Berøvet sit liv,hviler %1 nu i fred
+02:00=%1 er gået ud af drift
+02:00=Farvel %1, vi lærte dig næsten ikke at kende!
+02:00=%1 havde en lav smerteterskel
+02:00=%1 kunne godt have brugt ni liv
+02:00=Er der en læge i nærheden?
+
+; Hog (%1) drowned
+02:01=%1 leger ubåd!
+02:01=%1 efterligner Titanic!
+02:01=%1 svømmer som en sten!
+02:01=%1 flyder som en mursten!
+02:01=%1 tager et kig på den dybe ende
+02:01=%1 huskede ikke svømmebæltet
+02:01=%1 synker
+02:01=%1 glemte sine badevinger
+02:01=%1 burde virkelig have husket svømmeundervisningen
+02:01=%1 glemte surfbrættet derhjemme
+02:01=%1 skyller op længere nede af strømmen
+02:01=%1 er et vådt pindsvin
+02:01=%1 glemte at medbringe sin livvest
+02:01=%1 leder efter dykkerringe
+02:01=%1 sover med fiskene
+02:01=%1 hader vandfysikken i det her spil
+02:01=%1 ser tørstig ud
+02:01=Havet lagde beslag på %1
+02:01=%1 er fortabt til søs
+02:01=%1 burde have medbragt sit dykkerudstyr
+02:01=%1 får spredt sin aske over havet
+02:01=%1 har føler sig lidt tung bag i
+02:01=%1 øver sig på sin rygcrawl
+02:01=%1 leder efter Titanic
+02:01=%1 er desværre ikke Jesus
+02:01=%1 finder Nemo
+02:01=%1 er sprunget læk
+02:01=Man kan undre sig over, hvor mange pindsvin der er på bunden
+02:01=%1 gør havet lidt mere fast
+02:01=%1 er ikke i flåden
+02:01=%1 parodierer en død fisk
+02:01=I det mindste faldt du ikke i toiletkummen, %1
+02:01=Sonic kunne ikke svømme, og det kan %1 heller ikke
+02:01=%1 leger delfin
+02:01=%1 er taget til Lalandia
+02:01=%1 har fundet den forsvundne by Atlantis
+02:01=%1 håber på en hovedrolle i Bioshock 3
+02:01=Du burde arbejde lidt med din hundesvømning, %1
+02:01=%1 burde have medbragt jetski
+02:01=%1 bryder sig ikke om vandsport
+02:01=%1 blæser bobler
+02:01=%1 mangler en tømmerflåde
+02:01=%1 har hørt saltvand er godt for huden
+02:01=%1 gnider salt i sine sår
+02:01=%1 er gået planken ud
+02:01=%1 tager et bad
+02:01=%1 er meget våd
+02:01=%1 får våde pigge
+02:01=%1 synker til bunds
+
+; Round starts
+02:02=Så skal der kæmpes!
+02:02=Vis gevær!
+02:02=Så skal der rulles!
+02:02=Så tænder vi op!
+02:02=Så starter festen
+02:02=Sidste mand stående
+02:02=Sæt i værk!
+02:02=Så skal der rockes!
+02:02=Musikken spiller!
+02:02=Det begynder...
+02:02=Det her er starten på noget stort
+02:02=Velkommen til Hedgewars
+02:02=Velkommen til frontlinjen
+02:02=Knus dine fjender!
+02:02=Må det bedste pindsvin vinde
+02:02=Vind eller dø!
+02:02=Der er præmier til vinderen
+02:02=Du kan ikke give op nu
+02:02=Gør klar til dødsskrigene! Nu kommer krigspindsvinene!
+02:02=Hedgewars, produceret af Hedgewars.org
+02:02=Held og lykke, hav det sjovt
+02:02=Du er heldig ikke at være oppe mod Tiyuri
+02:02=Du er heldig ikke at være oppe mod unC0Rr
+02:02=Du er heldig ikke at være oppe mod Nemo
+02:02=Du er heldig ikke at være oppe mod Smaxx
+02:02=Du er heldig ikke at være oppe mod Jessor
+02:02=Giv den hele armen!
+02:02=Taberne ryder op!
+02:02=Lad årtusindets kamp begynde
+02:02=Lad århundredets kamp begynde
+02:02=Lad årtiets kamp begynde
+02:02=Lad årets kamp begynde
+02:02=Lad månedens kamp begynde
+02:02=Lad ugens kamp begynde
+02:02=Lad dagens kamp begynde
+02:02=Lad timens kamp begynde
+02:02=Gør dit bedste!
+02:02=Ødelæg fjenden!
+02:02=Held og lykke
+02:02=Hav det sjovt
+02:02=Kæmp en god kamp
+02:02=Brug feje tricks
+02:02=Kæmp med ære
+02:02=Giv ikke op
+02:02=Overgiv dig aldrig
+02:02=Giv den gas!
+02:02=Lad drabsfesten begynde!
+02:02=Jeg håber du er klar til et slagsmål!
+02:02=Så skal der krudt i røven!
+02:02=Pindsvin taget til næste niveau!
+02:02=Bring kampen til dem!
+02:02=Frygt intet!
+02:02=Vær modig og tapper
+
+; Round ends (win; unused atm)
+02:03=...
+
+; Round ends (draw; unused atm)
+02:04=...
+
+; New health crate
+02:05=Så er der hjælp at hente!
+02:05=Læge!
+02:05=Himmelsk førstehjælp!
+02:05=Wellness til dig
+02:05=Godt helbred... i en kasse!
+02:05=Doktoren ringe
+02:05=Friske bandager!
+02:05=Det her skal nok få dig til at føle dig godt tilpas
+02:05=Så er der trylledrik! Ups, forkert spil
+02:05=Saml mig op!
+02:05=Tag den
+02:05=Et sundt mellemmåltid
+02:05=Smertestillende
+02:05=Korrekt dosering: alt hvad du kan finde!
+02:05=Hastelevering
+02:05=Forsyninger!
+
+; New ammo crate
+02:06=Flere våben!
+02:06=Forstærkninger!
+02:06=Tid til at skifte magasin!
+02:06=Gæt hvilket våben der er indeni?
+02:06=Forsyninger!
+02:06=Hvad mon der er i pakken?
+02:06=Julen starter tidligt i år
+02:06=En lille gave!
+02:06=Hastelevering!
+02:06=Det var et mareridt at få den her gennem tolden
+02:06=Destruktivt legetøj fra himlen
+02:06=Advarsel! Sprængfarligt indhold
+02:06=Nap eller spring, frit valg
+02:06=Godter!
+02:06=Mmmmm! Ammunition
+02:06=En lille pakke med koncentreret destruktion
+02:06=Luftpost!
+02:06=Der er ikke pizza i den der pakke
+02:06=Nap den!
+02:06=Så er der våben
+02:06=Lad ikke modstanderen få fat i den dér!
+02:06=Nyt legetøj!
+02:06=En gådefuld pakke!
+
+; New utility crate
+02:07=Værktøjstid!
+02:07=Den her kan måske være nyttig...
+02:07=Nyttige værktøjer!
+02:07=Benyt dig af den her
+02:07=Pås på ryggen
+02:07=Flere værktøjer!
+02:07=Værktøjer til dig!
+02:07=Det her burde klare ærterne!
+02:07=Brug den med omtanke
+02:07=Åh, den her er tung
+02:07=Måske får du brug for den her
+
+; Hog (%1) skips his turn
+02:08=%1 er sååå kedelig...
+02:08=%1 gad ikke lige
+02:08=%1 er et dovent pindsvin
+02:08=%1 er tankeløs
+02:08=%1 gav op
+02:08=%1 prøver at sove de andre ihjel
+02:08=%1 springer skamløst sin tur over
+02:08=%1 er meget doven
+02:08=%1 har brug for lidt motivation
+02:08=%1 er pacifist
+02:08=%1 tager sig et pusterum
+02:08=%1 får sig et hvil
+02:08=%1 tager sig en slapper
+02:08=%1 tror ikke på sig selv
+02:08=%1 beslutter sig for slet ikke at gøre noget
+02:08=%1 håber på at modstanderne begår selvmord
+02:08=%1 må være frygtelig at have med til fester
+02:08=%1 gemmer sig under sengen
+02:08=%1 greb ikke chancen
+02:08=%1 besluttede sig for at det bedste han kunne gøre var... ingenting
+02:08=%1 er en pivskid
+02:08=Kluk, kluk, kluk, %1 er en kylling
+02:08=%1 ser lidt uerfaren ud
+02:08=%1 er en bangebuks!
+02:08=%1 venter på Pludselig Død
+02:08=%1 er ikke rigtig den type der slås
+02:08=%1 genovervejer meningen med livet
+02:08=%1 sigter godt, men skyder sjældent
+02:08=%1 ville egentlig ikke i hæren i første omgang
+02:08=Hold op med at spilde vores tid, %1
+02:08=Jeg er skuffet over dig, %1
+02:08=Kom nu, det kan du godt klare bedre, %1
+02:08=%1 er lidt af en kujon
+02:08=%1 har åbenbart andet at lave
+02:08=%1 er stiv af skræk
+02:08=%1 er vist faldet i søvn
+
+; Hog (%1) hurts himself only
+02:09=%1 burde øve sig i at sigte!
+02:09=%1 hader vist sig selv
+02:09=%1 står på den forkerte side!
+02:09=%1 er en sortseer
+02:09=%1 pegede løbet den forkerte vej
+02:09=%1 er en lille sadist
+02:09=%1 er en masochist
+02:09=%1 har ikke nogen selvopholdelsesdrift
+02:09=%1 lavede kludder i den
+02:09=%1 kludrede i den
+02:09=Det var et sølle skud, %1
+02:09=%1 er lidt for uforsvarlige med farlige våben
+02:09=%1 både overveje et karriereskift
+02:09=Værste. Skud. Nogensinde!
+02:09=Nej, nej, nej, %1, du skal skyde på FJENDEN!
+02:09=%1 burde kun sigte efter fjenden
+02:09=%1 bevæger sig et skridt tættere på selvmord
+02:09=%1 hjælper fjenden
+02:09=Det var dumt, %1
+02:09=%1 lever efter mantraet "det skal gøre ondt, før det gør godt"
+02:09=%1 er forvirret
+02:09=%1 sårede sig selv i sin forvirrelse
+02:09=%1 har en særlig evne til at gøre sig selv til grin
+02:09=%1 er en klodsmajor!
+02:09=%1 er klodset
+02:09=%1 viser fjenden hvad han er i stand til
+02:09=Man kan ikke forvente at %1 er perfekt hver gang
+02:09=Bare rolig %1, ingen re perfekte
+02:09=%1 gjorde det med vilje, helt sikkert
+02:09=Jeg skal nok holde munden lukket hvis du også gør, %1
+02:09=Hvor pinligt!
+02:09=Det er jeg helt sikker på at ingen så, %1
+02:09=%1 burde nokke kigge på sin feltmanual igen
+02:09=%1's våben er vist i stykker
+
+; Hog shot an home run (using the bat and another hog)
+02:10=Han kørte den lige hjem!
+02:10=Er det en fugl? Er det et fly? ...
+02:10=Den der er ude!
+
+; Hog (%1) has to leave (team is gone)
+02:11=%1 skal i seng nu!
+02:11=%1 har vist for travlt til spil
+02:11=Mor er klar med aftensmaden!
+02:11=%1 bliver nød til at gå
+
+; Weapon Categories
+03:00=Tidsindstillet Granat
+03:01=Tidsindstillet Granat
+03:02=Balistisk Våben
+03:03=Fjernstyret Våben
+03:04=Skydevåben (flere skud)
+03:05=Graveværktøj
+03:06=Handling
+03:07=Køretøj
+03:08=Bevægelsesaktiveret Bombe
+03:09=Skydevåben (flere skud)
+03:10=BUM!
+03:11=Bonk!
+03:12=Kampsport
+03:13=UBRUGT
+03:14=Køretøj
+03:15=Luftangreb
+03:16=Luftangreb
+03:17=Graveværktøj
+03:18=Værktøj
+03:19=Køretøj
+03:20=Handling
+03:21=Balistisk Våben
+03:22=Kald mig Indiana!
+03:23=(Seriøs) Kampsport
+03:24=Kagen findes!
+03:25=Sminkedåse
+03:26=Saftig Granat
+03:27=Hidsig Granat
+03:28=Balistisk Våben
+03:29=Balistisk Våben
+03:30=Luftangreb
+03:31=Fjernbetjent Bombe
+03:32=Midlertidig Effekt
+03:33=Midlertidig Effekt
+03:34=Midlertidig Effekt
+03:35=Midlertidig Effekt
+03:36=Midlertidig Effekt
+03:37=Midlertidig Effekt
+03:38=Skydevåben (flere skud)
+03:39=Køretøj
+03:40=Brændspåsættende Granat
+03:41=Stor fan af Squawks
+03:42=Jeg lægger lige en besked...
+; the misspelled "Beethoven" is intentional (-> to beat)
+03:43=Spil en himmelsk solo
+03:44=Mindst holdbar til: 1923
+03:45=Videnskab, det virker!
+03:46=Varm, varm, varm
+03:47=Sæt dem nu et brugbart sted, ikke?
+03:48=Sløjdtimerne vender tilbage
+03:49=Gør lige præcis hvad du forventer
+03:50=Ring til en muldvarp
+03:51=Lige til at samle op
+03:52=UBRUGT
+03:53=Årgang 40
+03:54=Byg noget
+03:55=Værktøj
+
+; Weapon Descriptions (use |as line breaks)
+04:00=Angrib dine fjender med en simpel granat.|Den eksploderer når uret når nul.|1-5: Indstil uret|Angrib: Hold knappen inde for at kaste hårdere
+04:01=Angrib dine fjender med en klyngebombe.|Den splitter sig op i flere bomber når uret|når nul.|1-5: Indstil uret|Angrib: Hold knappen inde for at kaste hårdere
+04:02=Angrib dine fjender med et balistisk projektil|som godt kan rammes af vindstød.|Angrib: Hold knappen inde for at skyde længere
+04:03=Affyr en eksplosiv bi som forsøger at ramme det|valgte mål. Mere præcis hvis du ikke sætter fuld|knald på.|Musemarkør: Vælg mål|Angrib: Hold knappen inde for at give mere fart på
+04:04=Angrib dine fjender med et haglgevær med to skud.|Takket være spredningen behøver du ikke ramme|helt præcist for at gøre skade.|Angrib: Skyd (flere gange)
+04:05=Gå under jorden! Brug hakken til at grave|dig et hul og nå nye højder, ehm...|Angrib: Start eller stop med at grave
+04:06=Keder du dig? Mangler våben? Vil spare på ammunitionen?|Intet problem! bare spring din tur over, kryster!|Angrib: Spring din tur over uden at angribe
+04:07=Overvind store kløfter på kort tid med rebet.|Ram ind i og skub andre pindsvin af vejen|eller lad det regne med granater.|Angrib: Affyr eller slip rebet|Langt Hop: Slip granater eller lignende våben
+04:08=Hold dine fjender på afstand med en mine for foden|af dem eller i tunnelen mellem dem og dig. Husk|at trække dig lidt tilbage før du trykker på aftrækkeren!|Angrib: Læg en mine lige foran dig
+04:09=Ikke så sikker på dine sigteevner? Med Desert Eagle-|pistolen kan du skyde op til fire gange.|Angrib: Skyd (flere gange)
+04:10=Vold er altid en mulighed. Læg en stang dynamit, træd|et skridt tilbage og fjenderne er solgt til stanglakrids.|Angrib: Læg en stang dynamit lige foran dig
+04:11=Et bat der batter. Slå fjenderne ud (af banen)|eller i vandet. Du kan også sende en mine afsted|med luftpost.|Angrib: Slå på alt hvad der står foran dig
+04:12=Gå helt tæt på og slip din indre energi løs med denne|(næsten) dødbringende kampsportsteknik.|Angrib: Udfør en fantastisk Shoryuken.
+04:13=UBRUGT
+04:14=Bange for højder? Nap hellere en faldskærm.|Den folder sig ud hvis du falder for langt|og sikrer dit pindsvin mod at slå sig.|Angrib: Fold paraplyen ud|Langt Hop: Slip granater eller lignende våben
+04:15=Send et fly ind for at angribe dine fjender|med en stribe af bomber.|Venstre/Højre: Vælg angrebsretning|Musemarkør: Vælg målzonen
+04:16=Send et fly ind for at kaste adskillige|miner ned over dine fjender.|Venstre/Højre: Vælg angrebsretning|Musemarkør: Vælg målzonen
+04:17=Brug for ly? Brug skærebrænderen til hurtigt|at grave en tunnel du kan gemme dig i.|Angrib: Start eller stop med at grave
+04:18=Brug for beskyttelse eller for et lille lift?|Placer nogle bærebjælker lige som du ønsker.|Venstre/Højre: Vælg bærebjælke du vil placere|Musemarkør: Placer bærebjælken hvis der er plads til den
+04:19=Hvis den bliver brugt på det rigtige tidpunkt kan teleportation|redde pindsvin fra farlige situationer og efterlade forvirrede fjender.|Musemarkør: Vælg hvor du vil teleportere hen
+04:20=Giver dig mulighed for at bruge et|andet pindsvin denne tur.|Angrib: Muliggør skift af aktivt pindsvin
+04:21=Affyr et granat-agtigt projektil som deler|sig op i mange mindre bomber ved kollision.|Angrib: Affyr med fuld kraft
+04:22=Set på film! Nu kan du være Indiana Jones for en dag!|Pisken er brugbar i mange situationer.|Specielt hvis du lige får lyst til at kaste nogen ud fra et bjerg.|Angrib: Pisk alt hvad der står foran dig
+04:23=Har du alligevel ikke noget at tabe, kan du ofre|er pindsvin og skyde det afsted i en valgfri retning.|Skader alt hvad pindsvinet rammer og slutter af med et stort brag.|Angrib: Affyr dette altødelæggende og dødbringende angreb
+04:24=Tillykke med fødselsdagen! Bare pust lysene ud, og send|kagen hen i den anden ende af bordet|Så får dine "venner" en eksplosiv fest.|Kagen passerer selv svært terræn, men pas på!|Måske springer den lidt tidligere på den måde.|Angrib: Start kagen eller få den til at stoppe og eksplodere
+04:25=Åben sminkedåsen og husk ikke at spare på pudderet.|De andre pindsvin bliver så imponerede, at de|ikke kan undlade at løbe efter dig|(og lige ned i en sprække eller et hul efter behag).|Angrib: Brug sminkedåsen and prøv at forføre et andet pindsvin
+04:26=Kast denne saftige vandmelon efter dine fjender.|Så snart uret ramme nul, splitter den op i|flere eksplosive stykker.|1-5: Indstil uret|Angrib: Hold knappen inde for at kaste hårdere
+04:27=Lad helvedes ild regne ned over dine fjender|med dette dæmoniske sprængstof. Men kom ikke for tæt på,|for der kan godt være mindre flammer efter eksplosionen.|Angrib: Hold knappen inde for at kaste hårdere
+04:28=Kort tid efter du affyrer raketten vil den grave sig|gennem forhindringer og eksplodere så snart dens|lunte bliver antændt eller den rammer jordoverfladen|igen.|Angrib: Hold knappen inde for at affyre med mere kraft
+04:29=Ikke egnet for småbørn! Boldpistolen affyrer |(ulig dens fætter, boltpistolen) masser af små farvede kugler fyldt med sprængstof.|Angrib: Affyr med fuld kraft|Op/Ned: Fortsæt med at sigte
+04:30=Send et fly ind for at kaste napalm ned over|dine fjender. Hvis den rammer kan den destruere|store områder samt et hvilket som helst|uheldigt pindsvin der befinder sig i nærheden.|Venstre/Højre: Vælg angrebsretning|Cursor: Vælg målzone
+04:31=Det Fjernstyrede Fly er det perfekte våben til at samle|kasser op eller angribe pindsvin der er for langt væk.|Du kan enten styre den direkte mod fjenderne|eller kaste nogle bomber først.|Angrib: Send flyet afsted og kast bomber|Langt Hop: Giv en valkyrie et lift til kampens centrum|Venstre/Højre: Styr flyet
+04:32=Svag Tyngdekraft er bedre end nogen slankekur!|Hop højere, svæv længere og send endnu flere|fjender flyvende.|Angrib: Aktiver
+04:33=Nogle gange har du bare brug for lidt mere|skade for virkelig at komme igennem.|Angrib: Aktiver
+04:34=Kom bare an!|Angrib: Aktiver
+04:35=Nogen gange går tiden dræbende langsomt.|Andre gange alt for hurtigt.|Nap et par sekunder ekstra til at angribe i.|Angrib: Aktiver
+04:36=Sigter godt, men rammer skidt? Få lidt moderne assistance.|Angrib: Aktiver
+04:37=Du behøver ikke være bange for sollyset. Det holder kun én tur,|men gør det muligt at suge liv ud af de pindsvin|du giver skade til.|Angrib: Aktiver
+04:38=Sniperriflen kan være det mest dødbringende våben i hele|dit arsenal, men virker dårligt på klods hold.|Giver mere skade jo længere der er til målet.|Angrib: Skyd (to gange)
+04:39=Flyv rundt i den Flyvende Talerken.|Den er svær at styre, men giver stor frihed og|mulighed for at bevæge sig på hele banen.|Angrib: Aktiver|Op/Venstre/Højre: Accellerer i en retning|Langt Hop: Slip granater eller lignende våben
+04:40=Tænd op for et flammehav med den (snart)|brændende væske i flasken.|Angrib: Hold inde for at kaste længere
+04:41=Måske slår naturen den Flyvende Talerken. |Pipfuglen kan bære dit pindsvin omkring|og kaste æg ned på dine fjender!|Angrib: Aktiver og kast æg|Op/Venstre/Højre: Flap vingerne i en retning
+04:42=Den Håndholdte Portal-Pistol er i stand til|øjeblikkeligt at transportere dig, dine fjender,|eller dine våben mellem to punkter på banen.|Brug den med omtanke og du vil få...|STOR SUCCES!|Angrib: Affyr en portal|Skift: Skifter mellem portalfarver
+04:43=Få en eksplosiv musikalsk debut!|Smid et klaver ned fra himlen, men husk...|en eller anden skal jo spille på det|og det kommer måske til at koste dig livet!|Musemarkør: Vælg målzone|F1-F9: Spil klaver
+04:44=Det er ikke bare en ost, det er biologisk krigsførsel!|Den giver ikke meget skade når uret rammer nul|men stanken skal nok forgifte alle i nærheden!|1-5: Indstil uret|Angrib: Hold knappen inde for at kaste længere
+04:45=Endelig betaler de endeløse fysiktimer sig.|Afspil en ødelæggende sinusbølge mod dine|modstandere. Men pas på, der er knald på!|(Dette våben er ikke færdigt)|Angrib: Skyd
+04:46=Dæk dine fjender i flydende flammer.|Hjertevarmende, ikke?|Angrib: Aktiver|Up/Down: Fortsæt med at sigte|Venstre/Højre: Ændr på affyringshastigheden
+04:47=Dobbel så meget sjov med to luskede, klæbrige miner.|Sæt en kædereaktion i gang eller forsvar dig|selv (eller begge dele!)|Angrib: Hold knappen inde for at skyde længere (to gange)
+04:48=Hvorfor er det kun muldvarpe vi mishandler?|Det er mindst lige så sjovt at slå til pindsvin!|Et ordentligt slag fra hammeren napper en tredjedel af et|pindsvins liv og slynger det samtidig ned i jorden.|Angrib: Aktiver
+04:49=Genopliv dine venner, men pas på!|Kan også ramme dine fjender|Angrib: Hold knappen inde for langsomt at genoplive|Op: Accelerer genoplivningen
+04:50=Er dine fjender gået under jorden?|Grav dig ind til dem med et Boreangreb!|Uret bestemmer hvor langt du når.
+04:51=Få et skud lige ind med en Mudderklat.|Bider en smule og slår fjender omkuld.
+04:52=UBRUGT
+04:53=Tag på et eventyr gennem tid og rum,|mens du efterlader kampen til dine kammerater.|Vær klar til at vende tilbage når som helst,|eller hvis Pludselig Død indtræder|eller alle dine andre pindsvin dør.|Advarsel! Virker ikke under Pludselig Død,|hvis du er alene eller er Konge.
+04:54=UFÆRDIG                                                                                                                                    
+04:55=Sprøjt rundt med klistrende flammer.|Byg broer, begrav fjender, luk tunneler af.|Pas på ikke selv at få noget på dig.
+
+; Game goal strings
+05:00=Spilsystemer
+05:01=De følgende regler gælder
+05:02=Forter: Forsvar din fæstning; knus dine modstandere!
+05:03=Svag Tyngdekraft: Gå forsigtigt
+05:04=Udødelighed: Pindsvin er (næsten) udødelige
+05:05=Vampyr: Pindsvin bliver helbredt når de giver skade
+05:06=Karma: Pindsvin tager skade når de giver skade
+05:07=Forsvar Kongen: Undgå at gå skakmat!|Placer din Konge: Vælg et beskyttet sted din konge kan starte
+05:08=Placer Pindsvin: Placer dine pindsvin før spillet starter
+05:09=Artilleri: Pindsvin kan ikke gå for at flytte sig rundt
+05:10=Uforgængeligt Terræn: De fleste våben kan ikke ændre på banen
+05:11=Delt Ammunition: Alle hold af samme farve deler ammunition
+05:12=Mineur: Miner detonerer efter %1 sekund(er)
+05:13=Mineur: Miner detonerer med det samme
+05:14=Mineur: Miner detonerer efter 0 - 5 sekunder
+05:15=Skademodifikator: Alle våben giver %1% skade
+05:16=Alle pindsvin bliver helbredt fuldt ud i slutningen af turen
+05:17=AI-pindsvin genopliver når de dør
+05:18=Uendelige Angreb
+05:19=Våben nulstilles i slutningen af turen
+05:20=Våben deles ikke mellem pindsvin
+05:21=Tagteam: Hold i en klan tager tur efter hinanden|Delt Tid: Hold i en klan deler tiden til hver tur
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Locale/hedgewars_da.ts	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,2704 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="da">
+<context>
+    <name>AmmoSchemeModel</name>
+    <message>
+        <source>new</source>
+        <translation>ny</translation>
+    </message>
+    <message>
+        <source>copy of</source>
+        <translation>kopi af</translation>
+    </message>
+</context>
+<context>
+    <name>DrawMapWidget</name>
+    <message>
+        <source>File error</source>
+        <translation>Fejl i fil</translation>
+    </message>
+    <message>
+        <source>Cannot open file &apos;%1&apos; for writing</source>
+        <translation>Kan ikke åbne filen &apos;%1&apos; til skrivning</translation>
+    </message>
+    <message>
+        <source>Cannot read file &apos;%1&apos;</source>
+        <translation>Kan ikke læse filen &apos;%1&apos;</translation>
+    </message>
+</context>
+<context>
+    <name>FreqSpinBox</name>
+    <message>
+        <source>Never</source>
+        <translation>Aldrig</translation>
+    </message>
+    <message numerus="yes">
+        <source>Every %1 turn</source>
+        <translation>
+            <numerusform>Hver %1 tur</numerusform>
+            <numerusform>Hver %1 tur</numerusform>
+        </translation>
+    </message>
+</context>
+<context>
+    <name>GameCFGWidget</name>
+    <message>
+        <source>Edit weapons</source>
+        <translation>Rediger våben</translation>
+    </message>
+    <message>
+        <source>Error</source>
+        <translation>Fejl</translation>
+    </message>
+    <message>
+        <source>Illegal ammo scheme</source>
+        <translation>Ugyldig ammunitionssystem</translation>
+    </message>
+    <message>
+        <source>Edit schemes</source>
+        <translation>Rediger spilsystemer</translation>
+    </message>
+    <message>
+        <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
+        <translation>Når denne indstilling er aktiveret vælges automatisk et våben når et spilsystem vælges</translation>
+    </message>
+    <message>
+        <source>Game Options</source>
+        <translation>Spilindstillinger</translation>
+    </message>
+</context>
+<context>
+    <name>HWChatWidget</name>
+    <message>
+        <source>%1 *** %2 has been removed from your ignore list</source>
+        <translation>%1 *** %2 er blevet fjernet fra din ignoreringsliste</translation>
+    </message>
+    <message>
+        <source>%1 *** %2 has been added to your ignore list</source>
+        <translation>%1 *** %2 er blevet tilføjet til din ignoreringsliste</translation>
+    </message>
+    <message>
+        <source>%1 *** %2 has been removed from your friends list</source>
+        <translation>%1 *** %2 er blevet fjernet fra din venneliste</translation>
+    </message>
+    <message>
+        <source>%1 *** %2 has been added to your friends list</source>
+        <translation>%1 *** %2 er blevet tilføjet til din venneliste</translation>
+    </message>
+    <message>
+        <source>%1 has been removed from your ignore list</source>
+        <translation>%1 er blevet fjernet fra din ignoreringsliste</translation>
+    </message>
+    <message>
+        <source>%1 has been added to your ignore list</source>
+        <translation>%1 er blevet tilføjet til din ignoreringsliste</translation>
+    </message>
+    <message>
+        <source>%1 has been removed from your friends list</source>
+        <translation>%1 er blevet fjernet fra din venneliste</translation>
+    </message>
+    <message>
+        <source>%1 has been added to your friends list</source>
+        <translation>%1 er blevet tilføjet til din venneliste</translation>
+    </message>
+    <message>
+        <source>Stylesheet imported from %1</source>
+        <translation>Typografiark importeret fra %1</translation>
+    </message>
+    <message>
+        <source>Enter %1 if you want to use the current StyleSheet in future, enter %2 to reset!</source>
+        <translation>Tryk %1 hvis du vil bruge det nuværende typografiark i fremtiden, tryk %2 for at nulstille!</translation>
+    </message>
+    <message>
+        <source>Couldn&apos;t read %1</source>
+        <translation>Kunne ikke læse %1</translation>
+    </message>
+    <message>
+        <source>StyleSheet discarded</source>
+        <translation>Typografiark kasseret</translation>
+    </message>
+    <message>
+        <source>StyleSheet saved to %1</source>
+        <translation>Typografiark gemt til %1</translation>
+    </message>
+    <message>
+        <source>Failed to save StyleSheet to %1</source>
+        <translation>Mislykkedes at gemme typografiark til %1</translation>
+    </message>
+    <message>
+        <source>%1 is not a valid command!</source>
+        <translation>%1 er ikke en gyldig kommando!</translation>
+    </message>
+    <message>
+        <source>Kicking %1 ...</source>
+        <translation>Smider %1 ud...</translation>
+    </message>
+</context>
+<context>
+    <name>HWForm</name>
+    <message>
+        <source>new</source>
+        <translation>ny</translation>
+    </message>
+    <message>
+        <source>Error</source>
+        <translation>Fejl</translation>
+    </message>
+    <message>
+        <source>OK</source>
+        <translation>OK</translation>
+    </message>
+    <message>
+        <source>Unable to start the server</source>
+        <translation>Ude af stand til at starte serveren</translation>
+    </message>
+    <message>
+        <source>Cannot save record to file %1</source>
+        <translation>Kan ikke gemme optagelse til fil %1</translation>
+    </message>
+    <message>
+        <source>Please select record from the list above</source>
+        <translation>Vælg venligst en optagelse fra den ovenstående liste</translation>
+    </message>
+    <message>
+        <source>DefaultTeam</source>
+        <translation>StandardHold</translation>
+    </message>
+    <message>
+        <source>Hedgewars Demo File</source>
+        <comment>File Types</comment>
+        <translation>Hedgewars Demofil</translation>
+    </message>
+    <message>
+        <source>Hedgewars Save File</source>
+        <comment>File Types</comment>
+        <translation>Hedgewars Spilfil</translation>
+    </message>
+    <message>
+        <source>Demo name</source>
+        <translation>Demonavn</translation>
+    </message>
+    <message>
+        <source>Demo name:</source>
+        <translation>Demonavn:</translation>
+    </message>
+    <message>
+        <source>Game aborted</source>
+        <translation>Spil afbrudt</translation>
+    </message>
+    <message>
+        <source>Password</source>
+        <translation>Kodeord</translation>
+    </message>
+    <message>
+        <source>Your nickname %1 is
+registered on Hedgewars.org
+Please provide your password below
+or pick another nickname in game config:</source>
+        <translation>Dit brugernavn %1 er
+registreret på Hedgewars.org
+Indtast venligst dit kodeord nedenfor
+eller vælg et andet brugernavn under spilkonfigurationen:</translation>
+    </message>
+    <message>
+        <source>No password supplied.</source>
+        <translation>Intet kodeord indtastet.</translation>
+    </message>
+    <message>
+        <source>Nickname</source>
+        <translation>Brugernavn</translation>
+    </message>
+    <message>
+        <source>Some one already uses
+ your nickname %1
+on the server.
+Please pick another nickname:</source>
+        <translation>En eller anden bruger allerede
+dit brugernavn %1
+på serveren.
+Vælg venligst et andet brugernavn:</translation>
+    </message>
+    <message>
+        <source>No nickname supplied.</source>
+        <translation>Intet brugernavn indtastet.</translation>
+    </message>
+</context>
+<context>
+    <name>HWGame</name>
+    <message>
+        <source>en.txt</source>
+        <translation>en.txt</translation>
+    </message>
+    <message>
+        <source>Cannot open demofile %1</source>
+        <translation>Kan ikke åbne demofil %1</translation>
+    </message>
+</context>
+<context>
+    <name>HWMapContainer</name>
+    <message>
+        <source>Map</source>
+        <translation>Bane</translation>
+    </message>
+    <message>
+        <source>Themes</source>
+        <translation>Temaer</translation>
+    </message>
+    <message>
+        <source>Filter</source>
+        <translation>Filter</translation>
+    </message>
+    <message>
+        <source>All</source>
+        <translation>Alle</translation>
+    </message>
+    <message>
+        <source>Small</source>
+        <translation>Lille</translation>
+    </message>
+    <message>
+        <source>Medium</source>
+        <translation>Medium</translation>
+    </message>
+    <message>
+        <source>Large</source>
+        <translation>Stor</translation>
+    </message>
+    <message>
+        <source>Cavern</source>
+        <translation>Grotte</translation>
+    </message>
+    <message>
+        <source>Wacky</source>
+        <translation>Skør</translation>
+    </message>
+    <message>
+        <source>Type</source>
+        <translation>Type</translation>
+    </message>
+    <message>
+        <source>Small tunnels</source>
+        <translation>Små tunneler</translation>
+    </message>
+    <message>
+        <source>Medium tunnels</source>
+        <translation>Mellemstore tunneler</translation>
+    </message>
+    <message>
+        <source>Large tunnels</source>
+        <translation>Store tunneler</translation>
+    </message>
+    <message>
+        <source>Small floating islands</source>
+        <translation>Små svævende øer</translation>
+    </message>
+    <message>
+        <source>Medium floating islands</source>
+        <translation>Mellemstore svævende øer</translation>
+    </message>
+    <message>
+        <source>Large floating islands</source>
+        <translation>Store svævende øer</translation>
+    </message>
+    <message>
+        <source>Seed</source>
+        <translation>Spire</translation>
+    </message>
+    <message>
+        <source>Set</source>
+        <translation>Indstil</translation>
+    </message>
+</context>
+<context>
+    <name>HWNetServersModel</name>
+    <message>
+        <source>Title</source>
+        <translation>Titel</translation>
+    </message>
+    <message>
+        <source>IP</source>
+        <translation>Ip</translation>
+    </message>
+    <message>
+        <source>Port</source>
+        <translation>Port</translation>
+    </message>
+</context>
+<context>
+    <name>HWNewNet</name>
+    <message>
+        <source>The host was not found. Please check the host name and port settings.</source>
+        <translation>Værtsmaskinen blev ikke fundet. Tjek venligst værtsnavnet og portindstillingerne.</translation>
+    </message>
+    <message>
+        <source>Connection refused</source>
+        <translation>Forbindelse afvist</translation>
+    </message>
+    <message>
+        <source>Room destroyed</source>
+        <translation>Rum fjernet</translation>
+    </message>
+    <message>
+        <source>Quit reason: </source>
+        <translation>Forlod fordi: </translation>
+    </message>
+    <message>
+        <source>You got kicked</source>
+        <translation>Du blev smidt ud</translation>
+    </message>
+    <message>
+        <source>Password</source>
+        <translation>Kodeord</translation>
+    </message>
+    <message>
+        <source>Your nickname %1 is
+registered on Hedgewars.org
+Please provide your password
+or pick another nickname:</source>
+        <translation type="obsolete">Your nickname %1 is
+registered on Hedgewars.org
+Please provide your password
+or pick another nickname:</translation>
+    </message>
+    <message>
+        <source>%1 *** %2 has joined the room</source>
+        <translation>%1 *** %2 har tilsluttet sig til rummet</translation>
+    </message>
+    <message>
+        <source>%1 *** %2 has joined</source>
+        <translation>%1 *** %2 har tilsluttet sig</translation>
+    </message>
+    <message>
+        <source>%1 *** %2 has left (%3)</source>
+        <translation>%1 *** %2 har forladt (%3)</translation>
+    </message>
+    <message>
+        <source>%1 *** %2 has left</source>
+        <translation>%1 *** %2 har forladt</translation>
+    </message>
+    <message>
+        <source>Your nickname %1 is
+registered on Hedgewars.org
+Please provide your password below
+or pick another nickname in game config:</source>
+        <translation type="obsolete">Your nickname %1 is
+registered on Hedgewars.org
+Please provide your password below
+or pick another nickname in game config:</translation>
+    </message>
+    <message>
+        <source>Nickname</source>
+        <translation>Brugernavn</translation>
+    </message>
+    <message>
+        <source>User quit</source>
+        <translation>En bruger forlod</translation>
+    </message>
+</context>
+<context>
+    <name>KB</name>
+    <message>
+        <source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It&apos;s recommended to update your freetype lib.</source>
+        <translation>SDL_ttf returnerede en fejl under tekstrendering, højst sandsynligt er den relateret til en fejl i freetype2. Det anbefales at opdatere dit freetype bibliotek.</translation>
+    </message>
+</context>
+<context>
+    <name>PageAdmin</name>
+    <message>
+        <source>Server message:</source>
+        <translation>Serverbesked:</translation>
+    </message>
+    <message>
+        <source>Set message</source>
+        <translation>Indstil besked</translation>
+    </message>
+    <message>
+        <source>Clear Accounts Cache</source>
+        <translation>Ryd Bruger-cache</translation>
+    </message>
+    <message>
+        <source>Fetch data</source>
+        <translation>Hent data</translation>
+    </message>
+    <message>
+        <source>Server message for latest version:</source>
+        <translation>Serverbesked for nyeste version:</translation>
+    </message>
+    <message>
+        <source>Server message for previous versions:</source>
+        <translation>Serverbesked for tidligere versioner:</translation>
+    </message>
+    <message>
+        <source>Latest version protocol number:</source>
+        <translation>Nyeste versions protokolnummer:</translation>
+    </message>
+    <message>
+        <source>MOTD preview:</source>
+        <translation>Forhåndsvisning af dagens besked:</translation>
+    </message>
+    <message>
+        <source>Set data</source>
+        <translation>Indstil data</translation>
+    </message>
+</context>
+<context>
+    <name>PageConnecting</name>
+    <message>
+        <source>Connecting...</source>
+        <translation>Opretter forbindelse...</translation>
+    </message>
+    <message>
+        <source>Cancel</source>
+        <translation>Annuler</translation>
+    </message>
+</context>
+<context>
+    <name>PageDrawMap</name>
+    <message>
+        <source>Undo</source>
+        <translation>Fortryd</translation>
+    </message>
+    <message>
+        <source>Clear</source>
+        <translation>Ryd</translation>
+    </message>
+    <message>
+        <source>Load</source>
+        <translation>Indlæs</translation>
+    </message>
+    <message>
+        <source>Save</source>
+        <translation>Gem</translation>
+    </message>
+    <message>
+        <source>Load drawn map</source>
+        <translation>Indlæs tegnet bane</translation>
+    </message>
+    <message>
+        <source>Save drawn map</source>
+        <translation>Gem tegnet bane</translation>
+    </message>
+    <message>
+        <source>Drawn Maps</source>
+        <translation>Tegnede Baner</translation>
+    </message>
+    <message>
+        <source>All files</source>
+        <translation>Alle filer</translation>
+    </message>
+</context>
+<context>
+    <name>PageEditTeam</name>
+    <message>
+        <source>General</source>
+        <translation>Generelt</translation>
+    </message>
+    <message>
+        <source>Advanced</source>
+        <translation>Advanceret</translation>
+    </message>
+</context>
+<context>
+    <name>PageGameStats</name>
+    <message>
+        <source>&lt;p&gt;The best shot award was won by &lt;b&gt;%1&lt;/b&gt; with &lt;b&gt;%2&lt;/b&gt; pts.&lt;/p&gt;</source>
+        <translation>&lt;p&gt;Prisen for det bedste skud gik til &lt;b&gt;%1&lt;/b&gt; med &lt;b&gt;%2&lt;/b&gt; point.&lt;/p&gt;</translation>
+    </message>
+    <message numerus="yes">
+        <source>&lt;p&gt;The best killer is &lt;b&gt;%1&lt;/b&gt; with &lt;b&gt;%2&lt;/b&gt; kills in a turn.&lt;/p&gt;</source>
+        <translation type="obsolete">
+            <numerusform>&lt;p&gt;The best killer is &lt;b&gt;%1&lt;/b&gt; with &lt;b&gt;%2&lt;/b&gt; kill in a turn.&lt;/p&gt;</numerusform>
+            <numerusform>&lt;p&gt;The best killer is &lt;b&gt;%1&lt;/b&gt; with &lt;b&gt;%2&lt;/b&gt; kills in a turn.&lt;/p&gt;</numerusform>
+        </translation>
+    </message>
+    <message numerus="yes">
+        <source>&lt;p&gt;A total of &lt;b&gt;%1&lt;/b&gt; hedgehog(s) were killed during this round.&lt;/p&gt;</source>
+        <translation type="obsolete">
+            <numerusform>&lt;p&gt;A total of &lt;b&gt;%1&lt;/b&gt; hedgehog was killed during this round.&lt;/p&gt;</numerusform>
+            <numerusform>&lt;p&gt;A total of &lt;b&gt;%1&lt;/b&gt; hedgehogs were killed during this round.&lt;/p&gt;</numerusform>
+        </translation>
+    </message>
+    <message>
+        <source>Details</source>
+        <translation>Detaljer</translation>
+    </message>
+    <message>
+        <source>Health graph</source>
+        <translation>Helbredsgraf</translation>
+    </message>
+    <message>
+        <source>Ranking</source>
+        <translation>Rangliste</translation>
+    </message>
+    <message>
+        <source>The best shot award was won by &lt;b&gt;%1&lt;/b&gt; with &lt;b&gt;%2&lt;/b&gt; pts.</source>
+        <translation>Prisen for det bedste skud gik til &lt;b&gt;%1&lt;/b&gt; med &lt;b&gt;%2&lt;/b&gt; point.</translation>
+    </message>
+    <message numerus="yes">
+        <source>The best killer is &lt;b&gt;%1&lt;/b&gt; with &lt;b&gt;%2&lt;/b&gt; kills in a turn.</source>
+        <translation>
+            <numerusform>Den bedste dræber er &lt;b&gt;%1&lt;/b&gt; med &lt;b&gt;%2&lt;/b&gt; drab på én tur.</numerusform>
+            <numerusform>Den bedste dræber er &lt;b&gt;%1&lt;/b&gt; med &lt;b&gt;%2&lt;/b&gt; drab på én tur.</numerusform>
+        </translation>
+    </message>
+    <message numerus="yes">
+        <source>A total of &lt;b&gt;%1&lt;/b&gt; hedgehog(s) were killed during this round.</source>
+        <translation>
+            <numerusform>&lt;b&gt;%1&lt;/b&gt; pindsvin blev dræbt i denne runde.</numerusform>
+            <numerusform>Totalt blev &lt;b&gt;%1&lt;/b&gt; pindsvin dræbt i denne runde.</numerusform>
+        </translation>
+    </message>
+    <message numerus="yes">
+        <source>(%1 kill)</source>
+        <translation>
+            <numerusform>(%1 drab)</numerusform>
+            <numerusform>(%1 drab)</numerusform>
+        </translation>
+    </message>
+    <message numerus="yes">
+        <source>&lt;b&gt;%1&lt;/b&gt; thought it&apos;s good to shoot his own hedgehogs with &lt;b&gt;%2&lt;/b&gt; pts.</source>
+        <translation>
+            <numerusform>&lt;b&gt;%1&lt;/b&gt; troede det var en god idé at skyde sine egne pindsvin med &lt;b&gt;%2&lt;/b&gt; point.</numerusform>
+            <numerusform>&lt;b&gt;%1&lt;/b&gt; troede det var en god idé at skyde sine egne pindsvin med &lt;b&gt;%2&lt;/b&gt; point.</numerusform>
+        </translation>
+    </message>
+    <message numerus="yes">
+        <source>&lt;b&gt;%1&lt;/b&gt; killed &lt;b&gt;%2&lt;/b&gt; of his own hedgehogs.</source>
+        <translation>
+            <numerusform>&lt;b&gt;%1&lt;/b&gt; dræbte &lt;b&gt;%2&lt;/b&gt; af sine egne pindsvin.</numerusform>
+            <numerusform>&lt;b&gt;%1&lt;/b&gt; dræbte &lt;b&gt;%2&lt;/b&gt; af sine egne pindsvin.</numerusform>
+        </translation>
+    </message>
+    <message numerus="yes">
+        <source>&lt;b&gt;%1&lt;/b&gt; was scared and skipped turn &lt;b&gt;%2&lt;/b&gt; times.</source>
+        <translation>
+            <numerusform>&lt;b&gt;%1&lt;/b&gt; blev bange og sprang over sin tur &lt;b&gt;%2&lt;/b&gt; gang.</numerusform>
+            <numerusform>&lt;b&gt;%1&lt;/b&gt; blev bange og sprang over sin tur &lt;b&gt;%2&lt;/b&gt; gange.</numerusform>
+        </translation>
+    </message>
+</context>
+<context>
+    <name>PageInGame</name>
+    <message>
+        <source>In game...</source>
+        <translation>I spillet...</translation>
+    </message>
+</context>
+<context>
+    <name>PageMain</name>
+    <message>
+        <source>Local Game (Play a game on a single computer)</source>
+        <translation>Lokalt spil (Spil et spil på én enkelt computer)</translation>
+    </message>
+    <message>
+        <source>Network Game (Play a game across a network)</source>
+        <translation>Netværksspil (Spil et spil over et netværk)</translation>
+    </message>
+    <message>
+        <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they&apos;ll win or lose together.</source>
+        <comment>Tips</comment>
+        <translation>Bare vælg samme farve som en ven for at spille sammen som et hold. Hver af jer vil stadig kontrollere sine egne pindsvin, men vil vinde eller tabe sammen.</translation>
+    </message>
+    <message>
+        <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
+        <comment>Tips</comment>
+        <translation>Nogle våben giver måske ikke særlig meget skade, men de kan være meget mere farlige i de rigtige situationer. Prøv at bruge Desert Eagle-pistolen til at skubbe flere pindsvin i vandet.</translation>
+    </message>
+    <message>
+        <source>If you&apos;re unsure what to do and don&apos;t want to waste ammo, skip one round. But don&apos;t let too much time pass as there will be Sudden Death!</source>
+        <comment>Tips</comment>
+        <translation>Hvis du er usikker på hvad du skal gøre og ikke vil spilde ammunition, kan du springe en runde over. Men lad der ikke gå alt for meget tid, for ellers indtræffer Pludselig Død!</translation>
+    </message>
+    <message>
+        <source>If you&apos;d like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
+        <comment>Tips</comment>
+        <translation>Hvis du ikke vil have at andre anvender dit foretrukne brugernavn på den officielle server, kan du registrere en bruger på http://www.hedgewars.org/.</translation>
+    </message>
+    <message>
+        <source>You&apos;re bored of default gameplay? Try one of the missions - they&apos;ll offer different gameplay depending on the one you picked.</source>
+        <comment>Tips</comment>
+        <translation>Er du træt af den almindelige måde at spille på? Prøv en af missionerne - de tilbyder forskellige måder at spille på afhængigt af hvilken en du vælger.</translation>
+    </message>
+    <message>
+        <source>By default the game will always record the last game played as a demo. Select &apos;Local Game&apos; and pick the &apos;Demos&apos; button on the lower right corner to play or manage them.</source>
+        <comment>Tips</comment>
+        <translation>Som standard optager spillet altid det sidste spil du har spillet som en demo. Tryk på &apos;Lokalt spil&apos; og vælg &apos;Demoer&apos;-knappen i nederste højre hjørne for at afspille eller administrere dem.</translation>
+    </message>
+    <message>
+        <source>Hedgewars is Open Source and Freeware we create in our spare time. If you&apos;ve got problems, ask on our forums but please don&apos;t expect 24/7 support!</source>
+        <comment>Tips</comment>
+        <translation>Hedgewars er Open Source og et gratis spil vi laver i vores fritid. Hvis du har problemer er du velkommen til at spørge på forummet, men forvent ikke at få hjælp 24 timer i døgnet!</translation>
+    </message>
+    <message>
+        <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
+        <comment>Tips</comment>
+        <translation>Hedgewars er Open Source og et gratis spil vi laver i vores fritid. Hvis du holder af det, kan du hjælpe os med en lille donation eller ved at indsende dine egne modifikationer!</translation>
+    </message>
+    <message>
+        <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
+        <comment>Tips</comment>
+        <translation>Hedgewars er Open Source og et gratis spil vi laver i vores fritid. Del det med dine venner og din familie som du ønsker!</translation>
+    </message>
+    <message>
+        <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
+        <comment>Tips</comment>
+        <translation>Fra tid til anden er der officielle turneringer. Kommende begivenheder vil blive annonceret på http://www.hedgewars.org/ et par dage i forvejen.</translation>
+    </message>
+    <message>
+        <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
+        <comment>Tips</comment>
+        <translation>Hedgewars er tilgængeligt på mange sprog. Hvis oversættelsen på dit sprog mangler noget eller er uddateret, skal du være velkommen til at kontakte os!</translation>
+    </message>
+    <message>
+        <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
+        <comment>Tips</comment>
+        <translation>Hedgewars kan køre på mange forskellige operativsystemer, herunder Microsoft Windows, Mac OS X og Linux.</translation>
+    </message>
+    <message>
+        <source>Always remember you&apos;re able to set up your own games in local and network/online play. You&apos;re not restricted to the &apos;Simple Game&apos; option.</source>
+        <comment>Tips</comment>
+        <translation>Husk altid at du kan sætte dine egne spil op under lokale-, netværks- og online-spil. Du er ikke begrænset til kun at bruge &apos;Simpelt spil&apos;-muligheden.</translation>
+    </message>
+    <message>
+        <source>While playing you should give yourself a short break at least once an hour.</source>
+        <comment>Tips</comment>
+        <translation>Mens du spiller bør du tage en kort pause mindst en gang i timen.</translation>
+    </message>
+    <message>
+        <source>If your graphics card isn&apos;t able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
+        <comment>Tips</comment>
+        <translation>Hvis dit grafikkort ikke understøtter hardware-accelereret OpenGL, kan du prøve at slå indstillingen &apos;Reduceret kvalitet&apos; til for at forbedre ydelsen.</translation>
+    </message>
+    <message>
+        <source>We&apos;re open to suggestions and constructive feedback. If you don&apos;t like something or got a great idea, let us know!</source>
+        <comment>Tips</comment>
+        <translation>Vi er åbne over for foreslag og konstruktive tilbagemeldinger. Fortæl os det hvis der er noget du ikke kan lide eller hvis du har en god idé!</translation>
+    </message>
+    <message>
+        <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
+        <comment>Tips</comment>
+        <translation>Specielt når du spiller online bør du være venlig og altid huske at du måske også spiller med eller mod børn!</translation>
+    </message>
+    <message>
+        <source>Special game modes such as &apos;Vampirism&apos; or &apos;Karma&apos; allow you to develop completely new tactics. Try them in a custom game!</source>
+        <comment>Tips</comment>
+        <translation>Specielle måder at spille på som f.eks. &apos;Varmpyr&apos; eller &apos;Karma&apos; tillader dig at udvikle helt nye taktikker. Prøv dem i et brugerdefineret spil!</translation>
+    </message>
+    <message>
+        <source>You should never install Hedgewars on computers you don&apos;t own (school, university, work, etc.). Please ask the responsible person instead!</source>
+        <comment>Tips</comment>
+        <translation>Du bør aldrig installere Hedgewars på computere du ikke ejer (skole, universitet, arbejde,e.l.). Spørg venligst den ansvarlige person i stedet!</translation>
+    </message>
+    <message>
+        <source>Hedgewars can be perfect for short games during breaks. Just ensure you don&apos;t add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
+        <comment>Tips</comment>
+        <translation>Hedgewars er perfekt til korte spil under pauser. Bare par på du ikke tilføjer for mange pindsvin eller bruger en kæmpe bane. Det kan også hjælpe at reducere tid og liv.</translation>
+    </message>
+    <message>
+        <source>No hedgehogs were harmed in making this game.</source>
+        <comment>Tips</comment>
+        <translation>Ingen pindsvin kom til skade under produktionen af dette spil.</translation>
+    </message>
+    <message>
+        <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
+        <comment>Tips</comment>
+        <translation>Hedgewars er Open Source og et gratis spil vi laver i vores fritid. Hvis nogen solgte dig spiller skal du bede om at få pengene tilbage!</translation>
+    </message>
+    <message>
+        <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
+        <comment>Tips</comment>
+        <translation>Tilslut en eller flere gamepads før du starter spiller for at kunne tildele dem til dit hold.</translation>
+    </message>
+    <message>
+        <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
+        <comment>Tips</comment>
+        <translation>Opret en bruger på %1 hvis du ikke vil have at andre anvender dit foretrukne brugernavn på den officielle server.</translation>
+    </message>
+    <message>
+        <source>If your graphics card isn&apos;t able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
+        <comment>Tips</comment>
+        <translation>Hvis du ikke er i stand til at slå hardware-accelereret OpenGL til, bør du prøve at opdatere dine grafikkort-drivere.</translation>
+    </message>
+    <message>
+        <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
+        <comment>Tips</comment>
+        <translation>Der er tre forskellige typer hop tilgængelige. Tryk hurtigt på [hight jump] to gange i træk for at lave et højt, baglæns hop.</translation>
+    </message>
+    <message>
+        <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
+        <comment>Tips</comment>
+        <translation>Er du bange for at falde ned fra en skrænt? Hold [precise] nede for at vende dig mod [left] eller [right] uden at bevæge dig.</translation>
+    </message>
+    <message>
+        <source>Some weapons require special strategies or just lots of training, so don&apos;t give up on a particular tool if you miss an enemy once.</source>
+        <comment>Tips</comment>
+        <translation>Nogle våben kræver specielle strategier eller bare masser af træning, så undlad ikke at bruge et bestemt våben bare fordi du rammer ved siden af én gang.</translation>
+    </message>
+    <message>
+        <source>Most weapons won&apos;t work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
+        <comment>Tips</comment>
+        <translation>De fleste våben virker ikke så snart de har rørt vandet. Den Målsøgende Bi og Kagen er de eneste undtagelser.</translation>
+    </message>
+    <message>
+        <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
+        <comment>Tips</comment>
+        <translation>Gamle Ole laver kun en lille eksplosion. Til gengæld kan den stænkende sky den udsender føres rundt af vinden og ramme mange pindsvin på én gang.</translation>
+    </message>
+    <message>
+        <source>The Piano Strike is the most damaging air strike. You&apos;ll lose the hedgehog performing it, so there&apos;s a huge downside as well.</source>
+        <comment>Tips</comment>
+        <translation>Klaveranslaget er det luftvåben der giver allermest skade. Til gengæld mister du det pindsvin som bruger angrebet, så der er også en bagside af medaljen.</translation>
+    </message>
+    <message>
+        <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
+        <comment>Tips</comment>
+        <translation>Klæbrige Miner er det perfekte værktøj til at lave små kædereaktioner og smide pindsvin ud i faretruende situationer... eller bare direkte i vandet.</translation>
+    </message>
+    <message>
+        <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
+        <comment>Tips</comment>
+        <translation>Hammeren er mest effektiv når den bruges enten på broer eller bærebjælker. Sigter du mod pindsvin med den, laver du bare huller i jorden.</translation>
+    </message>
+    <message>
+        <source>If you&apos;re stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
+        <comment>Tips</comment>
+        <translation>Hvis du sidder fast bag en af modstanderens pindsvin, kan du bruge Hammeren til at slå dig fri uden at tage skade under en eksplosion.</translation>
+    </message>
+    <message>
+        <source>The Cake&apos;s maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
+        <comment>Tips</comment>
+        <translation>Kagen kan gå kortere eller længere, afhængig af hvad den skal over på vejen. Du kan brrug [attack] til at detonere den før den når sin destination.</translation>
+    </message>
+    <message>
+        <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
+        <comment>Tips</comment>
+        <translation>Flammekasteren er et våben, men den kan også bruges til hurtigt at grave tunneler.</translation>
+    </message>
+    <message>
+        <source>Want to know who&apos;s behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
+        <comment>Tips</comment>
+        <translation>Vil du vide hvem der står bag spillet? Klik på Hedgewars-logoet i hovedmenuen for at se rulleteksterne.</translation>
+    </message>
+    <message>
+        <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
+        <comment>Tips</comment>
+        <translation>Er du glad for Hedgewars? Bliv fan på %1 eller følge vores opdateringer på %2!</translation>
+    </message>
+    <message>
+        <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you&apos;ll have to share them somewhere to use them online.</source>
+        <comment>Tips</comment>
+        <translation>Du skal være velkommen til at tegne dine egne gravsten, hatte, flag eller endda baner og temaer! Men læg mærke til at du bliver nød til at dele dem med andre hvis du vil spille med dem online.</translation>
+    </message>
+    <message>
+        <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
+        <comment>Tips</comment>
+        <translation>Vil du virkelig gerne have en specifik hat? Send os en donation, så kvitterer vi med en eksklusiv hat efter eget valg!</translation>
+    </message>
+    <message>
+        <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
+        <comment>Tips</comment>
+        <translation>Hold dine grafikkortdrivere opdaterede for at undgå problemmer i spillet.</translation>
+    </message>
+    <message>
+        <source>You can find your Hedgewars configuration files under &quot;My Documents\Hedgewars&quot;. Create backups or take the files with you, but don&apos;t edit them by hand.</source>
+        <comment>Tips</comment>
+        <translation>Du kan finde konfigurationsfilerne til Hedgewars under mappen &quot;(Mine) Dokumenter\Hedgewars&quot;. Opret gerne en back-up eller tag filerne med dig, men lad være med selv at ændre i dem.</translation>
+    </message>
+    <message>
+        <source>You&apos;re able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
+        <comment>Tips</comment>
+        <translation>Du kan indstille Hedgewars-filer (gemte spil og demooptagelser) til automatisk at åbne når du trykker på dem eller åbner dem i din internet-browser.</translation>
+    </message>
+    <message>
+        <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don&apos;t touch the ground you&apos;ll reuse your rope without wasting ammo!</source>
+        <comment>Tips</comment>
+        <translation>Vil du gerne spare på dine reb? Slip rebet midt i luften og skyd straks igen. Så længe du ikke rører jorden bruger du ikke noget ammunition!</translation>
+    </message>
+    <message>
+        <source>You can find your Hedgewars configuration files under &quot;Library/Application Support/Hedgewars&quot; in your home directory. Create backups or take the files with you, but don&apos;t edit them by hand.</source>
+        <comment>Tips</comment>
+        <translation>Du kan finde konfigurationsfilerne til Hedgewars under mappen &quot;Bibliotek/Application Support/Hedgewars&quot; i din hjemmemappe. Opret gerne en back-up eller tag filerne med dig, men lad være med selv at ændre i dem.</translation>
+    </message>
+    <message>
+        <source>You can find your Hedgewars configuration files under &quot;.hedgewars&quot; in your home directory. Create backups or take the files with you, but don&apos;t edit them by hand.</source>
+        <comment>Tips</comment>
+        <translation>Du kan finde konfigurationsfilerne til Hedgewars under mappen &quot;.hedgewars&quot; i din hjemmemappe. Opret gerne en back-up eller tag filerne med dig, men lad være med selv at ændre i dem.</translation>
+    </message>
+    <message>
+        <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
+        <comment>Tips</comment>
+        <translation>Windows-versionen af Hedgewars understøtter integrering med Xfire. Husk at tilføje Hedgewars til din liste med spil så dine venner kan se hvornår du spiller.</translation>
+    </message>
+    <message>
+        <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
+        <comment>Tips</comment>
+        <translation>Brug en Molotovcocktail eller Flammekasteren til midlertidigt at forhindre pindsvin i at passere et område, f.eks. en tunnel eller platform.</translation>
+    </message>
+    <message>
+        <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
+        <comment>Tips</comment>
+        <translation>Den Målsøgende Bi kan være svær at bruge. Den vender lettere hvis den ikke flyver alt for hurtigt, så prøv at spare på kraften når du affyrer den.</translation>
+    </message>
+    <message>
+        <source>Downloadable Content</source>
+        <translation>Indhold der kan Downloades</translation>
+    </message>
+</context>
+<context>
+    <name>PageMultiplayer</name>
+    <message>
+        <source>Start</source>
+        <translation>Start</translation>
+    </message>
+</context>
+<context>
+    <name>PageNet</name>
+    <message>
+        <source>Error</source>
+        <translation>Fejl</translation>
+    </message>
+    <message>
+        <source>Please select server from the list above</source>
+        <translation>Vælg venligst en server fra den ovenstående liste</translation>
+    </message>
+</context>
+<context>
+    <name>PageNetGame</name>
+    <message>
+        <source>Control</source>
+        <translation>Kontrol</translation>
+    </message>
+    <message>
+        <source>Error</source>
+        <translation>Fejl</translation>
+    </message>
+    <message>
+        <source>Please enter room name</source>
+        <translation>Indtast venligst navnet på rummet</translation>
+    </message>
+    <message>
+        <source>OK</source>
+        <translation>OK</translation>
+    </message>
+</context>
+<context>
+    <name>PageNetType</name>
+    <message>
+        <source>LAN game</source>
+        <translation>Netværksspil</translation>
+    </message>
+    <message>
+        <source>Official server</source>
+        <translation>Officiel server</translation>
+    </message>
+</context>
+<context>
+    <name>PageOptions</name>
+    <message>
+        <source>New team</source>
+        <translation>Nyt hold</translation>
+    </message>
+    <message>
+        <source>Edit team</source>
+        <translation>Rediger hold</translation>
+    </message>
+    <message>
+        <source>Delete team</source>
+        <translation>Slet hold</translation>
+    </message>
+    <message>
+        <source>New weapon scheme</source>
+        <translation>Nyt våbensystem</translation>
+    </message>
+    <message>
+        <source>Edit weapon scheme</source>
+        <translation>Rediger våbensystem</translation>
+    </message>
+    <message>
+        <source>Delete weapon scheme</source>
+        <translation>Slet våbensystem</translation>
+    </message>
+    <message>
+        <source>You can&apos;t edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
+        <translation>Du kan ikke ændre på holdene fra holdvalgsskærmen. Gå tilbage til hovedmenuen for at tilføje, redigere og slette hold.</translation>
+    </message>
+    <message>
+        <source>New scheme</source>
+        <translation>Nyt spilsystem</translation>
+    </message>
+    <message>
+        <source>Edit scheme</source>
+        <translation>Rediger spilsystem</translation>
+    </message>
+    <message>
+        <source>Delete scheme</source>
+        <translation>Slet spilsystem</translation>
+    </message>
+    <message>
+        <source>New weapon set</source>
+        <translation>Nyt våbensæt</translation>
+    </message>
+    <message>
+        <source>Edit weapon set</source>
+        <translation>Rediger våbensæt</translation>
+    </message>
+    <message>
+        <source>Delete weapon set</source>
+        <translation>Slet våbensæt</translation>
+    </message>
+</context>
+<context>
+    <name>PagePlayDemo</name>
+    <message>
+        <source>Error</source>
+        <translation>Fejl</translation>
+    </message>
+    <message>
+        <source>OK</source>
+        <translation>OK</translation>
+    </message>
+    <message>
+        <source>Rename dialog</source>
+        <translation>Dialogboks til omdøbelse</translation>
+    </message>
+    <message>
+        <source>Enter new file name:</source>
+        <translation>Indtast nyt filnavn:</translation>
+    </message>
+    <message>
+        <source>Cannot rename to</source>
+        <translation>Kan ikke omdøbe til</translation>
+    </message>
+    <message>
+        <source>Cannot delete file</source>
+        <translation>Kan ikke slette fil</translation>
+    </message>
+    <message>
+        <source>Please select record from the list</source>
+        <translation>Vælg venligst en optagelse fra listen</translation>
+    </message>
+</context>
+<context>
+    <name>PageRoomsList</name>
+    <message>
+        <source>Create</source>
+        <translation>Opret</translation>
+    </message>
+    <message>
+        <source>Join</source>
+        <translation>Tilslut</translation>
+    </message>
+    <message>
+        <source>Refresh</source>
+        <translation>Opdater</translation>
+    </message>
+    <message>
+        <source>Error</source>
+        <translation>Fejl</translation>
+    </message>
+    <message>
+        <source>OK</source>
+        <translation>OK</translation>
+    </message>
+    <message>
+        <source>Admin features</source>
+        <translation>Administratorfunktioner</translation>
+    </message>
+    <message>
+        <source>Room Name:</source>
+        <translation>Navn på Rum:</translation>
+    </message>
+    <message>
+        <source>This game is in lobby.
+You may join and start playing once the game starts.</source>
+        <translation>Dette spil er i lobbyen.
+Du kan tilslutte dig og spille med når spillet starter.</translation>
+    </message>
+    <message>
+        <source>This game is in progress.
+You may join and spectate now but you&apos;ll have to wait for the game to end to start playing.</source>
+        <translation>Dette spil er i gang.
+Du kan tilslutte dig og kigge med med det samme, men du må vente på at spillet slutter med selv at kunne spille med.</translation>
+    </message>
+    <message>
+        <source>%1 is the host. He may adjust settings and start the game.</source>
+        <translation>%1 er værten. Han kan ændre indstillingerne og starte spillet.</translation>
+    </message>
+    <message>
+        <source>Random Map</source>
+        <translation>Tilfældig Bane</translation>
+    </message>
+    <message>
+        <source>Games may be played on precreated or randomized maps.</source>
+        <translation>Man kan spille enten på allerede lavede eller tilfældigt genererede baner.</translation>
+    </message>
+    <message>
+        <source>The Game Scheme defines general options and preferences like Round Time, Sudden Death or Vampirism.</source>
+        <translation>Spilsystemet definerer generelle indstillinger og præferencer, så som rundelængden, Pludselig Død og Vampyr.</translation>
+    </message>
+    <message>
+        <source>The Weapon Scheme defines available weapons and their ammunition count.</source>
+        <translation>Våbensystemet definere hvilke våben der er tilgængelige og hvor meget ammunition de har.</translation>
+    </message>
+    <message numerus="yes">
+        <source>There are %1 clients connected to this room.</source>
+        <translation>
+            <numerusform>Der er %1 klient forbundet til dette rum.</numerusform>
+            <numerusform>Der er %1 klienter forbundet til dette rum.</numerusform>
+        </translation>
+    </message>
+    <message numerus="yes">
+        <source>There are %1 teams participating in this room.</source>
+        <translation>
+            <numerusform>Der deltager %1 hold i dette rum.</numerusform>
+            <numerusform>Der deltager %1 hold i dette rum.</numerusform>
+        </translation>
+    </message>
+    <message>
+        <source>Please enter room name</source>
+        <translation>Indtast venligst rummets navn</translation>
+    </message>
+    <message>
+        <source>Please select room from the list</source>
+        <translation>Vælg venligst et rum fra listen</translation>
+    </message>
+    <message>
+        <source>Random Maze</source>
+        <translation>Tilfældig Labyrint</translation>
+    </message>
+    <message>
+        <source>Rules:</source>
+        <translation>Regler:</translation>
+    </message>
+    <message>
+        <source>Weapons:</source>
+        <translation>Våben:</translation>
+    </message>
+    <message>
+        <source>Search:</source>
+        <translation>Søg:</translation>
+    </message>
+    <message>
+        <source>Clear</source>
+        <translation>Ryd</translation>
+    </message>
+    <message>
+        <source>Warning</source>
+        <translation>Advarsel</translation>
+    </message>
+    <message>
+        <source>The game you are trying to join has started.
+Do you still want to join the room?</source>
+        <translation>Det spil du forsøge at tilslutte dig er allerede startet.
+Har du stadig lyst til at tilslutte dig rummet?</translation>
+    </message>
+    <message numerus="yes">
+        <source>%1 players online</source>
+        <translation>
+            <numerusform>%1 spiller er online</numerusform>
+            <numerusform>%1 spillere er online</numerusform>
+        </translation>
+    </message>
+</context>
+<context>
+    <name>PageScheme</name>
+    <message>
+        <source>Defend your fort and destroy the opponents, two team colours max!</source>
+        <translation>Forsvar dit fort og udryd dine modstandere. Maksimalt to holdfarver!</translation>
+    </message>
+    <message>
+        <source>Teams will start on opposite sides of the terrain, two team colours max!</source>
+        <translation>Hold starter på hver sin side af banen. Maksimalt to holdfarver!</translation>
+    </message>
+    <message>
+        <source>Land can not be destroyed!</source>
+        <translation>Landmassen kan ikke ødelægges!</translation>
+    </message>
+    <message>
+        <source>Add an indestructable border around the terrain</source>
+        <translation>Tilføj en kant rundt om banen som ikke kan destrueres</translation>
+    </message>
+    <message>
+        <source>Lower gravity</source>
+        <translation>Svagere tyngdekraft</translation>
+    </message>
+    <message>
+        <source>Assisted aiming with laser sight</source>
+        <translation>Lasersigte til hjælp med at ramme</translation>
+    </message>
+    <message>
+        <source>All hogs have a personal forcefield</source>
+        <translation>Alle pindsvin har deres eget personlige kraftfelt</translation>
+    </message>
+    <message>
+        <source>Enable random mines</source>
+        <translation>Aktiver tilfældige miner</translation>
+    </message>
+    <message>
+        <source>Gain 80% of the damage you do back in health</source>
+        <translation>Få 80% af den skade du giver tilbage som liv</translation>
+    </message>
+    <message>
+        <source>Share your opponents pain, share their damage</source>
+        <translation>Del dine modstanderes lidelser, del deres skader</translation>
+    </message>
+    <message>
+        <source>Your hogs are unable to move, put your artillery skills to the test</source>
+        <translation>Dine pindsvin kan ikke bevæge sig, så nu skal du vinde kun ved artilleriet</translation>
+    </message>
+    <message>
+        <source>Random</source>
+        <translation>Tilfældig</translation>
+    </message>
+    <message>
+        <source>Seconds</source>
+        <translation>Sekunder</translation>
+    </message>
+    <message>
+        <source>New</source>
+        <translation>Ny</translation>
+    </message>
+    <message>
+        <source>Delete</source>
+        <translation>Slet</translation>
+    </message>
+    <message>
+        <source>Order of play is random instead of in room order.</source>
+        <translation>Turrækkefølgen er tilfældig i stedet for rækkefølgen i rummet.</translation>
+    </message>
+    <message>
+        <source>Play with a King. If he dies, your side dies.</source>
+        <translation>Spil med en Konge. Taber du ham, taber du.</translation>
+    </message>
+    <message>
+        <source>Take turns placing your hedgehogs before the start of play.</source>
+        <translation>Tag ture med at placere pindsvinene før spillet starter.</translation>
+    </message>
+    <message>
+        <source>Ammo is shared between all teams that share a colour.</source>
+        <translation>Ammunition deles melem alle hold der deler en farve.</translation>
+    </message>
+    <message>
+        <source>Disable girders when generating random maps.</source>
+        <translation>Deaktiver bærebjælker når der genereres tilfældige baner.</translation>
+    </message>
+    <message>
+        <source>Disable land objects when generating random maps.</source>
+        <translation>Deaktiver overfladeobjekter når der genereres tilfældige baner.</translation>
+    </message>
+    <message>
+        <source>AI respawns on death.</source>
+        <translation>AI-pindsvin genopliver straks efter de dør.</translation>
+    </message>
+    <message>
+        <source>All (living) hedgehogs are fully restored at the end of turn</source>
+        <translation>Alle (levende) pindsvin bliver helbredt helt i slutningen af turen</translation>
+    </message>
+    <message>
+        <source>Attacking does not end your turn.</source>
+        <translation>Angreb slutter ikke turen.</translation>
+    </message>
+    <message>
+        <source>Weapons are reset to starting values each turn.</source>
+        <translation>Våben bliver nulstillet til startværdier hver tur.</translation>
+    </message>
+    <message>
+        <source>Each hedgehog has its own ammo. It does not share with the team.</source>
+        <translation>Hvert pindsvin har sin egen ammunition. Den deler ikke med holdet.</translation>
+    </message>
+    <message>
+        <source>You will not have to worry about wind anymore.</source>
+        <translation>Du behøver ikke længere bekymre dig om vindstød.</translation>
+    </message>
+    <message>
+        <source>Wind will affect almost everything.</source>
+        <translation>Vinden tager fat i næsten alt.</translation>
+    </message>
+    <message>
+        <source>Copy</source>
+        <translation>Kopier</translation>
+    </message>
+    <message>
+        <source>Teams in each clan take successive turns sharing their turn time.</source>
+        <translation>Hold i hver klan deler én tidspulje, som de alle bruger af i løbet af deres tur.</translation>
+    </message>
+    <message>
+        <source>Add an indestructible border around the terrain</source>
+        <translation>Tilføj en kant rundt om banen som ikke kan destrueres</translation>
+    </message>
+    <message>
+        <source>Add an indestructible border along the bottom</source>
+        <translation>Tilføj en kant under banen som ikke kan destrueres</translation>
+    </message>
+</context>
+<context>
+    <name>PageSelectWeapon</name>
+    <message>
+        <source>Default</source>
+        <translation>Standard</translation>
+    </message>
+    <message>
+        <source>Delete</source>
+        <translation>Slet</translation>
+    </message>
+    <message>
+        <source>New</source>
+        <translation>Ny</translation>
+    </message>
+    <message>
+        <source>Copy</source>
+        <translation>Kopier</translation>
+    </message>
+</context>
+<context>
+    <name>PageSinglePlayer</name>
+    <message>
+        <source>Simple Game (a quick game against the computer, settings are chosen for you)</source>
+        <translation>Simpelt spil (et hurtigt spil mod computeren, hvor indstillingerne er valgt på forhånd)</translation>
+    </message>
+    <message>
+        <source>Multiplayer (play a hotseat game against your friends, or AI teams)</source>
+        <translation>Multiplayer (spil mod flere venner eller AI hold ved samme computer)</translation>
+    </message>
+    <message>
+        <source>Training Mode (Practice your skills in a range of training missions)</source>
+        <translation>Træningsspil (Rafiner dine evner i en række forskellige træningsmissioner)</translation>
+    </message>
+    <message>
+        <source>Demos (Watch recorded demos)</source>
+        <translation>Demoer (Afspil optagede demoer)</translation>
+    </message>
+    <message>
+        <source>Load (Load a previously saved game)</source>
+        <translation>Indlæs (Indlæs et tidligere gemt spil)</translation>
+    </message>
+    <message>
+        <source>Campaign Mode (...)</source>
+        <translation>Kampagnespil (...)</translation>
+    </message>
+</context>
+<context>
+    <name>PageTraining</name>
+    <message>
+        <source>No description available</source>
+        <translation>Ingen beskrivelse tilgængelig</translation>
+    </message>
+    <message>
+        <source>Select a mission!</source>
+        <translation>Vælg en mission!</translation>
+    </message>
+</context>
+<context>
+    <name>QAction</name>
+    <message>
+        <source>Kick</source>
+        <translation>Smid ud</translation>
+    </message>
+    <message>
+        <source>Info</source>
+        <translation>Info</translation>
+    </message>
+    <message>
+        <source>Start</source>
+        <translation>Start</translation>
+    </message>
+    <message>
+        <source>Restrict Joins</source>
+        <translation>Begræns tilslutninger</translation>
+    </message>
+    <message>
+        <source>Restrict Team Additions</source>
+        <translation>Begræns holdtilslutninger</translation>
+    </message>
+    <message>
+        <source>Ban</source>
+        <translation>Bandlys</translation>
+    </message>
+    <message>
+        <source>Follow</source>
+        <translation>Følg</translation>
+    </message>
+    <message>
+        <source>Ignore</source>
+        <translation>Ignorer</translation>
+    </message>
+    <message>
+        <source>Add friend</source>
+        <translation>Tilføj ven</translation>
+    </message>
+    <message>
+        <source>Unignore</source>
+        <translation>Hold op med at ignorere</translation>
+    </message>
+    <message>
+        <source>Remove friend</source>
+        <translation>Fjern ven</translation>
+    </message>
+    <message>
+        <source>Update</source>
+        <translation>Opdater</translation>
+    </message>
+</context>
+<context>
+    <name>QCheckBox</name>
+    <message>
+        <source>Check for updates at startup</source>
+        <translation>Tjek efter opdatering når spillet startes</translation>
+    </message>
+    <message>
+        <source>Fullscreen</source>
+        <translation>Fuldskærm</translation>
+    </message>
+    <message>
+        <source>Frontend fullscreen</source>
+        <translation>Fullskærm (frontend)</translation>
+    </message>
+    <message>
+        <source>Enable sound</source>
+        <translation>Aktiver lyd</translation>
+    </message>
+    <message>
+        <source>Enable music</source>
+        <translation>Aktiver musik</translation>
+    </message>
+    <message>
+        <source>Show FPS</source>
+        <translation>Fremvis antal billeder vist per sekund</translation>
+    </message>
+    <message>
+        <source>Alternative damage show</source>
+        <translation>Vis skade efter hvert skud</translation>
+    </message>
+    <message>
+        <source>Append date and time to record file name</source>
+        <translation>Tilføj dato og tidspunkt til filnavnet for optagelser</translation>
+    </message>
+    <message>
+        <source>Reduced quality</source>
+        <translation>Reduceret kvalitet</translation>
+    </message>
+    <message>
+        <source>Show ammo menu tooltips</source>
+        <translation>Vis værktøjstip i ammunitionsmenuer</translation>
+    </message>
+    <message>
+        <source>Enable frontend sounds</source>
+        <translation>Aktiver lyd (frontend)</translation>
+    </message>
+    <message>
+        <source>Enable frontend music</source>
+        <translation>Aktiver musik (frontend)</translation>
+    </message>
+    <message>
+        <source>Frontend effects</source>
+        <translation>Effekter (frontend)</translation>
+    </message>
+</context>
+<context>
+    <name>QComboBox</name>
+    <message>
+        <source>generated map...</source>
+        <translation>genereret bane...</translation>
+    </message>
+    <message>
+        <source>Human</source>
+        <translation>Menneske</translation>
+    </message>
+    <message>
+        <source>Level</source>
+        <translation>Niveau</translation>
+    </message>
+    <message>
+        <source>(System default)</source>
+        <translation>(Systemstandard)</translation>
+    </message>
+    <message>
+        <source>Mission</source>
+        <translation>Mission</translation>
+    </message>
+    <message>
+        <source>generated maze...</source>
+        <translation>genereret labyrint...</translation>
+    </message>
+    <message>
+        <source>Community</source>
+        <translation>Fællesskab</translation>
+    </message>
+    <message>
+        <source>Any</source>
+        <translation>Ethvert</translation>
+    </message>
+    <message>
+        <source>In lobby</source>
+        <translation>I lobbyen</translation>
+    </message>
+    <message>
+        <source>In progress</source>
+        <translation>I gang</translation>
+    </message>
+    <message>
+        <source>Default</source>
+        <translation>Standard</translation>
+    </message>
+    <message>
+        <source>hand drawn map...</source>
+        <translation>håndtegnet bane...</translation>
+    </message>
+    <message>
+        <source>Disabled</source>
+        <translation>Deaktiveret</translation>
+    </message>
+    <message>
+        <source>Red/Cyan</source>
+        <translation>Rød/Cyan</translation>
+    </message>
+    <message>
+        <source>Cyan/Red</source>
+        <translation>Cyan/Rød</translation>
+    </message>
+    <message>
+        <source>Red/Blue</source>
+        <translation>Rød/Blå</translation>
+    </message>
+    <message>
+        <source>Blue/Red</source>
+        <translation>Blå/Rød</translation>
+    </message>
+    <message>
+        <source>Red/Green</source>
+        <translation>Rød/Grøn</translation>
+    </message>
+    <message>
+        <source>Green/Red</source>
+        <translation>Grøn/Rød</translation>
+    </message>
+    <message>
+        <source>Side-by-side</source>
+        <translation>Side-om-side</translation>
+    </message>
+    <message>
+        <source>Top-Bottom</source>
+        <translation>Top-Bund</translation>
+    </message>
+    <message>
+        <source>Wiggle</source>
+        <translation>Vrikke</translation>
+    </message>
+    <message>
+        <source>Red/Cyan grayscale</source>
+        <translation>Rød/Cyan gråskala</translation>
+    </message>
+    <message>
+        <source>Cyan/Red grayscale</source>
+        <translation>Cyan/Rød gråskala</translation>
+    </message>
+    <message>
+        <source>Red/Blue grayscale</source>
+        <translation>Rød/Blå gråskala</translation>
+    </message>
+    <message>
+        <source>Blue/Red grayscale</source>
+        <translation>Blå/Rød gråskala</translation>
+    </message>
+    <message>
+        <source>Red/Green grayscale</source>
+        <translation>Rød/Grøn gråskala</translation>
+    </message>
+    <message>
+        <source>Green/Red grayscale</source>
+        <translation>Grøn/Rød gråskala</translation>
+    </message>
+</context>
+<context>
+    <name>QGroupBox</name>
+    <message>
+        <source>Team Members</source>
+        <translation>Holdmedlemmer</translation>
+    </message>
+    <message>
+        <source>Fort</source>
+        <translation>Fort</translation>
+    </message>
+    <message>
+        <source>Key binds</source>
+        <translation>Tasteindstillinger</translation>
+    </message>
+    <message>
+        <source>Teams</source>
+        <translation>Hold</translation>
+    </message>
+    <message>
+        <source>Weapons</source>
+        <translation>Våben</translation>
+    </message>
+    <message>
+        <source>Audio/Graphic options</source>
+        <translation>Lyd-/Grafikindstillinger</translation>
+    </message>
+    <message>
+        <source>Net game</source>
+        <translation>Netspil</translation>
+    </message>
+    <message>
+        <source>Playing teams</source>
+        <translation>Hold i spil</translation>
+    </message>
+    <message>
+        <source>Game Modifiers</source>
+        <translation>Spilmodifikatorer</translation>
+    </message>
+    <message>
+        <source>Basic Settings</source>
+        <translation>Grundlæggende indstillinger</translation>
+    </message>
+    <message>
+        <source>Team Settings</source>
+        <translation>Holdindstillinger</translation>
+    </message>
+    <message>
+        <source>Misc</source>
+        <translation>Diverse</translation>
+    </message>
+    <message>
+        <source>Schemes and Weapons</source>
+        <translation>Spilsystemer og Våben</translation>
+    </message>
+</context>
+<context>
+    <name>QLabel</name>
+    <message>
+        <source>Mines Time</source>
+        <translation>Mine-tid</translation>
+    </message>
+    <message>
+        <source>Mines</source>
+        <translation>Miner</translation>
+    </message>
+    <message>
+        <source>Version</source>
+        <translation>Version</translation>
+    </message>
+    <message>
+        <source>This program is distributed under the GNU General Public License</source>
+        <translation>Dette program distribueres under GNU General Public License</translation>
+    </message>
+    <message>
+        <source>Developers:</source>
+        <translation>Udviklere:</translation>
+    </message>
+    <message>
+        <source>Art:</source>
+        <translation>Grafik:</translation>
+    </message>
+    <message>
+        <source>Sounds:</source>
+        <translation>Lyde:</translation>
+    </message>
+    <message>
+        <source>Translations:</source>
+        <translation>Oversættelser:</translation>
+    </message>
+    <message>
+        <source>Special thanks:</source>
+        <translation>Særlig tak til:</translation>
+    </message>
+    <message>
+        <source>Weapons</source>
+        <translation>Våben</translation>
+    </message>
+    <message>
+        <source>Host:</source>
+        <translation>Vært:</translation>
+    </message>
+    <message>
+        <source>Port:</source>
+        <translation>Port:</translation>
+    </message>
+    <message>
+        <source>Net nick</source>
+        <translation>Brugernavn</translation>
+    </message>
+    <message>
+        <source>Resolution</source>
+        <translation>Opløsning</translation>
+    </message>
+    <message>
+        <source>FPS limit</source>
+        <translation>Grænse over antal billeder vist i sekundet</translation>
+    </message>
+    <message>
+        <source>Server name:</source>
+        <translation>Servernavn:</translation>
+    </message>
+    <message>
+        <source>Server port:</source>
+        <translation>Serverport:</translation>
+    </message>
+    <message>
+        <source>Initial sound volume</source>
+        <translation>Lydstyrke til start</translation>
+    </message>
+    <message>
+        <source>Damage Modifier</source>
+        <translation>Skademodifikator</translation>
+    </message>
+    <message>
+        <source>Turn Time</source>
+        <translation>Tur-tid</translation>
+    </message>
+    <message>
+        <source>Initial Health</source>
+        <translation>Liv til start</translation>
+    </message>
+    <message>
+        <source>Sudden Death Timeout</source>
+        <translation>Pludselig Død Timeout</translation>
+    </message>
+    <message>
+        <source>Scheme Name:</source>
+        <translation>Spilsystems Navn:</translation>
+    </message>
+    <message>
+        <source>Crate Drops</source>
+        <translation>Antal Kasser</translation>
+    </message>
+    <message>
+        <source>Game scheme</source>
+        <translation>Spilsystem</translation>
+    </message>
+    <message>
+        <source>% Dud Mines</source>
+        <translation>% Miner er Fusere</translation>
+    </message>
+    <message>
+        <source>Name</source>
+        <translation>Navn</translation>
+    </message>
+    <message>
+        <source>Type</source>
+        <translation>Type</translation>
+    </message>
+    <message>
+        <source>Grave</source>
+        <translation>Gravsten</translation>
+    </message>
+    <message>
+        <source>Flag</source>
+        <translation>Flag</translation>
+    </message>
+    <message>
+        <source>Voice</source>
+        <translation>Stemme</translation>
+    </message>
+    <message>
+        <source>Locale</source>
+        <translation>Lokalitet</translation>
+    </message>
+    <message>
+        <source>Restart game to apply</source>
+        <translation>Genstart spil for at anvende</translation>
+    </message>
+    <message>
+        <source>Explosives</source>
+        <translation>Eksplosiver</translation>
+    </message>
+    <message>
+        <source>Tip: </source>
+        <translation>Tip:</translation>
+    </message>
+    <message>
+        <source>This development build is &apos;work in progress&apos; and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
+        <translation>Denne udviklerversion er under konstruktion og er ikke nødvendigvis kompatibel med andre versioner af spillet. Nogle funktioner er måske i stykker eller ukomplette. Brug er på eget ansvar!</translation>
+    </message>
+    <message>
+        <source>Quality</source>
+        <translation>Kvalitet</translation>
+    </message>
+    <message>
+        <source>% Health Crates</source>
+        <translation>% Kasser der Helbreder</translation>
+    </message>
+    <message>
+        <source>Health in Crates</source>
+        <translation>Liv i hver kasse der helbreder</translation>
+    </message>
+    <message>
+        <source>Sudden Death Water Rise</source>
+        <translation>Pludselig Død Vandstigning</translation>
+    </message>
+    <message>
+        <source>Sudden Death Health Decrease</source>
+        <translation>Pludselig Død Skade</translation>
+    </message>
+    <message>
+        <source>% Rope Length</source>
+        <translation>% reblængde</translation>
+    </message>
+    <message>
+        <source>Stereo rendering</source>
+        <translation>3D-rendering</translation>
+    </message>
+    <message>
+        <source>Style</source>
+        <translation>Stil</translation>
+    </message>
+    <message>
+        <source>Scheme</source>
+        <translation>Spilsystem</translation>
+    </message>
+    <message>
+        <source>Password</source>
+        <translation>Kodeord</translation>
+    </message>
+    <message>
+        <source>% Get Away Time</source>
+        <translation>% Tid til at Løbe Væk</translation>
+    </message>
+    <message>
+        <source>This program is distributed under the GNU General Public License v2</source>
+        <translation>Dette program distribueres under GNU General Public License v2</translation>
+    </message>
+</context>
+<context>
+    <name>QLineEdit</name>
+    <message>
+        <source>unnamed</source>
+        <translation>unavngivet</translation>
+    </message>
+    <message>
+        <source>hedgehog %1</source>
+        <translation>pindsvin %1</translation>
+    </message>
+</context>
+<context>
+    <name>QMainWindow</name>
+    <message>
+        <source>Hedgewars %1</source>
+        <translation>Hedgewars %1</translation>
+    </message>
+</context>
+<context>
+    <name>QMessageBox</name>
+    <message>
+        <source>Network</source>
+        <translation>Netværk</translation>
+    </message>
+    <message>
+        <source>Connection to server is lost</source>
+        <translation>Forbindelse til serveren er gået tabt</translation>
+    </message>
+    <message>
+        <source>Error</source>
+        <translation>Fejl</translation>
+    </message>
+    <message>
+        <source>Failed to open data directory:
+%1
+Please check your installation</source>
+        <translation>Det mislykkedes at åbne data mappen:
+%1
+Tjek venligst om spillet er installeret korrekt</translation>
+    </message>
+    <message>
+        <source>Weapons</source>
+        <translation>Våben</translation>
+    </message>
+    <message>
+        <source>Can not edit default weapon set</source>
+        <translation>Kan ikke ændre standardvåbensæt</translation>
+    </message>
+    <message>
+        <source>Can not delete default weapon set</source>
+        <translation>Kan ikke slette standardvåbensæt</translation>
+    </message>
+    <message>
+        <source>Really delete this weapon set?</source>
+        <translation>Vil du virkelig slette dette våbensæt?</translation>
+    </message>
+    <message>
+        <source>Can not overwrite default weapon set &apos;%1&apos;!</source>
+        <translation>Kan ikke overskrive standardvåbensættet &apos;%1&apos;!</translation>
+    </message>
+    <message>
+        <source>All file associations have been set.</source>
+        <translation>Alle filtilknytninger er blevet indstillede.</translation>
+    </message>
+    <message>
+        <source>File association failed.</source>
+        <translation>Filtilknytninger mislykkedes.</translation>
+    </message>
+    <message>
+        <source>Teams</source>
+        <translation>Hold</translation>
+    </message>
+    <message>
+        <source>Really delete this team?</source>
+        <translation>Vil du virkelig slette dette hold?</translation>
+    </message>
+    <message>
+        <source>Schemes</source>
+        <translation>Spilsystemer</translation>
+    </message>
+    <message>
+        <source>Can not delete default scheme &apos;%1&apos;!</source>
+        <translation>Kan ikke slette standardspilsystemet &apos;%1&apos;!</translation>
+    </message>
+    <message>
+        <source>Really delete this game scheme?</source>
+        <translation>Vil du virkelig slette dette spilsystem?</translation>
+    </message>
+    <message>
+        <source>Can not delete default weapon set &apos;%1&apos;!</source>
+        <translation>Kan ikke slette standardvåbensættet &apos;%1&apos;!</translation>
+    </message>
+</context>
+<context>
+    <name>QObject</name>
+    <message>
+        <source>Error</source>
+        <translation>Fejl</translation>
+    </message>
+    <message>
+        <source>Cannot create directory %1</source>
+        <translation>Kan ikke oprette mappe %1</translation>
+    </message>
+    <message>
+        <source>OK</source>
+        <translation>OK</translation>
+    </message>
+    <message>
+        <source>Nickname</source>
+        <translation>Brugernavn</translation>
+    </message>
+    <message>
+        <source>Please enter your nickname</source>
+        <translation>Indtast venligst dit brugernavn</translation>
+    </message>
+</context>
+<context>
+    <name>QPushButton</name>
+    <message>
+        <source>default</source>
+        <translation>standard</translation>
+    </message>
+    <message>
+        <source>OK</source>
+        <translation>OK</translation>
+    </message>
+    <message>
+        <source>Cancel</source>
+        <translation>Annuler</translation>
+    </message>
+    <message>
+        <source>Start server</source>
+        <translation>Start server</translation>
+    </message>
+    <message>
+        <source>Connect</source>
+        <translation>Opretter forbindelse</translation>
+    </message>
+    <message>
+        <source>Update</source>
+        <translation>Opdater</translation>
+    </message>
+    <message>
+        <source>Specify</source>
+        <translation>Specificer</translation>
+    </message>
+    <message>
+        <source>Start</source>
+        <translation>Start</translation>
+    </message>
+    <message>
+        <source>Go!</source>
+        <translation>I gang!</translation>
+    </message>
+    <message>
+        <source>Play demo</source>
+        <translation>Afspil demo</translation>
+    </message>
+    <message>
+        <source>Rename</source>
+        <translation>Omdøb</translation>
+    </message>
+    <message>
+        <source>Delete</source>
+        <translation>Slet</translation>
+    </message>
+    <message>
+        <source>Load</source>
+        <translation>Indlæs</translation>
+    </message>
+    <message>
+        <source>Setup</source>
+        <translation>Indstillinger</translation>
+    </message>
+    <message>
+        <source>Ready</source>
+        <translation>Klar</translation>
+    </message>
+    <message>
+        <source>Random Team</source>
+        <translation>Tilfældige Hold</translation>
+    </message>
+    <message>
+        <source>Associate file extensions</source>
+        <translation>Tilknyt filtyper</translation>
+    </message>
+    <message>
+        <source>more</source>
+        <translation>mere</translation>
+    </message>
+</context>
+<context>
+    <name>QTableWidget</name>
+    <message>
+        <source>Room Name</source>
+        <translation>Navn på Rum</translation>
+    </message>
+    <message>
+        <source>C</source>
+        <translation>C</translation>
+    </message>
+    <message>
+        <source>T</source>
+        <translation>T</translation>
+    </message>
+    <message>
+        <source>Owner</source>
+        <translation>Ejer</translation>
+    </message>
+    <message>
+        <source>Map</source>
+        <translation>Bane</translation>
+    </message>
+    <message>
+        <source>Rules</source>
+        <translation>Regler</translation>
+    </message>
+    <message>
+        <source>Weapons</source>
+        <translation>Våben</translation>
+    </message>
+</context>
+<context>
+    <name>SelWeaponWidget</name>
+    <message>
+        <source>Weapon set</source>
+        <translation>Våbensæt</translation>
+    </message>
+    <message>
+        <source>Probabilities</source>
+        <translation>Sandsynligheder</translation>
+    </message>
+    <message>
+        <source>Ammo in boxes</source>
+        <translation>Ammunition i bokse</translation>
+    </message>
+    <message>
+        <source>Delays</source>
+        <translation>Forsinkelser</translation>
+    </message>
+    <message>
+        <source>new</source>
+        <translation>ny</translation>
+    </message>
+    <message>
+        <source>copy of</source>
+        <translation>kopi af</translation>
+    </message>
+</context>
+<context>
+    <name>TCPBase</name>
+    <message>
+        <source>Error</source>
+        <translation>Fejl</translation>
+    </message>
+    <message>
+        <source>Unable to start the server: %1.</source>
+        <translation>Ude af stand til at starte serveren: %1.</translation>
+    </message>
+    <message>
+        <source>Unable to run engine: %1 (</source>
+        <translation>Ude af stand til at starte spilmotoren: %1 (</translation>
+    </message>
+</context>
+<context>
+    <name>ToggleButtonWidget</name>
+    <message>
+        <source>Vampirism</source>
+        <translation>Vampyr</translation>
+    </message>
+    <message>
+        <source>Karma</source>
+        <translation>Karma</translation>
+    </message>
+    <message>
+        <source>Artillery</source>
+        <translation>Artilleri</translation>
+    </message>
+    <message>
+        <source>Fort Mode</source>
+        <translation>Brug Forter</translation>
+    </message>
+    <message>
+        <source>Divide Teams</source>
+        <translation>Opdel Hold</translation>
+    </message>
+    <message>
+        <source>Solid Land</source>
+        <translation>Fastland</translation>
+    </message>
+    <message>
+        <source>Add Border</source>
+        <translation>Tilføj Kant</translation>
+    </message>
+    <message>
+        <source>Low Gravity</source>
+        <translation>Svag Tyngdekraft</translation>
+    </message>
+    <message>
+        <source>Laser Sight</source>
+        <translation>Lasersigte</translation>
+    </message>
+    <message>
+        <source>Invulnerable</source>
+        <translation>Udødelighed</translation>
+    </message>
+    <message>
+        <source>Add Mines</source>
+        <translation>Tilføj Miner</translation>
+    </message>
+    <message>
+        <source>Random Order</source>
+        <translation>Tilfældig Rækkefølge</translation>
+    </message>
+    <message>
+        <source>King</source>
+        <translation>Konge</translation>
+    </message>
+    <message>
+        <source>Place Hedgehogs</source>
+        <translation>Placer Pindsvin</translation>
+    </message>
+    <message>
+        <source>Clan Shares Ammo</source>
+        <translation>Klan Deler Ammunition</translation>
+    </message>
+    <message>
+        <source>Disable Girders</source>
+        <translation>Deaktiver Bærebjælker</translation>
+    </message>
+    <message>
+        <source>Disable Land Objects</source>
+        <translation>Deaktiver Overfladeobjekter</translation>
+    </message>
+    <message>
+        <source>AI Survival Mode</source>
+        <translation>AI Overlevelse</translation>
+    </message>
+    <message>
+        <source>Reset Health</source>
+        <translation>Nulstil Liv</translation>
+    </message>
+    <message>
+        <source>Unlimited Attacks</source>
+        <translation>Uendelige Angreb</translation>
+    </message>
+    <message>
+        <source>Reset Weapons</source>
+        <translation>Nulstil Våben</translation>
+    </message>
+    <message>
+        <source>Per Hedgehog Ammo</source>
+        <translation>Indivuel Ammunition per Pindsvin</translation>
+    </message>
+    <message>
+        <source>Disable Wind</source>
+        <translation>Deaktiver Vind</translation>
+    </message>
+    <message>
+        <source>More Wind</source>
+        <translation>Mere Vind</translation>
+    </message>
+    <message>
+        <source>Tag Team</source>
+        <translation>Tagteam</translation>
+    </message>
+    <message>
+        <source>Add Bottom Border</source>
+        <translation>Tilføj Kant i Bunden</translation>
+    </message>
+</context>
+<context>
+    <name>binds</name>
+    <message>
+        <source>up</source>
+        <translation>op</translation>
+    </message>
+    <message>
+        <source>left</source>
+        <translation>venstre</translation>
+    </message>
+    <message>
+        <source>right</source>
+        <translation>højre</translation>
+    </message>
+    <message>
+        <source>down</source>
+        <translation>ned</translation>
+    </message>
+    <message>
+        <source>attack</source>
+        <translation>angrib</translation>
+    </message>
+    <message>
+        <source>precise aim</source>
+        <translation>sigt præcist</translation>
+    </message>
+    <message>
+        <source>put</source>
+        <translation>læg</translation>
+    </message>
+    <message>
+        <source>switch</source>
+        <translation>skift</translation>
+    </message>
+    <message>
+        <source>find hedgehog</source>
+        <translation>find pindsvin</translation>
+    </message>
+    <message>
+        <source>ammo menu</source>
+        <translation>ammunitionsmenu</translation>
+    </message>
+    <message>
+        <source>slot 1</source>
+        <translation>åbning 1</translation>
+    </message>
+    <message>
+        <source>slot 2</source>
+        <translation>åbning 2</translation>
+    </message>
+    <message>
+        <source>slot 3</source>
+        <translation>åbning 3</translation>
+    </message>
+    <message>
+        <source>slot 4</source>
+        <translation>åbning 4</translation>
+    </message>
+    <message>
+        <source>slot 5</source>
+        <translation>åbning 5</translation>
+    </message>
+    <message>
+        <source>slot 6</source>
+        <translation>åbning 6</translation>
+    </message>
+    <message>
+        <source>slot 7</source>
+        <translation>åbning 7</translation>
+    </message>
+    <message>
+        <source>slot 8</source>
+        <translation>åbning 8</translation>
+    </message>
+    <message>
+        <source>slot 9</source>
+        <translation>åbning 9</translation>
+    </message>
+    <message>
+        <source>timer 1 sec</source>
+        <translation>timer 1 sekund</translation>
+    </message>
+    <message>
+        <source>timer 2 sec</source>
+        <translation>timer 2 sekunder</translation>
+    </message>
+    <message>
+        <source>timer 3 sec</source>
+        <translation>timer 3 sekunder</translation>
+    </message>
+    <message>
+        <source>timer 4 sec</source>
+        <translation>timer 4 sekunder</translation>
+    </message>
+    <message>
+        <source>timer 5 sec</source>
+        <translation>timer 5 sekunder</translation>
+    </message>
+    <message>
+        <source>chat</source>
+        <translation>chat</translation>
+    </message>
+    <message>
+        <source>chat history</source>
+        <translation>chathistorie</translation>
+    </message>
+    <message>
+        <source>pause</source>
+        <translation>pause</translation>
+    </message>
+    <message>
+        <source>confirmation</source>
+        <translation>bekræftelse</translation>
+    </message>
+    <message>
+        <source>volume down</source>
+        <translation>lydstyrke ned</translation>
+    </message>
+    <message>
+        <source>volume up</source>
+        <translation>lydstyrke op</translation>
+    </message>
+    <message>
+        <source>change mode</source>
+        <translation>ændre tilstand</translation>
+    </message>
+    <message>
+        <source>capture</source>
+        <translation>fang</translation>
+    </message>
+    <message>
+        <source>hedgehogs
+info</source>
+        <translation>pindsvin
+info</translation>
+    </message>
+    <message>
+        <source>quit</source>
+        <translation>afslut</translation>
+    </message>
+    <message>
+        <source>zoom in</source>
+        <translation>zoom ind</translation>
+    </message>
+    <message>
+        <source>zoom out</source>
+        <translation>zoom ud</translation>
+    </message>
+    <message>
+        <source>reset zoom</source>
+        <translation>nulstil zoom</translation>
+    </message>
+    <message>
+        <source>long jump</source>
+        <translation>langt hop</translation>
+    </message>
+    <message>
+        <source>high jump</source>
+        <translation>højt hop</translation>
+    </message>
+    <message>
+        <source>slot 10</source>
+        <translation>åbning 10</translation>
+    </message>
+</context>
+<context>
+    <name>binds (categories)</name>
+    <message>
+        <source>Basic controls</source>
+        <translation>Grundlæggende styring</translation>
+    </message>
+    <message>
+        <source>Weapon controls</source>
+        <translation>Våbenstyring</translation>
+    </message>
+    <message>
+        <source>Camera and cursor controls</source>
+        <translation>Kamera og musestyring</translation>
+    </message>
+    <message>
+        <source>Other</source>
+        <translation>Andet</translation>
+    </message>
+</context>
+<context>
+    <name>binds (descriptions)</name>
+    <message>
+        <source>Move your hogs and aim:</source>
+        <translation>Bevæg dine pindsvin og sigt:</translation>
+    </message>
+    <message>
+        <source>Traverse gaps and obstacles by jumping:</source>
+        <translation>Hop over sprækker og forhinderinger:</translation>
+    </message>
+    <message>
+        <source>Fire your selected weapon or trigger an utility item:</source>
+        <translation>Affyr dit valgte våben eller udløs en hjælpeting:</translation>
+    </message>
+    <message>
+        <source>Pick a weapon or a target location under the cursor:</source>
+        <translation>Vælg et våben eller en målplacering under musemarkøren:</translation>
+    </message>
+    <message>
+        <source>Switch your currently active hog (if possible):</source>
+        <translation>Skift til et anden pindsvin (om muligt):</translation>
+    </message>
+    <message>
+        <source>Pick a weapon or utility item:</source>
+        <translation>Vælg et våben eller en hjælpeting:</translation>
+    </message>
+    <message>
+        <source>Set the timer on bombs and timed weapons:</source>
+        <translation>Indstil timeren på bomber eller tidsafhængige våben:</translation>
+    </message>
+    <message>
+        <source>Move the camera to the active hog:</source>
+        <translation>Flyt kameraet hen til det aktive pindsvin:</translation>
+    </message>
+    <message>
+        <source>Move the cursor or camera without using the mouse:</source>
+        <translation>Flyt musemarkøren eller kameraet uden at bruge musen:</translation>
+    </message>
+    <message>
+        <source>Modify the camera&apos;s zoom level:</source>
+        <translation>Ændr på kameraets zoom-niveau:</translation>
+    </message>
+    <message>
+        <source>Talk to your team or all participants:</source>
+        <translation>Tal til dit hold eller alle deltagere:</translation>
+    </message>
+    <message>
+        <source>Pause, continue or leave your game:</source>
+        <translation>Pause, fortsæt eller forlad spillet:</translation>
+    </message>
+    <message>
+        <source>Modify the game&apos;s volume while playing:</source>
+        <translation>Ændr på lydstyrken mens du spiller:</translation>
+    </message>
+    <message>
+        <source>Toggle fullscreen mode:</source>
+        <translation>Skift fra og til fuldskærm:</translation>
+    </message>
+    <message>
+        <source>Take a screenshot:</source>
+        <translation>Tag et skærmbillede:</translation>
+    </message>
+    <message>
+        <source>Toggle labels above hedgehogs:</source>
+        <translation>Slå mærkater over pindsvin fra og til:</translation>
+    </message>
+</context>
+<context>
+    <name>binds (keys)</name>
+    <message>
+        <source>Axis</source>
+        <translation>Akse</translation>
+    </message>
+    <message>
+        <source>(Up)</source>
+        <translation>(Op)</translation>
+    </message>
+    <message>
+        <source>(Down)</source>
+        <translation>(Ned)</translation>
+    </message>
+    <message>
+        <source>Hat</source>
+        <translation>Hat</translation>
+    </message>
+    <message>
+        <source>(Left)</source>
+        <translation>(Venstre)</translation>
+    </message>
+    <message>
+        <source>(Right)</source>
+        <translation>(Højre)</translation>
+    </message>
+    <message>
+        <source>Button</source>
+        <translation>Knap</translation>
+    </message>
+    <message>
+        <source>Keyboard</source>
+        <translation>Tastatur</translation>
+    </message>
+    <message>
+        <source>Delete</source>
+        <translation>Slet</translation>
+    </message>
+    <message>
+        <source>Mouse: Left button</source>
+        <translation>Mus: Venstre knap</translation>
+    </message>
+    <message>
+        <source>Mouse: Middle button</source>
+        <translation>Mus: Midterknap</translation>
+    </message>
+    <message>
+        <source>Mouse: Right button</source>
+        <translation>Mus: Højre knap</translation>
+    </message>
+    <message>
+        <source>Mouse: Wheel up</source>
+        <translation>Mus: Hjul opad</translation>
+    </message>
+    <message>
+        <source>Mouse: Wheel down</source>
+        <translation>Mus: Hjul nedad</translation>
+    </message>
+    <message>
+        <source>Backspace</source>
+        <translation>Tilbageknap</translation>
+    </message>
+    <message>
+        <source>Tab</source>
+        <translation>Tab-knap</translation>
+    </message>
+    <message>
+        <source>Clear</source>
+        <translation>Ryd</translation>
+    </message>
+    <message>
+        <source>Return</source>
+        <translation>Enter</translation>
+    </message>
+    <message>
+        <source>Pause</source>
+        <translation>Pause</translation>
+    </message>
+    <message>
+        <source>Escape</source>
+        <translation>Escape</translation>
+    </message>
+    <message>
+        <source>Space</source>
+        <translation>Mellemrumstast</translation>
+    </message>
+    <message>
+        <source>Numpad 0</source>
+        <translation>Numpad 0</translation>
+    </message>
+    <message>
+        <source>Numpad 1</source>
+        <translation>Numpad 1</translation>
+    </message>
+    <message>
+        <source>Numpad 2</source>
+        <translation>Numpad 2</translation>
+    </message>
+    <message>
+        <source>Numpad 3</source>
+        <translation>Numpad 3</translation>
+    </message>
+    <message>
+        <source>Numpad 4</source>
+        <translation>Numpad 4</translation>
+    </message>
+    <message>
+        <source>Numpad 5</source>
+        <translation>Numpad 5</translation>
+    </message>
+    <message>
+        <source>Numpad 6</source>
+        <translation>Numpad 6</translation>
+    </message>
+    <message>
+        <source>Numpad 7</source>
+        <translation>Numpad 7</translation>
+    </message>
+    <message>
+        <source>Numpad 8</source>
+        <translation>Numpad 8</translation>
+    </message>
+    <message>
+        <source>Numpad 9</source>
+        <translation>Numpad 9</translation>
+    </message>
+    <message>
+        <source>Numpad .</source>
+        <translation>Numpad .</translation>
+    </message>
+    <message>
+        <source>Numpad /</source>
+        <translation>Numpad /</translation>
+    </message>
+    <message>
+        <source>Numpad *</source>
+        <translation>Numpad *</translation>
+    </message>
+    <message>
+        <source>Numpad -</source>
+        <translation>Numpad -</translation>
+    </message>
+    <message>
+        <source>Numpad +</source>
+        <translation>Numpad +</translation>
+    </message>
+    <message>
+        <source>Enter</source>
+        <translation>Enter</translation>
+    </message>
+    <message>
+        <source>Equals</source>
+        <translation>Lig</translation>
+    </message>
+    <message>
+        <source>Up</source>
+        <translation>Op</translation>
+    </message>
+    <message>
+        <source>Down</source>
+        <translation>Ned</translation>
+    </message>
+    <message>
+        <source>Right</source>
+        <translation>Højre</translation>
+    </message>
+    <message>
+        <source>Left</source>
+        <translation>Venstre</translation>
+    </message>
+    <message>
+        <source>Insert</source>
+        <translation>Insert</translation>
+    </message>
+    <message>
+        <source>Home</source>
+        <translation>Home</translation>
+    </message>
+    <message>
+        <source>End</source>
+        <translation>End</translation>
+    </message>
+    <message>
+        <source>Page up</source>
+        <translation>Page up</translation>
+    </message>
+    <message>
+        <source>Page down</source>
+        <translation>Page down</translation>
+    </message>
+    <message>
+        <source>Num lock</source>
+        <translation>Num lock</translation>
+    </message>
+    <message>
+        <source>Caps lock</source>
+        <translation>Caps lock</translation>
+    </message>
+    <message>
+        <source>Scroll lock</source>
+        <translation>Scroll lock</translation>
+    </message>
+    <message>
+        <source>Right shift</source>
+        <translation>Højre shift</translation>
+    </message>
+    <message>
+        <source>Left shift</source>
+        <translation>Venstre shift</translation>
+    </message>
+    <message>
+        <source>Right ctrl</source>
+        <translation>Højre ctrl</translation>
+    </message>
+    <message>
+        <source>Left ctrl</source>
+        <translation>Venstre ctrl</translation>
+    </message>
+    <message>
+        <source>Right alt</source>
+        <translation>Højre alt</translation>
+    </message>
+    <message>
+        <source>Left alt</source>
+        <translation>Venstre alt</translation>
+    </message>
+    <message>
+        <source>Right meta</source>
+        <translation>Højre meta</translation>
+    </message>
+    <message>
+        <source>Left meta</source>
+        <translation>Venstre meta</translation>
+    </message>
+    <message>
+        <source>A button</source>
+        <translation>A-knap</translation>
+    </message>
+    <message>
+        <source>B button</source>
+        <translation>B-knap</translation>
+    </message>
+    <message>
+        <source>X button</source>
+        <translation>X-knap</translation>
+    </message>
+    <message>
+        <source>Y button</source>
+        <translation>Y-knap</translation>
+    </message>
+    <message>
+        <source>LB button</source>
+        <translation>LB-knap</translation>
+    </message>
+    <message>
+        <source>RB button</source>
+        <translation>RB-knap</translation>
+    </message>
+    <message>
+        <source>Back button</source>
+        <translation>Back-knap</translation>
+    </message>
+    <message>
+        <source>Start button</source>
+        <translation>Start-knap</translation>
+    </message>
+    <message>
+        <source>Left stick</source>
+        <translation>Venstre stick</translation>
+    </message>
+    <message>
+        <source>Right stick</source>
+        <translation>Højre stick</translation>
+    </message>
+    <message>
+        <source>Left stick (Right)</source>
+        <translation>Venstre stick (Højre)</translation>
+    </message>
+    <message>
+        <source>Left stick (Left)</source>
+        <translation>Venstre stick (Venstre)</translation>
+    </message>
+    <message>
+        <source>Left stick (Down)</source>
+        <translation>Venstre stick (Ned)</translation>
+    </message>
+    <message>
+        <source>Left stick (Up)</source>
+        <translation>Venstre stick (Op)</translation>
+    </message>
+    <message>
+        <source>Left trigger</source>
+        <translation>Venstre affyringsknap</translation>
+    </message>
+    <message>
+        <source>Right trigger</source>
+        <translation>Højre affyringsknap</translation>
+    </message>
+    <message>
+        <source>Right stick (Down)</source>
+        <translation>Højre stick (Ned)</translation>
+    </message>
+    <message>
+        <source>Right stick (Up)</source>
+        <translation>Højre stick (Op)</translation>
+    </message>
+    <message>
+        <source>Right stick (Right)</source>
+        <translation>Højre stick (Højre)</translation>
+    </message>
+    <message>
+        <source>Right stick (Left)</source>
+        <translation>Højre stick (Venstre)</translation>
+    </message>
+    <message>
+        <source>DPad</source>
+        <translation>DPad</translation>
+    </message>
+</context>
+</TS>
--- a/share/hedgewars/Data/Locale/hedgewars_sk.ts	Mon Nov 28 06:55:55 2011 +0100
+++ b/share/hedgewars/Data/Locale/hedgewars_sk.ts	Mon Dec 05 18:38:25 2011 -0500
@@ -70,7 +70,7 @@
     </message>
     <message>
         <source>Game Options</source>
-        <translation type="unfinished">Voľby hry</translation>
+        <translation>Voľby hry</translation>
     </message>
 </context>
 <context>
@@ -93,51 +93,51 @@
     </message>
     <message>
         <source>%1 has been removed from your ignore list</source>
-        <translation type="unfinished"></translation>
+        <translation>%1 bol odstránený zo zoznamu ignorovaných</translation>
     </message>
     <message>
         <source>%1 has been added to your ignore list</source>
-        <translation type="unfinished"></translation>
+        <translation>%1 bol pridaný na zoznam ignorovaných</translation>
     </message>
     <message>
         <source>%1 has been removed from your friends list</source>
-        <translation type="unfinished"></translation>
+        <translation>%1 bol odstránený zo zoznamu priateľov</translation>
     </message>
     <message>
         <source>%1 has been added to your friends list</source>
-        <translation type="unfinished"></translation>
+        <translation>%1 bol pridaný do zoznamu priateľov</translation>
     </message>
     <message>
         <source>Stylesheet imported from %1</source>
-        <translation type="unfinished"></translation>
+        <translation>Súbor so štýlom importovaný z %1</translation>
     </message>
     <message>
         <source>Enter %1 if you want to use the current StyleSheet in future, enter %2 to reset!</source>
-        <translation type="unfinished"></translation>
+        <translation>Zadajte %1, ak chcete použiť aktuálny súbor so štýlom v budúcnosti, zadajte %2 pre resetovanie!</translation>
     </message>
     <message>
         <source>Couldn&apos;t read %1</source>
-        <translation type="unfinished"></translation>
+        <translation>Nepodarilo sa prečítať %1</translation>
     </message>
     <message>
         <source>StyleSheet discarded</source>
-        <translation type="unfinished"></translation>
+        <translation>Súbor so štýlom zneplatnený</translation>
     </message>
     <message>
         <source>StyleSheet saved to %1</source>
-        <translation type="unfinished"></translation>
+        <translation>Súbor so štýlom uložený do %1</translation>
     </message>
     <message>
         <source>Failed to save StyleSheet to %1</source>
-        <translation type="unfinished"></translation>
+        <translation>Nepodarilo sa uložiť súbor so štýlom do %1</translation>
     </message>
     <message>
         <source>%1 is not a valid command!</source>
-        <translation type="unfinished"></translation>
+        <translation>%1 nie je platným príkazom!</translation>
     </message>
     <message>
         <source>Kicking %1 ...</source>
-        <translation type="unfinished"></translation>
+        <translation>Vyhadzujem %1...</translation>
     </message>
 </context>
 <context>
@@ -182,26 +182,26 @@
     </message>
     <message>
         <source>Demo name</source>
-        <translation type="unfinished"></translation>
+        <translation>Demo meno</translation>
     </message>
     <message>
         <source>Demo name:</source>
-        <translation type="unfinished"></translation>
+        <translation>Demo meno:</translation>
     </message>
     <message>
         <source>Game aborted</source>
-        <translation type="unfinished"></translation>
+        <translation>Hra zrušená</translation>
     </message>
     <message>
         <source>Password</source>
-        <translation type="unfinished">Heslo</translation>
+        <translation>Heslo</translation>
     </message>
     <message>
         <source>Your nickname %1 is
 registered on Hedgewars.org
 Please provide your password below
 or pick another nickname in game config:</source>
-        <translation type="unfinished">Prezývka %1, ktorú ste
+        <translation>Prezývka %1, ktorú ste
 si vybrali je registrovaná na
 Hedgewars.org.
 Prosím, napíšte heslo do poľa
@@ -210,25 +210,25 @@
     </message>
     <message>
         <source>No password supplied.</source>
-        <translation type="unfinished"></translation>
+        <translation>Nebolo zadané žiadne heslo.</translation>
     </message>
     <message>
         <source>Nickname</source>
-        <translation type="unfinished">Prezývka</translation>
+        <translation>Prezývka</translation>
     </message>
     <message>
         <source>Some one already uses
  your nickname %1
 on the server.
 Please pick another nickname:</source>
-        <translation type="unfinished">Niekto už používa
+        <translation>Niekto už používa
 vašu prezývku %1
 na serveri.
 Prosím vyberte si inú prezývku:</translation>
     </message>
     <message>
         <source>No nickname supplied.</source>
-        <translation type="unfinished"></translation>
+        <translation>Nebola zadaná žiadna prezývka.</translation>
     </message>
 </context>
 <context>
@@ -412,7 +412,7 @@
     </message>
     <message>
         <source>User quit</source>
-        <translation type="unfinished"></translation>
+        <translation>Užívateľ odišiel</translation>
     </message>
 </context>
 <context>
@@ -504,11 +504,11 @@
     </message>
     <message>
         <source>Drawn Maps</source>
-        <translation type="unfinished"></translation>
+        <translation>Kreslené mapy</translation>
     </message>
     <message>
         <source>All files</source>
-        <translation type="unfinished"></translation>
+        <translation>Všetky súbory</translation>
     </message>
 </context>
 <context>
@@ -617,7 +617,7 @@
     <name>PageInGame</name>
     <message>
         <source>In game...</source>
-        <translation type="unfinished"></translation>
+        <translation>Prebieha hra...</translation>
     </message>
 </context>
 <context>
@@ -793,7 +793,7 @@
     <message>
         <source>The Piano Strike is the most damaging air strike. You&apos;ll lose the hedgehog performing it, so there&apos;s a huge downside as well.</source>
         <comment>Tips</comment>
-        <translation>Klavírový útok je najzničujúcejší vzdušný útok. Pri jeho použití prídete o ježka, čo je jeho veľké mínus.</translation>
+        <translation>Klavírový útok je najničivejší vzdušný útok. Pri jeho použití prídete o ježka, čo je jeho veľké mínus.</translation>
     </message>
     <message>
         <source>The Homing Bee can be tricky to use. It&apos;s turn radius depends on it&apos;s velocity, so try to not use full power.</source>
@@ -912,7 +912,7 @@
     </message>
     <message>
         <source>Downloadable Content</source>
-        <translation type="unfinished"></translation>
+        <translation>Stiahnuteľný obsah</translation>
     </message>
 </context>
 <context>
@@ -1306,7 +1306,7 @@
     </message>
     <message>
         <source>Add an indestructible border along the bottom</source>
-        <translation type="unfinished"></translation>
+        <translation>Pridať nezničiteľný okraj popri spodku obrazovky</translation>
     </message>
 </context>
 <context>
@@ -1356,22 +1356,22 @@
     </message>
     <message>
         <source>Campaign Mode (...)</source>
-        <translation type="unfinished"></translation>
+        <translation>Režim kampane (...)</translation>
     </message>
     <message>
         <source>Training Mode (Practice your skills in a range of training missions)</source>
-        <translation type="unfinished"></translation>
+        <translation>Tréningový režim (Vycvičte sa v rade tréningových misií)</translation>
     </message>
 </context>
 <context>
     <name>PageTraining</name>
     <message>
         <source>No description available</source>
-        <translation type="unfinished"></translation>
+        <translation>Žiaden popis nie je dostupný</translation>
     </message>
     <message>
         <source>Select a mission!</source>
-        <translation type="unfinished"></translation>
+        <translation>Vyberte misiu!</translation>
     </message>
 </context>
 <context>
@@ -1893,7 +1893,7 @@
     </message>
     <message>
         <source>This program is distributed under the GNU General Public License v2</source>
-        <translation type="unfinished"></translation>
+        <translation>Tento program je distribuovaný pod licenciou GNU General Public License v2</translation>
     </message>
 </context>
 <context>
@@ -1904,7 +1904,7 @@
     </message>
     <message>
         <source>hedgehog %1</source>
-        <translation type="unfinished"></translation>
+        <translation>ježko %1</translation>
     </message>
 </context>
 <context>
@@ -2268,7 +2268,7 @@
     </message>
     <message>
         <source>Add Bottom Border</source>
-        <translation type="unfinished"></translation>
+        <translation>Pridať spodný okraj</translation>
     </message>
 </context>
 <context>
--- a/share/hedgewars/Data/Locale/it.txt	Mon Nov 28 06:55:55 2011 +0100
+++ b/share/hedgewars/Data/Locale/it.txt	Mon Dec 05 18:38:25 2011 -0500
@@ -324,7 +324,7 @@
 02:08=%1 adotta una nuova strategia
 02:08=%1 preferisce rimanere neutrale
 02:08=%1 ha alzato la bandiera bianca
-02:08=%Che vergogna!
+02:08=Che vergogna %1!
 02:08=Se ci fosse stato Chuck Norris dietro di te, ti avrebbe preso a calci volanti
 02:08=%1 pensava troppo alle donnine nude
 
--- a/share/hedgewars/Data/Scripts/plist/Gaudy Racer.plist	Mon Nov 28 06:55:55 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>command</key>
-	<string>escript Scripts/Multiplayer/GaudyRacer.lua</string>
-	<key>description</key>
-	<string></string>
-	<key>scheme</key>
-	<string>Default.plist</string>
-	<key>weapon</key>
-	<string>Default.plist</string>
-</dict>
-</plist>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Scripts/plist/Highlander.plist	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>command</key>
+	<string>escript Scripts/Multiplayer/Highlander.lua</string>
+	<key>description</key>
+	<string></string>
+	<key>scheme</key>
+	<string>Default.plist</string>
+	<key>weapon</key>
+	<string>Default.plist</string>
+</dict>
+</plist>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Scripts/plist/Racer.plist	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>command</key>
+	<string>escript Scripts/Multiplayer/Racer.lua</string>
+	<key>description</key>
+	<string></string>
+	<key>scheme</key>
+	<string>Shoppa.plist</string>
+	<key>weapon</key>
+	<string>Shoppa.plist</string>
+</dict>
+</plist>
--- a/tools/PascalBasics.hs	Mon Nov 28 06:55:55 2011 +0100
+++ b/tools/PascalBasics.hs	Mon Dec 05 18:38:25 2011 -0500
@@ -8,7 +8,7 @@
 import Text.Parsec.Language
 import Data.Char
 
-builtin = ["succ", "pred", "low", "high"]
+builtin = ["succ", "pred", "low", "high", "ord"]
     
 pascalLanguageDef
     = emptyDef
@@ -25,7 +25,7 @@
             , "type", "var", "const", "out", "array", "packed"
             , "procedure", "function", "with", "for", "to"
             , "downto", "div", "mod", "record", "set", "nil"
-            , "string", "shortstring", "cdecl", "external"
+            , "string", "cdecl", "external", "if", "then", "else"
             ] ++ builtin
     , reservedOpNames= [] 
     , caseSensitive  = False   
--- a/tools/PascalParser.hs	Mon Nov 28 06:55:55 2011 +0100
+++ b/tools/PascalParser.hs	Mon Dec 05 18:38:25 2011 -0500
@@ -12,89 +12,9 @@
 import Data.Maybe
 
 import PascalBasics
-
-data PascalUnit =
-    Program Identifier Implementation Phrase
-    | Unit Identifier Interface Implementation (Maybe Initialize) (Maybe Finalize)
-    deriving Show
-data Interface = Interface Uses TypesAndVars
-    deriving Show
-data Implementation = Implementation Uses TypesAndVars
-    deriving Show
-data Identifier = Identifier String
-    deriving Show
-data TypesAndVars = TypesAndVars [TypeVarDeclaration]
-    deriving Show
-data TypeVarDeclaration = TypeDeclaration Identifier TypeDecl
-    | VarDeclaration Bool ([Identifier], TypeDecl) (Maybe InitExpression)
-    | FunctionDeclaration Identifier TypeDecl [TypeVarDeclaration] (Maybe (TypesAndVars, Phrase))
-    | OperatorDeclaration String Identifier TypeDecl [TypeVarDeclaration] (Maybe (TypesAndVars, Phrase))
-    deriving Show
-data TypeDecl = SimpleType Identifier
-    | RangeType Range
-    | Sequence [Identifier]
-    | ArrayDecl (Maybe Range) TypeDecl
-    | RecordType [TypeVarDeclaration] (Maybe [[TypeVarDeclaration]])
-    | PointerTo TypeDecl
-    | String Integer
-    | Set TypeDecl
-    | FunctionType TypeDecl [TypeVarDeclaration]
-    | UnknownType
-    deriving Show
-data Range = Range Identifier
-           | RangeFromTo InitExpression InitExpression
-    deriving Show
-data Initialize = Initialize String
-    deriving Show
-data Finalize = Finalize String
-    deriving Show
-data Uses = Uses [Identifier]
-    deriving Show
-data Phrase = ProcCall Identifier [Expression]
-        | IfThenElse Expression Phrase (Maybe Phrase)
-        | WhileCycle Expression Phrase
-        | RepeatCycle Expression [Phrase]
-        | ForCycle Identifier Expression Expression Phrase
-        | WithBlock Reference Phrase
-        | Phrases [Phrase]
-        | SwitchCase Expression [([Expression], Phrase)] (Maybe Phrase)
-        | Assignment Reference Expression
-    deriving Show
-data Expression = Expression String
-    | BuiltInFunCall [Expression] Reference
-    | PrefixOp String Expression
-    | PostfixOp String Expression
-    | BinOp String Expression Expression
-    | StringLiteral String
-    | CharCode String
-    | HexCharCode String
-    | NumberLiteral String
-    | FloatLiteral String
-    | HexNumber String
-    | Reference Reference
-    | Null
-    deriving Show
-data Reference = ArrayElement [Expression] Reference
-    | FunCall [Expression] Reference
-    | SimpleReference Identifier
-    | Dereference Reference
-    | RecordField Reference Reference
-    | Address Reference
-    deriving Show
-data InitExpression = InitBinOp String InitExpression InitExpression
-    | InitPrefixOp String InitExpression
-    | InitReference Identifier
-    | InitArray [InitExpression]
-    | InitRecord [(Identifier, InitExpression)]
-    | InitFloat String
-    | InitNumber String
-    | InitHexNumber String
-    | InitString String
-    | InitChar String
-    | BuiltInFunction String [InitExpression]
-    | InitSet [Identifier]
-    | InitNull
-    deriving Show
+import PascalUnitSyntaxTree
+    
+knownTypes = ["shortstring", "char", "byte"]
 
 pascalUnit = do
     comments
@@ -103,7 +23,7 @@
     return u
 
 iD = do
-    i <- liftM Identifier (identifier pas)
+    i <- liftM (flip Identifier Unknown) (identifier pas)
     comments
     return i
         
@@ -121,13 +41,13 @@
 reference = buildExpressionParser table term <?> "reference"
     where
     term = comments >> choice [
-        parens pas (reference >>= postfixes) >>= postfixes
-        , char '@' >> reference >>= postfixes >>= return . Address
+        parens pas (liftM RefExpression expression >>= postfixes) >>= postfixes
+        , try $ typeCast >>= postfixes
+        , char '@' >> liftM Address reference >>= postfixes
         , liftM SimpleReference iD >>= postfixes 
         ] <?> "simple reference"
 
     table = [ 
-            [Infix (try (char '.' >> notFollowedBy (char '.')) >> return RecordField) AssocLeft]
         ]
     
     postfixes r = many postfix >>= return . foldl (flip ($)) r
@@ -135,8 +55,15 @@
             parens pas (option [] parameters) >>= return . FunCall
           , char '^' >> return Dereference
           , (brackets pas) (commaSep1 pas $ expression) >>= return . ArrayElement
+          , (char '.' >> notFollowedBy (char '.')) >> liftM (flip RecordField) reference
         ]
 
+    typeCast = do
+        t <- choice $ map (\s -> try $ caseInsensitiveString s >>= \i -> notFollowedBy alphaNum >> return i) knownTypes
+        e <- parens pas expression
+        comments
+        return $ TypeCast (Identifier t Unknown) e
+        
     
 varsDecl1 = varsParser sepEndBy1    
 varsDecl = varsParser sepEndBy
@@ -197,7 +124,7 @@
     , setDecl
     , functionType
     , sequenceDecl >>= return . Sequence
-    , try (identifier pas) >>= return . SimpleType . Identifier
+    , try iD >>= return . SimpleType
     , rangeDecl >>= return . RangeType
     ] <?> "type declaration"
     where
@@ -281,6 +208,7 @@
         semi pas
         comments
         return $ TypeDeclaration i t
+
         
 rangeDecl = choice [
     try $ rangeft
@@ -291,7 +219,7 @@
     e1 <- initExpression
     string ".."
     e2 <- initExpression
-    return $ RangeFromTo e1 e2
+    return $ RangeFromTo e1 e2        
     
 typeVarDeclaration isImpl = (liftM concat . many . choice) [
     varSection,
@@ -373,8 +301,10 @@
         
     functionDecorator = choice [
         try $ string "inline;"
-        , try $ string "cdecl;"
+        , try $ caseInsensitiveString "cdecl;"
         , try $ string "overload;"
+        , try $ string "export;"
+        , try $ string "varargs;"
         , try (string "external") >> comments >> iD >> optional (string "name" >> comments >> stringLiteral pas)>> string ";"
         ] >> comments
         
@@ -418,17 +348,19 @@
 expression = buildExpressionParser table term <?> "expression"
     where
     term = comments >> choice [
-        builtInFunction expression >>= \(n, e) -> return $ BuiltInFunCall e (SimpleReference (Identifier n))
-        , parens pas $ expression 
+        builtInFunction expression >>= \(n, e) -> return $ BuiltInFunCall e (SimpleReference (Identifier n Unknown))
+        , try (parens pas $ expression >>= \e -> notFollowedBy (comments >> char '.') >> return e)
+        , brackets pas (commaSep pas iD) >>= return . SetExpression
         , try $ natural pas >>= \i -> notFollowedBy (char '.') >> (return . NumberLiteral . show) i
-        , try $ float pas >>= return . FloatLiteral . show
-        , try $ natural pas >>= return . NumberLiteral . show
+        , float pas >>= return . FloatLiteral . show
+        , natural pas >>= return . NumberLiteral . show
         , stringLiteral pas >>= return . StringLiteral
         , try (string "#$") >> many hexDigit >>= \c -> comments >> return (HexCharCode c)
         , char '#' >> many digit >>= \c -> comments >> return (CharCode c)
         , char '$' >> many hexDigit >>=  \h -> comments >> return (HexNumber h)
         , char '-' >> expression >>= return . PrefixOp "-"
         , try $ string "nil" >> return Null
+        , try $ string "not" >> expression >>= return . PrefixOp "not"
         , reference >>= return . Reference
         ] <?> "simple expression"
 
@@ -437,11 +369,11 @@
            , Infix (char '/' >> return (BinOp "/")) AssocLeft
            , Infix (try (string "div") >> return (BinOp "div")) AssocLeft
            , Infix (try (string "mod") >> return (BinOp "mod")) AssocLeft
+           , Infix (try (string "in") >> return (BinOp "in")) AssocNone
           ]
         , [  Infix (char '+' >> return (BinOp "+")) AssocLeft
            , Infix (char '-' >> return (BinOp "-")) AssocLeft
           ]
-        , [Prefix (try (string "not") >> return (PrefixOp "not"))]
         , [  Infix (try (string "<>") >> return (BinOp "<>")) AssocNone
            , Infix (try (string "<=") >> return (BinOp "<=")) AssocNone
            , Infix (try (string ">=") >> return (BinOp ">=")) AssocNone
@@ -476,6 +408,7 @@
         , forCycle
         , (try $ reference >>= \r -> string ":=" >> return r) >>= \r -> expression >>= return . Assignment r
         , procCall
+        , char ';' >> comments >> return NOP
         ]
     optional $ char ';'
     comments
@@ -493,7 +426,7 @@
     o2 <- optionMaybe $ do
         try $ string "else" >> space
         comments
-        o <- phrase
+        o <- option NOP phrase
         comments
         return o
     return $ IfThenElse e o1 o2
@@ -556,9 +489,9 @@
     comments
     cs <- many1 aCase
     o2 <- optionMaybe $ do
-        try $ string "else"
+        try $ string "else" >> notFollowedBy alphaNum
         comments
-        o <- phrase
+        o <- many phrase
         comments
         return o
     string "end"
@@ -566,7 +499,7 @@
     return $ SwitchCase e cs o2
     where
     aCase = do
-        e <- (commaSep pas) expression
+        e <- (commaSep pas) $ (liftM InitRange rangeDecl <|> initExpression)
         comments
         char ':'
         comments
@@ -575,9 +508,9 @@
         return (e, p)
     
 procCall = do
-    i <- iD
+    r <- reference
     p <- option [] $ (parens pas) parameters
-    return $ ProcCall i p
+    return $ ProcCall r p
 
 parameters = (commaSep pas) expression <?> "parameters"
         
@@ -603,16 +536,18 @@
     where
     term = comments >> choice [
         liftM (uncurry BuiltInFunction) $ builtInFunction initExpression 
-        , try $ brackets pas (commaSep pas $ iD) >>= return . InitSet
+        , try $ brackets pas (commaSep pas $ initExpression) >>= return . InitSet
         , try $ parens pas (commaSep pas $ initExpression) >>= return . InitArray
-        , parens pas (semiSep pas $ recField) >>= return . InitRecord
+        , parens pas (sepEndBy recField (char ';' >> comments)) >>= return . InitRecord
         , try $ integer pas >>= \i -> notFollowedBy (char '.') >> (return . InitNumber . show) i
         , try $ float pas >>= return . InitFloat . show
         , try $ integer pas >>= return . InitNumber . show
         , stringLiteral pas >>= return . InitString
         , char '#' >> many digit >>= \c -> comments >> return (InitChar c)
         , char '$' >> many hexDigit >>= \h -> comments >> return (InitHexNumber h)
+        , char '@' >> initExpression >>= \c -> comments >> return (InitAddress c)
         , try $ string "nil" >> return InitNull
+        , itypeCast
         , iD >>= return . InitReference
         ]
         
@@ -652,6 +587,12 @@
         , [Prefix (try (string "not") >> return (InitPrefixOp "not"))]
         ]
 
+    itypeCast = do
+        t <- choice $ map (\s -> try $ caseInsensitiveString s >>= \i -> notFollowedBy alphaNum >> return i) knownTypes
+        i <- parens pas initExpression
+        comments
+        return $ InitTypeCast (Identifier t Unknown) i
+        
 builtInFunction e = do
     name <- choice $ map (\s -> try $ caseInsensitiveString s >>= \i -> notFollowedBy alphaNum >> return i) builtin
     spaces
--- a/tools/PascalPreprocessor.hs	Mon Nov 28 06:55:55 2011 +0100
+++ b/tools/PascalPreprocessor.hs	Mon Dec 05 18:38:25 2011 -0500
@@ -58,6 +58,7 @@
         s <- choice [
             include
             , ifdef
+            , if'
             , elseSwitch
             , endIf
             , define
@@ -89,10 +90,20 @@
         
         updateState $ \(m, b) ->
             (m, (f $ d `Map.member` m) : b)
-        
       
         return ""
+
+    if' = do
+        s <- try (string "IF" >> notFollowedBy alphaNum)
         
+        manyTill anyChar (char '}')
+        --char '}'
+        
+        updateState $ \(m, b) ->
+            (m, False : b)
+      
+        return ""
+
     elseSwitch = do
         try $ string "ELSE}"
         updateState $ \(m, b:bs) -> (m, (not b):bs)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/PascalUnitSyntaxTree.hs	Mon Dec 05 18:38:25 2011 -0500
@@ -0,0 +1,108 @@
+module PascalUnitSyntaxTree where
+
+import Data.Traversable
+
+data PascalUnit =
+    Program Identifier Implementation Phrase
+    | Unit Identifier Interface Implementation (Maybe Initialize) (Maybe Finalize)
+    | System
+    deriving Show
+data Interface = Interface Uses TypesAndVars
+    deriving Show
+data Implementation = Implementation Uses TypesAndVars
+    deriving Show
+data Identifier = Identifier String BaseType
+    deriving Show
+data TypesAndVars = TypesAndVars [TypeVarDeclaration]
+    deriving Show
+data TypeVarDeclaration = TypeDeclaration Identifier TypeDecl
+    | VarDeclaration Bool ([Identifier], TypeDecl) (Maybe InitExpression)
+    | FunctionDeclaration Identifier TypeDecl [TypeVarDeclaration] (Maybe (TypesAndVars, Phrase))
+    | OperatorDeclaration String Identifier TypeDecl [TypeVarDeclaration] (Maybe (TypesAndVars, Phrase))
+    deriving Show
+data TypeDecl = SimpleType Identifier
+    | RangeType Range
+    | Sequence [Identifier]
+    | ArrayDecl (Maybe Range) TypeDecl
+    | RecordType [TypeVarDeclaration] (Maybe [[TypeVarDeclaration]])
+    | PointerTo TypeDecl
+    | String Integer
+    | Set TypeDecl
+    | FunctionType TypeDecl [TypeVarDeclaration]
+    | UnknownType
+    deriving Show
+data Range = Range Identifier
+           | RangeFromTo InitExpression InitExpression
+    deriving Show
+data Initialize = Initialize String
+    deriving Show
+data Finalize = Finalize String
+    deriving Show
+data Uses = Uses [Identifier]
+    deriving Show
+data Phrase = ProcCall Reference [Expression]
+        | IfThenElse Expression Phrase (Maybe Phrase)
+        | WhileCycle Expression Phrase
+        | RepeatCycle Expression [Phrase]
+        | ForCycle Identifier Expression Expression Phrase
+        | WithBlock Reference Phrase
+        | Phrases [Phrase]
+        | SwitchCase Expression [([InitExpression], Phrase)] (Maybe [Phrase])
+        | Assignment Reference Expression
+        | NOP
+    deriving Show
+data Expression = Expression String
+    | BuiltInFunCall [Expression] Reference
+    | PrefixOp String Expression
+    | PostfixOp String Expression
+    | BinOp String Expression Expression
+    | StringLiteral String
+    | CharCode String
+    | HexCharCode String
+    | NumberLiteral String
+    | FloatLiteral String
+    | HexNumber String
+    | Reference Reference
+    | SetExpression [Identifier]
+    | Null
+    deriving Show
+data Reference = ArrayElement [Expression] Reference
+    | FunCall [Expression] Reference
+    | TypeCast Identifier Expression
+    | SimpleReference Identifier
+    | Dereference Reference
+    | RecordField Reference Reference
+    | Address Reference
+    | RefExpression Expression
+    deriving Show
+data InitExpression = InitBinOp String InitExpression InitExpression
+    | InitPrefixOp String InitExpression
+    | InitReference Identifier
+    | InitArray [InitExpression]
+    | InitRecord [(Identifier, InitExpression)]
+    | InitFloat String
+    | InitNumber String
+    | InitHexNumber String
+    | InitString String
+    | InitChar String
+    | BuiltInFunction String [InitExpression]
+    | InitSet [InitExpression]
+    | InitAddress InitExpression
+    | InitNull
+    | InitRange Range
+    | InitTypeCast Identifier InitExpression
+    deriving Show
+
+data BaseType = Unknown
+    | BTChar
+    | BTString
+    | BTInt
+    | BTRecord
+    | BTArray
+    | BTFunction
+    | BTPointerTo BaseType
+    | BTSet
+    | BTEnum [String]
+    | Void
+    deriving Show
+    
\ No newline at end of file
--- a/tools/pas2c.hs	Mon Nov 28 06:55:55 2011 +0100
+++ b/tools/pas2c.hs	Mon Dec 05 18:38:25 2011 -0500
@@ -1,6 +1,5 @@
 module Pas2C where
 
-import PascalParser
 import Text.PrettyPrint.HughesPJ
 import Data.Maybe
 import Data.Char
@@ -13,26 +12,34 @@
 import Control.Exception
 import System.IO.Error
 import qualified Data.Map as Map
+import Control.Monad.Reader
 
+import PascalParser
+import PascalUnitSyntaxTree
 
 pas2C :: String -> IO ()
 pas2C fn = do
     setCurrentDirectory "../hedgewars/"
-    flip evalStateT initState $ f fn
+    s <- flip execStateT initState $ f fn
+    mapM_ toCFiles (Map.toList s)
     where
     printLn = liftIO . hPutStrLn stderr
+    print = liftIO . hPutStr stderr
     initState = Map.empty
     f :: String -> StateT (Map.Map String PascalUnit) IO ()
     f fileName = do
         processed <- gets $ Map.member fileName
         unless processed $ do
+            print ("Preprocessing '" ++ fileName ++ ".pas'... ")
             fc' <- liftIO 
                 $ tryJust (guard . isDoesNotExistError) 
-                $ hPutStr stderr ("Preprocessing '" ++ fileName ++ ".pas'... ") >> preprocess (fileName ++ ".pas")
+                $ preprocess (fileName ++ ".pas")
             case fc' of
-                (Left a) -> printLn "doesn't exist"
+                (Left a) -> do
+                    modify (Map.insert fileName System)
+                    printLn "doesn't exist"
                 (Right fc) -> do
-                    printLn "ok"
+                    print "ok, parsing... "
                     let ptree = parse pascalUnit fileName fc
                     case ptree of
                          (Left a) -> do
@@ -40,65 +47,90 @@
                             printLn $ show a ++ "\nsee preprocess.out for preprocessed source"
                             fail "stop"
                          (Right a) -> do
+                            printLn "ok"
                             modify (Map.insert fileName a)
                             mapM_ f (usesFiles a)
-                            
-         
-usesFiles :: PascalUnit -> [String]         
+
+toCFiles :: (String, PascalUnit) -> IO ()
+toCFiles (_, System) = return ()
+toCFiles p@(fn, pu) = do
+    hPutStrLn stderr $ "Rendering '" ++ fn ++ "'..."
+    toCFiles' p
+    where
+    toCFiles' (fn, p@(Program {})) = writeFile (fn ++ ".c") $ (render2C . pascal2C) p
+    toCFiles' (fn, (Unit _ interface implementation _ _)) = do
+        writeFile (fn ++ ".h") $ "#pragma once\n" ++ (render2C . interface2C $ interface)
+        writeFile (fn ++ ".c") $ (render2C . implementation2C) implementation
+
+system :: [(String, String)]
+system = []
+        
+render2C = render . flip runReader system
+
+usesFiles :: PascalUnit -> [String]
 usesFiles (Program _ (Implementation uses _) _) = uses2List uses
 usesFiles (Unit _ (Interface uses1 _) (Implementation uses2 _) _ _) = uses2List uses1 ++ uses2List uses2
 
 
 
-pascal2C :: PascalUnit -> Doc
-pascal2C (Unit unitName interface implementation init fin) = 
-    interface2C interface
-    $+$ 
-    implementation2C implementation
-pascal2C (Program _ implementation mainFunction) =
-    implementation2C implementation
-    $+$
-    tvar2C (FunctionDeclaration (Identifier "main") (SimpleType $ Identifier "int") [] (Just (TypesAndVars [], mainFunction)))
-interface2C :: Interface -> Doc
-interface2C (Interface uses tvars) = uses2C uses $+$ typesAndVars2C tvars
+pascal2C :: PascalUnit -> Reader a Doc
+pascal2C (Unit _ interface implementation init fin) =
+    liftM2 ($+$) (interface2C interface) (implementation2C implementation)
+    
+pascal2C (Program _ implementation mainFunction) = do
+    impl <- implementation2C implementation
+    main <- tvar2C True 
+        (FunctionDeclaration (Identifier "main" BTInt) (SimpleType $ Identifier "int" BTInt) [] (Just (TypesAndVars [], mainFunction)))
+    return $ impl $+$ main
 
-implementation2C :: Implementation -> Doc
-implementation2C (Implementation uses tvars) = uses2C uses $+$ typesAndVars2C tvars
+    
+    
+interface2C :: Interface -> Reader a Doc
+interface2C (Interface uses tvars) = liftM2 ($+$) (uses2C uses) (typesAndVars2C True tvars)
+
+implementation2C :: Implementation -> Reader a Doc
+implementation2C (Implementation uses tvars) = liftM2 ($+$) (uses2C uses) (typesAndVars2C True tvars)
 
 
-typesAndVars2C :: TypesAndVars -> Doc
-typesAndVars2C (TypesAndVars ts) = vcat $ map tvar2C ts
+typesAndVars2C :: Bool -> TypesAndVars -> Reader a Doc
+typesAndVars2C b (TypesAndVars ts) = liftM vcat $ mapM (tvar2C b) ts
 
-uses2C :: Uses -> Doc
-uses2C uses = vcat $ map (\i -> text $ "#include \"" ++ i ++ ".h\"") $ uses2List uses
+uses2C :: Uses -> Reader a Doc
+uses2C uses = return $ vcat . map (\i -> text $ "#include \"" ++ i ++ ".h\"") $ uses2List uses
 
 uses2List :: Uses -> [String]
-uses2List (Uses ids) = map (\(Identifier i) -> i) ids
+uses2List (Uses ids) = map (\(Identifier i _) -> i) ids
 
-tvar2C :: TypeVarDeclaration -> Doc
-tvar2C (FunctionDeclaration (Identifier name) returnType params Nothing) = 
-    type2C returnType <+> text (name ++ "();")
-tvar2C (FunctionDeclaration (Identifier name) returnType params (Just (tvars, phrase))) = 
-    type2C returnType <+> text (name ++ "()") 
-    $+$
-    text "{" 
-    $+$ nest 4 (
-        typesAndVars2C tvars
+tvar2C :: Bool -> TypeVarDeclaration -> Reader a Doc
+tvar2C _ (FunctionDeclaration (Identifier name _) returnType params Nothing) = do
+    t <- type2C returnType 
+    p <- liftM hcat $ mapM (tvar2C False) params
+    return $ t <+> text name <> parens p <> text ";"
+tvar2C True (FunctionDeclaration (Identifier name _) returnType params (Just (tvars, phrase))) = do
+    t <- type2C returnType 
+    p <- liftM hcat $ mapM (tvar2C False) params
+    ph <- liftM2 ($+$) (typesAndVars2C False tvars) (phrase2C' phrase)
+    return $ 
+        t <+> text name <> parens p
         $+$
-        phrase2C' phrase
-        )
-    $+$
-    text "}"
+        text "{" 
+        $+$ 
+        nest 4 ph
+        $+$
+        text "}"
     where
-    phrase2C' (Phrases p) = vcat $ map phrase2C p
+    phrase2C' (Phrases p) = liftM vcat $ mapM phrase2C p
     phrase2C' p = phrase2C p
-tvar2C (TypeDeclaration (Identifier i) t) = text "type" <+> text i <+> type2C t <> text ";"
-tvar2C (VarDeclaration isConst (ids, t) mInitExpr) = 
+tvar2C False (FunctionDeclaration (Identifier name _) _ _ _) = error $ "nested functions not allowed: " ++ name
+tvar2C _ (TypeDeclaration (Identifier i _) t) = do
+    tp <- type2C t
+    return $ text "type" <+> text i <+> tp <> text ";"
+tvar2C _ (VarDeclaration isConst (ids, t) mInitExpr) = 
     if isConst then text "const" else empty
     <+>
     type2C t
     <+>
-    (hsep . punctuate (char ',') . map (\(Identifier i) -> text i) $ ids)
+    (hsep . punctuate (char ',') . map (\(Identifier i _) -> text i) $ ids)
     <+>
     initExpr mInitExpr
     <>
@@ -106,32 +138,36 @@
     where
     initExpr Nothing = empty
     initExpr (Just e) = text "=" <+> initExpr2C e
+tvar2C f (OperatorDeclaration op _ ret params body) = 
+    tvar2C f (FunctionDeclaration (Identifier ("<op " ++ op ++ ">") Unknown) ret params body)
 
-initExpr2C :: InitExpression -> Doc
+initExpr2C :: InitExpression -> Reader a Doc
 initExpr2C (InitBinOp op expr1 expr2) = parens $ (initExpr2C expr1) <+> op2C op <+> (initExpr2C expr2)
 initExpr2C (InitNumber s) = text s
 initExpr2C (InitFloat s) = text s
 initExpr2C (InitHexNumber s) = text "0x" <> (text . map toLower $ s)
 initExpr2C (InitString s) = doubleQuotes $ text s 
-initExpr2C (InitReference (Identifier i)) = text i
+initExpr2C (InitReference (Identifier i _)) = text i
 
 
 initExpr2C _ = text "<<expression>>"
 
-type2C :: TypeDecl -> Doc
+type2C :: TypeDecl -> Reader a Doc
 type2C UnknownType = text "void"
 type2C (String l) = text $ "string" ++ show l
-type2C (SimpleType (Identifier i)) = text i
+type2C (SimpleType (Identifier i _)) = text i
 type2C (PointerTo t) = type2C t <> text "*"
-type2C (RecordType tvs union) = text "{" $+$ (nest 4 . vcat . map tvar2C $ tvs) $+$ text "}"
+type2C (RecordType tvs union) = text "{" $+$ (nest 4 . vcat . map (tvar2C False) $ tvs) $+$ text "}"
 type2C (RangeType r) = text "<<range type>>"
 type2C (Sequence ids) = text "<<sequence type>>"
 type2C (ArrayDecl r t) = text "<<array type>>"
-
+type2C (Set t) = text "<<set>>"
+type2C (FunctionType returnType params) = text "<<function>>"
 
-phrase2C :: Phrase -> Doc
+phrase2C :: Phrase -> Reader a Doc
 phrase2C (Phrases p) = text "{" $+$ (nest 4 . vcat . map phrase2C $ p) $+$ text "}"
-phrase2C (ProcCall (Identifier name) params) = text name <> parens (hsep . punctuate (char ',') . map expr2C $ params) <> semi
+phrase2C (ProcCall f@(FunCall {}) []) = ref2C f <> semi
+phrase2C (ProcCall ref params) = ref2C ref <> parens (hsep . punctuate (char ',') . map expr2C $ params) <> semi
 phrase2C (IfThenElse (expr) phrase1 mphrase2) = text "if" <> parens (expr2C expr) $+$ (phrase2C . wrapPhrase) phrase1 $+$ elsePart
     where
     elsePart | isNothing mphrase2 = empty
@@ -140,44 +176,45 @@
 phrase2C (WhileCycle expr phrase) = text "while" <> parens (expr2C expr) $$ (phrase2C $ wrapPhrase phrase)
 phrase2C (SwitchCase expr cases mphrase) = text "switch" <> parens (expr2C expr) <> text "of" $+$ (nest 4 . vcat . map case2C) cases
     where
-    case2C :: ([Expression], Phrase) -> Doc
-    case2C (e, p) = text "case" <+> parens (hsep . punctuate (char ',') . map expr2C $ e) <> char ':' <> nest 4 (phrase2C p $+$ text "break;")
+    case2C :: ([InitExpression], Phrase) -> Doc
+    case2C (e, p) = text "case" <+> parens (hsep . punctuate (char ',') . map initExpr2C $ e) <> char ':' <> nest 4 (phrase2C p $+$ text "break;")
 phrase2C (WithBlock ref p) = text "namespace" <> parens (ref2C ref) $$ (phrase2C $ wrapPhrase p)
-phrase2C (ForCycle (Identifier i) e1 e2 p) = 
+phrase2C (ForCycle (Identifier i _) e1 e2 p) = 
     text "for" <> (parens . hsep . punctuate (char ';') $ [text i <+> text "=" <+> expr2C e1, text i <+> text "<=" <+> expr2C e2, text "++" <> text i])
     $$
     phrase2C (wrapPhrase p)
 phrase2C (RepeatCycle e p) = text "do" <+> phrase2C (Phrases p) <+> text "while" <> parens (text "!" <> parens (expr2C e))
+phrase2C NOP = text ";"
 
 
 wrapPhrase p@(Phrases _) = p
 wrapPhrase p = Phrases [p]
 
 
-expr2C :: Expression -> Doc
+expr2C :: Expression -> Reader a Doc
 expr2C (Expression s) = text s
 expr2C (BinOp op expr1 expr2) = parens $ (expr2C expr1) <+> op2C op <+> (expr2C expr2)
 expr2C (NumberLiteral s) = text s
+expr2C (FloatLiteral s) = text s
 expr2C (HexNumber s) = text "0x" <> (text . map toLower $ s)
 expr2C (StringLiteral s) = doubleQuotes $ text s 
 expr2C (Reference ref) = ref2C ref
 expr2C (PrefixOp op expr) = op2C op <+> expr2C expr
-    {-
-    | PostfixOp String Expression
-    | CharCode String
-    -}            
-expr2C _ = empty
+expr2C Null = text "NULL"
+expr2C (BuiltInFunCall params ref) = ref2C ref <> parens (hsep . punctuate (char ',') . map expr2C $ params)
+expr2C _ = text "<<expression>>"
 
 
-ref2C :: Reference -> Doc
+ref2C :: Reference -> Reader a Doc
 ref2C (ArrayElement exprs ref) = ref2C ref <> (brackets . hcat) (punctuate comma $ map expr2C exprs)
-ref2C (SimpleReference (Identifier name)) = text name
+ref2C (SimpleReference (Identifier name _)) = text name
 ref2C (RecordField (Dereference ref1) ref2) = ref2C ref1 <> text "->" <> ref2C ref2
 ref2C (RecordField ref1 ref2) = ref2C ref1 <> text "." <> ref2C ref2
 ref2C (Dereference ref) = parens $ text "*" <> ref2C ref
 ref2C (FunCall params ref) = ref2C ref <> parens (hsep . punctuate (char ',') . map expr2C $ params)
-ref2C (Address ref) = text "&" <> ref2C ref
-
+ref2C (Address ref) = text "&" <> parens (ref2C ref)
+ref2C (TypeCast (Identifier t _) expr) = parens (text t) <> expr2C expr
+ref2C (RefExpression expr) = expr2C expr
 
 op2C "or" = text "|"
 op2C "and" = text "&"