merge and changed also spacecampaign name spacecampaign
authorPeriklis Ntanasis <pntanasis@gmail.com>
Mon, 01 Jul 2013 23:23:22 +0300
branchspacecampaign
changeset 9308 4bddcc1a1450
parent 9296 5cc010e79431 (diff)
parent 9306 c9978ada9a3d (current diff)
child 9310 1469147c110f
merge and changed also spacecampaign name
QTfrontend/campaign.cpp
QTfrontend/hedgewars.qrc
QTfrontend/hwform.cpp
QTfrontend/res/campaign/A Classic Fairytale/backstab.png
QTfrontend/res/campaign/A Classic Fairytale/dragon.png
QTfrontend/res/campaign/A Classic Fairytale/enemy.png
QTfrontend/res/campaign/A Classic Fairytale/epil.png
QTfrontend/res/campaign/A Classic Fairytale/family.png
QTfrontend/res/campaign/A Classic Fairytale/first_blood.png
QTfrontend/res/campaign/A Classic Fairytale/journey.png
QTfrontend/res/campaign/A Classic Fairytale/queen.png
QTfrontend/res/campaign/A Classic Fairytale/shadow.png
QTfrontend/res/campaign/A Classic Fairytale/united.png
QTfrontend/res/campaign/A Space Adventure/cosmos.png
QTfrontend/res/campaign/A_Space_Adventure/cosmos.png
hedgewars/ArgParsers.inc
hedgewars/GSHandlers.inc
hedgewars/VGSHandlers.inc
share/hedgewars/Data/Locale/campaigns_en.txt
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/CMakeLists.txt
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/backstab.lua
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/campaign.ini
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/dragon.lua
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/enemy.lua
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/epil.lua
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/family.lua
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/first_blood.hwp
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/first_blood.lua
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/journey.hwp
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/journey.lua
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/queen.lua
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/shadow.hwp
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/shadow.lua
share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/united.lua
share/hedgewars/Data/Missions/Campaign/A Space Adventure/CMakeLists.txt
share/hedgewars/Data/Missions/Campaign/A Space Adventure/campaign.ini
share/hedgewars/Data/Missions/Campaign/A Space Adventure/cosmos.hwp
share/hedgewars/Data/Missions/Campaign/A Space Adventure/cosmos.lua
share/hedgewars/Data/Missions/Campaign/A Space Adventure/moon01.lua
share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/first_blood.lua
share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/journey.lua
share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/CMakeLists.txt
share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/campaign.ini
share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/cosmos.hwp
share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/cosmos.lua
share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/moon01.lua
share/hedgewars/Data/Missions/Campaign/CMakeLists.txt
--- a/QTfrontend/campaign.cpp	Mon Jul 01 20:04:32 2013 +0300
+++ b/QTfrontend/campaign.cpp	Mon Jul 01 23:23:22 2013 +0300
@@ -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	Mon Jul 01 20:04:32 2013 +0300
+++ b/QTfrontend/campaign.h	Mon Jul 01 23:23:22 2013 +0300
@@ -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	Mon Jul 01 20:04:32 2013 +0300
+++ b/QTfrontend/hedgewars.qrc	Mon Jul 01 23:23:22 2013 +0300
@@ -38,12 +38,14 @@
         <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/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	Mon Jul 01 20:04:32 2013 +0300
+++ b/QTfrontend/hwform.cpp	Mon Jul 01 23:23:22 2013 +0300
@@ -199,6 +199,7 @@
     UpdateTeamsLists();
     InitCampaignPage();
     UpdateCampaignPage(0);
+    UpdateCampaignPageMission(0);
     UpdateWeapons();
 
     // connect all goBack signals
@@ -1721,13 +1722,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);
 }
 
@@ -1892,85 +1889,34 @@
     }
 }
 
-
 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);
+		// Maybe not enforce the prefix Mission %1, isn't so nice for the misison with no
+		// specific order
+        ui.pageCampaign->CBMission->addItem(QString("Mission %1: ").arg(campaignMissionInfo.size()-i) + 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));
     }
 }
 
--- a/QTfrontend/hwform.h	Mon Jul 01 20:04:32 2013 +0300
+++ b/QTfrontend/hwform.h	Mon Jul 01 23:23:22 2013 +0300
@@ -34,6 +34,7 @@
 #include "ui_hwform.h"
 #include "SDLInteraction.h"
 #include "bgwidget.h"
+#include "campaign.h"
 
 #ifdef __APPLE__
 #include "InstallController.h"
@@ -194,8 +195,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
--- a/share/hedgewars/Data/Locale/campaigns_en.txt	Mon Jul 01 20:04:32 2013 +0300
+++ b/share/hedgewars/Data/Locale/campaigns_en.txt	Mon Jul 01 23:23:22 2013 +0300
@@ -17,3 +17,9 @@
 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="MOON TEST"
