merge spacecampaign
authorkoda
Mon, 28 Oct 2013 14:07:04 +0100
changeset 9648 3a3defce1b28
parent 9583 37a6d807c140 (current diff)
parent 9646 7588daa8d28f (diff)
child 9649 2d30721b1a11
merge spacecampaign
QTfrontend/hedgewars.qrc
QTfrontend/hwform.cpp
QTfrontend/hwform.h
hedgewars/uScript.pas
--- a/QTfrontend/campaign.cpp	Sun Oct 27 22:34:25 2013 -0400
+++ b/QTfrontend/campaign.cpp	Mon Oct 28 14:07:04 2013 +0100
@@ -17,47 +17,77 @@
  */
 
 #include "campaign.h"
-
 #include "hwconsts.h"
-
+#include "DataManager.h"
 #include <QSettings>
-
+#include <QObject>
+#include <QLocale>
 
-QStringList getCampMissionList(QString & campaign)
-{
-    QSettings campfile("physfs://Missions/Campaign/" + campaign + "/campaign.ini", QSettings::IniFormat, 0);
-    campfile.setIniCodec("UTF-8");
-    unsigned int mNum = campfile.value("MissionNum", 0).toInt();
-
-    QStringList missionList;
-    for (unsigned int i = 0; i < mNum; i++)
-    {
-      missionList += campfile.value(QString("Mission %1/Name").arg(i + 1)).toString();
-    }
-    return missionList;
-}
-
-unsigned int getCampProgress(QString & teamName, QString & campName)
+QList<MissionInfo> getCampMissionList(QString & campaignName, QString & teamName)
 {
-    QSettings teamfile(cfgdir->absolutePath() + "/Teams/" + teamName + ".hwt", QSettings::IniFormat, 0);
+    QList<MissionInfo> missionInfoList;
+	QSettings teamfile(cfgdir->absolutePath() + "/Teams/" + teamName + ".hwt", QSettings::IniFormat, 0);
     teamfile.setIniCodec("UTF-8");
-    return teamfile.value("Campaign " + campName + "/Progress", 0).toInt();
-}
+    int progress = teamfile.value("Campaign " + campaignName + "/Progress", 0).toInt();
+    int unlockedMissions = teamfile.value("Campaign " + campaignName + "/UnlockedMissions", 0).toInt();
+    
+    QSettings campfile("physfs://Missions/Campaign/" + campaignName + "/campaign.ini", QSettings::IniFormat, 0);
+    campfile.setIniCodec("UTF-8");
+    
+    DataManager & dataMgr = DataManager::instance();
+        // get locale
+        QSettings settings(dataMgr.settingsFileName(),
+                           QSettings::IniFormat);
+        QString loc = settings.value("misc/locale", "").toString();
+        if (loc.isEmpty())
+            loc = QLocale::system().name();
+        QString campaignDescFile = QString("physfs://Locale/campaigns_" + loc + ".txt");
+        // if file is non-existant try with language only
+        if (!QFile::exists(campaignDescFile))
+            campaignDescFile = QString("physfs://Locale/campaigns_" + loc.remove(QRegExp("_.*$")) + ".txt");
+
+        // fallback if file for current locale is non-existant
+        if (!QFile::exists(campaignDescFile))
+            campaignDescFile = QString("physfs://Locale/campaigns_en.txt");
 
-QString getCampaignScript(QString campaign, unsigned int mNum)
-{
-    QSettings campfile("physfs://Missions/Campaign/" + campaign + "/campaign.ini", QSettings::IniFormat, 0);
-    campfile.setIniCodec("UTF-8");
-    return campfile.value(QString("Mission %1/Script").arg(mNum)).toString();
+        QSettings m_info(campaignDescFile, QSettings::IniFormat, 0);
+        m_info.setIniCodec("UTF-8");
+    
+    if(progress>=0 and unlockedMissions==0)
+    {
+		for(unsigned int i=progress+1;i>0;i--)
+		{
+			MissionInfo missionInfo;
+			missionInfo.name = campfile.value(QString("Mission %1/Name").arg(i)).toString();
+			QString script = campfile.value(QString("Mission %1/Script").arg(i)).toString();
+            missionInfo.script = script;
+			missionInfo.description = m_info.value(campaignName+"-"+ script.replace(QString(".lua"),QString("")) + ".desc",
+                                            QObject::tr("No description available")).toString();
+            QString image = campfile.value(QString("Mission %1/Script").arg(i)).toString().replace(QString(".lua"),QString(".png"));
+            missionInfo.image = ":/res/campaign/"+campaignName+"/"+image;
+            if (!QFile::exists(missionInfo.image))
+				missionInfo.image = ":/res/CampaignDefault.png";
+			missionInfoList.append(missionInfo);
+		}
+	} 
+	else if(unlockedMissions>0)
+	{
+		for(int i=1;i<=unlockedMissions;i++)
+		{
+			QString missionNum = QString("%1").arg(i);
+			int missionNumber = teamfile.value("Campaign " + campaignName + "/Mission"+missionNum, -1).toInt();
+			MissionInfo missionInfo;
+			missionInfo.name = campfile.value(QString("Mission %1/Name").arg(missionNumber)).toString();
+			QString script = campfile.value(QString("Mission %1/Script").arg(missionNumber)).toString();
+            missionInfo.script = script;
+			missionInfo.description = m_info.value(campaignName+"-"+ script.replace(QString(".lua"),QString("")) + ".desc",
+                                            QObject::tr("No description available")).toString();
+            QString image = campfile.value(QString("Mission %1/Script").arg(missionNumber)).toString().replace(QString(".lua"),QString(".png"));
+            missionInfo.image = ":/res/campaign/"+campaignName+"/"+image;
+            if (!QFile::exists(missionInfo.image))
+				missionInfo.image = ":/res/CampaignDefault.png";
+			missionInfoList.append(missionInfo);
+		}
+	}
+	return missionInfoList;
 }
-
-QString getCampaignImage(QString campaign, unsigned int mNum)
-{
-    return getCampaignScript(campaign,mNum).replace(QString(".lua"),QString(".png"));
-}
-
-QString getCampaignMissionName(QString campaign, unsigned int mNum)
-{
-    return getCampaignScript(campaign,mNum).replace(QString(".lua"),QString(""));
-}
-
--- a/QTfrontend/campaign.h	Sun Oct 27 22:34:25 2013 -0400
+++ b/QTfrontend/campaign.h	Mon Oct 28 14:07:04 2013 +0100
@@ -20,12 +20,16 @@
 #define CAMPAIGN_H
 
 #include <QString>
-#include <QStringList>
 
-QStringList getCampMissionList(QString & campaign);
-unsigned int getCampProgress(QString & teamName, QString & campName);
-QString getCampaignScript(QString campaign, unsigned int mNum);
-QString getCampaignImage(QString campaign, unsigned int mNum);
-QString getCampaignMissionName(QString campaign, unsigned int mNum);
+class MissionInfo
+{
+	public:
+		QString name;
+		QString description;
+		QString script;
+		QString image;
+};
+
+QList<MissionInfo> getCampMissionList(QString & campaignName, QString & teamName);
 
 #endif
--- a/QTfrontend/hedgewars.qrc	Sun Oct 27 22:34:25 2013 -0400
+++ b/QTfrontend/hedgewars.qrc	Mon Oct 28 14:07:04 2013 +0100
@@ -38,12 +38,27 @@
         <file>res/campaign/A_Classic_Fairytale/queen.png</file>
         <file>res/campaign/A_Classic_Fairytale/enemy.png</file>
         <file>res/campaign/A_Classic_Fairytale/epil.png</file>
+        <file>res/campaign/A_Space_Adventure/cosmos.png</file>
+        <file>res/campaign/A_Space_Adventure/moon01.png</file>
+        <file>res/campaign/A_Space_Adventure/moon02.png</file>
+        <file>res/campaign/A_Space_Adventure/ice01.png</file>
+        <file>res/campaign/A_Space_Adventure/ice02.png</file>
+        <file>res/campaign/A_Space_Adventure/desert01.png</file>
+        <file>res/campaign/A_Space_Adventure/desert02.png</file>
+        <file>res/campaign/A_Space_Adventure/desert03.png</file>
+        <file>res/campaign/A_Space_Adventure/fruit01.png</file>
+        <file>res/campaign/A_Space_Adventure/fruit02.png</file>
+        <file>res/campaign/A_Space_Adventure/fruit03.png</file>
+        <file>res/campaign/A_Space_Adventure/death01.png</file>
+        <file>res/campaign/A_Space_Adventure/death02.png</file>
+        <file>res/campaign/A_Space_Adventure/final.png</file>
         <file>res/bonus.png</file>
         <file>res/Hedgehog.png</file>
         <file>res/net.png</file>
         <file>res/About.png</file>
         <file>res/SimpleGame.png</file>
         <file>res/Campaign.png</file>
+        <file>res/CampaignDefault.png</file>
         <file>res/Multiplayer.png</file>
         <file>res/Trainings.png</file>
         <file>res/Background.png</file>
--- a/QTfrontend/hwform.cpp	Sun Oct 27 22:34:25 2013 -0400
+++ b/QTfrontend/hwform.cpp	Mon Oct 28 14:07:04 2013 +0100
@@ -198,6 +198,7 @@
     UpdateTeamsLists();
     InitCampaignPage();
     UpdateCampaignPage(0);
+    UpdateCampaignPageMission(0);
     UpdateWeapons();
 
     // connect all goBack signals
@@ -305,6 +306,7 @@
     connect(ui.pageTraining, SIGNAL(startMission(const QString&)), this, SLOT(startTraining(const QString&)));
 
     connect(ui.pageCampaign->BtnStartCampaign, SIGNAL(clicked()), this, SLOT(StartCampaign()));
+    connect(ui.pageCampaign->btnPreview, SIGNAL(clicked()), this, SLOT(StartCampaign()));
     connect(ui.pageCampaign->CBTeam, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateCampaignPage(int)));
     connect(ui.pageCampaign->CBCampaign, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateCampaignPage(int)));
     connect(ui.pageCampaign->CBMission, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateCampaignPageMission(int)));
@@ -1729,13 +1731,9 @@
 void HWForm::StartCampaign()
 {
     CreateGame(0, 0, 0);
-
-    QComboBox *combo = ui.pageCampaign->CBMission;
     QString camp = ui.pageCampaign->CBCampaign->currentText().replace(QString(" "),QString("_"));
-    unsigned int mNum = combo->count() - combo->currentIndex();
-    QString miss = getCampaignScript(camp, mNum);
+    QString miss = campaignMissionInfo[ui.pageCampaign->CBMission->currentIndex()].script;
     QString campTeam = ui.pageCampaign->CBTeam->currentText();
-
     game->StartCampaign(camp, miss, campTeam);
 }
 
@@ -1900,85 +1898,32 @@
     }
 }
 
-
 void HWForm::UpdateCampaignPage(int index)
 {
     Q_UNUSED(index);
-
     HWTeam team(ui.pageCampaign->CBTeam->currentText());
-    ui.pageCampaign->CBMission->clear();
-
     QString campaignName = ui.pageCampaign->CBCampaign->currentText().replace(QString(" "),QString("_"));
-    QStringList missionEntries = getCampMissionList(campaignName);
-    QString tName = team.name();
-    unsigned int n = missionEntries.count();
-    unsigned int m = getCampProgress(tName, campaignName);
-
-    // if the campaign name changes update the campaignMissionDescriptions list
-    // this will be used later in UpdateCampaignPageMission() to update
-    // the mission description in the campaign page
-    bool updateMissionList = false;
-    QSettings * m_info;
-    if(previousCampaignName.compare(campaignName)!=0 ||
-            previousTeamName.compare(tName) != 0)
+    QString tName = team.name();    
+    
+    campaignMissionInfo = getCampMissionList(campaignName,tName);    
+	ui.pageCampaign->CBMission->clear();
+	
+    for(int i=0;i<campaignMissionInfo.size();i++)
     {
-        if (previousTeamName.compare(tName) != 0 &&
-                previousTeamName.compare("") != 0)
-            index = qMin(m + 1, n);
-        previousCampaignName = campaignName;
-        previousTeamName = tName;
-        updateMissionList = true;
-        // the following code was based on pagetraining.cpp
-        DataManager & dataMgr = DataManager::instance();
-        // get locale
-        QSettings settings(dataMgr.settingsFileName(),
-                           QSettings::IniFormat);
-        QString loc = settings.value("misc/locale", "").toString();
-        if (loc.isEmpty())
-            loc = QLocale::system().name();
-        QString campaignDescFile = QString("physfs://Locale/campaigns_" + loc + ".txt");
-        // if file is non-existant try with language only
-        if (!QFile::exists(campaignDescFile))
-            campaignDescFile = QString("physfs://Locale/campaigns_" + loc.remove(QRegExp("_.*$")) + ".txt");
-
-        // fallback if file for current locale is non-existant
-        if (!QFile::exists(campaignDescFile))
-            campaignDescFile = QString("physfs://Locale/campaigns_en.txt");
-
-        m_info = new QSettings(campaignDescFile, QSettings::IniFormat, this);
-        m_info->setIniCodec("UTF-8");
-        campaignMissionDescriptions.clear();
-        ui.pageCampaign->CBMission->clear();
-    }
-
-    for (unsigned int i = qMin(m + 1, n); i > 0; i--)
-    {
-        if(updateMissionList)
-        {
-            campaignMissionDescriptions += m_info->value(campaignName+"-"+ getCampaignMissionName(campaignName,i) + ".desc",
-                                            tr("No description available")).toString();
-        }
-        ui.pageCampaign->CBMission->addItem(QString("Mission %1: ").arg(i) + QString(missionEntries[i-1]), QString(missionEntries[i-1]));
-    }
-    if(updateMissionList)
-        delete m_info;
-
-    UpdateCampaignPageMission(index);
+        ui.pageCampaign->CBMission->addItem(QString(campaignMissionInfo[i].name), QString(campaignMissionInfo[i].name));
+	}
 }
 
 void HWForm::UpdateCampaignPageMission(int index)
 {
-    // update thumbnail
+    // update thumbnail and description
     QString campaignName = ui.pageCampaign->CBCampaign->currentText().replace(QString(" "),QString("_"));
-    unsigned int mNum = ui.pageCampaign->CBMission->count() - ui.pageCampaign->CBMission->currentIndex();
-    QString image = getCampaignImage(campaignName,mNum);
-    ui.pageCampaign->btnPreview->setIcon(QIcon((":/res/campaign/"+campaignName+"/"+image)));
-    // update description
     // when campaign changes the UpdateCampaignPageMission is triggered with wrong values
     // this will cause segfault. This check prevents illegal memory reads
-    if(index > -1 && index < campaignMissionDescriptions.count()) {
+    if(index > -1 && index < campaignMissionInfo.count()) {
         ui.pageCampaign->lbltitle->setText("<h2>"+ui.pageCampaign->CBMission->currentText()+"</h2>");
-        ui.pageCampaign->lbldescription->setText(campaignMissionDescriptions[index]);
+        ui.pageCampaign->lbldescription->setText(campaignMissionInfo[index].description);
+		ui.pageCampaign->btnPreview->setIcon(QIcon(campaignMissionInfo[index].image));
     }
 }
 
@@ -1986,9 +1931,16 @@
 {
     Q_UNUSED(index);
 
-    int missionIndex = ui.pageCampaign->CBMission->currentIndex();
+    QString missionTitle = ui.pageCampaign->CBMission->currentText();
     UpdateCampaignPage(0);
-    ui.pageCampaign->CBMission->setCurrentIndex(missionIndex);
+    for(int i=0;i<ui.pageCampaign->CBMission->count();i++)
+    {
+		if (ui.pageCampaign->CBMission->itemText(i)==missionTitle)
+		{
+			ui.pageCampaign->CBMission->setCurrentIndex(i);
+			break;
+		}
+	}
 }
 
 // used for --set-everything [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen] [show FPS] [alternate damage] [timer value] [reduced quality]
--- a/QTfrontend/hwform.h	Sun Oct 27 22:34:25 2013 -0400
+++ b/QTfrontend/hwform.h	Mon Oct 28 14:07:04 2013 +0100
@@ -34,6 +34,7 @@
 #include "ui_hwform.h"
 #include "SDLInteraction.h"
 #include "bgwidget.h"
+#include "campaign.h"
 
 #ifdef __APPLE__
 #include "InstallController.h"
@@ -195,8 +196,8 @@
         AmmoSchemeModel * ammoSchemeModel;
         QStack<int> PagesStack;
         QString previousCampaignName;
-        QString previousTeamName;
-        QStringList campaignMissionDescriptions;
+        QString previousTeamName;     
+        QList<MissionInfo> campaignMissionInfo;
         QTime eggTimer;
         BGWidget * wBackground;
         QSignalMapper * pageSwitchMapper;
Binary file QTfrontend/res/CampaignDefault.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/cosmos.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/death01.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/death02.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/desert01.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/desert02.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/desert03.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/final.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/fruit01.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/fruit02.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/fruit03.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/ice01.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/ice02.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/moon01.png has changed
Binary file QTfrontend/res/campaign/A_Space_Adventure/moon02.png has changed
--- a/hedgewars/uScript.pas	Sun Oct 27 22:34:25 2013 -0400
+++ b/hedgewars/uScript.pas	Mon Oct 28 14:07:04 2013 +0100
@@ -1292,7 +1292,7 @@
 var i : LongInt;
 var color : shortstring;
 begin
-	statInfo := TStatInfoType(GetEnumValue(TypeInfo(TStatInfoType),lua_tostring(L, 1)));
+	statInfo := TStatInfoType(lua_tointeger(L, 1));
 	if (lua_gettop(L) <> 2) and ((statInfo <> siPlayerKills) 
 			and (statInfo <> siClanHealth)) then
         begin
@@ -2316,6 +2316,7 @@
 var at : TGearType;
     vgt: TVisualGearType;
     am : TAmmoType;
+    si : TStatInfoType;
     st : TSound;
     he : THogEffect;
     cg : TCapGroup;
@@ -2399,6 +2400,9 @@
 for am:= Low(TAmmoType) to High(TAmmoType) do
     ScriptSetInteger(EnumToStr(am), ord(am));
 
+for si:= Low(TStatInfoType) to High(TStatInfoType) do
+    ScriptSetInteger(EnumToStr(si), ord(si));
+
 for he:= Low(THogEffect) to High(THogEffect) do
     ScriptSetInteger(EnumToStr(he), ord(he));
 
--- a/hedgewars/uUtils.pas	Sun Oct 27 22:34:25 2013 -0400
+++ b/hedgewars/uUtils.pas	Mon Oct 28 14:07:04 2013 +0100
@@ -31,6 +31,7 @@
 function  EnumToStr(const en : TVisualGearType) : shortstring; overload;
 function  EnumToStr(const en : TSound) : shortstring; overload;
 function  EnumToStr(const en : TAmmoType) : shortstring; overload;
+function  EnumToStr(const en : TStatInfoType) : shortstring; overload;
 function  EnumToStr(const en : THogEffect) : shortstring; overload;
 function  EnumToStr(const en : TCapGroup) : shortstring; overload;
 
@@ -150,6 +151,11 @@
 EnumToStr:= GetEnumName(TypeInfo(TAmmoType), ord(en))
 end;
 
+function EnumToStr(const en : TStatInfoType) : shortstring; overload;
+begin
+EnumToStr:= GetEnumName(TypeInfo(TStatInfoType), ord(en))
+end;
+
 function EnumToStr(const en: THogEffect) : shortstring; overload;
 begin
 EnumToStr := GetEnumName(TypeInfo(THogEffect), ord(en))
--- a/share/hedgewars/Data/Locale/campaigns_en.txt	Sun Oct 27 22:34:25 2013 -0400
+++ b/share/hedgewars/Data/Locale/campaigns_en.txt	Mon Oct 28 14:07:04 2013 +0100
@@ -17,3 +17,18 @@
 A_Classic_Fairytale-enemy.desc="What a great twist! Leaks a lot has to fight side by side with the… “cannibals” against the common enemy. The evil cyborgs!"
 
 A_Classic_Fairytale-epil.desc="Congratulations! Leaks a lot can finally leave in peace and get praised by his new friends and his tribe. Be proud for what you succeed! You can play again previous missions and see the other possible endings."
+
+A_Space_Adventure-cosmos.desc="Hogera, the planet of hogs is about to be hit by a gigantic meteorite. In this race for survival you have to lead PAotH's best pilot, Hog Solo, in a space trip around the neighbor planets to collect all the 4 pieces of the long lost anti gravity device!"
+A_Space_Adventure-moon01.desc="Hog Solo has landed on the moon to refuel his saucer but professor Hogevil has gone there first and set an ambush! Rescue the catpured PAotH researchers and drive professor Hogevil away!"
+A_Space_Adventure-moon02.desc="Hog Solo visits an hermit, old PAotH veteran, who lives in moon in order to collect some intel about Pr. Hogevil. However, he has to beat the hermit, Soneek the Crazy Runner, in a chase game first!"
+A_Space_Adventure-ice01.desc="Welcome to the planet of ice. Here, it's so cold that most of Hog Solo's weapons won't work. You have to get the lost part from the bandit leader Thanta using the weapons that you'll find there!"
+A_Space_Adventure-ice02.desc="Hog Solo couldn't just visit the Ice Planet without visiting the olympic stadium of saucer flying! In this mission you can proove your flying skills and claim your place between the best!"
+A_Space_Adventure-desert01.desc="You have landed to the planet of sand! Hog Solo has to find the missing part in the underground tunnels. Be careful as vicious smugglers await to attack and rob you!"
+A_Space_Adventure-desert02.desc="Hog Solo was searching for the part in this tunnel when it unexpectedly start getting flooded! Get to the surface as soon as possible and be careful not to trigger a mine."
+A_Space_Adventure-desert03.desc="Hog Solo has some time to fly his RC plane and have some fun. Fly the RC plane and hit all the targets!"
+A_Space_Adventure-fruit01.desc="In the fruit planet things aren't going so well. Hogs aren't collecting fruits but they are preparing for battle. You'll have to choose if you'll fight or if you'll flee."
+A_Space_Adventure-fruit02.desc="Hog Solo gets closer to the lost part in the Fruit Planet. Will Captain Lime help him acquire the part or not?"
+A_Space_Adventure-fruit03.desc="Hog Solo got lost and got ambushed by the Red Strawberies. Help him eliminate them and win some extra ammo for the Getting to the device mission."
+A_Space_Adventure-death01.desc="In the Death Planet, the most infertile planet around, Hog Solo is very close to get the last part of the device! However an upleasant surprise awaits him..."
+A_Space_Adventure-death02.desc="Again Hog Solo has got himself in a difficult situation. Help him defeat the “5 deadly hogs“ in their own game!"
+A_Space_Adventure-final.desc="Hog Solo has to detonate some explosives that have been placed on the meteorite. Help him complete his mission without getting hurt!"
--- a/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/campaign.ini	Sun Oct 27 22:34:25 2013 -0400
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/campaign.ini	Mon Oct 28 14:07:04 2013 +0100
@@ -2,41 +2,41 @@
 ResetRetry=1
 
 [Mission 1]
-Name=First Blood
+Name=Mission 1: First Blood
 Script=first_blood.lua
 
 [Mission 2]
-Name=The Shadow Falls
+Name=Mission 2: The Shadow Falls
 Script=shadow.lua
 
 [Mission 3]
-Name=The Journey Back
+Name=Mission 3: The Journey Back
 Script=journey.lua
 
 [Mission 4]
-Name=United We Stand
+Name=Mission 4: United We Stand
 Script=united.lua
 
 [Mission 5]
-Name=Backstab
+Name=Mission 5: Backstab
 Script=backstab.lua
 
 [Mission 6]
-Name=Dragon's Lair
+Name=Mission 6: Dragon's Lair
 Script=dragon.lua
 
 [Mission 7]
-Name=Family Reunion
+Name=Mission 7: Family Reunion
 Script=family.lua
 
 [Mission 8]
-Name=Long Live The Queen
+Name=Mission 8: Long Live The Queen
 Script=queen.lua
 
 [Mission 9]
-Name=The Enemy Of My Enemy
+Name=Mission 9: The Enemy Of My Enemy
 Script=enemy.lua
 
 [Mission 10]
-Name=Epilogue
+Name=Mission 10: Epilogue
 Script=epil.lua
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/CMakeLists.txt	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,9 @@
+file(GLOB Config *.ini)
+file(GLOB Missions *.lua)
+file(GLOB Packs *.hwp)
+
+install(FILES
+    ${Config}
+    ${Missions}
+    ${Packs}
+    DESTINATION "${SHAREPATH}Data/Missions/Campaign/A_Space_Adventure")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/campaign.ini	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,58 @@
+MissionNum=5
+ResetRetry=1
+
+[Mission 1]
+Name=Menu: Spacetrip
+Script=cosmos.lua
+
+[Mission 2]
+Name=Main Mission: The first stop
+Script=moon01.lua
+
+[Mission 3]
+Name=Main Mission: Bad timing
+Script=fruit01.lua
+
+[Mission 4]
+Name=Main Mission: Searching in the dust
+Script=desert01.lua
+
+[Mission 5]
+Name=Main Mission: A frozen adventure
+Script=ice01.lua
+
+[Mission 6]
+Name=Side Mission: Hard flying
+Script=ice02.lua
+
+[Mission 7]
+Name=Side Mission: Running for survival
+Script=desert02.lua
+
+[Mission 8]
+Name=Main Mission: Getting to the device
+Script=fruit02.lua
+
+[Mission 9]
+Name=Main Mission: The last encounter
+Script=death01.lua
+
+[Mission 10]
+Name=Side Mission: Precise shooting
+Script=fruit03.lua
+
+[Mission 11]
+Name=Side Mission: Killing the specialists
+Script=death02.lua
+
+[Mission 12]
+Name=Side Mission: Precise flying
+Script=desert03.lua
+
+[Mission 13]
+Name=Side Mission: Chasing the blue hog
+Script=moon02.lua
+
+[Mission 14]
+Name=Main Mission: The big bang
+Script=final.lua
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/cosmos.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/cosmos.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,576 @@
+------------------- ABOUT ----------------------
+--
+-- This map works as a menu for the hero hog to
+-- navigate through planets. It portrays the hogs
+-- planet and above the planets that he'll later
+-- visit.
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local missionName = loc("Spacetrip")
+local timeForGuard1ToTurn = 1000 * 5 -- 5 sec
+local timeForGuard1ToTurnLeft = timeForGuard1ToTurn
+local saucerAcquired = false
+local status
+local checkPointReached = 1 -- 1 is start of the game
+local objectives = loc("Go to moon by the flying saucer and complete the main mission").."|"..
+loc("Come back to this mission and visit the other planets to collect the crates").."|"..
+loc("Visit the Death Planet after completing all the other planets' main missions").."|"..
+loc("Come back to this mission after collecting all the parts")
+-- dialogs
+local dialog01 = {}
+local dialog02 = {}
+local dialog03 = {}
+local dialog04 = {}
+local dialog05 = {}
+local dialog06 = {}
+local dialog07 = {}
+local dialog08 = {}
+-- mission objectives
+local goals = {
+	[dialog01] = {missionName, loc("Getting ready"), loc("Go and collect the crate").."|"..loc("Try not to get spotted by the guards!"), 1, 4500},
+	[dialog02] = {missionName, loc("The adventure begins!"), loc("Use the saucer and fly to the moon").."|"..loc("Travel carefully as your fuels are limited"), 1, 4500},
+	[dialog03] = {missionName, loc("An unexpected event!"), loc("Use the saucer and fly away").."|"..loc("Beware, any damage taken will stay until you complete the moon's main mission"), 1, 7000},
+	[dialog04] = {missionName, loc("Objectives"), objectives, 1, 7000},
+	[dialog05] = {missionName, loc("Objectives"), objectives, 1, 7000},
+	[dialog06] = {missionName, loc("Objectives"), objectives, 1, 7000},
+	[dialog07] = {missionName, loc("Searching the stars!"), loc("Use the saucer and fly away").."|"..loc("Visit first the planets of Ice, Desert and Fruit"), 1, 6000},
+	[dialog08] = {missionName, loc("Saving Hogera"), loc("Fly to the meteorite and detonate the explosives"), 1, 7000}
+}
+-- crates
+local saucerX = 3270
+local saucerY = 1500
+-- hogs
+local hero = {}
+local director = {}
+local doctor = {}
+local guard1 = {}
+local guard2 = {}
+-- teams
+local teamA = {}
+local teamB = {}
+local teamC = {}
+-- hedgehogs values
+hero.name = loc("Hog Solo")
+hero.x = 1450
+hero.y = 1550
+director.name = loc("H")
+director.x = 1350
+director.y = 1550
+doctor.name = loc("Dr.Cornelius")
+doctor.x = 1300
+doctor.y = 1550
+guard1.name = loc("Bob")
+guard1.x = 3350
+guard1.y = 1800
+guard1.turn = false
+guard1.keepTurning = true
+guard2.name = loc("Sam")
+guard2.x = 3400
+guard2.y = 1800
+teamA.name = loc("PAoTH")
+teamA.color = tonumber("FF0000",16) -- red
+teamB.name = loc("Guards")
+teamB.color = tonumber("0033FF",16) -- blue
+teamC.name = loc("Hog Solo")
+teamC.color = tonumber("38D61C",16) -- green
+
+-------------- LuaAPI EVENT HANDLERS ------------------
+function onGameInit()
+	Seed = 35
+	GameFlags = gfSolidLand + gfDisableWind
+	TurnTime = 40000
+	CaseFreq = 0
+	MinesNum = 0
+	Explosives = 0
+	Delay = 5
+	-- completed main missions
+	status = getCompletedStatus()
+	if status.death01 then
+		Map = "cosmos2_map"
+	else
+		Map = "cosmos_map" -- custom map included in file
+	end
+	Theme = "Nature"
+	-- I had originally hero in PAoTH team and changed it, may reconsider though
+	-- PAoTH
+	AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy")	
+	hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1")
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)	
+	HogTurnLeft(hero.gear, true)
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")	
+	director.gear = AddHog(director.name, 0, 100, "hair_yellow")
+	AnimSetGearPosition(director.gear, director.x, director.y)
+	doctor.gear = AddHog(doctor.name, 0, 100, "Glasses")
+	AnimSetGearPosition(doctor.gear, doctor.x, doctor.y)
+	-- Guards
+	AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	guard1.gear = AddHog(guard1.name, 1, 100, "policecap")
+	AnimSetGearPosition(guard1.gear, guard1.x, guard1.y)
+	guard2.gear = AddHog(guard2.name, 1, 100, "policecap")
+	AnimSetGearPosition(guard2.gear, guard2.x, guard2.y)
+	-- get the check point
+	if tonumber(GetCampaignVar("CosmosCheckPoint")) then
+		checkPointReached = tonumber(GetCampaignVar("CosmosCheckPoint"))
+	end
+	-- do checkpoint stuff needed before game starts
+	if checkPointReached == 1 then
+		-- Start of the game
+	elseif checkPointReached == 2 then
+		-- Hero on the column, just took space ship unnoticed
+		AnimSetGearPosition(hero.gear, saucerX, saucerY)
+	elseif checkPointReached == 3 then
+		-- Hero near column, without space ship unnoticed
+	elseif checkPointReached == 4 then
+		-- Hero visited moon for fuels
+		AnimSetGearPosition(hero.gear, 1110, 850)
+	elseif checkPointReached == 5 then
+		-- Hero has visited a planet, he has plenty of fuels and can change planet
+		if GetCampaignVar("Planet") == "moon" then
+			AnimSetGearPosition(hero.gear, 1110, 850)
+		elseif GetCampaignVar("Planet") == "desertPlanet" then
+			AnimSetGearPosition(hero.gear, 3670, 270)
+		elseif GetCampaignVar("Planet") == "fruitPlanet" then
+			AnimSetGearPosition(hero.gear, 2400, 375)
+		elseif GetCampaignVar("Planet") == "icePlanet" then
+			AnimSetGearPosition(hero.gear, 1440, 260)
+		elseif GetCampaignVar("Planet") == "deathPlanet" then
+			AnimSetGearPosition(hero.gear, 620, 530)
+		elseif GetCampaignVar("Planet") == "meteorite" then
+			AnimSetGearPosition(hero.gear, 3080, 850)
+		end
+	end
+	
+	AnimInit()
+	AnimationSetup()
+end
+
+function onGameStart()
+	-- wait for the first turn to start
+	AnimWait(hero.gear, 3000)
+
+	FollowGear(hero.gear)
+	ShowMission(loc("Spacetrip"), loc("Getting ready"), loc("Help Hog Solo to find all the parts of the anti-gravity device.")..
+	"|"..loc("Travel to all the neighbor planets and collect all the pieces"), -amSkip, 0)
+	
+	-- do checkpoint stuff needed after game starts
+	if checkPointReached == 1 then	
+		AddAnim(dialog01)
+		AddAmmo(hero.gear, amRope, 1)
+		AddAmmo(guard1.gear, amDEagle, 2)
+		AddAmmo(guard2.gear, amDEagle, 2)
+		SpawnAmmoCrate(saucerX, saucerY, amJetpack)	
+		-- EVENT HANDLERS
+		AddEvent(onHeroBeforeTreePosition, {hero.gear}, heroBeforeTreePosition, {hero.gear}, 0)
+		AddEvent(onHeroAtSaucerPosition, {hero.gear}, heroAtSaucerPosition, {hero.gear}, 0)
+		AddEvent(onHeroOutOfGuardSight, {hero.gear}, heroOutOfGuardSight, {hero.gear}, 0)
+	elseif checkPointReached == 2 then
+		AddAmmo(hero.gear, amJetpack, 1)
+		AddAnim(dialog02)
+	elseif checkPointReached == 3 then
+		-- Hero near column, without space ship unnoticed
+	elseif checkPointReached == 4 then
+		-- Hero visited moon for fuels
+		AddAnim(dialog05)
+	elseif checkPointReached == 5 then
+		-- Hero has visited a planet, he has plenty of fuels and can change planet
+		AddAmmo(hero.gear, amJetpack, 99)
+	end
+	
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	AddEvent(onNoFuelAtLand, {hero.gear}, noFuelAtLand, {hero.gear}, 0)
+	-- always check for landings
+	if GetCampaignVar("Planet") ~= "moon" then
+		AddEvent(onMoonLanding, {hero.gear}, moonLanding, {hero.gear}, 0)
+	end
+	if GetCampaignVar("Planet") ~= "desertPlanet" then
+		AddEvent(onDesertPlanetLanding, {hero.gear}, desertPlanetLanding, {hero.gear}, 0)
+	end	
+	if GetCampaignVar("Planet") ~= "fruitPlanet" then
+		AddEvent(onFruitPlanetLanding, {hero.gear}, fruitPlanetLanding, {hero.gear}, 0)
+	end
+	if GetCampaignVar("Planet") ~= "icePlanet" then
+		AddEvent(onIcePlanetLanding, {hero.gear}, icePlanetLanding, {hero.gear}, 0)
+	end
+	if GetCampaignVar("Planet") ~= "deathPlanet" then
+		AddEvent(onDeathPlanetLanding, {hero.gear}, deathPlanetLanding, {hero.gear}, 0)
+	end
+	
+	if status.death01 and not status.final then
+		AddAnim(dialog08)
+		if GetCampaignVar("Planet") ~= "meteorite" then
+			AddEvent(onMeteoriteLanding, {hero.gear}, meteoriteLanding, {hero.gear}, 0)
+		end
+	end
+	
+	SendHealthStatsOff()
+end
+
+function onGameTick()
+	-- maybe alert this to avoid timeForGuard1ToTurnLeft overflow
+	if timeForGuard1ToTurnLeft == 0 and guard1.keepTurning then
+		guard1.turn = not guard1.turn
+		HogTurnLeft(guard1.gear, guard1.turn)
+		timeForGuard1ToTurnLeft = timeForGuard1ToTurn
+	end
+	timeForGuard1ToTurnLeft = timeForGuard1ToTurnLeft - 1
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+end
+
+function onPrecise()
+	if GameTime > 3000 then
+		SetAnimSkip(true)   
+	end
+end
+
+function onAmmoStoreInit()
+	SetAmmo(amJetpack, 0, 0, 0, 1)
+end
+
+function onNewTurn()
+	if CurrentHedgehog == director.gear or CurrentHedgehog == doctor.gear then
+		TurnTimeLeft = 0
+	end
+	if guard1.keepTurning then
+		AnimSwitchHog(hero.gear)
+		TurnTimeLeft = -1
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onHeroBeforeTreePosition(gear)
+	if GetHealth(hero.gear) and GetX(gear) > 2350 then
+		return true
+	end
+	return false
+end
+
+function onHeroAtSaucerPosition(gear)
+	if GetHealth(hero.gear) and GetX(gear) >= saucerX-25 and GetX(gear) <= saucerX+32 and GetY(gear) >= saucerY-32 and GetY(gear) <= saucerY+32 then
+		saucerAcquired = true
+	end
+	if saucerAcquired and GetHealth(hero.gear) and StoppedGear(gear) then
+		return true
+	end
+	return false
+end
+
+function onHeroOutOfGuardSight(gear)
+	if GetHealth(hero.gear) and GetX(gear) < 3100 and GetY(gear) > saucerY-25 and StoppedGear(gear) and not guard1.keepTurning then
+		return true
+	end
+	return false
+end
+
+function onMoonLanding(gear)
+	if GetHealth(hero.gear) and GetX(gear) > 1010 and GetX(gear) < 1220  and GetY(gear) < 1300 and GetY(gear) > 750 and StoppedGear(gear) then
+		return true
+	end
+	return false
+end
+
+function onFruitPlanetLanding(gear)
+	if GetHealth(hero.gear) and GetX(gear) > 2240 and GetX(gear) < 2540  and GetY(gear) < 1100 and StoppedGear(gear) then
+		return true
+	end
+	return false
+end
+
+function onDesertPlanetLanding(gear)
+	if GetHealth(hero.gear) and GetX(gear) > 3568 and GetX(gear) < 4052  and GetY(gear) < 500 and StoppedGear(gear) then
+		return true
+	end
+	return false
+end
+
+function onIcePlanetLanding(gear)
+	if GetHealth(hero.gear) and GetX(gear) > 1330 and GetX(gear) < 1650  and GetY(gear) < 500 and StoppedGear(gear) then
+		return true
+	end
+	return false
+end
+
+function onDeathPlanetLanding(gear)
+	if GetHealth(hero.gear) and GetX(gear) > 280 and GetX(gear) < 700  and GetY(gear) < 720 and StoppedGear(gear) then
+		return true
+	end
+	return false
+end
+
+function onMeteoriteLanding(gear)
+	if GetHealth(hero.gear) and GetX(gear) > 2990 and GetX(gear) < 3395  and GetY(gear) < 940 and StoppedGear(gear) then
+		return true
+	end
+	return false
+end
+
+function onNoFuelAtLand(gear)
+	if checkPointReached > 1 and GetHealth(hero.gear) and GetY(gear) > 1400 and 
+			GetAmmoCount(gear, amJetpack) == 0 and StoppedGear(gear) then
+		return true
+	end
+	return false
+end
+
+function onHeroDeath(gear)
+	if not GetHealth(hero.gear) then
+		return true
+	end
+	return false
+end
+
+-------------- ACTIONS ------------------
+
+function heroBeforeTreePosition(gear)
+	AnimSay(gear,loc("Now I have to climb these trees"), SAY_SAY, 4000)
+	AnimCaption(hero.gear, loc("Use the rope to get to the crate"),  4000)
+end
+
+function heroAtSaucerPosition(gear)
+	TurnTimeLeft = 0
+	-- save check point	
+	SaveCampaignVar("CosmosCheckPoint", "2")
+	checkPointReached = 2
+	AddAnim(dialog02)
+	-- check if he was spotted by the guard
+	if guard1.turn and GetX(hero.gear) > saucerX-150 then
+		guard1.keepTurning = false
+		AddAnim(dialog03)
+	end	
+end
+
+function heroOutOfGuardSight(gear)
+	guard1.keepTurning = true
+	AddAnim(dialog04)
+end
+
+function moonLanding(gear)
+	if checkPointReached == 1 then
+		-- player climbed the moon with rope
+		FollowGear(doctor.gear)
+		AnimSay(doctor.gear, loc("One cannot simply walk in moon with rope!"), SAY_SHOUT, 4000)
+		SendStat(siGameResult, loc("This is the wrong way!"))
+		SendStat(siCustomAchievement, loc("Collect the crate with the flying saucer"))
+		SendStat(siCustomAchievement, loc("Fly to the moon"))
+		SendStat(siPlayerKills,'0',teamC.name)
+		EndGame()
+	else
+		if checkPointReached ~= 5 then
+			SaveCampaignVar("CosmosCheckPoint", "4")
+			SaveCampaignVar("HeroHealth",GetHealth(hero.gear))
+		end
+		AnimCaption(hero.gear,loc("Welcome to the moon!"))
+		SaveCampaignVar("HeroHealth", GetHealth(hero.gear))
+		SaveCampaignVar("Planet", "moon")
+		SaveCampaignVar("UnlockedMissions", "3")
+		SaveCampaignVar("Mission1", "2")
+		SaveCampaignVar("Mission2", "13")
+		SaveCampaignVar("Mission3", "1")
+		sendStats(loc("the moon"))
+	end
+end
+
+function fruitPlanetLanding(gear)
+	if checkPointReached < 5 then
+		AddAnim(dialog06)
+	else		
+		AnimCaption(hero.gear,loc("Welcome to the Fruit Planet!"))
+		SaveCampaignVar("Planet", "fruitPlanet")
+		if status.fruit02 then
+			SaveCampaignVar("UnlockedMissions", "4")
+			SaveCampaignVar("Mission1", "3")
+			SaveCampaignVar("Mission2", "8")
+			SaveCampaignVar("Mission3", "10")
+			SaveCampaignVar("Mission4", "1")
+		else
+			SaveCampaignVar("UnlockedMissions", "3")
+			SaveCampaignVar("Mission1", "3")
+			SaveCampaignVar("Mission2", "10")
+			SaveCampaignVar("Mission3", "1")
+		end
+		sendStats(loc("the Fruit Planet"))
+	end
+end
+
+function desertPlanetLanding(gear)
+	if checkPointReached < 5 then
+		AddAnim(dialog06)
+	else		
+		AnimCaption(hero.gear,loc("Welcome to the Desert Planet!"))
+		SaveCampaignVar("Planet", "desertPlanet")
+		SaveCampaignVar("UnlockedMissions", "4")
+		SaveCampaignVar("Mission1", "4")
+		SaveCampaignVar("Mission2", "7")
+		SaveCampaignVar("Mission3", "12")
+		SaveCampaignVar("Mission4", "1")
+		sendStats(loc("the Desert Planet"))
+	end
+end
+
+function icePlanetLanding(gear)
+	if checkPointReached < 5 then
+		AddAnim(dialog06)
+	else
+		AnimCaption(hero.gear,loc("Welcome to the Planet of Ice!"))
+		SaveCampaignVar("Planet", "icePlanet")
+		SaveCampaignVar("UnlockedMissions", "3")
+		SaveCampaignVar("Mission1", "5")
+		SaveCampaignVar("Mission2", "6")
+		SaveCampaignVar("Mission3", "1")
+		sendStats(loc("the Ice Planet"))
+	end
+end
+
+function deathPlanetLanding(gear)
+	if checkPointReached < 5 then
+		AddAnim(dialog06)
+	elseif not (status.fruit02 and status.ice01 and status.desert01) then
+		AddAnim(dialog07)
+	else
+		AnimCaption(hero.gear,loc("Welcome to the Death Planet!"))
+		SaveCampaignVar("Planet", "deathPlanet")
+		SaveCampaignVar("UnlockedMissions", "3")
+		SaveCampaignVar("Mission1", "9")
+		SaveCampaignVar("Mission2", "11")
+		SaveCampaignVar("Mission3", "1")
+		sendStats(loc("the Planet of Death"))
+	end
+end
+
+function meteoriteLanding(gear)
+	-- first two conditionals are not possible but I'll leave it there...
+	if checkPointReached < 5 then
+		AddAnim(dialog06)
+	elseif not (status.fruit02 and status.ice01 and status.desert01) then
+		AddAnim(dialog07)
+	else
+		AnimCaption(hero.gear,loc("Welcome to the meteorite!"))
+		SaveCampaignVar("Planet", "meteorite")
+		SaveCampaignVar("UnlockedMissions", "2")
+		SaveCampaignVar("Mission1", "14")
+		SaveCampaignVar("Mission2", "1")
+		sendStats(loc("the meteorite"))
+	end
+end
+
+function noFuelAtLand(gear)
+	AddAnim(dialog06)
+end
+
+function heroDeath(gear)
+	sendStatsOnRetry()
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+	if goals[anim] ~= nil then
+		ShowMission(unpack(goals[anim]))
+    end
+    if CurrentHedgehog ~= hero.gear and anim ~= dialog03 then
+		AnimSwitchHog(hero.gear)
+	elseif anim == dialog03 then
+		startCombat()
+	elseif anim == dialog05 or anim == dialog06 then
+		sendStatsOnRetry()
+	end
+end
+
+function AnimationSetup()
+	-- DIALOG 01 - Start
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {doctor.gear, 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Near secret base 17 of PAotH in the rural Hogland..."),  4000}})
+	table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("So Hog Solo, here we are..."), SAY_SAY, 2000}})
+	table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("Behind these trees on the East there is secret base 17"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("You have to continue alone from now on."), SAY_SAY, 3000}})
+	table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("Be careful, the future of Hogera is in your hands!"), SAY_SAY, 7200}})
+	table.insert(dialog01, {func = AnimSay, args = {doctor.gear, loc("We'll use our communicators to contact you"), SAY_SAY, 2600}})
+	table.insert(dialog01, {func = AnimSay, args = {doctor.gear, loc("In am also entrusting you with some rope"), SAY_SAY, 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {doctor.gear, loc("You may find it handy"), SAY_SAY, 2300}})
+	table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("Thank you Dr.Cornelius"), SAY_SAY, 1600}})
+	table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("I'll make good use of it"), SAY_SAY, 4500}})
+	table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("It would be wiser to steal the space ship while PAotH guards are taking a brake!"), SAY_SAY, 7000}})
+	table.insert(dialog01, {func = AnimSay, args = {director.gear, loc("Remember! Many will seek the anti-gravity device! Now go, hurry up!"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimSwitchHog, args = {hero.gear}})
+	-- DIALOG 02 - Hero got the saucer
+	AddSkipFunction(dialog02, Skipanim, {dialog02})
+	table.insert(dialog02, {func = AnimWait, args = {hero.gear, 500}})
+	table.insert(dialog02, {func = AnimCaption, args = {hero.gear, loc("CheckPoint reached!"),  4000}})
+	table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("Got the saucer!"), SAY_SHOUT, 2000}})
+	table.insert(dialog02, {func = AnimSay, args = {director.gear, loc("Nice!"), SAY_SHOUT, 1000}})
+	table.insert(dialog02, {func = AnimSay, args = {director.gear, loc("Now use it and go to the moon PAotH station to get more fuels!"), SAY_SHOUT, 5000}})
+    table.insert(dialog02, {func = AnimGearWait, args = {hero.gear, 500}})
+    -- DIALOG 03 - Hero got spotted by guard
+	AddSkipFunction(dialog03, Skipanim, {dialog03})
+	table.insert(dialog03, {func = AnimWait, args = {guard1.gear, 4000}})
+	table.insert(dialog03, {func = AnimCaption, args = {guard1.gear, loc("Prepare to flee!"),  4000}})	
+	table.insert(dialog03, {func = AnimSay, args = {guard1.gear, loc("Hey").." "..guard2.name.."! "..loc("Look, someone is stealing the saucer!"), SAY_SHOUT, 4000}})
+	table.insert(dialog03, {func = AnimSay, args = {guard2.gear, loc("I'll get him!"), SAY_SAY, 4000}})
+	table.insert(dialog03, {func = startCombat, args = {guard1.gear}})
+	-- DIALOG 04 - Hero out of sight
+	AddSkipFunction(dialog04, Skipanim, {dialog04})
+	table.insert(dialog04, {func = AnimCaption, args = {guard1.gear, loc("You are out of danger, time to go to the moon!"),  4000}})
+	table.insert(dialog04, {func = AnimSay, args = {guard1.gear, loc("I guess we lost him!"), SAY_SAY, 3000}})
+	table.insert(dialog04, {func = AnimSay, args = {guard2.gear, loc("We should better report this and continue our watch!"), SAY_SAY, 5000}})
+	table.insert(dialog04, {func = AnimSwitchHog, args = {hero.gear}})
+	-- DIALOG 05 - Hero returned from moon without fuels
+	AddSkipFunction(dialog05, Skipanim, {dialog05})
+	table.insert(dialog05, {func = AnimSay, args = {hero.gear, loc("I guess I can't go far without fuels!"), SAY_THINK, 6000}})
+	table.insert(dialog05, {func = AnimSay, args = {hero.gear, loc("Go to go back"), SAY_THINK, 2000}})
+	table.insert(dialog05, {func = sendStatsOnRetry, args = {hero.gear}})
+	-- DIALOG 06 - Landing on wrong planet or on earth if not enough fuels
+	AddSkipFunction(dialog06, Skipanim, {dialog06})
+	table.insert(dialog06, {func = AnimCaption, args = {hero.gear, loc("You have to try again!"),  5000}})
+	table.insert(dialog06, {func = AnimSay, args = {hero.gear, loc("Hm... Now I run out of fuels..."), SAY_THINK, 3000}})
+	table.insert(dialog06, {func = sendStatsOnRetry, args = {hero.gear}})
+	-- DIALOG 07 - Hero lands on Death Planet but isn't allowed yet to play this map
+	AddSkipFunction(dialog07, Skipanim, {dialog07})
+	table.insert(dialog07, {func = AnimCaption, args = {hero.gear, loc("This planet seems dangerous!"),  5000}})
+	table.insert(dialog07, {func = AnimSay, args = {hero.gear, loc("I am not ready for this planet yet. I should visit it when I have found all the other parts"), SAY_THINK, 4000}})
+	-- DIALOG 08 - Hero wins death01
+	AddSkipFunction(dialog08, Skipanim, {dialog08})
+	table.insert(dialog08, {func = AnimCaption, args = {hero.gear, loc("Under the meteorite shadow..."),  4000}})
+	table.insert(dialog08, {func = AnimSay, args = {doctor.gear, loc("You did great Hog Solo! However we aren't out of danger yet!"), SAY_SHOUT, 4500}})
+	table.insert(dialog08, {func = AnimSay, args = {doctor.gear, loc("The meteorite has come too close and the anti-gravity device isn't powerful enough to get it out of order"), SAY_SHOUT, 5000}})
+	table.insert(dialog08, {func = AnimSay, args = {doctor.gear, loc("We need it to get split into at least two parts"), SAY_SHOUT, 3000}})
+	table.insert(dialog08, {func = AnimSay, args = {doctor.gear, loc("PAotH has sent explosives but unfortunately the trigger mechanism seems to be faulty!"), SAY_SHOUT, 5000}})
+	table.insert(dialog08, {func = AnimSay, args = {doctor.gear, loc("We need you to go there and detonate them yourself! Good luck!"), SAY_SHOUT, 500}})
+	table.insert(dialog08, {func = AnimWait, args = {doctor.gear, 3000}})
+	table.insert(dialog08, {func = AnimSwitchHog, args = {hero.gear}})
+end
+
+------------------- custom "animation" functions --------------------------
+
+function startCombat()
+	-- use this so guard2 will gain control
+	AnimSwitchHog(hero.gear)
+	TurnTimeLeft = 0
+end
+
+function sendStats(planet)
+	SendStat(siGameResult, loc("Hog Solo arrived to "..planet))
+	SendStat(siCustomAchievement, loc("Return to the mission menu by pressing the \"Go back\" button"))
+	SendStat(siCustomAchievement, loc("Choose another planet by replaying the mission"))
+	SendStat(siPlayerKills,'1',teamC.name)
+	EndGame()
+end
+
+function sendStatsOnRetry()
+	SendStat(siGameResult, loc("You have to travel again"))
+	SendStat(siCustomAchievement, loc("Your first destination is moon in order to get more fuels"))
+	SendStat(siCustomAchievement, loc("You have to complete the moon main mission in order to travel to other planets"))
+	SendStat(siCustomAchievement, loc("You have to be careful and not die!"))
+	SendStat(siPlayerKills,'0',teamC.name)
+	EndGame()
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/death01.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/death01.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,319 @@
+------------------- ABOUT ----------------------
+--
+-- This is the mission to acquire the last part.
+-- This mission is the cameo of Professor Hogevil
+-- who has took hostages H and Dr. Cornelius.
+-- Hog Solo has to defeat him and his thugs.
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local missionName = loc("The last encounter")
+-- dialogs
+local dialog01 = {}
+-- missions objectives
+local goals = {
+	[dialog01] = {missionName, loc("The final part"), loc("Defeat Professor Hogevil!"), 1, 4500},
+}
+-- crates
+local teleportCrate = {x = 1935, y = 1830}
+local drillCrate = {x = 3810, y = 1705}
+local batCrate = {x = 1975, y = 1830}
+local blowtorchCrate = {x = 1520, y = 1950}
+local cakeCrate = {x = 325, y = 1500}
+local ropeCrate = {x = 1860, y = 500}
+local pickHammerCrate = {x = 1900, y = 400}
+-- hogs
+local hero = {}
+local paoth1 = {}
+local paoth2 = {}
+local professor = {}
+local thug1 = {}
+local thug2 = {}
+local thug3 = {}
+local thug4 = {}
+local thug5 = {}
+local thug6 = {}
+local thug7 = {}
+local thugs = { thug1, thug2, thug3, thug4, thug5, thug6, thug7 }
+-- teams
+local teamA = {}
+local teamB = {}
+local teamC = {}
+-- hedgehogs values
+hero.name = "Hog Solo"
+hero.x = 520
+hero.y = 845
+hero.dead = false
+paoth1.name = "H"
+paoth1.x = 3730
+paoth1.y = 1480
+paoth2.name = "Dr.Cornelius"
+paoth2.x = 3800
+paoth2.y = 1480
+professor.name = "Prof. Hogevil"
+professor.dead = false
+thug1.x = 1265
+thug1.y = 1400
+thug1.health = 70
+thug2.x = 2035
+thug2.y = 1320
+thug2.health = 95
+thug3.x = 1980
+thug3.y = 815
+thug3.health = 35
+thug3.turnLeft = true
+thug4.x = 2830
+thug4.y = 1960
+thug4.health = 80
+thug5.x = 2890
+thug5.y = 1960
+thug5.health = 80
+thug6.x = 2940
+thug6.y = 1960
+thug6.health = 80
+thug7.x = 2990
+thug7.y = 1960
+thug7.health = 80
+teamA.name = loc("Hog Solo")
+teamA.color = tonumber("38D61C",16) -- green
+teamB.name = loc("PAotH")
+teamB.color = tonumber("0033FF",16) -- blue because otherwise enemies attack them
+teamC.name = loc("Professor")
+teamC.color = tonumber("0033FF",16) -- blue
+
+-------------- LuaAPI EVENT HANDLERS ------------------
+
+function onGameInit()
+	Seed = 1
+	TurnTime = 25000
+	CaseFreq = 0
+	MinesNum = 3
+	MinesTime = 1500
+	Explosives = 2
+	Delay = 3
+	HealthCaseAmount = 50
+	SuddenDeathTurns = 100
+	Map = "death01_map"
+	Theme = "Hell"
+	
+	-- Hog Solo
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1")
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)
+	-- PAotH
+	AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	paoth1.gear = AddHog(paoth1.name, 0, 100, "hair_yellow")
+	AnimSetGearPosition(paoth1.gear, paoth1.x, paoth1.y)
+	HogTurnLeft(paoth1.gear, true)
+	paoth2.gear = AddHog(paoth2.name, 0, 100, "Glasses")
+	AnimSetGearPosition(paoth2.gear, paoth2.x, paoth2.y)
+	HogTurnLeft(paoth2.gear, true)
+	-- Professor and Thugs	
+	AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	professor.human = AddHog(professor.name, 0, 300, "tophats")
+	AnimSetGearPosition(professor.human, hero.x + 70, hero.y)
+	HogTurnLeft(professor.human, true)
+	AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	professor.bot = AddHog(professor.name, 1, 300, "tophats")
+	AnimSetGearPosition(professor.bot, paoth1.x - 100, paoth1.y)
+	HogTurnLeft(professor.bot, true)
+	professor.gear = professor.bot
+	for i=1,table.getn(thugs) do
+		thugs[i].gear = AddHog(loc("thug").." #"..i, 1, thugs[i].health, "war_desertgrenadier1")
+		AnimSetGearPosition(thugs[i].gear, thugs[i].x, thugs[i].y)
+		HogTurnLeft(thugs[i].gear, not thugs[i].turnLeft)
+	end
+	
+	initCheckpoint("death01")
+	
+	AnimInit()
+	AnimationSetup()
+end
+
+function onGameStart()
+	AnimWait(hero.gear, 3000)
+	FollowGear(hero.gear)
+	
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	AddEvent(onEnemiesDeath, {hero.gear}, enemiesDeath, {hero.gear}, 0)
+	
+	-- add crates
+	SpawnAmmoCrate(teleportCrate.x, teleportCrate.y, amTeleport)
+	SpawnAmmoCrate(drillCrate.x, drillCrate.y, amTeleport)
+	SpawnAmmoCrate(drillCrate.x, drillCrate.y, amDrill)
+	SpawnAmmoCrate(batCrate.x, batCrate.y, amBaseballBat)
+	SpawnAmmoCrate(blowtorchCrate.x, blowtorchCrate.y, amBlowTorch)
+	SpawnAmmoCrate(cakeCrate.x, cakeCrate.y, amCake)
+	SpawnAmmoCrate(ropeCrate.x, ropeCrate.y, amRope)
+	SpawnAmmoCrate(pickHammerCrate.x, pickHammerCrate.y, amPickHammer)
+	SpawnHealthCrate(cakeCrate.x + 40, cakeCrate.y)
+	SpawnHealthCrate(blowtorchCrate.x + 40, blowtorchCrate.y)
+	-- add explosives
+	AddGear(1900, 850, gtExplosives, 0, 0, 0, 0)
+	AddGear(1900, 800, gtExplosives, 0, 0, 0, 0)
+	AddGear(1900, 750, gtExplosives, 0, 0, 0, 0)
+	AddGear(1900, 710, gtExplosives, 0, 0, 0, 0)
+	-- add mines
+	AddGear(3520, 1650, gtMine, 0, 0, 0, 0)
+	AddGear(3480, 1680, gtMine, 0, 0, 0, 0)
+	AddGear(3440, 1690, gtMine, 0, 0, 0, 0)
+	AddGear(3400, 1710, gtMine, 0, 0, 0, 0)
+	AddGear(2100, 1730, gtMine, 0, 0, 0, 0)
+	AddGear(2150, 1730, gtMine, 0, 0, 0, 0)
+	AddGear(2200, 1750, gtMine, 0, 0, 0, 0)
+	-- add girders
+	PlaceGirder(3770, 1370, 4)
+	PlaceGirder(3700, 1460, 6)
+	PlaceGirder(3840, 1460, 6)
+	
+	-- add ammo
+	-- hero ammo
+	AddAmmo(hero.gear, amRope, 2)
+	AddAmmo(hero.gear, amBazooka, 3)
+	AddAmmo(hero.gear, amParachute, 1)
+	AddAmmo(hero.gear, amGrenade, 6)
+	AddAmmo(hero.gear, amDEagle, 4)
+	AddAmmo(hero.gear, amSkip, 100)
+	local bonus = tonumber(getBonus(3))
+	if bonus > 0 then
+		SetHealth(hero.gear, 120)
+		AddAmmo(hero.gear, amLaserSight, 1)
+		saveBonus(3, bonus-1)
+	end
+	-- evil ammo
+	AddAmmo(professor.gear, amRope, 4)
+	AddAmmo(professor.gear, amBazooka, 8)
+	AddAmmo(professor.gear, amSwitch, 100)
+	AddAmmo(professor.gear, amGrenade, 8)
+	AddAmmo(professor.gear, amDEagle, 8)
+	
+	HideHog(professor.bot)
+	AddAnim(dialog01)
+	
+	SendHealthStatsOff()
+end
+
+function onNewTurn()
+	if CurrentHedgehog == paoth1.gear or CurrentHedgehog == paoth2.gear then
+		AnimSwitchHog(hero.gear)
+		TurnTimeLeft = 0
+	end
+end
+
+function onGameTick()
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+end
+
+function onAmmoStoreInit()
+	SetAmmo(amCake, 0, 0, 0, 1)
+	SetAmmo(amTeleport, 0, 0, 0, 1)
+	SetAmmo(amBaseballBat, 0, 0, 0, 4)
+	SetAmmo(amBlowTorch, 0, 0, 0, 1)
+	SetAmmo(amRope, 0, 0, 0, 2)
+	SetAmmo(amPickHammer, 0, 0, 0, 1)
+	SetAmmo(amDrill, 0, 0, 0, 1)
+end
+
+function onGearDelete(gear)
+	if gear == hero.gear then
+		hero.dead = true
+	elseif gear == professor.gear then
+		professor.dead = true
+	end
+end
+
+function onPrecise()
+	if GameTime > 3000 then
+		SetAnimSkip(true)   
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onHeroDeath(gear)
+	if hero.dead then
+		return true
+	end
+	return false
+end
+
+function onEnemiesDeath(gear)
+	local allDead = true
+	if professor.dead then
+		for i=1,table.getn(thugs) do
+			if GetHealth(thugs[i]) then
+				allDead = false
+				break
+			end
+		end
+	else
+		allDead = false
+	end
+	return allDead
+end
+
+-------------- ACTIONS ------------------
+
+function heroDeath(gear)
+	SendStat(siGameResult, loc("Hog Solo lost, try again!"))
+	SendStat(siCustomAchievement, loc("To win the game you have to eliminate all your enemies"))
+	SendStat(siPlayerKills,'1',teamC.name)
+	SendStat(siPlayerKills,'0',teamA.name)
+	EndGame()
+end
+
+function enemiesDeath(gear)
+	saveCompletedStatus(6)
+	SendStat(siGameResult, loc("Congratulations, you won!"))
+	SendStat(siCustomAchievement, loc("You have successfuly eliminated Professor Hogevil"))
+	SendStat(siCustomAchievement, loc("You have rescued H and Dr.Cornelius"))
+	SendStat(siCustomAchievement, loc("You have acquired the last part"))
+	SendStat(siCustomAchievement, loc("Now go and play the menu mission to complete the campaign"))
+	SendStat(siPlayerKills,'1',teamA.name)
+	SendStat(siPlayerKills,'0',teamC.name)
+	EndGame()
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+	if goals[anim] ~= nil then
+		ShowMission(unpack(goals[anim]))
+    end
+    startBattle()
+end
+
+function AnimationSetup()
+	-- DIALOG01, GAME START, INTRODUCTION
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Somewhere in the uninhabitable Death Planet..."), 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {professor.human, loc("Welcome Hog Solo, surpised to see me?"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {professor.human, loc("As you can see I have survived our last encounter and I had time to plot my master plan!"), SAY_SAY, 4000}})	
+	table.insert(dialog01, {func = AnimSay, args = {professor.human, loc("I've thought that the best way to get the device is to let you collect most of the parts for me!"), SAY_SAY, 4000}})	
+	table.insert(dialog01, {func = AnimSay, args = {professor.human, loc("So, now I got the last part and I have your friends captured..."), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {professor.human, loc("Will you give me the other parts?"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("I will never hand you the parts!"), SAY_SAY, 4000}})	
+	table.insert(dialog01, {func = AnimWait, args = {professor.human, 3000}})
+	table.insert(dialog01, {func = AnimSay, args = {professor.human, loc("Then prepare for battle!"), SAY_SAY, 4000}})	
+	table.insert(dialog01, {func = startBattle, args = {}})	
+end
+
+-------------- OTHER FUNCTIONS -----------------
+
+function startBattle()
+	DeleteGear(professor.human)
+	RestoreHog(professor.bot)
+	AnimSwitchHog(professor.gear)
+	TurnTimeLeft = 0
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/death02.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/death02.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,292 @@
+------------------- ABOUT ----------------------
+--
+-- Hero has been surrounded my some space villains
+-- He has to defeat them in order to escape
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local missionName = loc("Killing the specialists")
+local challengeObjectives = loc("Use your available weapons in order to eliminate the enemies").."|"..
+	loc("Each time you play this missions enemy hogs will play in a random order").."|"..
+	loc("At the start of the game each enemy hog has only the weapon that he is named of").."|"..
+	loc("A random hog will inherit the weapons of the deceased hogs").."|"..
+	loc("If you kill a hog with the weapon your hp will be 100").."|"..
+	loc("If you injure a hog you'll get 35% of the damage dealt").."|"..
+	loc("Every time you kill an enemy hog your ammo will get reseted").."|"..
+	loc("Rope won't get reseted")
+-- dialogs
+local dialog01 = {}
+-- mission objectives
+local goals = {
+	[dialog01] = {missionName, loc("Challenge Objectives"), challengeObjectives, 1, 4500},
+}
+-- hogs
+local hero = {
+	name = loc("Hog Solo"),
+	x = 850,
+	y = 460,
+	mortarAmmo = 2,
+	firepunchAmmo = 1,
+	deagleAmmo = 4,
+	bazookaAmmo = 2,
+	grenadeAmmo = 4,
+}
+local enemies = {
+	{ name = loc("Mortar"), x = 1890, y = 520, weapon = amMortar, additionalWeapons = {}},
+	{ name = loc("Desert Eagle"), x = 1390, y = 790, weapon = amDEagle, additionalWeapons = {}},
+	{ name = loc("Grenade"), x = 186, y = 48, weapon = amGrenade, additionalWeapons = {}},
+	{ name = loc("Shoryuken"), x = 330, y = 270, weapon = amFirePunch, additionalWeapons = {}},
+	{ name = loc("Bazooka"), x = 1950, y = 150, weapon = amBazooka, additionalWeapons = {}},
+}
+-- teams
+local teamA = {
+	name = loc("Hog Solo"),
+	color = tonumber("38D61C",16) -- green
+}
+local teamB = {
+	name = loc("5 deadly hogs"),
+	color = tonumber("FF0000",16) -- red
+}
+
+-------------- LuaAPI EVENT HANDLERS ------------------
+
+function onGameInit()
+	Seed = 1
+	TurnTime = 25000
+	CaseFreq = 0
+	MinesNum = 0
+	MinesTime = 1
+	Explosives = 0
+	Map = "death02_map"
+	Theme = "Hell"
+	
+	-- Hog Solo
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1")
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)
+	-- enemies
+	shuffleHogs(enemies)
+	AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	for i=1,table.getn(enemies) do
+		enemies[i].gear = AddHog(enemies[i].name, 1, 100, "war_desertgrenadier1")
+		AnimSetGearPosition(enemies[i].gear, enemies[i].x, enemies[i].y)
+	end
+	
+	initCheckpoint("death02")
+	
+	AnimInit()
+	AnimationSetup()
+end
+
+function onGameStart()
+	AnimWait(hero.gear, 3000)
+	FollowGear(hero.gear)
+	ShowMission(missionName, loc("Challenge Objectives"), challengeObjectives, -amSkip, 0)
+	
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	AddEvent(onHeroWin, {hero.gear}, heroWin, {hero.gear}, 0)
+
+	--hero ammo
+	AddAmmo(hero.gear, amSkip, 100)
+	AddAmmo(hero.gear, amRope, 2)
+	refreshHeroAmmo()
+
+	SendHealthStatsOff()
+	AddAnim(dialog01)
+end
+
+function onNewTurn()
+	if CurrentHedgehog ~= hero.gear then
+		enemyWeapons()
+	end
+end
+
+function onGearDelete(gear)
+	if isHog(gear) then
+		SetHealth(hero.gear, 100)
+		local deadHog = getHog(gear)
+		if deadHog.weapon == amMortar then
+			hero.mortarAmmo = 0
+		elseif deadHog.weapon == amFirePunch then
+			hero.firepunchAmmo = 0
+		elseif deadHog.weapon == amDEagle then
+			hero.deagleAmmo = 0
+		elseif deadHog.weapon == amBazooka then
+			hero.bazookaAmmo = 0
+		elseif deadHog.weapon == amGrenade then
+			hero.grenadeAmmo = 0
+		end		
+		local randomHog = math.random(1,table.getn(enemies))
+		while not GetHealth(enemies[randomHog].gear) do
+			randomHog = math.random(1,table.getn(enemies))
+		end
+		table.insert(enemies[randomHog].additionalWeapons, deadHog.weapon)
+		for i=1,table.getn(deadHog.additionalWeapons) do
+			table.insert(enemies[randomHog].additionalWeapons, deadHog.additionalWeapons[i])
+		end
+		refreshHeroAmmo()
+	end
+end
+
+function onGearDamage(gear, damage)
+	if isHog(gear) and GetHealth(hero.gear) then
+		SetHealth(hero.gear, GetHealth(hero.gear) + damage/3)
+	end
+end
+
+function onGameTick()
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+end
+
+function onPrecise()
+	if GameTime > 3000 then
+		SetAnimSkip(true)   
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onHeroDeath(gear)
+	if not GetHealth(hero.gear) then
+		return true
+	end
+	return false
+end
+
+function onHeroWin(gear)
+	local allDead = true
+	for i=1,table.getn(enemies) do
+		if GetHealth(enemies[i].gear) then
+			allDead = false
+			break
+		end
+	end
+	return allDead
+end
+
+-------------- ACTIONS ------------------
+
+function heroDeath(gear)
+	SendStat(siGameResult, loc("Hog Solo lost, try again!"))
+	SendStat(siCustomAchievement, loc("You have to eliminate all the enemies"))			
+	SendStat(siCustomAchievement, loc("Read the Challenge Objectives from within the mission for more details"))		
+	SendStat(siPlayerKills,'1',teamB.name)
+	SendStat(siPlayerKills,'0',teamA.name)
+	EndGame()
+end
+
+function heroWin(gear)
+	saveBonus(3, 4)
+	SendStat(siGameResult, loc("Congratulations, you won!"))
+	SendStat(siCustomAchievement, loc("You complete the mission in "..TotalRounds.." rounds"))			
+	SendStat(siCustomAchievement, loc("The next 4 times you'll play the \"The last encounter\" mission you'll get 20 more hit points and a Laser Sight"))		
+	SendStat(siPlayerKills,'1',teamA.name)
+	EndGame()
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+	if goals[anim] ~= nil then
+		ShowMission(unpack(goals[anim]))
+    end
+    startBattle()
+end
+
+function AnimationSetup()
+	-- DIALOG 01 - Start, game instructions
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Somewhere in the Planet of Death..."), 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("...Hog Solo fights for his life"), 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Each time you play this missions enemy hogs will play in a random order"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("At the start of the game each enemy hog has only the weapon that he is named of"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("A random hog will inherit the weapons of the deceased hogs"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("If you kill a hog with the weapon your hp will be 100"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("If you injure a hog you'll get 35% of the damage dealt"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Every time you kill an enemy hog your ammo will get reseted"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Rope won't get reseted"), 2000}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}})
+	table.insert(dialog01, {func = startBattle, args = {hero.gear}})	
+end
+
+------------ Other Functions -------------------
+
+function startBattle()
+	AnimSwitchHog(hero.gear)
+	TurnTimeLeft = TurnTime
+end
+
+function shuffleHogs(hogs)
+    local hogsNumber = table.getn(hogs)
+    for i=1,hogsNumber do
+		local randomHog = math.random(hogsNumber)
+		hogs[i], hogs[randomHog] = hogs[randomHog], hogs[i]
+    end
+end
+
+function refreshHeroAmmo()
+	local extraAmmo = 0
+	if getAliveEnemiesCount() == 1 then
+		extraAmmo = 2
+	end
+	AddAmmo(hero.gear, amMortar, hero.mortarAmmo + extraAmmo)
+	AddAmmo(hero.gear, amFirePunch, hero.firepunchAmmo + extraAmmo)
+	AddAmmo(hero.gear, amDEagle, hero.deagleAmmo + extraAmmo)
+	AddAmmo(hero.gear, amBazooka, hero.bazookaAmmo + extraAmmo)
+	AddAmmo(hero.gear, amGrenade, hero.grenadeAmmo + extraAmmo)
+end
+
+function enemyWeapons()
+	for i=1,table.getn(enemies) do
+		if GetHealth(enemies[i].gear) and enemies[i].gear == CurrentHedgehog then
+			AddAmmo(enemies[i].gear, amMortar, 0)
+			AddAmmo(enemies[i].gear, amFirePunch, 0)
+			AddAmmo(enemies[i].gear, amDEagle, 0)
+			AddAmmo(enemies[i].gear, amBazooka, 0)
+			AddAmmo(enemies[i].gear, amGrenade, 0)
+			AddAmmo(enemies[i].gear, enemies[i].weapon, 1)
+			for w=1,table.getn(enemies[i].additionalWeapons) do
+				AddAmmo(enemies[i].gear, enemies[i].additionalWeapons[w], 1)
+			end
+		end
+	end
+end
+
+function isHog(gear)
+	local hog = false
+	for i=1,table.getn(enemies) do
+		if gear == enemies[i].gear then
+			hog = true
+			break
+		end
+	end
+	return hog
+end
+
+function getHog(gear)
+	for i=1,table.getn(enemies) do
+		if gear == enemies[i].gear then
+			return enemies[i]
+		end
+	end
+end
+
+function getAliveEnemiesCount()
+	local count = 0
+	for i=1,table.getn(enemies) do
+		if GetHealth(enemies[i].gear) then
+			count = count + 1
+		end
+	end
+	return count
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert01.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert01.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,513 @@
+------------------- ABOUT ----------------------
+--
+-- In the desert planet Hero will have to explore
+-- the dunes below the surface and find the hidden
+-- crates. It is told that one crate contains the
+-- lost part.
+
+-- Idea: game will be successfully end when the 2 lower crates are collected
+-- it would be more defficult (and sadistic) if one should collect *all* the crates
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local campaignName = loc("A Space Adventure")
+local missionName = loc("Searching in the dust")
+local heroIsInBattle = false
+local ongoingBattle = 0
+local cratesFound = 0
+local checkPointReached = 1 -- 1 is normal spawn
+-- dialogs
+local dialog01 = {}
+-- mission objectives
+local goals = {
+	[dialog01] = {missionName, loc("Getting ready"), loc("The part is hidden in one of the crates! Go and get it!"), 1, 4500},
+}
+-- crates
+local btorch1Y = 60
+local btorch1X = 2700
+local btorch2Y = 1900
+local btorch2X = 2150
+local btorch3Y = 980
+local btorch3X = 3260
+local rope1Y = 970
+local rope1X = 3200
+local rope2Y = 1900
+local rope2X = 680
+local rope3Y = 1850
+local rope3X = 2460
+local portalY = 480
+local portalX = 1465
+local girderY = 1630
+local girderX = 3350
+-- hogs
+local hero = {}
+local ally = {}
+local smuggler1 = {}
+local smuggler2 = {}
+local smuggler3 = {}
+-- teams
+local teamA = {}
+local teamB = {}
+local teamC = {}
+-- hedgehogs values
+hero.name = loc("Hog Solo")
+hero.x = 1740
+hero.y = 40
+hero.dead = false
+ally.name = loc("Chief Sandologist")
+ally.x = 1660
+ally.y = 40
+smuggler1.name = loc("Sandy")
+smuggler1.x = 400
+smuggler1.y = 235
+smuggler2.name = loc("Spike")
+smuggler2.x = 736
+smuggler2.y = 860
+smuggler3.name = loc("Sandstorm")
+smuggler3.x = 1940
+smuggler3.y = 1625
+teamA.name = loc("PAotH")
+teamA.color = tonumber("FF0000",16) -- red
+teamB.name = loc("Smugglers")
+teamB.color = tonumber("0033FF",16) -- blues
+teamC.name = loc("Hog Solo")
+teamC.color = tonumber("38D61C",16) -- green
+
+-------------- LuaAPI EVENT HANDLERS ------------------
+
+function onGameInit()
+	Seed = 1
+	TurnTime = 20000
+	CaseFreq = 0
+	MinesNum = 0
+	MinesTime = 1
+	Explosives = 0
+	Delay = 3
+	HealthCaseAmount = 30
+	Map = "desert01_map"
+	Theme = "Desert"
+	
+	-- get the check point
+	checkPointReached = initCheckpoint("desert01")
+	-- get hero health
+	local heroHealth = 100
+	if checkPointReached > 1 and tonumber(GetCampaignVar("HeroHealth")) then
+		heroHealth = tonumber(GetCampaignVar("HeroHealth"))
+	end
+	
+	-- Hog Solo
+	AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	hero.gear = AddHog(hero.name, 0, heroHealth, "war_desertgrenadier1")
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)
+	HogTurnLeft(hero.gear, true)
+	-- PAotH undercover scientist and chief Sandologist
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	ally.gear = AddHog(ally.name, 0, 100, "Cowboy")
+	AnimSetGearPosition(ally.gear, ally.x, ally.y)
+	-- Smugglers
+	AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	smuggler1.gear = AddHog(smuggler1.name, 1, 100, "hair_orange")
+	AnimSetGearPosition(smuggler1.gear, smuggler1.x, smuggler1.y)
+	smuggler2.gear = AddHog(smuggler2.name, 1, 100, "lambda")
+	AnimSetGearPosition(smuggler2.gear, smuggler2.x, smuggler2.y)	
+	smuggler3.gear = AddHog(smuggler3.name, 1, 100, "beefeater")
+	AnimSetGearPosition(smuggler3.gear, smuggler3.x, smuggler3.y)	
+	
+	if checkPointReached == 1 then
+		-- Start of the game
+	elseif checkPointReached == 2 then
+		AnimSetGearPosition(hero.gear, 1050, 615)
+		HogTurnLeft(hero.gear, true)
+	elseif checkPointReached == 3 then
+		AnimSetGearPosition(hero.gear, 1680, 920)
+		HogTurnLeft(hero.gear, true)
+	elseif checkPointReached == 4 then
+		AnimSetGearPosition(hero.gear, 1160, 1180)
+	elseif checkPointReached == 5 then
+		AnimSetGearPosition(hero.gear, girderX+40, girderY-30)
+	end
+	
+	AnimInit()
+	AnimationSetup()	
+end
+
+function onGameStart()
+	AnimWait(hero.gear, 3000)
+	FollowGear(hero.gear)
+	
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	AddEvent(onHeroAtFirstBattle, {hero.gear}, heroAtFirstBattle, {hero.gear}, 1)
+	AddEvent(onHeroFleeFirstBattle, {hero.gear}, heroFleeFirstBattle, {hero.gear}, 1)
+	AddEvent(onHeroAtCheckpoint4, {hero.gear}, heroAtCheckpoint4, {hero.gear}, 0)
+	AddEvent(onHeroAtThirdBattle, {hero.gear}, heroAtThirdBattle, {hero.gear}, 0)
+	AddEvent(onCheckForWin1, {hero.gear}, checkForWin1, {hero.gear}, 0)
+	AddEvent(onCheckForWin2, {hero.gear}, checkForWin2, {hero.gear}, 0)
+	
+	-- smugglers ammo
+	AddAmmo(smuggler1.gear, amBazooka, 2)
+	AddAmmo(smuggler1.gear, amGrenade, 2)
+	AddAmmo(smuggler1.gear, amDEagle, 2)	
+	AddAmmo(smuggler3.gear, amRope, 2)
+	
+	-- spawn crates
+	SpawnAmmoCrate(btorch2X, btorch2Y, amBlowTorch)
+	SpawnAmmoCrate(btorch3X, btorch3Y, amBlowTorch)
+	SpawnAmmoCrate(rope1X, rope1Y, amRope)
+	SpawnAmmoCrate(rope2X, rope2Y, amRope)
+	SpawnAmmoCrate(rope3X, rope3Y, amRope)
+	SpawnAmmoCrate(portalX, portalY, amPortalGun)	
+	SpawnAmmoCrate(girderX, girderY, amGirder)
+	
+	SpawnHealthCrate(3300, 970)
+	
+	-- adding mines - BOOM!
+	AddGear(1280, 460, gtMine, 0, 0, 0, 0)
+	AddGear(270, 460, gtMine, 0, 0, 0, 0)
+	AddGear(3460, 60, gtMine, 0, 0, 0, 0)
+	AddGear(3500, 240, gtMine, 0, 0, 0, 0)
+	AddGear(3410, 670, gtMine, 0, 0, 0, 0)
+	AddGear(3450, 720, gtMine, 0, 0, 0, 0)
+	
+	local x = 800
+	while x < 1630 do
+		AddGear(x, 900, gtMine, 0, 0, 0, 0)
+		x = x + math.random(8,20)
+	end
+	x = 1890
+	while x < 2988 do
+		AddGear(x, 760, gtMine, 0, 0, 0, 0)
+		x = x + math.random(8,20)
+	end
+	x = 2500
+	while x < 3300 do
+		AddGear(x, 1450, gtMine, 0, 0, 0, 0)
+		x = x + math.random(8,20)
+	end
+	x = 1570
+	while x < 2900 do
+		AddGear(x, 470, gtMine, 0, 0, 0, 0)
+		x = x + math.random(8,20)
+	end
+	
+	if checkPointReached == 1 then	
+		AddEvent(onHeroAtCheckpoint2, {hero.gear}, heroAtCheckpoint2, {hero.gear}, 0)
+		AddEvent(onHeroAtCheckpoint3, {hero.gear}, heroAtCheckpoint3, {hero.gear}, 0)
+		-- crates
+		SpawnAmmoCrate(btorch1X, btorch1Y, amBlowTorch)
+		SpawnHealthCrate(680, 460)
+		-- hero ammo
+		AddAmmo(hero.gear, amRope, 2)
+		AddAmmo(hero.gear, amBazooka, 3)
+		AddAmmo(hero.gear, amParachute, 1)
+		AddAmmo(hero.gear, amGrenade, 6)
+		AddAmmo(hero.gear, amDEagle, 4)
+		AddAmmo(hero.gear, amRCPlane, tonumber(getBonus(1)))
+	
+		AddAnim(dialog01)
+	elseif checkPointReached == 2 or checkPointReached == 3 then
+		ShowMission(campaignName, missionName, loc("The part is hidden in one of the crates! Go and get it!"), -amSkip, 0)
+		loadHeroAmmo()
+		
+		secondBattle()
+	elseif checkPointReached == 4 or checkPointReached == 5 then
+		ShowMission(campaignName, missionName, loc("The part is hidden in one of the crates! Go and get it!"), -amSkip, 0)
+		loadHeroAmmo()
+	end
+	
+	SendHealthStatsOff()
+end
+
+function onNewTurn()
+	if CurrentHedgehog ~= hero.gear and not heroIsInBattle then
+		TurnTimeLeft = 0
+	elseif CurrentHedgehog == hero.gear and not heroIsInBattle then
+		TurnTimeLeft = -1
+	elseif (CurrentHedgehog == smuggler2.gear or CurrentHedgehog == smuggler3.gear) and ongoingBattle == 1 then
+		AnimSwitchHog(hero.gear)
+		TurnTimeLeft = 0
+	elseif (CurrentHedgehog == smuggler1.gear or CurrentHedgehog == smuggler3.gear) and ongoingBattle == 2 then
+		AnimSwitchHog(hero.gear)
+		TurnTimeLeft = 0
+	elseif (CurrentHedgehog == smuggler1.gear or CurrentHedgehog == smuggler2.gear) and ongoingBattle == 3 then
+		AnimSwitchHog(hero.gear)
+		TurnTimeLeft = 0
+	elseif CurrentHedgehog == ally.gear then
+		TurnTimeLeft = 0
+	end
+end
+
+function onGameTick()
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+end
+
+function onAmmoStoreInit()
+	SetAmmo(amBlowTorch, 0, 0, 0, 1)
+	SetAmmo(amRope, 0, 0, 0, 1)
+	SetAmmo(amPortalGun, 0, 0, 0, 1)	
+	SetAmmo(amGirder, 0, 0, 0, 3)
+end
+
+function onGearDelete(gear)
+	if gear == hero.gear then
+		hero.dead = true
+	elseif (gear == smuggler1.gear or gear == smuggler2.gear or gear == smuggler3.gear) and heroIsInBattle then
+		heroIsInBattle = false
+		ongoingBattle = 0
+	end
+end
+
+function onPrecise()
+	if GameTime > 3000 then
+		SetAnimSkip(true)   
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onHeroDeath(gear)
+	if hero.dead then
+		return true
+	end
+	return false
+end
+
+function onHeroAtFirstBattle(gear)
+	if not hero.dead and not heroIsInBattle and GetHealth(smuggler1.gear) and GetX(hero.gear) <= 1450 
+			and GetY(hero.gear) <= GetY(smuggler1.gear)+5 and GetY(hero.gear) >= GetY(smuggler1.gear)-5 then
+		return true
+	end
+	return false
+end
+
+function onHeroFleeFirstBattle(gear)
+	if not hero.dead and GetHealth(smuggler1.gear) and heroIsInBattle and ongoingBattle == 1 and (GetX(hero.gear) > 1450 
+			or (GetY(hero.gear) < GetY(smuggler1.gear)-80 or GetY(hero.gear) > smuggler1.y+300)) then
+		return true
+	end
+	return false
+end
+
+-- saves the location of the hero and prompts him for the second battle
+function onHeroAtCheckpoint2(gear)
+	if not hero.dead and GetX(hero.gear) > 1000 and GetX(hero.gear) < 1100
+			and GetY(hero.gear) > 590 and GetY(hero.gear) < 700 then
+		return true
+	end
+	return false
+end
+
+function onHeroAtCheckpoint3(gear)
+	if not hero.dead and GetX(hero.gear) > 1610 and GetX(hero.gear) < 1680
+			and GetY(hero.gear) > 850 and GetY(hero.gear) < 1000 then
+		return true
+	end
+	return false
+end
+
+function onHeroAtCheckpoint4(gear)
+	if not hero.dead and GetX(hero.gear) > 1110 and GetX(hero.gear) < 1300
+			and GetY(hero.gear) > 1100 and GetY(hero.gear) < 1220 then
+		return true
+	end
+	return false
+end
+
+function onHeroAtThirdBattle(gear)
+	if not hero.dead and GetX(hero.gear) > 2000 and GetX(hero.gear) < 2200
+			and GetY(hero.gear) > 1430 and GetY(hero.gear) < 1670 then
+		return true
+	end
+	return false
+end
+
+function onCheckForWin1(gear)
+	if not hero.dead and GetX(hero.gear) > btorch2X-30 and GetX(hero.gear) < btorch2X+30
+			and GetY(hero.gear) > btorch2Y-30 and GetY(hero.gear) < btorch2Y+30 then
+		return true
+	end
+	return false
+end
+
+function onCheckForWin2(gear)
+	if not hero.dead and GetX(hero.gear) > girderX-30 and GetX(hero.gear) < girderX+30
+			and GetY(hero.gear) > girderY-30 and GetY(hero.gear) < girderY+30 then
+		return true
+	end
+	return false
+end
+
+-------------- ACTIONS ------------------
+
+function heroDeath(gear)
+	SendStat(siGameResult, loc("Hog Solo lost, try again!"))
+	SendStat(siCustomAchievement, loc("To win the game you have to find the right crate"))
+	SendStat(siCustomAchievement, loc("You can avoid some battles"))
+	SendStat(siCustomAchievement, loc("Use your ammo wisely"))
+	SendStat(siPlayerKills,'1',teamB.name)
+	SendStat(siPlayerKills,'0',teamC.name)
+	EndGame()
+end
+
+function heroAtFirstBattle(gear)
+	AnimCaption(hero.gear, loc("A smuggler! Prepare for battle"), 5000)
+	TurnTimeLeft = 0
+	heroIsInBattle = true
+	ongoingBattle = 1	
+	AnimSwitchHog(smuggler1.gear)
+	TurnTimeLeft = 0
+end
+
+function heroFleeFirstBattle(gear)
+	AnimSay(smuggler1.gear, loc("Run away you coward!"), SAY_SHOUT, 4000)
+	TurnTimeLeft = 0
+	heroIsInBattle = false
+	ongoingBattle = 0
+end
+
+function heroAtCheckpoint2(gear)
+	if GetAmmoCount(hero.gear, amRope) > 0 or GetAmmoCount(hero.gear, amParachute) > 0 then
+		saveCheckPointLocal("2")
+	end
+	secondBattle()
+end
+
+function heroAtCheckpoint3(gear)
+	if GetAmmoCount(hero.gear, amRope) > 0 then
+		saveCheckPointLocal("3")
+	end
+	secondBattle()
+end
+
+function heroAtCheckpoint4(gear)
+	saveCheckPointLocal("4")
+end
+
+function heroAtThirdBattle(gear)
+	heroIsInBattle = true
+	ongoingBattle = 3
+	AnimSay(smuggler3.gear, loc("Who's there?! I'll get you..."), SAY_SHOUT, 5000)	
+	AnimSwitchHog(smuggler3.gear)
+	TurnTimeLeft = 0
+end
+
+-- for some weird reson I couldn't call the same action for both events
+function checkForWin1(gear)
+	checkForWin()
+end
+
+function checkForWin2(gear)
+	-- ok lets place one more checkpoint as next part seems challenging without rope
+	if cratesFound ==  0 then
+		saveCheckPointLocal("5")
+	end
+	
+	checkForWin()	
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+	if goals[anim] ~= nil then
+		ShowMission(unpack(goals[anim]))
+    end
+    AnimSwitchHog(hero.gear)
+	if anim == dialog01 then
+		startMission()
+	end
+end
+
+function AnimationSetup()
+	-- DIALOG 01 - Start, getting info about the device
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("In the Planet of Sand, you have to double check your moves..."), 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Finaly you are here..."), SAY_SAY, 2000}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 2000}})
+	table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("Thank you for meeting me in such a short notice!"), SAY_SAY, 3000}})
+	table.insert(dialog01, {func = AnimWait, args = {ally.gear, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("No problem, I would do anything for H!"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Now listen carefully! Below us there are tunnels that have been created naturally over the years"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("I have heared the local tribes saying that many years ago some PAotH scientists were dumping their waste here"), SAY_SAY, 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("H confimed that there isn't such a PAotH activity logged"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("So, I believe that it's a good place to start"), SAY_SAY, 3000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Beware though! Many smugglers come often to explore these tunnels and scavage whatever valuable items they can find"), SAY_SAY, 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("They won't hesitate to attack you in order to rob you!"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 6000}})
+	table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("OK, I'll be extra careful!"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimWait, args = {ally.gear, 2000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("There is the tunnel entrance"), SAY_SAY, 3000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Good luck!"), SAY_SAY, 3000}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}})
+	table.insert(dialog01, {func = startMission, args = {hero.gear}})	
+end
+
+--------------- OTHER FUNCTIONS ------------------
+
+function startMission()
+	AnimSwitchHog(ally.gear)
+	TurnTimeLeft = 0
+end
+
+function secondBattle()
+	-- second battle
+	heroIsInBattle = true
+	ongoingBattle = 2
+	AnimSay(smuggler2.gear, loc("This is seems like a wealthy hedgehog, nice..."), SAY_THINK, 5000)	
+	AnimSwitchHog(smuggler2.gear)
+	TurnTimeLeft = 0
+end
+
+function saveCheckPointLocal(cpoint)
+	-- save checkpoint
+	saveCheckpoint(cpoint)	
+	SaveCampaignVar("HeroHealth", GetHealth(hero.gear))
+	-- bazooka - grenade - rope - parachute - deagle - btorch - construct - portal - rcplane
+	SaveCampaignVar("HeroAmmo", GetAmmoCount(hero.gear, amBazooka)..GetAmmoCount(hero.gear, amGrenade)..
+			GetAmmoCount(hero.gear, amRope)..GetAmmoCount(hero.gear, amParachute)..GetAmmoCount(hero.gear, amDEagle)..
+			GetAmmoCount(hero.gear, amBlowTorch)..GetAmmoCount(hero.gear, amConstruction)..
+			GetAmmoCount(hero.gear, amPortalGun)..GetAmmoCount(hero.gear, amRCPlane))
+	AnimCaption(hero.gear, loc("Checkpoint reached!"), 5000)
+end
+
+function loadHeroAmmo()
+	-- hero ammo
+	local ammo = GetCampaignVar("HeroAmmo")
+	AddAmmo(hero.gear, amRope, tonumber(ammo:sub(3,3)))
+	AddAmmo(hero.gear, amBazooka, tonumber(ammo:sub(1,1)))
+	AddAmmo(hero.gear, amParachute, tonumber(ammo:sub(4,4)))
+	AddAmmo(hero.gear, amGrenade, tonumber(ammo:sub(2,2)))
+	AddAmmo(hero.gear, amDEagle, tonumber(ammo:sub(5,5)))
+	AddAmmo(hero.gear, amBlowTorch, tonumber(ammo:sub(6,6)))
+	-- weird, if 0 bazooka isn't displayed in the weapons menu
+	if tonumber(ammo:sub(7,7)) > 0 then
+		AddAmmo(hero.gear, amConstruction, tonumber(ammo:sub(7,7)))
+	end
+	AddAmmo(hero.gear, amPortalGun, tonumber(ammo:sub(8,8)))
+	AddAmmo(hero.gear, amRCPlane, tonumber(ammo:sub(9,9)))
+end
+
+function checkForWin()
+	if cratesFound ==  0 then
+		-- have to look more		
+		AnimSay(hero.gear, loc("Haven't found it yet..."), SAY_THINK, 5000)
+		cratesFound = cratesFound + 1
+	elseif cratesFound == 1 then
+		-- end game
+		saveCompletedStatus(5)
+		AnimSay(hero.gear, loc("Hoo Ray!!!"), SAY_SHOUT, 5000)
+		SendStat(siGameResult, loc("Congratulations, you won!"))
+		SendStat(siCustomAchievement, loc("To win the game you had to collect the 2 crates with no specific order"))
+		SendStat(siPlayerKills,'1',teamC.name)
+		SendStat(siPlayerKills,'0',teamB.name)
+		EndGame()
+	end
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert02.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert02.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,187 @@
+------------------- ABOUT ----------------------
+--
+-- Hero has to get to the surface as soon as possible.
+-- Tunnel is about to get flooded.
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local missionName = loc("Running for survival")
+local startChallenge = false
+-- dialogs
+local dialog01 = {}
+-- mission objectives
+local goals = {
+	[dialog01] = {missionName, loc("Getting ready"), loc("Use the rope and get asap to the surface!"), 1, 4500},
+}
+-- health crates
+healthX = 565
+health1Y = 1400
+health2Y = 850
+-- hogs
+local hero = {}
+-- teams
+local teamA = {}
+-- hedgehogs values
+hero.name = loc("Hog Solo")
+hero.x = 1600
+hero.y = 1950
+hero.dead = false
+teamA.name = loc("Hog Solo")
+teamA.color = tonumber("38D61C",16) -- green
+-- way points
+local current waypoint = 1
+local waypoints = { 
+	[1] = {x=1450, y=140},
+	[2] = {x=990, y=580},
+	[3] = {x=1650, y=950},
+	[4] = {x=620, y=630},
+	[5] = {x=1470, y=540},
+	[6] = {x=1960, y=60},
+	[7] = {x=1600, y=400},
+	[8] = {x=240, y=940},
+	[9] = {x=200, y=530},
+	[10] = {x=1180, y=120},
+	[11] = {x=1950, y=660},
+	[12] = {x=1280, y=980},
+	[13] = {x=590, y=1100},
+	[14] = {x=20, y=620},
+	[15] = {x=hero.x, y=hero.y}
+}
+
+-------------- LuaAPI EVENT HANDLERS ------------------
+
+function onGameInit()
+	GameFlags = gfOneClanMode
+	Seed = 1
+	TurnTime = 8000
+	Delay = 2
+	CaseFreq = 0
+	HealthCaseAmount = 50
+	MinesNum = 500
+	MinesTime = 1000
+	MineDudPercent = 75
+	Explosives = 0
+	SuddenDeathTurns = 1
+	WaterRise = 150
+	HealthDecrease = 0
+	Map = "desert02_map"
+	Theme = "Desert"
+	
+	-- Hog Solo
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1")
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)
+	HogTurnLeft(hero.gear, true)
+	
+	initCheckpoint("desert02")
+	
+	AnimInit()
+	AnimationSetup()
+end
+
+function onGameStart()
+	AnimWait(hero.gear, 3000)
+	FollowGear(hero.gear)
+	
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	AddEvent(onHeroSafe, {hero.gear}, heroSafe, {hero.gear}, 0)
+	
+	SpawnHealthCrate(healthX, health1Y)
+	SpawnHealthCrate(healthX, health2Y)
+	
+	AddAmmo(hero.gear, amRope, 99)
+	
+	SendHealthStatsOff()
+	AddAnim(dialog01)
+end
+
+function onNewTurn()
+	ParseCommand("setweap " .. string.char(amRope))
+end
+
+function onGameTick()
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+end
+
+function onGearDelete(gear)
+	if gear == hero.gear then
+		hero.dead = true
+	end
+end
+
+function onPrecise()
+	if GameTime > 3000 then
+		SetAnimSkip(true)   
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onHeroDeath(gear)
+	if hero.dead then
+		return true
+	end
+	return false
+end
+
+function onHeroSafe(gear)
+	if not hero.dead and GetY(hero.gear) < 170 and StoppedGear(hero.gear) then
+		return true
+	end
+	return false
+end
+
+-------------- ACTIONS ------------------
+
+function heroDeath(gear)
+	SendStat(siGameResult, loc("Hog Solo lost, try again!"))
+	SendStat(siCustomAchievement, loc("To win the game you have to go to the surface"))
+	SendStat(siCustomAchievement, loc("Most mines are not active"))
+	SendStat(siCustomAchievement, loc("From the second turn and beyond the water rises"))
+	SendStat(siPlayerKills,'0',teamA.name)
+	EndGame()
+end
+
+function heroSafe(gear)
+	SendStat(siGameResult, loc("Congratulations, you won!"))
+	SendStat(siCustomAchievement, loc("You have escaped successfully"))
+	SendStat(siCustomAchievement, loc("Your escape took you "..TotalRounds.." turns"))
+	SendStat(siPlayerKills,'1',teamA.name)
+	EndGame()
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+	if goals[anim] ~= nil then
+		ShowMission(unpack(goals[anim]))
+    end
+	challengeStart()
+end
+
+function AnimationSetup()
+	-- DIALOG 01 - Start
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Many meters below the surface..."), 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("The tunnel is about to get flooded..."), SAY_THINK, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("I have to reach the surface asap..."), SAY_THINK, 4000}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}})
+	table.insert(dialog01, {func = challengeStart, args = {hero.gear}})
+end
+
+------------------ Other Functions -------------------
+
+function challengeStart()
+	startChallenge = true
+	TurnTimeLeft = 0
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert03.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/desert03.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,226 @@
+------------------- ABOUT ----------------------
+--
+-- Hero has to use the rc plane end perform some
+-- flying tasks
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+-- globals
+local missionName = loc("Precise flying")
+local challengeObjectives = loc("Use the rc plane and destroy the all the targets").."|"..
+	loc("Each time you destroy your level targets you'll get teleported to the next level").."|"..
+	loc("You'll have only one rc plane at the start of the mission").."|"..
+	loc("During the game you can get new planes by getting the weapon crates")
+local currentTarget = 1
+-- dialogs
+local dialog01 = {}
+-- mission objectives
+local goals = {
+	[dialog01] = {missionName, loc("Challenge Objectives"), challengeObjectives, 1, 4500},
+}
+-- hogs
+local hero = {
+	name = loc("Hog Solo"),
+	x = 100,
+	y = 170
+}
+-- teams
+local teamA = {
+	name = loc("Hog Solo"),
+	color = tonumber("38D61C",16) -- green
+}
+-- creates & targets
+local rcCrates = {
+	{ x = 1680, y = 240},
+	{ x = 2810, y = 720},
+	{ x = 2440, y = 660},
+	{ x = 256, y = 1090},
+}
+local targets = {
+	{ x = 2070, y = 410},
+	{ x = 3880, y = 1430},
+	{ x = 4000, y = 1430},
+	{ x = 2190, y = 1160},
+	{ x = 2190, y = 1460},
+	{ x = 2110, y = 1700},
+	{ x = 2260, y = 1700},
+	{ x = 2085, y = 1330},
+	{ x = 156, y = 1400},
+	{ x = 324, y = 1400},
+	{ x = 660, y = 1310},
+	{ x = 1200, y = 1310},
+	{ x = 1700, y = 1310},
+}
+
+-------------- LuaAPI EVENT HANDLERS ------------------
+
+function onGameInit()
+	GameFlags = gfOneClanMode
+	Seed = 1
+	TurnTime = -1
+	CaseFreq = 0
+	MinesNum = 0
+	MinesTime = 1
+	Explosives = 0
+	Map = "desert03_map"
+	Theme = "Desert"
+	
+	-- Hog Solo
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	hero.gear = AddHog(hero.name, 0, 1, "war_desertgrenadier1")
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)
+	
+	initCheckpoint("desert03")
+	
+	AnimInit()
+	AnimationSetup()
+end
+
+function onGameStart()
+	AnimWait(hero.gear, 3000)
+	FollowGear(hero.gear)
+	ShowMission(missionName, loc("Challenge Objectives"), challengeObjectives, -amSkip, 0)
+
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	AddEvent(onLose, {hero.gear}, lose, {hero.gear}, 0)
+
+	-- original crates and targets
+	SpawnAmmoCrate(rcCrates[1].x, rcCrates[1].y, amRCPlane)
+	targets[1].gear = AddGear(targets[1].x, targets[1].y, gtTarget, 0, 0, 0, 0)
+	
+	-- hero ammo
+	AddAmmo(hero.gear, amRCPlane, 1)
+
+	SendHealthStatsOff()
+	AddAnim(dialog01)
+end
+
+function onGameTick()
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+end
+
+function onGameTick20()
+	checkTargetsDestroyed()
+end
+
+function onAmmoStoreInit()
+	SetAmmo(amNothing, 0, 0, 0, 0)
+	SetAmmo(amRCPlane, 0, 0, 0, 1)
+end
+
+function onPrecise()
+	if GameTime > 3000 then
+		SetAnimSkip(true)   
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onHeroDeath(gear)
+	if not GetHealth(hero.gear) then
+		return true
+	end
+	return false
+end
+
+function onLose(gear)
+	if GetHealth(hero.gear) and currentTarget < 4 and GetAmmoCount(hero.gear, amRCPlane) == 0 then
+		return true
+	end
+	return false
+end
+
+-------------- ACTIONS ------------------
+
+function heroDeath(gear)
+	gameOver()
+end
+
+function lose(gear)
+	gameOver()
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+	if goals[anim] ~= nil then
+		ShowMission(unpack(goals[anim]))
+    end
+end
+
+function AnimationSetup()
+	-- DIALOG 01 - Start, game instructions
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("In the Desert Planet, Hog Solo found some time to play with his RC plane..."), 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Each time you destroy your level targets you'll get teleported to the next level"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("You'll have only one rc plane at the start of the mission"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("During the game you can get new planes by getting the weapon crates"), 5000}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}})	
+end
+
+----------------- Other Functions -----------------
+
+function checkTargetsDestroyed()
+	if currentTarget == 1 then
+		if not GetHealth(targets[1].gear) then
+			AddCaption(loc("Level 1 clear!"))
+			SetGearPosition(hero.gear, 3590, 90)
+			currentTarget = 2
+			setTargets(currentTarget)
+		end
+	elseif currentTarget == 2 then
+		if not (GetHealth(targets[2].gear) or GetHealth(targets[3].gear))  then
+			AddCaption(loc("Level 2 clear!"))
+			SetGearPosition(hero.gear, 1110, 580)
+			currentTarget = 3
+			setTargets(currentTarget)
+		end
+	elseif currentTarget == 3 then
+		
+	else
+		win()
+	end
+end
+
+function setTargets(ct)
+	if ct == 2 then
+		SpawnAmmoCrate(rcCrates[2].x, rcCrates[2].y, amRCPlane)
+		for i=2,3 do
+			targets[i].gear = AddGear(targets[i].x, targets[i].y, gtTarget, 0, 0, 0, 0)
+		end
+	elseif ct == 3 then
+		SpawnAmmoCrate(rcCrates[3].x, rcCrates[3].y, amRCPlane)
+		SpawnAmmoCrate(rcCrates[3].x, rcCrates[3].y, amRCPlane)
+		SpawnAmmoCrate(rcCrates[4].x, rcCrates[4].y, amNothing)
+		for i=4,13 do
+			targets[i].gear = AddGear(targets[i].x, targets[i].y, gtTarget, 0, 0, 0, 0)
+		end
+	end
+end
+
+function win()
+	saveBonus(1, 1)
+	SendStat(siGameResult, loc("Congratulations, you are the best!"))
+	SendStat(siCustomAchievement, loc("You have destroyed all the targets"))	
+	SendStat(siCustomAchievement, loc("You are indeed the best PAotH pilot"))
+	SendStat(siCustomAchievement, loc("Next you play \"Searching in the dust\" you'll have an RC plane available"))
+	SendStat(siPlayerKills,'1',teamA.name)
+	EndGame()
+end
+
+function gameOver()
+	SendStat(siGameResult, loc("Hog Solo lost, try again!"))
+	SendStat(siCustomAchievement, loc("You have to destroy all the targets"))		
+	SendStat(siCustomAchievement, loc("You will fail if you run out of ammo and there are still targets available"))		
+	SendStat(siCustomAchievement, loc("Read the Challenge Objectives from within the mission for more details"))		
+	SendStat(siPlayerKills,'0',teamA.name)
+	EndGame()
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/final.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/final.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,153 @@
+------------------- ABOUT ----------------------
+--
+-- Hero has collected all the anti-gravity device
+-- parts but because of the size of the meteorite
+-- he needs to detonate some faulty explosives that
+-- PAotH have previously placed on it.
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local missionName = loc("The big bang")
+local challengeObjectives = loc("Find a way to detonate all the explosives and stay alive!")
+local explosives = {}
+local currentHealth = 1
+local currentDamage = 0
+-- hogs
+local hero = {
+	name = loc("Hog Solo"),
+	x = 790,
+	y = 70
+}
+-- teams
+local teamA = {
+	name = loc("Hog Solo"),
+	color = tonumber("38D61C",16) -- green
+}
+
+-------------- LuaAPI EVENT HANDLERS ------------------
+
+function onGameInit()
+	GameFlags = gfDisableWind + gfOneClanMode
+	Seed = 1
+	TurnTime = -1
+	CaseFreq = 0
+	MinesNum = 0
+	MinesTime = 1
+	Explosives = 0
+	HealthCaseAmount = 50
+	Map = "final_map"
+	Theme = "EarthRise"
+	
+	-- Hog Solo
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	hero.gear = AddHog(hero.name, 0, 1, "war_desertgrenadier1")
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)
+	
+	initCheckpoint("final")
+	
+	AnimInit()
+end
+
+function onGameStart()
+	AnimWait(hero.gear, 3000)
+	FollowGear(hero.gear)
+	ShowMission(missionName, loc("Challenge Objectives"), challengeObjectives, -amSkip, 0)
+	
+	-- explosives
+	x = 400
+	while x < 815 do
+		local gear = AddGear(x, 500, gtExplosives, 0, 0, 0, 0)
+		x = x + math.random(15,40)
+		table.insert(explosives, gear)
+	end
+	-- mines
+	local x = 360
+	while x < 815 do
+		AddGear(x, 480, gtMine, 0, 0, 0, 0)
+		x = x + math.random(5,20)
+	end
+	-- health crate	
+	SpawnHealthCrate(900, 5)
+	-- ammo crates
+	SpawnAmmoCrate(930, 1000,amRCPlane)
+	SpawnAmmoCrate(1220, 672,amPickHammer)
+	SpawnAmmoCrate(1220, 672,amGirder)
+	
+	-- ammo
+	AddAmmo(hero.gear, amPortalGun, 1)	
+	AddAmmo(hero.gear, amFirePunch, 1)
+	
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	AddEvent(onHeroWin, {hero.gear}, heroWin, {hero.gear}, 0)
+	
+	SendHealthStatsOff()
+end
+
+function onGameTick()
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+end
+
+function onAmmoStoreInit()
+	SetAmmo(amRCPlane, 0, 0, 0, 1)
+	SetAmmo(amPickHammer, 0, 0, 0, 2)
+	SetAmmo(amGirder, 0, 0, 0, 1)
+end
+
+function onNewTurn()
+	currentDamage = 0
+	currentHealth = GetHealth(hero.gear)
+end
+
+function onGearDamage(gear, damage)
+	if gear == hero.gear then
+		currentDamage = currentDamage + damage
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onHeroDeath(gear)
+	if not GetHealth(hero.gear) then
+		return true
+	end
+	return false
+end
+
+function onHeroWin(gear)
+	local win = true
+	for i=1,table.getn(explosives) do
+		if GetHealth(explosives[i]) then
+			win = false
+			break
+		end
+	end
+	if currentHealth <= currentDamage then
+		win = false
+	end
+	return win
+end
+
+-------------- ACTIONS ------------------
+
+function heroDeath(gear)
+	SendStat(siGameResult, loc("Hog Solo lost, try again!"))
+	SendStat(siCustomAchievement, loc("You have to destroy all the explosives without dying!"))
+	SendStat(siPlayerKills,'0',teamA.name)
+	EndGame()
+end
+
+function heroWin(gear)
+	SendStat(siGameResult, loc("Congratulations, you have saved Hogera!"))
+	SendStat(siCustomAchievement, loc("Hogera is safe!"))
+	SendStat(siPlayerKills,'1',teamA.name)
+	EndGame()
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit01.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit01.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,494 @@
+------------------- ABOUT ----------------------
+--
+-- In this adventure hero visits the fruit planet
+-- to search for the missing part. However, a war
+-- has broke out and hero has to take part or leave.
+
+-- NOTES:
+-- There is an ugly hack out there! I use 2 Captain Limes
+-- One in human level and one in bot level
+-- I want to have a Captain Lime in human level when the game
+-- begins because in animation if the hog is in bot level skip
+-- doesn't work - onPrecise() isn't triggered
+-- Later I want the hog to take place in the battle in bot level
+-- However if I use SetHogLevel I get an error: Engine bug: AI may break demos playing
+-- So I have 2 hogs, one in bot level and one in hog level that I hide them
+-- or restore them regarding the case
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local missionName = loc("Bad timing")
+local chooseToBattle = false
+local previousHog = 0
+local heroPlayedFirstTurn = false
+local startBattleCalled = false
+-- dialogs
+local dialog01 = {}
+local dialog02 = {}
+local dialog03 = {}
+-- mission objectives
+local goals = {
+	[dialog01] = {missionName, loc("Ready for Battle?"), loc("Walk left if you want to join Captain Lime or right if you want to decline his offer"), 1, 4000},
+	[dialog02] = {missionName, loc("Battle Starts Now!"), loc("You have choose to fight! Lead the Green Bananas to battle and eliminate all the enemies"), 1, 4000},
+	[dialog03] = {missionName, loc("Time to run!"), loc("You have choose to flee... Unfortunately the only place where you can launch your saucer is in the most left side of the map"), 1, 4000},
+}
+-- crates
+local crateWMX = 2170
+local crateWMY = 1950
+local health1X = 2680
+local health1Y = 916
+-- hogs
+local hero = {}
+local yellow1 = {}
+local green1 = {}
+local green2 = {}
+local green3 = {}
+local green4 = {}
+local green5 = {}
+-- teams
+local teamA = {}
+local teamB = {}
+local teamC = {}
+local teamD = {}
+-- hedgehogs values
+hero.name = loc("Hog Solo")
+hero.x = 3350
+hero.y = 365
+hero.dead = false
+green1.name = loc("Captain Lime")
+green1.x = 3300
+green1.y = 395
+green1.dead = false
+green2.name = loc("Mister Pear")
+green2.x = 3600
+green2.y = 1570
+green3.name = loc("Lady Mango")
+green3.x = 2170
+green3.y = 980
+green4.name = loc("Green Hog Grape")
+green4.x = 2900
+green4.y = 1650
+green5.name = loc("Mr Mango")
+green5.x = 1350
+green5.y = 850
+yellow1.name = loc("General Lemon")
+yellow1.x = 140
+yellow1.y = 1980
+local yellowArmy = {
+	{name = loc("Robert Yellow Apple"), x = 710, y = 1780, health = 100},
+	{name = loc("Summer Squash"), x = 315 , y = 1960, health = 100},
+	{name = loc("Tall Potato"), x = 830 , y = 1748, health = 80},
+	{name = loc("Yellow Pepper"), x = 2160 , y = 820, health = 60},
+	{name = loc("Corn"), x = 1320 , y = 740, health = 60},
+	{name = loc("Max Citrus"), x = 1900 , y = 1700, health = 40},
+	{name = loc("Naranja Jed"), x = 960 , y = 516, health = 40},
+}
+teamA.name = loc("Hog Solo")
+teamA.color = tonumber("38D61C",16) -- green  
+teamB.name = loc("Green Bananas")
+teamB.color = tonumber("38D61C",16) -- green
+teamC.name = loc("Yellow Watermelons")
+teamC.color = tonumber("DDFF00",16) -- yellow
+teamD.name = loc("Captain Lime")
+teamD.color = tonumber("38D61C",16) -- green
+
+function onGameInit()
+	Seed = 1
+	TurnTime = 20000
+	CaseFreq = 0
+	MinesNum = 0
+	MinesTime = 1
+	Explosives = 0
+	Delay = 3
+	SuddenDeathTurns = 100
+	HealthCaseAmount = 50
+	Map = "fruit01_map"
+	Theme = "Fruit"
+	
+	-- Hog Solo
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1")
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)
+	HogTurnLeft(hero.gear, true)
+	-- Captain Lime
+	AddTeam(teamD.name, teamD.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	green1.bot = AddHog(green1.name, 1, 200, "war_desertofficer")
+	AnimSetGearPosition(green1.bot, green1.x, green1.y)
+	green1.human =  AddHog(green1.name, 0, 200, "war_desertofficer")
+	AnimSetGearPosition(green1.human, green1.x, green1.y)
+	green1.gear = green1.human
+	-- Green Bananas
+	AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	green2.gear = AddHog(green2.name, 0, 100, "war_britmedic")
+	AnimSetGearPosition(green2.gear, green2.x, green2.y)
+	HogTurnLeft(green2.gear, true)
+	green3.gear = AddHog(green3.name, 0, 100, "hair_red")
+	AnimSetGearPosition(green3.gear, green3.x, green3.y)
+	HogTurnLeft(green3.gear, true)
+	green4.gear = AddHog(green4.name, 0, 100, "war_desertsapper1")
+	AnimSetGearPosition(green4.gear, green4.x, green4.y)
+	HogTurnLeft(green4.gear, true)
+	green5.gear = AddHog(green5.name, 0, 100, "war_sovietcomrade2")
+	AnimSetGearPosition(green5.gear, green5.x, green5.y)
+	HogTurnLeft(green5.gear, true)
+	-- Yellow Watermelons
+	AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	yellow1.gear = AddHog(yellow1.name, 1, 100, "war_desertgrenadier2")
+	AnimSetGearPosition(yellow1.gear, yellow1.x, yellow1.y)
+	-- the rest of the Yellow Watermelons
+	local yellowHats = { "fr_apple", "fr_banana", "fr_lemon", "fr_orange" }
+	for i=1,7 do
+		yellowArmy[i].gear = AddHog(yellowArmy[i].name, 1, yellowArmy[i].health, yellowHats[math.random(1,4)])
+		AnimSetGearPosition(yellowArmy[i].gear, yellowArmy[i].x, yellowArmy[i].y)
+	end
+	
+	initCheckpoint("fruit01")
+
+	AnimInit()
+	AnimationSetup()	
+end
+
+function onGameStart()
+	AnimWait(hero.gear, 3000)
+	FollowGear(hero.gear)
+	
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	AddEvent(onHeroSelect, {hero.gear}, heroSelect, {hero.gear}, 0)
+	
+	-- Hog Solo weapons
+	AddAmmo(hero.gear, amRope, 2)
+	AddAmmo(hero.gear, amBazooka, 3)
+	AddAmmo(hero.gear, amParachute, 1)
+	AddAmmo(hero.gear, amGrenade, 6)
+	AddAmmo(hero.gear, amDEagle, 4)
+	AddAmmo(hero.gear, amSkip, 100)
+	-- Green team weapons
+	local greenArmy = { green1, green2 }
+	for i=1,2 do
+		AddAmmo(greenArmy[i].gear, amBlowTorch, 5)
+		AddAmmo(greenArmy[i].gear, amRope, 5)
+		AddAmmo(greenArmy[i].gear, amBazooka, 10)
+		AddAmmo(greenArmy[i].gear, amGrenade, 7)
+		AddAmmo(greenArmy[i].gear, amFirePunch, 2)
+		AddAmmo(greenArmy[i].gear, amDrill, 3)	
+		AddAmmo(greenArmy[i].gear, amSwitch, 2)	
+		AddAmmo(greenArmy[i].gear, amSkip, 100)
+	end
+	-- Yellow team weapons
+	AddAmmo(yellow1.gear, amBlowTorch, 1)
+	AddAmmo(yellow1.gear, amRope, 1)
+	AddAmmo(yellow1.gear, amBazooka, 10)
+	AddAmmo(yellow1.gear, amGrenade, 10)
+	AddAmmo(yellow1.gear, amFirePunch, 5)
+	AddAmmo(yellow1.gear, amDrill, 3)	
+	AddAmmo(yellow1.gear, amBee, 1)	
+	AddAmmo(yellow1.gear, amMortar, 3)
+	AddAmmo(yellow1.gear, amDEagle, 4)
+	AddAmmo(yellow1.gear, amDynamite, 1)	
+	AddAmmo(yellow1.gear, amSwitch, 100)
+	for i=3,7 do
+		HideHog(yellowArmy[i].gear)
+	end
+	HideHog(green1.bot)
+	
+	-- crates
+	SpawnHealthCrate(health1X, health1Y)
+	SpawnAmmoCrate(crateWMX, crateWMY, amWatermelon)
+	
+	AddAnim(dialog01)
+	SendHealthStatsOff()
+end
+
+function onNewTurn()
+	if not heroPlayedFirstTurn and CurrentHedgehog ~= hero.gear and startBattleCalled then
+		TurnTimeLeft = 0
+	elseif not heroPlayedFirstTurn and CurrentHedgehog == hero.gear and startBattleCalled then
+		heroPlayedFirstTurn = true
+	else
+		if chooseToBattle then
+			if CurrentHedgehog == green1.gear then
+				TotalRounds = TotalRounds - 2
+				AnimSwitchHog(previousHog)
+				TurnTimeLeft = 0
+			end
+			previousHog = CurrentHedgehog
+		end
+		getNextWave()
+	end
+end
+
+function onGameTick()
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+end
+
+function onGearDelete(gear)
+	if gear == hero.gear then
+		hero.dead = true
+	elseif gear == green1.gear then
+		green1.dead = true
+	end
+end
+
+function onAmmoStoreInit()
+	SetAmmo(amWatermelon, 0, 0, 0, 1)
+end
+
+function onPrecise()
+	if GameTime > 3000 then
+		SetAnimSkip(true)   
+	end
+end
+
+function onHogHide(gear)
+	for i=3,7 do
+		if gear == yellowArmy[i].gear then
+			yellowArmy[i].hidden = true
+			break
+		end
+	end
+end
+
+function onHogRestore(gear)
+	for i=3,7 do
+		if gear == yellowArmy[i].gear then
+			yellowArmy[i].hidden = false
+			break
+		end
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onHeroDeath(gear)
+	if hero.dead then
+		return true
+	end
+	return false
+end
+
+function onGreen1Death(gear)
+	if green1.dead then
+		return true
+	end
+	return false
+end
+
+function onBattleWin(gear)
+	local win = true
+	for i=1,7 do
+		if i<3 then
+			if GetHealth(yellowArmy[i].gear) then
+				win = false
+			end
+		else
+			if GetHealth(yellowArmy[i].gear) and not yellowArmy[i].hidden then
+				win = false
+			end
+		end
+	end
+	if GetHealth(yellow1.gear) then
+		win = false
+	end
+	return win
+end
+
+function onEscapeWin(gear)
+	local escape = false
+	if not hero.dead and GetX(hero.gear) < 170 and GetY(hero.gear) > 1980 and StoppedGear(hero.gear) then
+		escape = true
+		local yellowTeam = { yellow1, unpack(yellowArmy) }
+		for i=1,8 do
+			if not yellowTeam[i].hidden and GetHealth(yellowTeam[i].gear) and GetX(yellowTeam[i].gear) < 170 then
+				escape = false
+				break
+			end
+		end
+	end
+	return escape
+end
+
+function onHeroSelect(gear)
+	if GetX(hero.gear) ~= hero.x then
+		return true
+	end
+	return false
+end
+
+-------------- ACTIONS ------------------
+
+function heroDeath(gear)
+	gameLost()
+end
+
+function green1Death(gear)
+	gameLost()
+end
+
+function battleWin(gear)
+	-- add stats
+	saveVariables()
+	SendStat(siGameResult, loc("Green Bananas won!"))
+	SendStat(siCustomAchievement, loc("You have eliminated all the visible enemy hogs!"))
+	SendStat(siPlayerKills,'1',teamA.name)
+	SendStat(siPlayerKills,'1',teamB.name)
+	SendStat(siPlayerKills,'0',teamC.name)
+	EndGame()
+end
+
+function escapeWin(gear)
+	-- add stats
+	saveVariables()
+	SendStat(siGameResult, loc("Hog Solo escaped successfully!"))
+	SendStat(siCustomAchievement, loc("You have reached the flying area successfully!"))
+	SendStat(siPlayerKills,'1',teamA.name)
+	SendStat(siPlayerKills,'0',teamB.name)
+	SendStat(siPlayerKills,'0',teamC.name)
+	EndGame()
+end
+
+function heroSelect(gear)
+	TurnTimeLeft = 0
+	FollowGear(hero.gear)
+	if GetX(hero.gear) < hero.x then
+		chooseToBattle = true		
+		AddEvent(onGreen1Death, {green1.gear}, green1Death, {green1.gear}, 0)
+		AddEvent(onBattleWin, {hero.gear}, battleWin, {hero.gear}, 0)
+		AddAnim(dialog02)
+	elseif GetX(hero.gear) > hero.x then
+		HogTurnLeft(hero.gear, true)
+		AddAmmo(green1.gear, amSwitch, 100)
+		AddEvent(onEscapeWin, {hero.gear}, escapeWin, {hero.gear}, 0)
+		local greenTeam = { green2, green3, green4, green5 }
+		for i=1,4 do
+			SetHogLevel(greenTeam[i].gear, 1)
+		end
+		AddAnim(dialog03)
+	end
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+	if goals[anim] ~= nil then
+		ShowMission(unpack(goals[anim]))
+    end
+    if anim == dialog01 then
+		AnimSwitchHog(hero.gear)
+	elseif anim == dialog02 or anim == dialog03 then
+		startBattle()
+    end
+end
+
+function AnimationSetup()
+	-- DIALOG 01 - Start, Captain Lime talks explains to Hog Solo
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Somewhere in the Planet of Fruits a terrible war is about to begin..."), 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("I was told that as the leader of the king's guard, no one knows this world better than you!"), SAY_SAY, 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("So, I kindly ask for your help"), SAY_SAY, 3000}})
+	table.insert(dialog01, {func = AnimWait, args = {green1.gear, 2000}})
+	table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("You couldn't have come to a worse time Hog Solo!"), SAY_SAY, 3000}})
+	table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("The clan of the Red Strawberry wants to take over the dominion and overthrone king Pineapple."), SAY_SAY, 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("Under normal circumstances we could easily defeat them but we have kindly sent most of our men to the kingdom of Sand to help to the annual dusting of the king's palace."), SAY_SAY, 8000}})
+	table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("However the army of Yellow Watermelons is about to attack any moment now."), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("I would gladly help you if we won this battle but under these circumstances I'll only help you if you fight for our side."), SAY_SAY, 6000}})
+	table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("What do you say? Will you fight for us?"), SAY_SAY, 3000}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}})
+	table.insert(dialog01, {func = ShowMission, args = {missionName, loc("Ready for Battle?"), loc("Walk left if you want to join Captain Lime or right if you want to decline his offer"), 1, 7000}})
+	table.insert(dialog01, {func = AnimSwitchHog, args = {hero.gear}})
+	-- DIALOG 02 - Hero selects to fight	
+	AddSkipFunction(dialog02, Skipanim, {dialog02})
+	table.insert(dialog02, {func = AnimWait, args = {green1.gear, 3000}})
+	table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("You choose well Hog Solo!"), SAY_SAY, 3000}})
+	table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("I have only 3 hogs available and they are all cadets"), SAY_SAY, 4000}})
+	table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("As more experienced I want you to lead them to the battle"), SAY_SAY, 4000}})
+	table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("I of cource will observe the battle and intervene if necessary"), SAY_SAY, 5000}})
+	table.insert(dialog02, {func = AnimWait, args = {hero.gear, 5000}})
+	table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("No problem Captain! The enemies aren't many anyway, it is going to be easy!"), SAY_SAY, 5000}})
+	table.insert(dialog02, {func = AnimWait, args = {green1.gear, 5000}})
+	table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("Don't be fool son, they'll be more"), SAY_SAY, 3000}})
+	table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("Try to be smart and eliminate them quickly. This way you might scare the rest!"), SAY_SAY, 5000}})
+	table.insert(dialog02, {func = AnimWait, args = {hero.gear, 5000}})
+	table.insert(dialog02, {func = startBattle, args = {hero.gear}})
+	-- DIALOG 03 - Hero selects to flee
+	AddSkipFunction(dialog03, Skipanim, {dialog03})
+	table.insert(dialog03, {func = AnimWait, args = {green1.gear, 3000}})
+	table.insert(dialog03, {func = AnimSay, args = {green1.gear, loc("Too bad... Then you should really leave!"), SAY_SAY, 3000}})
+	table.insert(dialog03, {func = AnimSay, args = {green1.gear, loc("Things are going to get messy around here"), SAY_SAY, 3000}})
+	table.insert(dialog03, {func = AnimSay, args = {green1.gear, loc("Also, you should know that the only place that you can fly would be the most left part of the map"), SAY_SAY, 5000}})
+	table.insert(dialog03, {func = AnimSay, args = {green1.gear, loc("All the other places are protected by our anti flying weapons"), SAY_SAY, 4000}})
+	table.insert(dialog03, {func = AnimSay, args = {green1.gear, loc("Now go and don't waste more of my time you coward..."), SAY_SAY, 4000}})
+	table.insert(dialog03, {func = AnimWait, args = {hero.gear, 5000}})
+	table.insert(dialog03, {func = startBattle, args = {hero.gear}})
+end
+
+------------- OTHER FUNCTIONS ---------------
+
+function startBattle()
+	RestoreHog(green1.bot)
+	DeleteGear(green1.human)
+	green1.gear = green1.bot
+	startBattleCalled = true
+	TurnTimeLeft = 0
+end
+
+function gameLost()
+	if chooseToBattle then
+		SendStat(siGameResult, loc("Green Bananas lost, try again!"))
+		SendStat(siCustomAchievement, loc("You have to eliminate all the visible enemies"))
+		SendStat(siCustomAchievement, loc("5 additional enemies will be spawned during the game"))
+		SendStat(siCustomAchievement, loc("You are controlling all the active ally units"))
+		SendStat(siCustomAchievement, loc("The ally units share their ammo"))
+		SendStat(siCustomAchievement, loc("Try to keep as many allies alive as possible"))
+	else
+		SendStat(siGameResult, loc("Hog Solo couldn't escape, try again!"))
+		SendStat(siCustomAchievement, loc("You have to get to the most left land and remove any enemy hog from there"))
+		SendStat(siCustomAchievement, loc("You will play every 3 turns"))
+		SendStat(siCustomAchievement, loc("Green hogs won't intenionally hurt you"))
+	end	
+	SendStat(siPlayerKills,'1',teamC.name)
+	SendStat(siPlayerKills,'0',teamA.name)
+	SendStat(siPlayerKills,'0',teamB.name)
+	EndGame()
+end
+
+function getNextWave()
+	if TotalRounds == 4 then
+		RestoreHog(yellowArmy[3].gear)
+		AnimCaption(hero.gear, loc("Next wave in 3 turns"), 5000)		
+		if not chooseToBattle and not GetHealth(yellow1.gear) then
+			SetGearPosition(yellowArmy[3].gear, yellow1.x, yellow1.y)
+		end
+	elseif TotalRounds == 7 then
+		RestoreHog(yellowArmy[4].gear)
+		RestoreHog(yellowArmy[5].gear)
+		AnimCaption(hero.gear, loc("Last wave in 3 turns"), 5000)
+		if not chooseToBattle and not GetHealth(yellow1.gear) and not GetHealth(yellowArmy[3].gear) then
+			SetGearPosition(yellowArmy[4].gear, yellow1.x, yellow1.y)
+		end
+	elseif TotalRounds == 10 then
+		RestoreHog(yellowArmy[6].gear)
+		RestoreHog(yellowArmy[7].gear)
+		if not chooseToBattle and not GetHealth(yellow1.gear) and not GetHealth(yellowArmy[3].gear) 
+				and not GetHealth(yellowArmy[4].gear) then
+			SetGearPosition(yellowArmy[6].gear, yellow1.x, yellow1.y)
+		end
+	end
+end
+
+function saveVariables()
+	saveCompletedStatus(2)
+	SaveCampaignVar("UnlockedMissions", "3")
+	SaveCampaignVar("Mission1", "3")
+	SaveCampaignVar("Mission2", "8")
+	SaveCampaignVar("Mission3", "1")
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit02.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit02.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,612 @@
+------------------- ABOUT ----------------------
+--
+-- In this adventure hero gets the lost part with
+-- the help of the green bananas hogs.
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local missionName = loc("Getting to the device")
+local inBattle = false
+local tookPartInBattle = false
+local previousHog = -1
+local checkPointReached = 1 -- 1 is normal spawn
+-- dialogs
+local dialog01 = {}
+local dialog02 = {}
+local dialog03 = {}
+local dialog04 = {}
+-- mission objectives
+local goals = {
+	[dialog01] = {missionName, loc("Exploring the tunnel"), loc("With the help of the other hogs search for the device").."|"..loc("Hog Solo has to reach the last crates"), 1, 4000},
+	[dialog02] = {missionName, loc("Exploring the tunnel"), loc("Explore the tunnel with the other hogs and search for the device").."|"..loc("Hog Solo has to reach the last crates"), 1, 4000},
+	[dialog03] = {missionName, loc("Return to the Surface"), loc("Go to the surface!").."|"..loc("Attack Captain Lime before he attacks back"), 1, 4000},
+	[dialog04] = {missionName, loc("Return to the Surface"), loc("Go to the surface!").."|"..loc("Attack the assasins before they attack back"), 1, 4000},
+}
+-- crates
+local eagleCrate = {name = amDEagle, x = 1680, y = 1650}
+local girderCrate =	{name = amGirder, x = 1680, y = 1160}
+local ropeCrate = {name = amRope, x = 1400, y = 1870}
+local weaponCrate = { x = 1360, y = 1870}
+-- hogs
+local hero = {}
+local green1 = {}
+local green2 = {}
+local green3 = {}
+-- teams
+local teamA = {}
+local teamB = {}
+local teamC = {}
+-- hedgehogs values
+hero.name = loc("Hog Solo")
+hero.x = 1200
+hero.y = 820
+hero.dead = false
+green1.name = loc("Captain Lime")
+green1.x = 1050
+green1.y = 820
+green1.dead = false
+green2.name = loc("Mister Pear")
+green2.x = 1350
+green2.y = 820
+green3.name = loc("Lady Mango")
+green3.x = 1450
+green3.y = 820
+local redHedgehogs = {
+	{ name = loc("Poisonous Apple") },
+	{ name = loc("Dark Strawberry") },
+	{ name = loc("Watermelon Heart") },
+	{ name = loc("Deadly Grape") }
+}
+teamA.name = loc("Hog Solo and GB")
+teamA.color = tonumber("38D61C",16) -- green
+teamB.name = loc("Captain Lime")
+teamB.color = tonumber("38D61D",16) -- greenish
+teamC.name = loc("Fruit Assasins")
+teamC.color = tonumber("FF0000",16) -- red
+
+function onGameInit()
+	GameFlags = gfDisableWind
+	Seed = 1
+	TurnTime = 20000
+	CaseFreq = 0
+	MinesNum = 0
+	MinesTime = 1
+	Explosives = 0
+	Delay = 3
+	SuddenDeathTurns = 200
+	Map = "fruit02_map"
+	Theme = "Fruit"
+	
+	-- load checkpoints, problem getting the campaign variable
+	local health = 100
+	checkPointReached = initCheckpoint("fruit02")
+	if checkPointReached ~= 1 then
+		loadHogsPositions()
+		health = tonumber(GetCampaignVar("HeroHealth"))
+	end
+	
+	-- Hog Solo and Green Bananas
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	hero.gear = AddHog(hero.name, 0, health, "war_desertgrenadier1")
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)
+	HogTurnLeft(hero.gear, true)	
+	green2.gear = AddHog(green2.name, 0, 100, "war_britmedic")
+	AnimSetGearPosition(green2.gear, green2.x, green2.y)
+	HogTurnLeft(green2.gear, true)
+	green3.gear = AddHog(green3.name, 0, 100, "hair_red")
+	AnimSetGearPosition(green3.gear, green3.x, green3.y)
+	HogTurnLeft(green3.gear, true)
+	-- Captain Lime
+	AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	green1.human = AddHog(green1.name, 0, 100, "war_desertofficer")
+	AnimSetGearPosition(green1.human, green1.x, green1.y)
+	green1.bot = AddHog(green1.name, 1, 100, "war_desertofficer")
+	AnimSetGearPosition(green1.bot, green1.x, green1.y)
+	green1.gear = green1.human
+	-- Fruit Assasins
+	local assasinsHats = { "NinjaFull", "NinjaStraight", "NinjaTriangle" }
+	AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	for i=1,table.getn(redHedgehogs) do
+		redHedgehogs[i].gear =  AddHog(redHedgehogs[i].name, 1, 100, assasinsHats[math.random(1,3)])
+		AnimSetGearPosition(redHedgehogs[i].gear, 2010 + 50*i, 630)
+	end
+
+	AnimInit()
+	AnimationSetup()	
+end
+
+function onGameStart()
+	AnimWait(hero.gear, 3000)
+	FollowGear(hero.gear)
+	
+	if GetCampaignVar("Fruit01JoinedBattle") and GetCampaignVar("Fruit01JoinedBattle") == "true" then
+		tookPartInBattle = true
+	end
+	
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	AddEvent(onDeviceCrates, {hero.gear}, deviceCrates, {hero.gear}, 0)
+	
+	-- Hog Solo and GB weapons
+	AddAmmo(hero.gear, amSwitch, 100)
+	-- Captain Lime weapons
+	AddAmmo(green1.bot, amBazooka, 6)
+	AddAmmo(green1.bot, amGrenade, 6)
+	AddAmmo(green1.bot, amDEagle, 2)
+	HideHog(green1.bot)
+	-- Assasins weapons
+	AddAmmo(redHedgehogs[1].gear, amBazooka, 6)
+	AddAmmo(redHedgehogs[1].gear, amGrenade, 6)
+	AddAmmo(redHedgehogs[1].bot, amDEagle, 6)
+	for i=1,table.getn(redHedgehogs) do
+		HideHog(redHedgehogs[i].gear)
+	end
+	
+	-- explosives
+	-- I wanted to use FindPlace but doesn't accept height values...
+	local x1 = 950
+	local x2 = 1306
+	local y1 = 1210
+	local y2 = 1620
+	while true do
+		if y2<y1 then
+			break
+		end
+		if x2<x1 then
+			x2 = 1305
+			y2 = y2 - 50
+		end
+		if not TestRectForObstacle(x2+25, y2+25, x2-25, y2-25, true) then
+			AddGear(x2, y2, gtExplosives, 0, 0, 0, 0)
+		end
+		x2 = x2 - 25
+	end
+	AddGear(3128, 1680, gtExplosives, 0, 0, 0, 0)
+	
+	--mines
+	AddGear(3135, 1680, gtMine, 0, 0, 0, 0)
+	AddGear(3145, 1680, gtMine, 0, 0, 0, 0)
+	AddGear(3155, 1680, gtMine, 0, 0, 0, 0)
+	AddGear(3165, 1680, gtMine, 0, 0, 0, 0)
+	AddGear(3175, 1680, gtMine, 0, 0, 0, 0)
+	AddGear(3115, 1680, gtMine, 0, 0, 0, 0)
+	AddGear(3105, 1680, gtMine, 0, 0, 0, 0)
+	AddGear(3095, 1680, gtMine, 0, 0, 0, 0)
+	AddGear(3085, 1680, gtMine, 0, 0, 0, 0)
+	AddGear(3075, 1680, gtMine, 0, 0, 0, 0)	
+
+	if checkPointReached == 1 then
+		AddAmmo(hero.gear, amFirePunch, 3)
+		AddEvent(onCheckPoint1, {hero.gear}, checkPoint1, {hero.gear}, 0)
+		AddEvent(onCheckPoint2, {hero.gear}, checkPoint2, {hero.gear}, 0)
+		AddEvent(onCheckPoint3, {hero.gear}, checkPoint3, {hero.gear}, 0)
+		AddEvent(onCheckPoint4, {hero.gear}, checkPoint4, {hero.gear}, 0)
+		if tookPartInBattle then
+			AddAnim(dialog01)
+		else
+			AddAnim(dialog02)
+		end
+	elseif checkPointReached == 2 then
+		AddEvent(onCheckPoint2, {hero.gear}, checkPoint2, {hero.gear}, 0)
+		AddEvent(onCheckPoint3, {hero.gear}, checkPoint3, {hero.gear}, 0)
+		AddEvent(onCheckPoint4, {hero.gear}, checkPoint4, {hero.gear}, 0)
+	elseif checkPointReached == 3 then
+		AddEvent(onCheckPoint1, {hero.gear}, checkPoint1, {hero.gear}, 0)
+		AddEvent(onCheckPoint3, {hero.gear}, checkPoint3, {hero.gear}, 0)
+		AddEvent(onCheckPoint4, {hero.gear}, checkPoint4, {hero.gear}, 0)
+	elseif checkPointReached == 4 then
+		AddEvent(onCheckPoint4, {hero.gear}, checkPoint4, {hero.gear}, 0)		
+	elseif checkPointReached == 5 then
+		-- EMPTY
+	end
+	if checkPointReached ~= 1 then
+		loadWeapons()
+	end
+	
+	-- girders
+	if checkPointReached > 1 then
+		PlaceGirder(1580, 875, 4)
+		PlaceGirder(1800, 875, 4)
+	end
+	
+	-- place crates
+	if checkPointReached < 2 then
+		SpawnAmmoCrate(girderCrate.x, girderCrate.y, girderCrate.name)
+	end
+	if checkPointReached < 5 then
+		SpawnAmmoCrate(eagleCrate.x, eagleCrate.y, eagleCrate.name)
+	end
+	SpawnAmmoCrate(ropeCrate.x, ropeCrate.y, ropeCrate.name)
+
+	if tookPartInBattle then
+		SpawnAmmoCrate(weaponCrate.x, weaponCrate.y, amWatermelon)
+	else
+		SpawnAmmoCrate(weaponCrate.x, weaponCrate.y, amSniperRifle)		
+	end
+	
+	SendHealthStatsOff()
+end
+
+function onNewTurn()
+	if not inBattle and CurrentHedgehog == green1.gear then
+		TurnTimeLeft = 0
+	elseif CurrentHedgehog == green2.gear or CurrentHedgehog == green3.gear then
+		TurnTimeLeft = 0
+	elseif inBattle then
+		if CurrentHedgehog == green1.gear and previousHog ~= hero.gear then
+			TurnTimeLeft = 0
+			return
+		end
+		for i=1,table.getn(redHedgehogs) do
+			if CurrentHedgehog == redHedgehogs[i].gear and previousHog ~= hero.gear then
+				TurnTimeLeft = 0
+				return
+			end
+		end
+		TurnTimeLeft = 20000
+		wind()
+	elseif not inBattle and CurrentHedgehog == hero.gear then
+		TurnTimeLeft = -1
+		wind()
+	else
+		TurnTimeLeft = 0
+	end
+	previousHog = CurrentHedgehog
+end
+
+function onGameTick()
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+end
+
+function onGearDelete(gear)
+	if gear == hero.gear then
+		hero.dead = true
+	elseif gear == green1.bot then
+		green1.dead = true
+	end
+end
+
+function onAmmoStoreInit()
+	SetAmmo(amDEagle, 0, 0, 0, 6)
+	SetAmmo(amGirder, 0, 0, 0, 2)
+	SetAmmo(amRope, 0, 0, 0, 1)
+	if tonumber(getBonus(2)) == 1 then
+		SetAmmo(amWatermelon, 0, 0, 0, 2)
+		SetAmmo(amSniperRifle, 0, 0, 0, 2)
+	else
+		SetAmmo(amWatermelon, 0, 0, 0, 1)
+		SetAmmo(amSniperRifle, 0, 0, 0, 1)
+	end
+end
+
+function onPrecise()
+	if GameTime > 3000 then
+		SetAnimSkip(true)   
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onHeroDeath(gear)
+	if hero.dead then
+		return true
+	end
+	return false
+end
+
+function onDeviceCrates(gear)
+	if not hero.dead and GetY(hero.gear)>1850 and GetX(hero.gear)>1340 and GetX(hero.gear)<1640 then
+		return true
+	end
+	return false
+end
+
+function onSurface(gear)
+	if not hero.dead and GetY(hero.gear)<850 and  StoppedGear(hero.gear) then
+		return true
+	end
+	return false
+end
+
+function onGaptainLimeDeath(gear)
+	if green1.dead then
+		return true
+	end
+	return false
+end
+
+function onRedTeamDeath(gear)
+	local redDead = true
+	for i=1,table.getn(redHedgehogs) do
+		if GetHealth(redHedgehogs[i].gear) then
+			redDead = false
+			break
+		end
+	end
+	return redDead
+end
+
+function onCheckPoint1(gear)
+	-- before barrel jump
+	if not hero.dead and GetX(hero.gear) > 2850 and GetX(hero.gear) < 2945 
+			and GetY(hero.gear) > 808 and GetY(hero.gear) < 852 and	not isHeroAtWrongPlace() then
+		return true
+	end
+	return false
+end
+
+function onCheckPoint2(gear)
+	-- before barrel jump
+	if ((GetHealth(green2.gear) and GetX(green2.gear) > 2850 and GetX(green2.gear) < 2945 and GetY(green2.gear) > 808 and GetY(green2.gear) < 852)
+			or (GetHealth(green3.gear) and GetX(green3.gear) > 2850 and GetX(green3.gear) < 2945 and GetY(green3.gear) > 808 and GetY(green3.gear) < 852))
+			and not isHeroAtWrongPlace() then
+		return true
+	end
+	return false
+end
+
+function onCheckPoint3(gear)
+	-- after barrel jump
+	if ((GetHealth(green2.gear) and GetY(green2.gear) > 1550 and GetX(green2.gear) < 3000 and StoppedGear(green2.gear)) 
+			or (GetHealth(green3.gear) and GetY(green3.gear) > 1550 and GetX(green3.gear) < 3000 and StoppedGear(green2.gear)))
+			and not isHeroAtWrongPlace() then
+		return true
+	end
+	return false
+end
+
+function onCheckPoint4(gear)
+	-- hero at crates
+	if not hero.dead and GetX(hero.gear) > 1288 and GetX(hero.gear) < 1420 
+			and GetY(hero.gear) > 1840 and	not isHeroAtWrongPlace() then
+		return true
+	end
+	return false
+end
+
+-------------- ACTIONS ------------------
+
+function heroDeath(gear)
+	SendStat(siGameResult, loc("Hog Solo lost, try again!"))
+	SendStat(siCustomAchievement, loc("To win the game Hog Solo has to get the bottom crates and come back to the surface"))
+	SendStat(siCustomAchievement, loc("You can use the other 2 hogs to assist you"))
+	if tookPartInBattle then
+		SendStat(siCustomAchievement, loc("You'll have to eliminate the Strawberry Assasins at the end"))
+	else
+		SendStat(siCustomAchievement, loc("You'll have to eliminate Captain Lime at the end"))	
+	end
+	SendStat(siPlayerKills,'0',teamA.name)
+	EndGame()
+end
+
+function deviceCrates(gear)
+	TurnTimeLeft = 0
+	if not tookPartInBattle then
+		AddAnim(dialog03)
+	else
+		for i=1,table.getn(redHedgehogs) do
+			RestoreHog(redHedgehogs[i].gear)
+		end
+		AddAnim(dialog04)
+	end
+	AddAmmo(hero.gear, amSwitch, 0)
+	AddEvent(onSurface, {hero.gear}, surface, {hero.gear}, 0)
+end
+
+function surface(gear)
+	previousHog = -1
+	if tookPartInBattle then
+		if GetHealth(green1.gear) then
+			HideHog(green1.gear)
+		end
+		AddEvent(onRedTeamDeath, {green1.gear}, redTeamDeath, {green1.gear}, 0)
+	else
+		DeleteGear(green1.human)
+		RestoreHog(green1.bot)
+		green1.gear = green1.bot
+		AddEvent(onGaptainLimeDeath, {green1.gear}, captainLimeDeath, {green1.gear}, 0)
+	end
+	if GetHealth(green2.gear) then
+		HideHog(green2.gear)
+	end
+	if GetHealth(green3.gear) then
+		HideHog(green3.gear)
+	end
+	inBattle = true
+end
+
+function captainLimeDeath(gear)
+	-- hero win in scenario of escape in 1st part
+	saveCompletedStatus(3)
+	SendStat(siGameResult, loc("Congratulations, you won!"))
+	SendStat(siCustomAchievement, loc("You retrieved the lost part"))
+	SendStat(siCustomAchievement, loc("You defended yourself against Captain Lime"))
+	SendStat(siPlayerKills,'1',teamA.name)
+	SendStat(siPlayerKills,'0',teamB.name)
+	EndGame()
+end
+
+function redTeamDeath(gear)
+	-- hero win in battle scenario
+	saveCompletedStatus(3)
+	SendStat(siGameResult, loc("Congratulations, you won!"))
+	SendStat(siCustomAchievement, loc("You retrieved the lost part"))
+	SendStat(siCustomAchievement, loc("You defended yourself against Strawberry Assasins"))
+	SendStat(siPlayerKills,'1',teamA.name)
+	SendStat(siPlayerKills,'0',teamC.name)
+	EndGame()
+end
+
+function checkPoint1(gear)
+	saveCheckPointLocal(2)
+end
+
+function checkPoint2(gear)
+	saveCheckPointLocal(3)
+end
+
+function checkPoint3(gear)
+	saveCheckPointLocal(4)
+end
+
+function checkPoint4(gear)
+	saveCheckPointLocal(5)
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+	if goals[anim] ~= nil then
+		ShowMission(unpack(goals[anim]))
+    end
+    TurnTimeLeft = 0
+end
+
+function AnimationSetup()
+	-- DIALOG 01 - Start, Captain Lime helps Hog Solo because he took part in the battle
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Somewhere else in the planet of fruits Captain Lime helps Hog Solo..."), 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("You fought bravely and you helped us win this battle!"), SAY_SAY, 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("So, as promised I have brought you where I think that the device you are looking for is hidden."), SAY_SAY, 7000}})
+	table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("I know that your resources are low due to the battle but I'll send with you two of my best hogs to assist you."), SAY_SAY, 7000}})
+	table.insert(dialog01, {func = AnimSay, args = {green1.gear, loc("Good luck!"), SAY_SAY, 2000}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}})
+	table.insert(dialog01, {func = AnimSwitchHog, args = {hero.gear}})
+	-- DIALOG02 - Start, Hog Solo escaped from the previous battle
+	AddSkipFunction(dialog02, Skipanim, {dialog02})
+	table.insert(dialog02, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog02, {func = AnimCaption, args = {hero.gear, loc("Somewhere else in the planet of fruits Hog Solo gets closer to the device..."), 5000}})
+	table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("You are the one who fled! So, you are alive..."), SAY_SAY, 4000}})
+	table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("I'm still low on hogs. If you are not afraid I could use a set of extra hands"), SAY_SAY, 4000}})
+	table.insert(dialog02, {func = AnimWait, args = {hero.gear, 8000}})
+	table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("I am sorry but I was looking for a device that may be hidden somewhere around here"), SAY_SAY, 4500}})
+	table.insert(dialog02, {func = AnimWait, args = {green1.gear, 12500}})
+	table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("Many long forgotten things can be found in the same tunnels that we are about to explore!"), SAY_SAY, 7000}})
+	table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("If you help us you can keep the device if you find it but we'll keep everything else"), SAY_SAY, 7000}})
+	table.insert(dialog02, {func = AnimSay, args = {green1.gear, loc("What do you say? Are you in?"), SAY_SAY, 3000}})
+	table.insert(dialog02, {func = AnimWait, args = {hero.gear, 1800}})
+	table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("Ok then!"), SAY_SAY, 2000}})
+	table.insert(dialog02, {func = AnimSwitchHog, args = {hero.gear}})
+	-- DIALOG03 - At crates, hero learns that Captain Lime is bad
+	AddSkipFunction(dialog03, Skipanim, {dialog03})
+	table.insert(dialog03, {func = AnimWait, args = {hero.gear, 4000}})
+	table.insert(dialog03, {func = FollowGear, args = {hero.gear}})
+	table.insert(dialog03, {func = AnimSay, args = {hero.gear, loc("Hoo Ray! I've found it, now I have to get back to Captain Lime!"), SAY_SAY, 4000}})
+	table.insert(dialog03, {func = AnimWait, args = {green1.gear, 4000}})
+	table.insert(dialog03, {func = AnimSay, args = {green1.gear, loc("This Hog Solo is so naive! I am gonna shoot him when he returns and keep his device for me!"), SAY_THINK, 4000}})
+	table.insert(dialog03, {func = goToThesurface, args = {hero.gear}})
+	-- DIALOG04 - At crates, hero learns about the assasins ambush
+	AddSkipFunction(dialog04, Skipanim, {dialog04})
+	table.insert(dialog04, {func = AnimWait, args = {hero.gear, 4000}})
+	table.insert(dialog04, {func = FollowGear, args = {hero.gear}})
+	table.insert(dialog04, {func = AnimSay, args = {hero.gear, loc("Hoo Ray! I've found it, now I have to get back to Captain Lime!"), SAY_SAY, 4000}})
+	table.insert(dialog04, {func = AnimWait, args = {redHedgehogs[1].gear, 4000}})
+	table.insert(dialog04, {func = AnimSay, args = {redHedgehogs[1].gear, loc("We have spotted the enemy! We'll attack when the enemies start gathering!"), SAY_THINK, 4000}})
+	table.insert(dialog04, {func = goToThesurface, args = {hero.gear}})
+end
+
+------------- OTHER FUNCTIONS ---------------
+
+function goToThesurface()
+	TurnTimeLeft = 0
+end
+
+function wind()
+	if GetY(CurrentHedgehog) > 1350 then
+		SetWind(-40)
+	else
+		SetWind(math.random(-100,100))
+	end
+end
+
+function saveHogsPositions()
+	local positions;
+	positions = GetX(hero.gear)..","..GetY(hero.gear)
+	if GetHealth(green2.gear) then
+		positions = positions..","..GetX(green2.gear)..","..GetY(green2.gear)
+	end
+	if GetHealth(green3.gear) then
+		positions = positions..","..GetX(green3.gear)..","..GetY(green3.gear)
+	end
+	SaveCampaignVar("HogsPosition", positions)
+end
+
+function loadHogsPositions()
+	local positions;
+	if GetCampaignVar("HogsPosition") then
+		positions = GetCampaignVar("HogsPosition")
+	else
+		return
+	end
+	positions = split(positions,",")
+	if positions[1] then
+		hero.x = positions[1]
+		hero.y = positions[2]
+	end
+	if positions[3] then
+		green2.x = tonumber(positions[3])
+		green2.y = tonumber(positions[4])
+	end
+	if positions[5] then
+		green3.x = tonumber(positions[5])
+		green3.y = tonumber(positions[6])
+	end
+end
+
+function saveWeapons()
+	-- firepunch - gilder - deagle - watermelon - sniper
+	SaveCampaignVar("HeroAmmo", GetAmmoCount(hero.gear, amFirePunch)..GetAmmoCount(hero.gear, amGirder)..
+			GetAmmoCount(hero.gear, amDEagle)..GetAmmoCount(hero.gear, amWatermelon)..GetAmmoCount(hero.gear, amSniperRifle))
+end
+
+function loadWeapons()
+	local ammo = GetCampaignVar("HeroAmmo")
+	AddAmmo(hero.gear, amFirePunch, tonumber(ammo:sub(1,1)))
+	AddAmmo(hero.gear, amGirder, tonumber(ammo:sub(2,2)))
+	AddAmmo(hero.gear, amDEagle, tonumber(ammo:sub(3,3)))
+	AddAmmo(hero.gear, amWatermelon, tonumber(ammo:sub(4,4)))
+	AddAmmo(hero.gear, amSniperRifle, tonumber(ammo:sub(5,5)))
+end
+
+function isHeroAtWrongPlace()
+	if GetX(hero.gear) > 1480 and GetX(hero.gear) < 1892 and GetY(hero.gear) > 1000 and GetY(hero.gear) < 1220 then
+		return true
+	end
+	return false
+end
+
+-- splits number by delimiter
+function split(s, delimiter)
+	local res = {}
+	local first = ""
+	for i=1,s:len() do
+		if s:sub(1,1) == delimiter then
+			table.insert(res, tonumber(first))
+			first = ""
+		else
+			first = first..s:sub(1,1)
+		end
+		s = s:sub(2)
+	end
+	if first:len() > 0 then
+		table.insert(res, tonumber(first))
+	end
+	return res
+end
+
+function saveCheckPointLocal(cpoint)
+	AnimCaption(hero.gear, loc("Checkpoint reached!"), 3000)
+	saveCheckpoint(cpoint)
+	SaveCampaignVar("HeroHealth", GetHealth(hero.gear))
+	saveHogsPositions()
+	saveWeapons()
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit03.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/fruit03.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,299 @@
+------------------- ABOUT ----------------------
+--
+-- Hero has get into an Red Strawberies ambush
+-- He has to eliminate the enemies by using limited
+-- ammo of sniper rifle and watermelon
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local missionName = loc("Precise shooting")
+local timeLeft = 10000
+local lastWeaponUsed = amSniperRifle
+local challengeObjectives = loc("Use your available weapons in order to eliminate the enemies").."|"..
+	loc("You can only use the Sniper Rifle or the Watermelon bomb").."|"..
+	loc("You'll have only 2 watermelon bombs during the game").."|"..
+	loc("You'll get an extra Sniper Rifle every time you kill an enemy hog with a limit of max 4 rifles").."|"..
+	loc("You'll get an extra Teleport every time you kill an enemy hog with a limit of max 2 teleports").."|"..
+	loc("The first turn will last 25 sec and every other turn 15 sec").."|"..
+	loc("If you skip the game your time left will be added to your next turn").."|"..
+	loc("Some parts of the land are indestructible")
+-- dialogs
+local dialog01 = {}
+-- mission objectives
+local goals = {
+	[dialog01] = {missionName, loc("Challenge Objectives"), challengeObjectives, 1, 4500},
+}
+-- hogs
+local hero = {
+	name = loc("Hog Solo"),
+	x = 1100,
+	y = 560
+}
+local enemiesOdd = {
+	{name = loc("Hog 1"), x = 2000 , y = 175},
+	{name = loc("Hog III"), x = 1950 , y = 1110},
+	{name = loc("Hog 100"), x = 1270 , y = 1480},
+	{name = loc("Hog Saturn"), x = 240 , y = 790},
+	{name = loc("Hog nueve"), x = 620 , y = 1950},
+	{name = loc("Hog onze"), x = 720 , y = 1950},
+	{name = loc("Hog dertien"), x = 1620 , y = 1950},
+	{name = loc("Hog 3x5"), x = 1720 , y = 1950},
+}
+local enemiesEven = {
+	{name = loc("Hog two"), x = 660, y = 140},
+	{name = loc("Hog D"), x = 1120, y = 1250},
+	{name = loc("Hog exi"), x = 1290, y = 1250},
+	{name = loc("Hog octo"), x = 820, y = 1950},
+	{name = loc("Hog decar"), x = 920, y = 1950},
+	{name = loc("Hog Hephaestus"), x = 1820, y = 1950},
+	{name = loc("Hog 7+7"), x = 1920, y = 1950},
+	{name = loc("Hog EOF"), x = 1200, y = 560},
+}
+-- teams
+local teamA = {
+	name = loc("Hog Solo"),
+	color = tonumber("38D61C",16) -- green
+}
+local teamB = {
+	name = loc("RS1"),
+	color = tonumber("FF0000",16) -- red
+}
+local teamC = {
+	name = loc("RS2"),
+	color = tonumber("FF0000",16) -- red
+}
+
+-------------- LuaAPI EVENT HANDLERS ------------------
+
+function onGameInit()
+	GameFlags = gfDisableWind + gfInfAttack
+	Seed = 1
+	TurnTime = 15000
+	CaseFreq = 0
+	MinesNum = 0
+	MinesTime = 1
+	Explosives = 0
+	Map = "fruit03_map"
+	Theme = "Fruit"
+	
+	-- Hog Solo
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1")
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)
+	-- enemies
+	local hats = { "Bandit", "fr_apple", "fr_banana", "fr_lemon", "fr_orange",
+					"fr_pumpkin", "Gasmask", "NinjaFull", "NinjaStraight", "NinjaTriangle" }
+	AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	for i=1,table.getn(enemiesEven) do
+		enemiesEven[i].gear = AddHog(enemiesEven[i].name, 1, 100, hats[math.random(1,table.getn(hats))])
+		AnimSetGearPosition(enemiesEven[i].gear, enemiesEven[i].x, enemiesEven[i].y)
+	end	
+	AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	for i=1,table.getn(enemiesOdd) do
+		enemiesOdd[i].gear = AddHog(enemiesOdd[i].name, 1, 100, hats[math.random(1,table.getn(hats))])
+		AnimSetGearPosition(enemiesOdd[i].gear, enemiesOdd[i].x, enemiesOdd[i].y)
+	end
+	
+	initCheckpoint("fruit03")
+	
+	AnimInit()
+	AnimationSetup()
+end
+
+function onGameStart()
+	AnimWait(hero.gear, 3000)
+	FollowGear(hero.gear)
+	ShowMission(missionName, loc("Challenge Objectives"), challengeObjectives, -amSkip, 0)
+	
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	AddEvent(onHeroWin, {hero.gear}, heroWin, {hero.gear}, 0)
+	
+	--hero ammo
+	AddAmmo(hero.gear, amTeleport, 2)
+	AddAmmo(hero.gear, amSniperRifle, 2)
+	AddAmmo(hero.gear, amWatermelon, 2)
+	--enemies ammo
+	AddAmmo(enemiesOdd[1].gear, amDEagle, 100)
+	AddAmmo(enemiesOdd[1].gear, amSniperRifle, 100)
+	AddAmmo(enemiesOdd[1].gear, amWatermelon, 1)
+	AddAmmo(enemiesOdd[1].gear, amGrenade, 5)
+	AddAmmo(enemiesEven[1].gear, amDEagle, 100)
+	AddAmmo(enemiesEven[1].gear, amSniperRifle, 100)
+	AddAmmo(enemiesEven[1].gear, amWatermelon, 1)
+	AddAmmo(enemiesEven[1].gear, amGrenade, 5)
+	
+	SendHealthStatsOff()
+	AddAnim(dialog01)
+end
+
+function onNewTurn()
+	if CurrentHedgehog == hero.gear then
+		if GetAmmoCount(hero.gear, amSkip) == 0 then
+			TurnTimeLeft = TurnTime + timeLeft
+			AddAmmo(hero.gear, amSkip, 1)
+		end
+		timeLeft = 0
+	end
+	turnHogs()
+end
+
+function onGameTick()
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+end
+
+function onGameTick20()
+	if CurrentHedgehog == hero.gear and TurnTimeLeft ~= 0 then
+		timeLeft = TurnTimeLeft
+	end
+end
+
+function onGearDelete(gear)
+	if (isHog(gear)) then
+		local availableTeleports = GetAmmoCount(hero.gear,amTeleport)
+		local availableSniper = GetAmmoCount(hero.gear,amSniperRifle)
+		if availableTeleports < 2 then
+			AddAmmo(hero.gear, amTeleport, availableTeleports + 1 )
+		end
+		if availableSniper < 4 then
+			AddAmmo(hero.gear, amSniperRifle, availableSniper + 1 )
+		end
+	end
+end
+
+function onPrecise()
+	if GameTime > 3000 then
+		SetAnimSkip(true)   
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onHeroDeath(gear)
+	if not GetHealth(hero.gear) then
+		return true
+	end
+	return false
+end
+
+function onHeroWin(gear)
+	local enemies = enemiesOdd
+	for i=1,table.getn(enemiesEven) do
+		table.insert(enemies, enemiesEven[i])
+	end
+	local allDead = true
+	for i=1,table.getn(enemies) do
+		if GetHealth(enemies[i].gear) then
+			allDead = false
+			break
+		end
+	end
+	return allDead
+end
+
+-------------- ACTIONS ------------------
+
+function heroDeath(gear)
+	SendStat(siGameResult, loc("Hog Solo lost, try again!"))
+	SendStat(siCustomAchievement, loc("You have to eliminate all the enemies"))			
+	SendStat(siCustomAchievement, loc("Read the Challenge Objectives from within the mission for more details"))		
+	SendStat(siPlayerKills,'1',teamB.name)
+	SendStat(siPlayerKills,'0',teamA.name)
+	EndGame()
+end
+
+function heroWin(gear)
+	saveBonus(2, 1)
+	SendStat(siGameResult, loc("Congratulations, you won!"))
+	SendStat(siCustomAchievement, loc("You complete the mission in "..TotalRounds.." rounds"))			
+	SendStat(siCustomAchievement, loc("You will gain some extra ammo from the crates the next time you play the \"Getting to the device\" mission"))		
+	SendStat(siPlayerKills,'1',teamA.name)
+	EndGame()
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+	if goals[anim] ~= nil then
+		ShowMission(unpack(goals[anim]))
+    end
+    startBattle()
+end
+
+function AnimationSetup()
+	-- DIALOG 01 - Start, game instructions
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Somewhere in the Fruit Planet Hog Solo got lost..."), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("...and got ambushed by the Red Strawberies"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Use your available weapons in order to eliminate the enemies"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("You can only use the Sniper Rifle or the Watermelon bomb"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("You'll have only 2 watermelon bombs during the game"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("You'll get an extra Sniper Rifle every time you kill an enemy hog with a limit of max 4 rifles"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("You'll get an extra Teleport every time you kill an enemy hog with a limit of max 2 teleports"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("The first turn will last 25 sec and every other turn 15 sec"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("If you skip the game your time left will be added to your next turn"), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Some parts of the land are indestructible"), 5000}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}})
+	table.insert(dialog01, {func = startBattle, args = {hero.gear}})	
+end
+
+------------------ Other Functions -------------------
+
+function turnHogs()
+	if GetHealth(hero.gear) then
+		for i=1,table.getn(enemiesEven) do
+			if GetHealth(enemiesEven[i].gear) then
+				if GetX(enemiesEven[i].gear) < GetX(hero.gear) then
+					HogTurnLeft(enemiesEven[i].gear, false)
+				elseif GetX(enemiesEven[i].gear) > GetX(hero.gear) then
+					HogTurnLeft(enemiesEven[i].gear, true)
+				end
+			end
+		end
+		for i=1,table.getn(enemiesOdd) do
+			if GetHealth(enemiesOdd[i].gear) then
+				if GetX(enemiesOdd[i].gear) < GetX(hero.gear) then
+					HogTurnLeft(enemiesOdd[i].gear, false)
+				elseif GetX(enemiesOdd[i].gear) > GetX(hero.gear) then
+					HogTurnLeft(enemiesOdd[i].gear, true)
+				end
+			end
+		end
+	end
+end
+
+function startBattle()
+	AnimSwitchHog(enemiesOdd[table.getn(enemiesOdd)].gear)
+	TurnTimeLeft = 0
+	-- these 2 are needed in order hero has 10 sec more in the first turn
+	timeLeft = 10000
+	AddAmmo(hero.gear, amSkip, 0)
+end
+
+function isHog(gear)
+	local hog = false
+	for i=1,table.getn(enemiesOdd) do
+		if gear == enemiesOdd[i].gear then
+			hog = true
+			break
+		end
+	end
+	if not hog then
+		for i=1,table.getn(enemiesEven) do
+			if gear == enemiesEven then
+				hog = true
+				break
+			end
+		end
+	end
+	return hog
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/global_functions.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,99 @@
+function saveCompletedStatus(planetNum)
+	--        1       2        3        4      5         6        7
+	-- order: moon01, fruit01, fruit02, ice01, desert01, death01, final
+	local status = "0000000"
+	if tonumber(GetCampaignVar("MainMissionsStatus")) then
+		status = GetCampaignVar("MainMissionsStatus")
+	end
+	if i == 1 then
+		status = "1"..status:sub(planetNum+1)
+	elseif i == status:len() then
+		status = status:sub(1,planetNum-1).."1"
+	else
+		status = status:sub(1,planetNum-1).."1"..status:sub(planetNum+1)
+	end
+	SaveCampaignVar("MainMissionsStatus",status)
+end
+
+function getCompletedStatus()
+	local allStatus = ""
+	if tonumber(GetCampaignVar("MainMissionsStatus")) then
+		allStatus = GetCampaignVar("MainMissionsStatus")
+	end
+	local status = {
+		moon01 = false,
+		fruit01 = false,
+		fruit02 = false,
+		ice01 = false,
+		desert01 = false,
+		death01 = false,
+		final = false
+	}
+	if allStatus ~= "" then
+		if allStatus:sub(1,1) == "1" then
+			status.moon01 = true
+		end
+		if allStatus:sub(2,2) == "1" then
+			status.fuit01 = true
+		end
+		if allStatus:sub(3,3) == "1" then
+			status.fruit02 = true
+		end
+		if allStatus:sub(4,4) == "1" then
+			status.ice01 = true
+		end
+		if allStatus:sub(5,5) == "1" then
+			status.desert01 = true
+		end
+		if allStatus:sub(6,6) == "1" then
+			status.death01 = true
+		end
+		if allStatus:sub(7,7) == "1" then
+			status.final = true
+		end
+	end
+	return status
+end
+
+function initCheckpoint(mission)
+	local checkPoint = 1
+	if GetCampaignVar("CurrentMission") ~= mission then
+		SaveCampaignVar("CurrentMission", mission)
+		SaveCampaignVar("CurrentMissionCheckpoint", 1)
+	else
+		checkPoint = tonumber(GetCampaignVar("currentMissionCheckpoint"))
+	end
+	return checkPoint
+end
+
+function saveCheckpoint(cp)
+	SaveCampaignVar("CurrentMissionCheckpoint", cp)
+end
+
+-- saves what bonuses are available
+-- times is how many times the bonus will be available, this will be mission specific
+function saveBonus(index, times)
+	--        1         2        3
+	-- order: desert03, fruit03, death02
+	local bonus = "000"
+	if tonumber(GetCampaignVar("SideMissionsBonuses")) then
+		bonus = GetCampaignVar("SideMissionsBonuses")
+	end
+	if i == 1 then
+		bonus = times..bonus:sub(index+1)
+	elseif i == bonus:len() then
+		bonus = bonus:sub(1,index-1)..times
+	else
+		bonus = bonus:sub(1,index-1)..times..bonus:sub(index+1)
+	end
+	SaveCampaignVar("SideMissionsBonuses",bonus)
+end
+
+function getBonus(index)
+	local bonus = 0
+	if tonumber(GetCampaignVar("SideMissionsBonuses")) then
+		bonusString = GetCampaignVar("SideMissionsBonuses")
+		bonus = bonusString:sub(index,index)
+	end
+	return bonus
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/ice01.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/ice01.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,514 @@
+------------------- ABOUT ----------------------
+--
+-- In this cold planet hero seeks for a part of the
+-- antigravity device. He has to capture Thanta who
+-- knows where the device is hidden. Hero will be
+-- able to use only the ice gun for this mission.
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local missionName = loc("A frozen adventure")
+local heroAtAntiFlyArea = false
+local heroVisitedAntiFlyArea = false
+local heroAtFinalStep = false
+local iceGunTaken = false
+local checkPointReached = 1 -- 1 is normal spawn
+local heroDamageAtCurrentTurn = 0
+-- dialogs
+local dialog01 = {}
+local dialog02 = {}
+-- mission objectives
+local goals = {
+	[dialog01] = {missionName, loc("Getting ready"), loc("Collect the icegun and get the device part from Thanta"), 1, 4500},
+	[dialog02] = {missionName, loc("Win"), loc("Congratulations, you got the part!"), 1, 3500},
+}
+-- crates
+local icegunY = 1950
+local icegunX = 260
+-- hogs
+local hero = {}
+local ally = {}
+local bandit1 = {}
+local bandit2 = {}
+local bandit3 = {}
+local bandit4 = {}
+local bandit5 = {}
+-- teams
+local teamA = {}
+local teamB = {}
+local teamC = {}
+-- hedgehogs values
+hero.name = loc("Hog Solo")
+hero.x = 340
+hero.y = 1840
+hero.dead = false
+ally.name = loc("Paul McHoggy")
+ally.x = 300
+ally.y = 1840
+bandit1.name = loc("Thanta")
+bandit1.x = 3240
+bandit1.y = 1280
+bandit1.dead = false
+bandit1.frozen = false
+bandit1.roundsToUnfreeze = 0
+bandit2.name = loc("Billy Frost")
+bandit2.x = 1480
+bandit2.y = 1990
+bandit3.name = loc("Ice Jake")
+bandit3.x = 1860
+bandit3.y = 1150
+bandit4.name = loc("John Snow")
+bandit4.x = 3200
+bandit4.y = 970
+bandit4.frozen = false
+bandit4.roundsToUnfreeze = 0
+bandit5.name = loc("White Tee")
+bandit5.x = 3280
+bandit5.y = 600
+bandit5.frozen = false
+bandit5.roundsToUnfreeze = 0
+teamA.name = loc("Allies")
+teamA.color = tonumber("FF0000",16) -- red
+teamB.name = loc("Frozen Bandits")
+teamB.color = tonumber("0033FF",16) -- blues
+teamC.name = loc("Hog Solo")
+teamC.color = tonumber("38D61C",16) -- green
+
+-------------- LuaAPI EVENT HANDLERS ------------------
+
+function onGameInit()
+	Seed = 1
+	TurnTime = 25000
+	CaseFreq = 0
+	MinesNum = 0
+	MinesTime = 1
+	Explosives = 0
+	Delay = 3
+	Map = "ice01_map"
+	Theme = "Snow"
+	
+	-- get the check point
+	checkPointReached = initCheckpoint("ice01")
+	-- get hero health
+	local heroHealth = 100
+	if tonumber(GetCampaignVar("HeroHealth")) then
+		heroHealth = tonumber(GetCampaignVar("HeroHealth"))
+	end
+	
+	if heroHealth ~= 100 then
+		heroHealth = heroHealth + 5
+		if heroHealth > 100 then
+			heroHealth = 100
+		end
+		SaveCampaignVar("HeroHealth", heroHealth)	
+	end
+	
+	-- Hog Solo
+	AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	hero.gear = AddHog(hero.name, 0, heroHealth, "war_desertgrenadier1")
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)
+	HogTurnLeft(hero.gear, true)
+	-- Ally
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	ally.gear = AddHog(ally.name, 0, 100, "war_airwarden02")
+	AnimSetGearPosition(ally.gear, ally.x, ally.y)
+	-- Frozen Bandits
+	AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	bandit1.gear = AddHog(bandit1.name, 1, 120, "Santa")
+	AnimSetGearPosition(bandit1.gear, bandit1.x, bandit1.y)	
+	HogTurnLeft(bandit1.gear, true)
+	bandit2.gear = AddHog(bandit2.name, 1, 100, "ushanka")
+	AnimSetGearPosition(bandit2.gear, bandit2.x, bandit2.y)
+	bandit3.gear = AddHog(bandit3.name, 1, 100, "thug")
+	AnimSetGearPosition(bandit3.gear, bandit3.x, bandit3.y)
+	bandit4.gear = AddHog(bandit4.name, 1, 40, "tophats")
+	AnimSetGearPosition(bandit4.gear, bandit4.x, bandit4.y)
+	HogTurnLeft(bandit4.gear, true)
+	bandit5.gear = AddHog(bandit5.name, 1, 40, "Sniper")
+	AnimSetGearPosition(bandit5.gear, bandit5.x, bandit5.y)
+	HogTurnLeft(bandit5.gear, true)
+	
+	if checkPointReached == 1 then
+		-- Start of the game
+	elseif checkPointReached == 2 then
+		iceGunTaken = true
+		AnimSetGearPosition(hero.gear, 840, 1650)
+	elseif checkPointReached == 3 then		
+		iceGunTaken = true
+		heroAtFinalStep = true
+		heroVisitedAntiFlyArea = true
+		AnimSetGearPosition(hero.gear, 1450, 910)
+	end
+	
+	AnimInit()
+	AnimationSetup()	
+end
+
+function onGameStart()
+	AnimWait(hero.gear, 3000)
+	FollowGear(hero.gear)
+	
+	-- Add mines
+	AddGear(1612, 940, gtMine, 0, 0, 0, 0)
+	AddGear(1622, 945, gtMine, 0, 0, 0, 0)
+	AddGear(1645, 950, gtMine, 0, 0, 0, 0)
+	AddGear(1655, 960, gtMine, 0, 0, 0, 0)
+	AddGear(1665, 965, gtMine, 0, 0, 0, 0)
+	
+	AddGear(1800, 1000, gtMine, 0, 0, 0, 0)
+	AddGear(1810, 1005, gtMine, 0, 0, 0, 0)
+	AddGear(1820, 1010, gtMine, 0, 0, 0, 0)
+	AddGear(1830, 1015, gtMine, 0, 0, 0, 0)
+	AddGear(1840, 1020, gtMine, 0, 0, 0, 0)
+	
+	AddGear(1900, 1020, gtMine, 0, 0, 0, 0)
+	AddGear(1910, 1020, gtMine, 0, 0, 0, 0)
+	AddGear(1920, 1020, gtMine, 0, 0, 0, 0)
+	AddGear(1930, 1030, gtMine, 0, 0, 0, 0)
+	AddGear(1940, 1040, gtMine, 0, 0, 0, 0)
+	
+	AddGear(2130, 1110, gtMine, 0, 0, 0, 0)
+	AddGear(2140, 1120, gtMine, 0, 0, 0, 0)
+	AddGear(2180, 1120, gtMine, 0, 0, 0, 0)
+	AddGear(2200, 1130, gtMine, 0, 0, 0, 0)
+	AddGear(2210, 1130, gtMine, 0, 0, 0, 0)
+	
+	local x=2300
+	local step=0
+	while x<3100 do
+		AddGear(x, 1150, gtMine, 0, 0, 0, 0)
+		step = step + 1
+		if step == 5 then
+			step = 0
+			x = x + math.random(100,300)
+		else
+			x = x + math.random(10,30)
+		end
+	end
+	
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	AddEvent(onHeroFinalStep, {hero.gear}, heroFinalStep, {hero.gear}, 0)
+	AddEvent(onAntiFlyArea, {hero.gear}, antiFlyArea, {hero.gear}, 1)
+	AddEvent(onNonAntiFlyArea, {hero.gear}, nonAntiFlyArea, {hero.gear}, 1)
+	AddEvent(onThantaDeath, {bandit1.gear}, thantaDeath, {bandit1.gear}, 0)
+	AddEvent(onHeroWin, {hero.gear}, heroWin, {hero.gear}, 0)
+	
+	AddAmmo(hero.gear, amJetpack, 99)
+	AddAmmo(bandit1.gear, amBazooka, 5)
+	AddAmmo(bandit2.gear, amBazooka, 4)
+	AddAmmo(bandit3.gear, amMine, 2)
+	AddAmmo(bandit3.gear, amGrenade, 3)
+	AddAmmo(bandit4.gear, amBazooka, 5)
+	AddAmmo(bandit5.gear, amBazooka, 5)
+	
+	if checkPointReached == 1 then
+		AddAmmo(hero.gear, amBazooka, 1)
+		SpawnAmmoCrate(icegunX, icegunY, amIceGun)
+		AddEvent(onColumnCheckPoint, {hero.gear}, columnCheckPoint, {hero.gear}, 0)
+		AddEvent(onHeroAtIceGun, {hero.gear}, heroAtIceGun, {hero.gear}, 0)
+		AddAnim(dialog01)
+	elseif checkPointReached == 2 then
+		AddAmmo(hero.gear, amIceGun, 8)
+		AnimCaption(hero.gear, loc("Go to Thanta and get the device part!"), 5000)
+	elseif checkPointReached == 3 then
+		AddAmmo(hero.gear, amIceGun, 6)
+		AnimCaption(hero.gear, loc("Go to Thanta and get the device part!"), 5000)
+	end
+	
+	SendHealthStatsOff()
+end
+
+function onNewTurn()
+	heroDamageAtCurrentTurn = 0
+	-- round has to start if hero goes near the column
+	if not heroVisitedAntiFlyArea and CurrentHedgehog ~= hero.gear then
+		TurnTimeLeft = 0
+	elseif not heroVisitedAntiFlyArea and CurrentHedgehog == hero.gear then
+		TurnTimeLeft = -1
+	elseif not heroAtFinalStep and (CurrentHedgehog == bandit1.gear or CurrentHedgehog == bandit4.gear or CurrentHedgehog == bandit5.gear) then		
+		AnimSwitchHog(hero.gear)
+		TurnTimeLeft = 0
+	elseif heroAtFinalStep and (CurrentHedgehog == bandit2.gear or CurrentHedgehog == bandit3.gear) then
+		if (GetHealth(bandit1.gear) and GetEffect(bandit1.gear,heFrozen) > 256) and
+			((GetHealth(bandit4.gear) and GetEffect(bandit4.gear,heFrozen) > 256) or not GetHealth(bandit4.gear)) and
+			((GetHealth(bandit5.gear) and GetEffect(bandit5.gear,heFrozen) > 256) or not GetHealth(bandit5.gear)) then
+			TurnTimeLeft = 0
+		else
+			AnimSwitchHog(hero.gear)
+			TurnTimeLeft = 0
+		end
+	elseif CurrentHedgehog == ally.gear then
+		TurnTimeLeft = 0
+	end
+	-- frozen hogs accounting
+	if CurrentHedgehog == hero.gear and heroAtFinalStep and TurnTimeLeft > 0 then
+		if bandit1.frozen then
+			if bandit1.roundsToUnfreeze == 0 then
+				SetEffect(bandit1.gear, heFrozen, 255)
+				bandit1.frozen = false
+			else
+				bandit1.roundsToUnfreeze = bandit1.roundsToUnfreeze - 1
+			end
+		end
+		if bandit4.frozen then
+			if bandit4.roundsToUnfreeze == 0 then
+				SetEffect(bandit4.gear, heFrozen, 255)
+				bandit4.frozen = false
+			else
+				bandit4.roundsToUnfreeze = bandit4.roundsToUnfreeze - 1
+			end
+		end
+		if bandit5.frozen then
+			if bandit5.roundsToUnfreeze == 0 then
+				SetEffect(bandit5.gear, heFrozen, 255)
+				bandit5.frozen = false
+			else
+				bandit5.roundsToUnfreeze = bandit5.roundsToUnfreeze - 1
+			end
+		end
+	else
+		if bandit1.frozen then
+			SetEffect(bandit1.gear, heFrozen, 9999999999)
+		end
+		if bandit4.frozen then
+			SetEffect(bandit4.gear, heFrozen, 9999999999)
+		end
+		if bandit5.frozen then
+			SetEffect(bandit5.gear, heFrozen, 9999999999)
+		end
+	end
+end
+
+function onGameTick()
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+	
+	if GetEffect(bandit1.gear, heFrozen) > 256 and not bandit1.frozen then
+		bandit1.frozen = true
+		SetEffect(bandit1.gear, heFrozen, 9999999999)
+		bandit1.roundsToUnfreeze = 1
+	end
+	if GetEffect(bandit4.gear, heFrozen) > 256 and not bandit4.frozen then
+		bandit4.frozen = true
+		SetEffect(bandit4.gear, heFrozen, 9999999999)
+		bandit4.roundsToUnfreeze = 2
+	end
+	if GetEffect(bandit5.gear, heFrozen) > 256 and not bandit5.frozen then
+		bandit5.frozen = true
+		SetEffect(bandit5.gear, heFrozen, 9999999999)
+		bandit5.roundsToUnfreeze = 2
+	end
+end
+
+function onAmmoStoreInit()
+	SetAmmo(amIceGun, 0, 0, 0, 8)
+end
+
+function onGearDelete(gear)
+	if gear == hero.gear then
+		hero.dead = true
+	elseif gear == bandit1.gear then
+		bandit1.dead = true
+	end
+end
+
+function onPrecise()
+	if GameTime > 3000 then
+		SetAnimSkip(true)   
+	end
+end
+
+function onGearDamage(gear, damage)
+	if gear == hero.gear then
+		heroDamageAtCurrentTurn = heroDamageAtCurrentTurn + damage
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onAntiFlyArea(gear)
+	if not hero.dead and (GetX(gear) > 860 or GetY(gear) < 1400) and not heroAtAntiFlyArea then
+		return true
+	end
+	return false
+end
+
+function onNonAntiFlyArea(gear)
+	if not hero.dead and (GetX(gear) < 860 and GetY(gear) > 1400) and heroAtAntiFlyArea then
+		return true
+	end
+	return false
+end
+
+function onHeroDeath(gear)
+	if hero.dead then
+		return true
+	end
+	return false
+end
+
+function onHeroFinalStep(gear)
+	if not hero.dead and GetY(gear) < 960 and GetX(gear) > 1400 then
+		return true
+	end
+	return false
+end
+
+function onColumnCheckPoint(gear)
+	if not hero.dead and iceGunTaken and GetX(gear) < 870 and GetX(gear) > 850 and GetY(gear) > 1500 and StoppedGear(gear) then
+		return true
+	end
+	return false
+end
+
+function onHeroAtIceGun(gear)
+	if not hero.dead and GetX(gear) < icegunX+15 and GetX(gear) > icegunX-15 and GetY(gear) > icegunY-15 and GetY(gear) < icegunY+15 then
+		return true
+	end
+	return false
+end
+
+function onThantaDeath(gear)
+	if bandit1.dead then
+		return true
+	end
+	return false
+end
+
+function onHeroWin(gear)
+	if (not hero.dead and not bandit1.dead) and heroDamageAtCurrentTurn == 0 and (GetX(hero.gear)>=GetX(bandit1.gear)-80
+		and GetX(hero.gear)<=GetX(bandit1.gear)+80)	and (GetY(hero.gear)>=GetY(bandit1.gear)-30 and GetY(hero.gear)<=GetY(bandit1.gear)+30) then
+		return true
+	end
+	return false
+end
+
+-------------- ACTIONS ------------------
+
+function antiFlyArea(gear)
+	heroAtAntiFlyArea = true
+	if TurnTimeLeft < -1 then
+		heroVisitedAntiFlyArea = true
+		TurnTimeLeft = 0	
+		FollowGear(hero.gear)
+		AddAmmo(hero.gear, amJetpack, 0)
+		AnimSwitchHog(bandit1.gear)	
+		FollowGear(hero.gear)
+		TurnTimeLeft = 0
+	else
+		AddAmmo(hero.gear, amJetpack, 0)	
+	end
+end
+
+function nonAntiFlyArea(gear)
+	heroAtAntiFlyArea = false
+	AddAmmo(hero.gear, amJetpack, 99)
+end
+
+function heroDeath(gear)
+	SendStat(siGameResult, loc("Hog Solo lost, try again!"))
+	SendStat(siCustomAchievement, loc("To win the game you have to go next to Thanta"))
+	SendStat(siCustomAchievement, loc("Most of the time you'll be able to use only the icegun"))
+	SendStat(siCustomAchievement, loc("Use the bazooka and the flying saucer to get the icegun"))
+	SendStat(siPlayerKills,'1',teamB.name)
+	SendStat(siPlayerKills,'0',teamC.name)
+	EndGame()
+end
+
+function heroFinalStep(gear)
+	heroAtFinalStep = true
+	saveCheckpoint("3")
+	SaveCampaignVar("HeroHealth", GetHealth(hero.gear))
+end
+
+function columnCheckPoint(gear)
+	saveCheckpoint("2")
+	SaveCampaignVar("HeroHealth", GetHealth(hero.gear))
+	AnimCaption(hero.gear, loc("Checkpoint reached!"), 5000)
+end
+
+function heroAtIceGun(gear)
+	iceGunTaken=true
+end
+
+function thantaDeath(gear)
+	SendStat(siGameResult, loc("Hog Solo lost, try again!"))
+	SendStat(siCustomAchievement, loc("Noooo, Thanta has to stay alive!"))
+	SendStat(siCustomAchievement, loc("To win the game you have to go next to Thanta"))
+	SendStat(siCustomAchievement, loc("Most of the time you'll be able to use only the icegun"))
+	SendStat(siCustomAchievement, loc("Use the bazooka and the flying saucer to get the icegun"))
+	SendStat(siPlayerKills,'1',teamB.name)
+	SendStat(siPlayerKills,'0',teamC.name)
+	EndGame()
+end
+
+function heroWin(gear)
+	TurnTimeLeft=0
+	if GetX(hero.gear) < GetX(bandit1.gear) then
+		HogTurnLeft(bandit1.gear, true)
+	else
+		HogTurnLeft(bandit1.gear, false)
+	end
+	AddAnim(dialog02)
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+	if goals[anim] ~= nil then
+		ShowMission(unpack(goals[anim]))
+    end
+    if anim == dialog02 then
+		actionsOnWin()
+	end
+end
+
+function AnimationSetup()
+	-- DIALOG 01 - Start, welcome to moon
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("In the Ice Planet, where ice rules..."), 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Finaly you are here..."), SAY_SAY, 2000}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 2000}})
+	table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("Hi! Nice to meet you"), SAY_SAY, 3000}})
+	table.insert(dialog01, {func = AnimWait, args = {ally.gear, 2000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Listen carefuly! The bandit leader, Thanta, has recently found a very strange device"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("He doesn't know it but this device is a part of the anti-gravity device"), SAY_SAY, 2500}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 8000}})
+	table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("Nice, then I should get the part as soon as possible!"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimWait, args = {ally.gear, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Be careful, your gadgets won't work in the bandit area. You should get an ice gun"), SAY_SAY, 7000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("There is one below us!"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}})
+	table.insert(dialog01, {func = AnimSwitchHog, args = {hero.gear}})
+	-- DIALOG 02 - Hero got to Thant2
+	AddSkipFunction(dialog02, Skipanim, {dialog02})
+	table.insert(dialog02, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog02, {func = AnimCaption, args = {hero.gear, loc("Congratulations, now you can take Thanta's part..."), 5000}})
+	table.insert(dialog02, {func = AnimSay, args = {bandit1.gear, loc("Oh! Please spare me. You can take all my treasures!"), SAY_SAY, 3000}})
+	table.insert(dialog02, {func = AnimWait, args = {hero.gear, 5000}})
+	table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("I just want the strange device you found!"), SAY_SAY, 3000}})
+	table.insert(dialog02, {func = AnimWait, args = {bandit1.gear, 4000}})
+	table.insert(dialog02, {func = AnimSay, args = {bandit1.gear, loc("Here! Take it..."), SAY_SAY, 3000}})
+	table.insert(dialog02, {func = actionsOnWin, args = {}})	
+end
+
+-------------- Other Functions -------------------
+
+function actionsOnWin()
+	saveCompletedStatus(4)	
+	SendStat(siGameResult, loc("Congratulations, you got the part!"))
+	SendStat(siCustomAchievement, loc("At the end of the game your health was ")..GetHealth(hero.gear))
+	-- maybe add number of tries for each part?
+	SendStat(siPlayerKills,'1',teamC.name)
+	SendStat(siPlayerKills,'0',teamB.name)
+	EndGame()
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/ice02.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/ice02.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,269 @@
+------------------- ABOUT ----------------------
+--
+-- Hero has to pass as fast as possible inside the
+-- rings as in the racer mode
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local missionName = loc("Hard flying")
+local challengeStarted = false
+local currentWaypoint = 1
+local radius = 75
+local totalTime = 15000
+local totalSaucers = 3
+local gameEnded = false
+local RED = 0xff0000ff
+local GREEN = 0x38d61cff
+local challengeObjectives = loc("To win the game you have to pass into the rings in time")..
+	"|"..loc("You'll get extra time in case you need it when you pass a ring").."|"..
+	loc("Every 2 rings, the ring color will be green and you'll get an extra flying saucer").."|"..
+	loc("Use space button twice to change flying saucer while being on air")
+-- dialogs
+local dialog01 = {}
+-- mission objectives
+local goals = {
+	[dialog01] = {missionName, loc("Getting ready"), challengeObjectives, 1, 4500},
+}
+-- hogs
+local hero = {}
+local ally = {}
+-- teams
+local teamA = {}
+local teamB = {}
+-- hedgehogs values
+hero.name = loc("Hog Solo")
+hero.x = 750
+hero.y = 130
+hero.dead = false
+ally.name = loc("Paul McHoggy")
+ally.x = 860
+ally.y = 130
+teamA.name = loc("Hog Solo")
+teamA.color = tonumber("38D61C",16) -- green
+teamB.name = loc("Allies")
+teamB.color = tonumber("FF0000",16) -- red
+-- way points
+local current waypoint = 1
+local waypoints = { 
+	[1] = {x=1450, y=140},
+	[2] = {x=990, y=580},
+	[3] = {x=1650, y=950},
+	[4] = {x=620, y=630},
+	[5] = {x=1470, y=540},
+	[6] = {x=1960, y=60},
+	[7] = {x=1600, y=400},
+	[8] = {x=240, y=940},
+	[9] = {x=200, y=530},
+	[10] = {x=1180, y=120},
+	[11] = {x=1950, y=660},
+	[12] = {x=1280, y=980},
+	[13] = {x=590, y=1100},
+	[14] = {x=20, y=620},
+	[15] = {x=hero.x, y=hero.y}
+}
+
+-------------- LuaAPI EVENT HANDLERS ------------------
+
+function onGameInit()
+	GameFlags = gfInvulnerable
+	Seed = 1
+	TurnTime = 15000
+	CaseFreq = 0
+	MinesNum = 0
+	MinesTime = 1
+	Explosives = 0
+	Map = "ice02_map"
+	Theme = "Snow"
+	
+	-- Hog Solo
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1")
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)
+	-- Ally
+	AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	ally.gear = AddHog(ally.name, 0, 100, "war_airwarden02")
+	AnimSetGearPosition(ally.gear, ally.x, ally.y)
+	HogTurnLeft(ally.gear, true)
+	
+	initCheckpoint("ice02")
+	
+	AnimInit()
+	AnimationSetup()
+end
+
+function onGameStart()
+	AnimWait(hero.gear, 3000)
+	FollowGear(hero.gear)
+	ShowMission(missionName, loc("Challenge Objectives"), challengeObjectives, -amSkip, 0)
+	
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	
+	AddAmmo(hero.gear, amJetpack, 3)
+	
+	-- place a waypoint
+	placeNextWaypoint()
+	
+	SendHealthStatsOff()
+	AddAnim(dialog01)
+end
+
+function onNewTurn()
+	if not hero.dead and CurrentHedgehog == ally.gear and challengeStarted then
+		heroLost()
+	elseif not hero.dead and CurrentHedgehog == hero.gear and challengeStarted then
+		ParseCommand("setweap " .. string.char(amJetpack))
+	end
+end
+
+function onGameTick()
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+end
+
+function onGameTick20()
+	if checkIfHeroInWaypoint() then
+		if not gameEnded and not placeNextWaypoint() then
+			gameEnded = true
+			-- GAME OVER, WIN!
+			totalTime = totalTime - TurnTimeLeft
+			totalTime = totalTime / 1000
+			local saucersLeft = GetAmmoCount(hero.gear, amJetpack)
+			local saucersUsed = totalSaucers - saucersLeft
+			SendStat(siGameResult, loc("Hoo Ray! You are a champion!"))
+			SendStat(siCustomAchievement, loc("You complete the mission in "..totalTime.." seconds"))			
+			SendStat(siCustomAchievement, loc("You have used "..saucersUsed.." flying saucers"))			
+			SendStat(siCustomAchievement, loc("You had "..saucersLeft.." more flying saucers left"))			
+			SendStat(siPlayerKills,'1',teamA.name)
+			EndGame()
+		end
+	end
+end
+
+function onGearDelete(gear)
+	if gear == hero.gear then
+		hero.dead = true
+	end
+end
+
+function onPrecise()
+	if GameTime > 3000 then
+		SetAnimSkip(true)   
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onHeroDeath(gear)
+	if hero.dead then
+		return true
+	end
+	return false
+end
+
+-------------- ACTIONS ------------------
+
+function heroDeath(gear)
+	heroLost()
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+	if goals[anim] ~= nil then
+		ShowMission(unpack(goals[anim]))
+    end
+    startFlying()
+end
+
+function AnimationSetup()
+	-- DIALOG 01 - Start, some story telling
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("In the Ice Planet flying saucer stadium..."), 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("This is the olympic stadium of saucer flying..."), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("All the saucer pilots dream one day to come here and compete with the best!"), SAY_SAY, 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("Now you have the chance to try and get the place that you deserve between the best..."), SAY_SAY, 6000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Use the saucer and pass from the rings..."), 5000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Pause the game by pressing \"P\" for more details"), 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {ally.gear, loc("... can you do it?"), SAY_SAY, 2000}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}})
+	table.insert(dialog01, {func = startFlying, args = {hero.gear}})	
+end
+
+------------------ Other Functions -------------------
+
+function startFlying()
+	AnimSwitchHog(ally.gear)
+	TurnTimeLeft = 0
+	challengeStarted = true
+end
+
+function placeNextWaypoint()
+	if currentWaypoint > 1 then
+		local wp = waypoints[currentWaypoint-1]
+		DeleteVisualGear(wp.gear)
+	end
+	if currentWaypoint < 16 then
+		local wp = waypoints[currentWaypoint]
+		wp.gear = AddVisualGear(1,1,vgtCircle,1,true)
+		-- add bonus time and "fuel"
+		if currentWaypoint % 2 == 0 then
+			PlaySound(sndBump) -- what's the crate sound?
+			SetVisualGearValues(wp.gear, wp.x,wp.y, 20, 200, 0, 0, 100, radius, 3, RED)
+			AddAmmo(hero.gear, amJetpack, GetAmmoCount(hero.gear, amJetpack)+1)
+			totalSaucers = totalSaucers + 1
+			local message = loc("Got 1 more saucer")
+			if TurnTimeLeft <= 22000 then
+				TurnTimeLeft = TurnTimeLeft + 8000
+				totalTime = totalTime + 8000
+				message = message..loc(" and 8 more seconds added to the clock")
+			end
+			AnimCaption(hero.gear, message, 4000)
+		else
+			SetVisualGearValues(wp.gear, wp.x,wp.y, 20, 200, 0, 0, 100, radius, 3, GREEN)
+			if TurnTimeLeft <= 16000 then
+				TurnTimeLeft = TurnTimeLeft + 6000
+				totalTime = totalTime + 6000
+				if currentWaypoint ~= 1 then
+					AnimCaption(hero.gear, loc("6 more seconds added to the clock"), 4000)
+				end
+			end
+		end	
+		radius = radius - 4
+		currentWaypoint = currentWaypoint + 1
+		return true
+	else
+		AnimCaption(hero.gear, loc("Congratulations, you won!"), 4000)
+	end
+	return false
+end
+
+function checkIfHeroInWaypoint()
+	if not hero.dead then
+		local wp = waypoints[currentWaypoint-1]
+		local distance = math.sqrt((GetX(hero.gear)-wp.x)^2 + (GetY(hero.gear)-wp.y)^2)
+		if distance <= radius+4 then
+			SetWind(math.random(-100,100))
+			return true
+		end
+	end
+	return false
+end
+
+function heroLost()
+	SendStat(siGameResult, loc("Oh man! Learn how to fly!"))
+	SendStat(siCustomAchievement, loc("To win the game you have to pass into the rings in time"))
+	SendStat(siCustomAchievement, loc("You'll get extra time in case you need it when you pass a ring"))
+	SendStat(siCustomAchievement, loc("Every 2 rings you'll get extra flying saucers"))
+	SendStat(siCustomAchievement, loc("Use space button twice to change flying saucer while being on air"))
+	SendStat(siPlayerKills,'0',teamA.name)
+	EndGame()
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/moon01.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/moon01.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,450 @@
+------------------- ABOUT ----------------------
+--
+-- This is the first stop of hero's journey.
+-- Here he'll get fuels to continue traveling.
+-- However, the PAoTH allies of the hero have
+-- been taken hostages by professor Hogevil.
+-- So hero has to get whatever available equipement
+-- there is and rescue them.
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local campaignName = loc("A Space Adventure")
+local missionName = loc("The first stop")
+local weaponsAcquired = false
+local battleZoneReached = false
+local checkPointReached = 1 -- 1 is start of the game
+-- dialogs
+local dialog01 = {}
+local dialog02 = {}
+local dialog03 = {}
+local dialog04 = {}
+-- mission objectives
+local goals = {
+	[dialog01] = {missionName, loc("Getting ready"), loc("Go to the upper platform and get the weapons in the crates!"), 1, 4500},
+	[dialog02] = {missionName, loc("Prepare to fight"), loc("Go down and save these PAotH hogs!"), 1, 5000},
+	[dialog03] = {missionName, loc("The fight begins!"), loc("Neutralize your enemies and be careful!"), 1, 5000},
+	[dialog04] = {missionName, loc("The fight begins!"), loc("Neutralize your enemies and be careful!"), 1, 5000}
+}
+-- crates
+local weaponsY = 100
+local bazookaX = 70
+local parachuteX = 110
+local grenadeX = 160
+local deserteagleX = 200
+-- hogs
+local hero = {}
+local paoth1 = {}
+local paoth2 = {}
+local paoth3 = {}
+local paoth4 = {}
+local professor = {}
+local minion1 = {}
+local minion2 = {}
+local minion3 = {}
+local minion4 = {}
+-- teams
+local teamA = {}
+local teamB = {}
+local teamC = {}
+local teamD = {}
+-- hedgehogs values
+hero.name = loc("Hog Solo")
+hero.x = 1380
+hero.y = 1750
+hero.dead = false
+paoth1.name = loc("Joe")
+paoth1.x = 1430
+paoth1.y = 1750
+paoth2.name = loc("Bruce")
+paoth2.x = 3760
+paoth2.y = 1800
+paoth3.name = loc("Helena")
+paoth3.x = 3800
+paoth3.y = 1800
+paoth4.name = loc("Boris")
+paoth4.x = 3860
+paoth4.y = 1800
+professor.name = loc("Prof. Hogevil")
+professor.x = 3800
+professor.y = 1600
+professor.dead = false
+professor.health = 100
+minion1.name = loc("Minion")
+minion1.x = 2460
+minion1.y = 1450
+minion2.name = loc("Minion")
+minion2.x = 2450
+minion2.y = 1900
+minion3.name = loc("Minion")
+minion3.x = 3500
+minion3.y = 1750
+teamA.name = loc("PAoTH")
+teamA.color = tonumber("FF0000",16) -- red
+teamB.name = loc("Minions")
+teamB.color = tonumber("0033FF",16) -- blue
+teamC.name = loc("Professor")
+teamC.color = tonumber("0033FF",16) -- blue
+teamD.name = loc("Hog Solo")
+teamD.color = tonumber("38D61C",16) -- green
+
+-------------- LuaAPI EVENT HANDLERS ------------------
+
+function onGameInit()
+	Seed = 1
+	GameFlags = gfSolidLand + gfDisableWind
+	TurnTime = 25000
+	CaseFreq = 0
+	MinesNum = 0
+	MinesTime = 3000
+	Explosives = 0
+	Delay = 5 
+	Map = "moon01_map"
+	Theme = "Cheese" -- Because ofc moon is made of cheese :)
+	-- Hog Solo
+	AddTeam(teamD.name, teamD.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	if tonumber(GetCampaignVar("HeroHealth")) then
+		hero.gear = AddHog(hero.name, 0, tonumber(GetCampaignVar("HeroHealth")), "war_desertgrenadier1")
+	else
+		hero.gear = AddHog(hero.name, 0, 100, "war_desertgrenadier1")
+	end
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)
+	-- PAoTH
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	paoth1.gear = AddHog(paoth1.name, 0, 100, "scif_2001O")
+	AnimSetGearPosition(paoth1.gear, paoth1.x, paoth1.y)
+	HogTurnLeft(paoth1.gear, true)
+	paoth2.gear = AddHog(paoth2.name, 0, 100, "scif_2001Y")
+	AnimSetGearPosition(paoth2.gear, paoth2.x, paoth2.y)
+	HogTurnLeft(paoth2.gear, true)
+	paoth3.gear = AddHog(paoth3.name, 0, 100, "hair_purple")
+	AnimSetGearPosition(paoth3.gear, paoth3.x, paoth3.y)
+	HogTurnLeft(paoth3.gear, true)
+	paoth4.gear = AddHog(paoth4.name, 0, 100, "scif_2001Y")
+	AnimSetGearPosition(paoth4.gear, paoth4.x, paoth4.y)
+	HogTurnLeft(paoth4.gear, true)
+	-- Professor
+	AddTeam(teamC.name, teamC.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	professor.gear = AddHog(professor.name, 0, 120, "tophats")
+	AnimSetGearPosition(professor.gear, professor.x, professor.y)
+	HogTurnLeft(professor.gear, true)
+	-- Minions
+	AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	minion1.gear = AddHog(minion1.name, 1, 50, "Gasmask")
+	AnimSetGearPosition(minion1.gear, minion1.x, minion1.y)
+	HogTurnLeft(minion1.gear, true)
+	minion2.gear = AddHog(minion2.name, 1, 50, "Gasmask")
+	AnimSetGearPosition(minion2.gear, minion2.x, minion2.y)
+	HogTurnLeft(minion2.gear, true)
+	minion3.gear = AddHog(minion3.name, 1, 50, "Gasmask")
+	AnimSetGearPosition(minion3.gear, minion3.x, minion3.y)
+	HogTurnLeft(minion3.gear, true)
+	
+	-- get the check point
+	checkPointReached = initCheckpoint("moon01")
+	if checkPointReached == 1 then
+		-- Start of the game
+	elseif checkPointReached == 2 then
+		AnimSetGearPosition(hero.gear, parachuteX, weaponsY)
+		if GetHealth(hero.gear) + 5 > 100 then			
+			SaveCampaignVar("HeroHealth", 100)
+		else
+			SaveCampaignVar("HeroHealth", GetHealth(hero.gear) + 5)
+		end
+	end
+	
+	AnimInit()
+	AnimationSetup()	
+end
+
+function onGameStart()
+	-- wait for the first turn to start
+	AnimWait(hero.gear, 3000)
+	FollowGear(hero.gear)
+	
+	ShowMission(campaignName, missionName, loc("Hog Solo has to refuel his saucer.")..
+	"|"..loc("Rescue the imprisoned PAotH team and get your fuels!"), -amSkip, 0)
+	
+	AddAmmo(minion1.gear, amDEagle, 10)
+	AddAmmo(minion2.gear, amDEagle, 10)
+	AddAmmo(minion3.gear, amDEagle, 10)
+	AddAmmo(minion1.gear, amBazooka, 2)
+	AddAmmo(minion2.gear, amBazooka, 2)
+	AddAmmo(minion3.gear, amBazooka, 2)
+	AddAmmo(minion1.gear, amGrenade, 2)
+	AddAmmo(minion2.gear, amGrenade, 2)
+	AddAmmo(minion3.gear, amGrenade, 2)
+	
+	-- check for death has to go first
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	AddEvent(onProfessorDeath, {professor.gear}, professorDeath, {professor.gear}, 0)
+	AddEvent(onMinionsDeath, {professor.gear}, minionsDeath, {professor.gear}, 0)
+	AddEvent(onProfessorHit, {professor.gear}, professorHit, {professor.gear}, 1)
+
+	if checkPointReached == 1 then
+		AddAmmo(hero.gear, amRope, 2)
+		SpawnAmmoCrate(bazookaX, weaponsY, amBazooka)
+		SpawnAmmoCrate(parachuteX, weaponsY, amParachute)
+		SpawnAmmoCrate(grenadeX, weaponsY, amGrenade)
+		SpawnAmmoCrate(deserteagleX, weaponsY, amDEagle)
+		AddEvent(onWeaponsPlatform, {hero.gear}, weaponsPlatform, {hero.gear}, 0)
+		TurnTimeLeft = 0
+		AddAnim(dialog01)
+	elseif checkPointReached == 2 then	
+		AddAmmo(hero.gear, amBazooka, 3)
+		AddAmmo(hero.gear, amParachute, 1)
+		AddAmmo(hero.gear, amGrenade, 6)
+		AddAmmo(hero.gear, amDEagle, 4)
+		SetWind(60)		
+		GameFlags = bor(GameFlags,gfDisableWind)
+		weaponsAcquired = true
+		TurnTimeLeft = 0
+		AddAnim(dialog02)
+	end
+	-- this event check goes here to be executed after the onWeaponsPlatform check
+	AddEvent(onBattleZone, {hero.gear}, battleZone, {hero.gear}, 0)
+	
+	SendHealthStatsOff()
+end
+
+function onAmmoStoreInit()
+	SetAmmo(amBazooka, 0, 0, 0, 3)
+	SetAmmo(amParachute, 0, 0, 0, 1)
+	SetAmmo(amGrenade, 0, 0, 0, 6)
+	SetAmmo(amDEagle, 0, 0, 0, 4)
+end
+
+function onGameTick()
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+	if CurrentHedgehog ~= hero.gear and not battleZone then
+		TurnTimeLeft = 0
+	end
+end
+
+function onNewTurn()		
+	-- rounds start if hero got his weapons or got near the enemies
+	if not weaponsAcquired and not battleZoneReached and CurrentHedgehog ~= hero.gear then
+		TurnTimeLeft = 0
+	elseif weaponsAcquired and not battleZoneReached and CurrentHedgehog ~= hero.gear then
+		battleZoneReached = true
+		AddAnim(dialog04)
+	elseif not weaponsAcquired and not battleZoneReached and CurrentHedgehog == hero.gear then
+		TurnTimeLeft = -1
+	elseif CurrentHedgehog == paoth1.gear or CurrentHedgehog == paoth2.gear
+		or CurrentHedgehog == paoth3.gear or CurrentHedgehog == paoth4.gear then
+		TurnTimeLeft = 0
+	elseif CurrentHedgehog == professor.gear then
+		AnimSwitchHog(hero.gear)
+		TurnTimeLeft = 0
+	end
+end
+
+function onPrecise()
+	if GameTime > 3000 then
+		SetAnimSkip(true)   
+	end
+end
+
+function onGearDelete(gear)
+	if gear == hero.gear then
+		hero.dead = true
+	elseif gear == professor.gear then
+		professor.dead = true
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onWeaponsPlatform(gear)
+	if not hero.dead and (GetAmmoCount(hero.gear, amBazooka) > 0 or GetAmmoCount(hero.gear, amParachute) > 0 or 
+			GetAmmoCount(hero.gear, amGrenade) > 0 or GetAmmoCount(hero.gear, amDEagle) > 0) and StoppedGear(hero.gear) then
+		return true
+	end
+	return false
+end
+
+function onHeroDeath(gear)
+	if hero.dead then
+		return true
+	end
+	return false
+end
+
+function onBattleZone(gear)
+	if not battleZoneReached and not hero.dead and GetX(gear) > 1900 and StoppedGear(gear) then
+		return true
+	end
+	return false
+end
+
+function onProfessorHit(gear)
+	if GetHealth(gear) then
+		if CurrentHedgehog ~= hero.gear and GetHealth(gear) < professor.health then
+			professor.health = GetHealth(gear)
+			return true
+		elseif GetHealth(gear) < professor.health then
+			professor.health = GetHealth(gear)
+		end
+	end
+	return false
+end
+
+function onProfessorDeath(gear)
+	if professor.dead then
+		return true
+	end
+	return false
+end
+
+function onMinionsDeath(gear)
+	if not (GetHealth(minion1.gear) or GetHealth(minion2.gear) or GetHealth(minion3.gear)) then
+		return true
+	end
+	return false
+end
+
+-------------- ACTIONS ------------------
+
+function weaponsPlatform(gear)
+	saveCheckpoint("2")
+	SaveCampaignVar("HeroHealth",GetHealth(hero.gear))
+	TurnTimeLeft = 0
+	weaponsAqcuired = true
+	SetWind(60)		
+	GameFlags = bor(GameFlags,gfDisableWind)
+	AddAmmo(hero.gear, amRope, 0)
+	if GetX(hero.gear) < 1900 then
+		AddAnim(dialog02)
+	end
+end
+
+function heroDeath(gear)
+	SendStat(siGameResult, loc("Hog Solo lost, try again!"))
+	SendStat(siCustomAchievement, loc("You have to get the weapons and rescue the PAotH researchers"))
+	SendStat(siPlayerKills,'1',teamC.name)
+	SendStat(siPlayerKills,'0',teamD.name)
+	EndGame()
+end
+
+function battleZone(gear)
+	TurnTimeLeft = 0
+	battleZoneReached = true
+	if weaponsAqcuired then
+		AddAnim(dialog04)
+	else
+		AddAnim(dialog03)
+	end
+end
+
+function professorHit(gear)
+	if currentHedgehog ~= hero.gear then
+		AnimSay(professor.gear,loc("Don't hit me you fools!"), SAY_SHOUT, 2000)
+	end
+end
+
+function professorDeath(gear)
+	if GetHealth(minion1.gear) then
+		AnimSay(minion1.gear, loc("The boss has fallen! Retreat!"), SAY_SHOUT, 6000)
+	elseif GetHealth(minion2.gear) then
+		AnimSay(minion2.gear, loc("The boss has fallen! Retreat!"), SAY_SHOUT, 6000)
+	elseif GetHealth(minion3.gear) then
+		AnimSay(minion3.gear, loc("The boss has fallen! Retreat!"), SAY_SHOUT, 6000)
+	end
+	ParseCommand("teamgone " .. teamB.name)
+	AnimCaption(hero.gear, loc("Congrats! You made them run away!"), 6000)
+	AnimWait(hero.gear,5000)	
+	
+	saveCompletedStatus(1)
+	SendStat(siGameResult, loc("Hog Solo win, conrgatulations!"))
+	SendStat(siCustomAchievement, loc("Eliminated the professor Hogevil"))
+	SendStat(siCustomAchievement, loc("Drove the minions away"))
+	SendStat(siPlayerKills,'1',teamD.name)
+	SendStat(siPlayerKills,'0',teamC.name)
+	SaveCampaignVar("CosmosCheckPoint", "5") -- hero got fuels
+	EndGame()
+end
+
+function minionsDeath(gear)
+	-- do staffs here
+	AnimSay(professor.gear, loc("I may lost that battle, but I haven't lost the war yet!"), SAY_SHOUT, 6000)
+	ParseCommand("teamgone " .. teamC.name)
+	AnimCaption(hero.gear, loc("Congrats! You won!"), 6000)
+	AnimWait(hero.gear,5000)	
+	
+	saveCompletedStatus(1)
+	SendStat(siGameResult, loc("Congratulations, you won!"))
+	SendStat(siCustomAchievement, loc("Eliminated the evil minions"))
+	SendStat(siCustomAchievement, loc("Drove the professor away"))
+	SendStat(siPlayerKills,'1',teamD.name)
+	SendStat(siPlayerKills,'0',teamC.name)
+	SaveCampaignVar("CosmosCheckPoint", "5") -- hero got fuels	
+	EndGame()
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+	if goals[anim] ~= nil then
+		ShowMission(unpack(goals[anim]))
+    end
+    if anim == dialog03 then
+		startCombat()
+	else
+		AnimSwitchHog(hero.gear)
+	end
+end
+
+function AnimationSetup()
+	-- DIALOG 01 - Start, welcome to moon
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3000}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("Near PAotH base at moon..."),  4000}})
+	table.insert(dialog01, {func = AnimSay, args = {paoth1.gear, loc("Hey Hog Solo! Finaly you have come..."), SAY_SAY, 2000}})
+	table.insert(dialog01, {func = AnimSay, args = {paoth1.gear, loc("It seems that Professor Hogevil learned for your arrival!"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {paoth1.gear, loc("Now he have captured the rest of the PAotH team and awaits to capture you!"), SAY_SAY, 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {paoth1.gear, loc("We have to hurry! Are you armed?"), SAY_SAY, 4300}})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 500}})
+	table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("No, I am afraid I had to travel light"), SAY_SAY, 2500}})
+	table.insert(dialog01, {func = AnimWait, args = {paoth1.gear, 500}})
+	table.insert(dialog01, {func = AnimSay, args = {paoth1.gear, loc("Ok, then you have to go and take some of the waepons we have hidden in case of an emergency!"), SAY_SAY, 7000}})
+	table.insert(dialog01, {func = AnimSay, args = {paoth1.gear, loc("They are up there! Take that rope and hurry!"), SAY_SAY, 7000}})
+	table.insert(dialog01, {func = AnimSay, args = {hero.gear, loc("Ehm... ok..."), SAY_SAY, 2500}})
+	table.insert(dialog01, {func = AnimSwitchHog, args = {hero.gear}})
+	-- DIALOG 02 - To the weapons platform
+	AddSkipFunction(dialog02, Skipanim, {dialog02})
+	table.insert(dialog02, {func = AnimCaption, args = {hero.gear, loc("Checkpoint reached!"),  4000}})
+	table.insert(dialog02, {func = AnimSay, args = {hero.gear, loc("I've made it! YEAAAAAH!"), SAY_SHOUT, 4000}})
+	table.insert(dialog02, {func = AnimSay, args = {paoth1.gear, loc("Nice! Now hurry up and get down! You have to rescue my friends!"), SAY_SHOUT, 7000}})
+	table.insert(dialog02, {func = AnimSwitchHog, args = {hero.gear}})
+	-- DIALOG 03 - Hero spotted and has no weapons
+	AddSkipFunction(dialog03, Skipanim, {dialog03})
+	table.insert(dialog03, {func = AnimCaption, args = {hero.gear, loc("Get ready to fight!"), 4000}})
+	table.insert(dialog03, {func = AnimSay, args = {minion1.gear, loc("Look boss! There is the target!"), SAY_SHOUT, 4000}})
+	table.insert(dialog03, {func = AnimSay, args = {professor.gear, loc("Prepare for battle!"), SAY_SHOUT, 4000}})
+	table.insert(dialog03, {func = AnimSay, args = {hero.gear, loc("Oops, I've been spotted and I have no weapons! I am doomed!"), SAY_THINK, 4000}})
+	table.insert(dialog03, {func = startCombat, args = {hero.gear}})
+	-- DIALOG 04 - Hero spotted and *HAS* weapons
+	AddSkipFunction(dialog04, Skipanim, {dialog04})
+	table.insert(dialog04, {func = AnimCaption, args = {hero.gear, loc("Get ready to fight!"), 4000}})
+	table.insert(dialog04, {func = AnimSay, args = {minion1.gear, loc("Look boss! There is the target!"), SAY_SHOUT, 4000}})
+	table.insert(dialog04, {func = AnimSay, args = {professor.gear, loc("Prepare for battle!"), SAY_SHOUT, 4000}})
+	table.insert(dialog04, {func = AnimSay, args = {hero.gear, loc("Here we go!"), SAY_THINK, 4000}})
+	table.insert(dialog04, {func = startCombat, args = {hero.gear}})
+end
+
+------------------- custom "animation" functions --------------------------
+
+function startCombat()
+	-- use this so guard2 will gain control
+	AnimSwitchHog(minion3.gear)
+	TurnTimeLeft = 0
+end
Binary file share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/moon02.hwp has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/moon02.lua	Mon Oct 28 14:07:04 2013 +0100
@@ -0,0 +1,234 @@
+------------------- ABOUT ----------------------
+--
+-- Hog Solo has to catch the other hog in order
+-- to get informations about the origin of Pr. Hogevil
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local missionName = loc("Chasing the blue hog")
+local challengeObjectives = loc("Use your available weapons in order to catch the other hog").."|"..
+	loc("You have to stand very close to him")
+local currentPosition = 1
+local previousTimeLeft = 0
+local startChallenge = false
+-- dialogs
+local dialog01 = {}
+local dialog02 = {}
+-- mission objectives
+local goals = {
+	[dialog01] = {missionName, loc("Challenge Objectives"), challengeObjectives, 1, 4500},
+}
+-- hogs
+local hero = {
+	name = loc("Hog Solo"),
+	x = 1300,
+	y = 850
+}
+local runner = {
+	name = loc("Crazy Runner"),
+	places = {
+		{x = 1400,y = 850, turnTime = 0},
+		{x = 3880,y = 33, turnTime = 30000},
+		{x = 250,y = 1780, turnTime = 25000},
+		{x = 3850,y = 1940, turnTime = 20000},
+	}
+}
+-- teams
+local teamA = {
+	name = loc("Hog Solo"),
+	color = tonumber("38D61C",16) -- green
+}
+local teamB = {
+	name = loc("Crazy Runner"),
+	color = tonumber("FF0000",16) -- red
+}
+
+-------------- LuaAPI EVENT HANDLERS ------------------
+
+function onGameInit()
+	GameFlags = gfDisableWind
+	Seed = 1
+	TurnTime = 25000
+	CaseFreq = 0
+	MinesNum = 0
+	MinesTime = 1
+	Explosives = 0
+	Map = "moon02_map"
+	Theme = "Cheese"
+	
+	-- Hog Solo
+	AddTeam(teamA.name, teamA.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	hero.gear = AddHog(hero.name, 0, 1, "war_desertgrenadier1")
+	AnimSetGearPosition(hero.gear, hero.x, hero.y)
+	-- Crazy Runner
+	AddTeam(teamB.name, teamB.color, "Bone", "Island", "HillBilly", "cm_birdy")
+	runner.gear = AddHog(runner.name, 0, 100, "sth_Sonic")
+	AnimSetGearPosition(runner.gear, runner.places[1].x, runner.places[1].y)
+	HogTurnLeft(runner.gear, true)
+	
+	initCheckpoint("moon02")
+	
+	AnimInit()
+	AnimationSetup()
+end
+
+function onGameStart()
+	AnimWait(hero.gear, 3000)
+	FollowGear(hero.gear)
+	ShowMission(missionName, loc("Challenge Objectives"), challengeObjectives, -amSkip, 0)
+	
+	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
+	
+	AddAmmo(hero.gear, amRope, 1)
+	AddAmmo(hero.gear, amSkip, 1)
+	
+	SendHealthStatsOff()
+	hogTurn = runner.gear
+	AddAnim(dialog01)
+end
+
+function onNewTurn()
+	if startChallenge then
+		if CurrentHedgehog ~= hero.gear then
+			TurnTimeLeft = 0
+		else
+			if GetAmmoCount(hero.gear, amRope) == 0  then
+				lose()
+			end
+			ParseCommand("setweap " .. string.char(amRope))
+			TurnTimeLeft = runner.places[currentPosition].turnTime + previousTimeLeft
+			previousTimeLeft = 0
+		end
+	end
+end
+
+function onGameTick()
+	AnimUnWait()
+	if ShowAnimation() == false then
+		return
+	end
+	ExecuteAfterAnimations()
+	CheckEvents()
+end
+
+function onGameTick20()
+	if isHeroNextToRunner() then
+		moveRunner()
+	end
+end
+
+function onPrecise()
+	if GameTime > 3000 then
+		SetAnimSkip(true)   
+	end
+end
+
+-------------- EVENTS ------------------
+
+function onHeroDeath(gear)
+	if not GetHealth(hero.gear) then
+		return true
+	end
+	return false
+end
+
+-------------- ACTIONS ------------------
+
+function heroDeath(gear)
+	lose()
+end
+
+-------------- ANIMATIONS ------------------
+
+function Skipanim(anim)
+	if goals[anim] ~= nil then
+		ShowMission(unpack(goals[anim]))
+    end
+    if anim == dialog01 then
+		moveRunner()
+    end
+end
+
+function AnimationSetup()
+	-- DIALOG 01 - Start, game instructions
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3200}})
+	table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("In the other side of the moon..."), 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {runner.gear, loc("So you are interested in Pr. Hogevil"), SAY_SAY, 3000}})
+	table.insert(dialog01, {func = AnimSay, args = {runner.gear, loc("We'll play a game first"), SAY_SAY, 3000}})
+	table.insert(dialog01, {func = AnimSay, args = {runner.gear, loc("I'll let you know whatever I know about him if you manage to catch me 3 times"), SAY_SAY, 4000}})
+	table.insert(dialog01, {func = AnimSay, args = {runner.gear, loc("Let's go!"), SAY_SAY, 2000}})	
+	table.insert(dialog01, {func = moveRunner, args = {}})
+	-- DIALOG 02 - Hog Solo story    
+	AddSkipFunction(dialog02, Skipanim, {dialog02})
+	table.insert(dialog02, {func = AnimWait, args = {hero.gear, 3200}})
+	table.insert(dialog02, {func = AnimCaption, args = {hero.gear, loc("The truth about Pr. Hogevil"), 5000}})
+	table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("Amazing! I was never beaten in running before!"), SAY_SAY, 4000}})
+	table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("So, let me tell you what I know about Pr. Hogevil..."), SAY_SAY, 4000}})
+	table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("Pr. Hogevil, then known as James Hogus, worked for PAotH back in my time"), SAY_SAY, 4000}})
+	table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("He was the lab assistant of Dr. Goodhogan, the inventor of the anti-gravity device"), SAY_SAY, 5000}})
+	table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("In one of the last tests during the construction of the device an accident happpened"), SAY_SAY, 5000}})
+	table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("In this accident Pr. Hogevil lost all his nails from his head!"), SAY_SAY, 5000}})
+	table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("That's why he always wears a hat since then"), SAY_SAY, 4000}})
+	table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("After that incident he got underground and start working his plan to steal the device"), SAY_SAY, 5000}})
+	table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("He is a very taugh and very determined hedgehog. I would be extremely careful if I were you"), SAY_SAY, 5000}})
+	table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("I should go now, goodbye!"), SAY_SAY, 3000}})
+	table.insert(dialog02, {func = win, args = {}})
+end
+
+------------- other functions ---------------
+
+function isHeroNextToRunner()
+	if GetHealth(hero.gear) and math.abs(GetX(hero.gear) - GetX(runner.gear)) < 75 and
+			math.abs(GetY(hero.gear) - GetY(runner.gear)) < 75 and StoppedGear(hero.gear) then
+		return true
+	end
+	return false
+end
+
+function moveRunner()
+	if currentPosition > 3 then
+		if GetX(hero.gear) > GetX(runner.gear) then
+			HogTurnLeft(runner.gear, false)
+		end
+		TurnTimeLeft = 0
+		AddAnim(dialog02)
+	else
+		if not startChallenge then
+			startChallenge = true
+		end
+		AddAmmo(hero.gear, amRope, 1)
+		if currentPosition ~= 1 then
+			PlaySound(sndVictory)
+			if currentPosition > 1 and currentPosition < 4 then
+				AnimCaption(hero.gear, loc("Go get him again"), 3000)
+				AnimSay(runner.gear, loc("You got me"), SAY_SAY, 3000)
+			end
+			previousTimeLeft = TurnTimeLeft
+		end
+		currentPosition = currentPosition + 1
+		SetGearPosition(runner.gear, runner.places[currentPosition].x, runner.places[currentPosition].y)
+		TurnTimeLeft = 0
+	end
+end
+
+function lose()
+	SendStat(siGameResult, loc("Too slow! Try again..."))
+	SendStat(siCustomAchievement, loc("You have to caught the other hog 3 times"))
+	SendStat(siCustomAchievement, loc("The time that you'll have left when you reach the hog will be added to the next turn"))
+	SendStat(siCustomAchievement, loc("Each turn you'll have only one rope to use"))
+	SendStat(siCustomAchievement, loc("You'll lose if you die or if your time is up"))
+	SendStat(siPlayerKills,'0',teamA.name)
+	EndGame()
+end
+
+function win()
+	SendStat(siGameResult, loc("Congratulations, you are the fastest!"))
+	SendStat(siCustomAchievement, loc("You have managed to caught the other hog in time"))
+	SendStat(siPlayerKills,'1',teamA.name)
+	EndGame()
+end
--- a/share/hedgewars/Data/Missions/Campaign/CMakeLists.txt	Sun Oct 27 22:34:25 2013 -0400
+++ b/share/hedgewars/Data/Missions/Campaign/CMakeLists.txt	Mon Oct 28 14:07:04 2013 +0100
@@ -1,4 +1,5 @@
 add_subdirectory("A_Classic_Fairytale")
+add_subdirectory("A_Space_Adventure")
 
 file(GLOB Scripts *.lua)