+A_Space_Adventure-ice.desc="ICE TEST"
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Campaign/A_Space_Adventure/CMakeLists.txt	Mon Jul 01 23:23:22 2013 +0300
@@ -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 Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,22 @@
+MissionNum=5
+ResetRetry=1
+
+[Mission 1]
+Name=The Spacetrip
+Script=cosmos.lua
+
+[Mission 2]
+Name=Moon:The First Stop
+Script=moon01.lua
+
+[Mission 3]
+Name=FRUIT
+Script=fruit.lua
+
+[Mission 4]
+Name=DESERT
+Script=desert.lua
+
+[Mission 5]
+Name=ICE
+Script=ice.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 Jul 01 23:23:22 2013 +0300
@@ -0,0 +1,390 @@
+------------------- 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.
+
+-- TODO
+-- Save and Load All Check Points
+-- Save hero health
+-- Decide and implement if hero will use gas bombs...
+-- ofc add custom stats page
+-- PROBLEM : What if one makes a bad choice and wants to replay it map, how to reset?
+-- POSSIBLE SOLUTIONS: In game function keys, frontend button...
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
+
+----------------- VARIABLES --------------------
+-- globals
+local campaignName = loc("A Space Adventure")
+local missionName = loc("Cosmos")
+local timeForGuard1ToTurn = 1000 * 5 -- 5 sec
+local timeForGuard1ToTurnLeft = timeForGuard1ToTurn
+local saucerAcquired = false
+local checkPointReached = 1 -- 1 is start of the game
+-- dialogs
+local dialog01 = {}
+local dialog02 = {}
+local dialog03 = {}
+local dialog04 = {}
+local dialog05 = {}
+local dialog06 = {}
+-- mission objectives
+local goals = {
+	[dialog01] = {missionName, loc("Getting ready"), loc("Go and collect the crate on top of the column").."|"..loc("Use the sleep gas bomb if the guards spot you!"), 1, 4500},
+	[dialog02] = {missionName, loc("The adventure begins!"), loc("Use the saucer and fly to the moon").."|"..loc("Drive carefully as your fuels are limited"), 1, 4500},
+	[dialog03] = {missionName, loc("An unexpected event!"), loc("Use the saucer and fly away or use the gas bomb to neutralize the guards").."|"..loc("Beware, any damage taken will stay until you take some medicine or visit moon"), 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
+	Map = "cosmos_map" -- custom map included in file
+	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
+	end
+	
+	AnimInit()
+	AnimationSetup()
+end
+
+function onGameStart()
+	-- wait for the first turn to start
+	AnimWait(hero.gear, 3000)
+
+	FollowGear(hero.gear)
+	ShowMission(loc("A Space Adventure"), loc("Cosmos"), 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, amGasBomb, 5)
+		AddAmmo(hero.gear, amRope, 2)
+		-- Added for dev/debug purposes, remove before release
+		AddAmmo(hero.gear, amJetpack, 2)
+		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
+	end
+	-- 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
+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 GetX(gear) > 2444 then
+		return true
+	end
+	return false
+end
+
+function onHeroAtSaucerPosition(gear)
+	if GetX(gear) >= saucerX-32 and GetX(gear) <= saucerX+32 and GetY(gear) >= saucerY-32 and GetY(gear) <= saucerY+32 then
+		saucerAcquired = true
+	end
+	if saucerAcquired and StoppedGear(gear) then
+		return true
+	end
+	return false
+end
+
+function onHeroOutOfGuardSight(gear)
+	if 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 GetX(gear) > 1010 and GetX(gear) < 1220  and GetY(gear) < 1300 and StoppedGear(gear) then
+		return true
+	end
+	return false
+end
+
+function onFruitPlanetLanding(gear)
+	if 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 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 GetX(gear) > 1330 and GetX(gear) < 1650  and GetY(gear) < 500 and StoppedGear(gear) then
+		return true
+	end
+	return false
+end
+
+-------------- OUTCOMES ------------------
+
+function heroBeforeTreePosition(gear)
+	AnimSay(gear,loc("Now I have to climb the 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")
+	AddAnim(dialog02)
+	-- check if he was spotted by the guard
+	if guard1.turn then
+		guard1.keepTurning = false
+		AddAnim(dialog03)
+	end	
+end
+
+function heroOutOfGuardSight(gear)
+	guard1.keepTurning = true
+	AddAnim(dialog04)
+end
+
+function moonLanding(gear)
+	WriteLnToConsole("MOON LANDING, HOORAY!")
+	AnimCaption(hero.gear,loc("Welcome to the moon!"))
+	SaveCampaignVar("CosmosCheckPoint", "4")
+	SaveCampaignVar("Planet", "moon")
+	EndGame()
+end
+
+function fruitPlanetLanding(gear)
+	if checkPointReached < 5 then
+		AddAnim(dialog06)
+	end
+end
+
+function desertPlanetLanding(gear)
+	if checkPointReached < 5 then
+		AddAnim(dialog06)
+	end
+end
+
+function icePlanetLanding(gear)
+	if checkPointReached < 5 then
+		AddAnim(dialog06)
+	end
+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
+		EndGame()
+	end
+end
+
+function AnimationSetup()
+	-- DIALOG 01 - Start
+	AddSkipFunction(dialog01, Skipanim, {dialog01})
+	table.insert(dialog01, {func = AnimWait, args = {doctor.gear, 3000}})
+	--table.insert(dialog01, {func = AnimWait, args = {hero.gear, 2500}, skipFunc = Skipanim, skipArgs = dialog01})
+	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 a rope and a sleep gas bomb"), SAY_SAY, 5000}})
+	table.insert(dialog01, {func = AnimSay, args = {doctor.gear, loc("You may find them 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 them"), 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 battle or 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 = EndGame, 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 = EndGame, args = {hero.gear}})
+end
+
+------------------- custom "animation" functions --------------------------
+
+function startCombat()
+	-- use this so guard2 will gain control
+	AnimSwitchHog(hero.gear)
+	TurnTimeLeft = 0
+end
--- a/share/hedgewars/Data/Missions/Campaign/CMakeLists.txt	Mon Jul 01 20:04:32 2013 +0300
+++ b/share/hedgewars/Data/Missions/Campaign/CMakeLists.txt	Mon Jul 01 23:23:22 2013 +0300
@@ -1,4 +1,5 @@
 add_subdirectory("A_Classic_Fairytale")
+add_subdirectory("A_Space_Adventure")
 
 file(GLOB Scripts *.lua)