QTfrontend/game.cpp
branchui-scaling
changeset 15283 c4fd2813b127
parent 13389 24b531dcebe7
parent 15278 16f389fcd462
child 15663 d92eeb468dad
equal deleted inserted replaced
13390:0135e64c6c66 15283:c4fd2813b127
    27 #include <QTextStream>
    27 #include <QTextStream>
    28 #include <utility>
    28 #include <utility>
    29 
    29 
    30 #include "hwform.h"
    30 #include "hwform.h"
    31 #include "ui/page/pageoptions.h"
    31 #include "ui/page/pageoptions.h"
       
    32 #include "ui/page/pagetraining.h"
       
    33 #include "ui/page/pagecampaign.h"
    32 #include "game.h"
    34 #include "game.h"
    33 #include "hwconsts.h"
    35 #include "hwconsts.h"
    34 #include "gameuiconfig.h"
    36 #include "gameuiconfig.h"
    35 #include "gamecfgwidget.h"
    37 #include "gamecfgwidget.h"
    36 #include "teamselect.h"
    38 #include "teamselect.h"
    42 #include "ThemeModel.h"
    44 #include "ThemeModel.h"
    43 
    45 
    44 // last game info
    46 // last game info
    45 QList<QVariant> lastGameStartArgs = QList<QVariant>();
    47 QList<QVariant> lastGameStartArgs = QList<QVariant>();
    46 GameType lastGameType = gtNone;
    48 GameType lastGameType = gtNone;
    47 QString lastTrainingSubFolder = NULL;
       
    48 GameCFGWidget * lastGameCfg = NULL;
    49 GameCFGWidget * lastGameCfg = NULL;
    49 QString lastGameAmmo = NULL;
    50 QString lastGameAmmo = NULL;
    50 TeamSelWidget * lastGameTeamSel = NULL;
    51 TeamSelWidget * lastGameTeamSel = NULL;
    51 
    52 
    52 QString training, campaign, campaignScript, campaignTeam; // TODO: Cleaner solution?
    53 QString trainingName, trainingScript, trainingTeam, campaign, campaignScript, campaignTeam; // TODO: Cleaner solution?
    53 
    54 
    54 HWGame::HWGame(GameUIConfig * config, GameCFGWidget * gamecfg, QString ammo, TeamSelWidget* pTeamSelWidget) :
    55 HWGame::HWGame(GameUIConfig * config, GameCFGWidget * gamecfg, QString ammo, TeamSelWidget* pTeamSelWidget) :
    55     TCPBase(true, 0),
    56     TCPBase(true, !config->language().isEmpty(), 0),
    56     ammostr(ammo),
    57     ammostr(ammo),
    57     m_pTeamSelWidget(pTeamSelWidget)
    58     m_pTeamSelWidget(pTeamSelWidget)
    58 {
    59 {
    59     this->config = config;
    60     this->config = config;
    60     this->gamecfg = gamecfg;
    61     this->gamecfg = gamecfg;
    73     SetGameState(gsDestroyed);
    74     SetGameState(gsDestroyed);
    74 }
    75 }
    75 
    76 
    76 void HWGame::onClientDisconnect()
    77 void HWGame::onClientDisconnect()
    77 {
    78 {
    78     switch (gameType)
    79     if (demoIsPresent)
    79     {
    80     {
    80         case gtDemo:
    81         switch (gameType)
    81             // for video recording we need demo anyway
    82         {
    82             emit HaveRecord(rtNeither, demo);
    83             case gtDemo:
    83             break;
    84                 // for video recording we need demo anyway
    84         case gtNet:
    85                 emit HaveRecord(rtNeither, demo);
    85             emit HaveRecord(rtDemo, demo);
    86                 break;
    86             break;
    87             case gtNet:
    87         default:
       
    88             if (gameState == gsInterrupted || gameState == gsHalted)
       
    89                 emit HaveRecord(rtSave, demo);
       
    90             else if (gameState == gsFinished)
       
    91                 emit HaveRecord(rtDemo, demo);
    88                 emit HaveRecord(rtDemo, demo);
    92             else
    89                 break;
    93                 emit HaveRecord(rtNeither, demo);
    90             default:
       
    91                 if (gameState == gsInterrupted || gameState == gsHalted)
       
    92                     emit HaveRecord(rtSave, demo);
       
    93                 else if (gameState == gsFinished)
       
    94                     emit HaveRecord(rtDemo, demo);
       
    95                 else
       
    96                     emit HaveRecord(rtNeither, demo);
       
    97         }
       
    98     }
       
    99     else
       
   100     {
       
   101         emit HaveRecord(rtNeither, demo);
    94     }
   102     }
    95     SetGameState(gsStopped);
   103     SetGameState(gsStopped);
    96 }
   104 }
    97 
   105 
    98 void HWGame::commonConfig()
   106 void HWGame::commonConfig()
   137     commonConfig();
   145     commonConfig();
   138 }
   146 }
   139 
   147 
   140 void HWGame::SendQuickConfig()
   148 void HWGame::SendQuickConfig()
   141 {
   149 {
       
   150     /* Load and increase Quick Game experience level.
       
   151     Experience increases by 1 for each started game and maxes out
       
   152     at 20. Low experience levels will introduce a "beginner's bias" to make
       
   153     the first quick games easier and simpler. The max. possible difficulty
       
   154     increases progressively the longer you play.
       
   155     If experience is maxed out, the beginner's bias is gone and quick games
       
   156     are completely random. */
       
   157     int exp = config->quickGameExperience();
       
   158     if(exp < 20)
       
   159     {
       
   160        config->setQuickGameExperience(exp + 1);
       
   161     }
       
   162     qDebug("Starting quick game ...");
       
   163     qDebug("Quick Game experience level: %d", exp);
       
   164 
       
   165     // Init stuff
   142     QByteArray teamscfg;
   166     QByteArray teamscfg;
   143     QAbstractItemModel * themeModel = DataManager::instance().themeModel()->withoutHidden();
   167     QAbstractItemModel * themeModel = DataManager::instance().themeModel()->withoutHidden();
   144 
   168 
   145     HWProto::addStringToBuffer(teamscfg, "TL");
   169     HWProto::addStringToBuffer(teamscfg, "TL");
       
   170 
       
   171     // Random seed
       
   172     HWProto::addStringToBuffer(teamscfg, "eseed " + QUuid::createUuid().toString());
       
   173 
       
   174     int r, minhogs, maxhogs;
       
   175 
       
   176     // Random map type
       
   177     r = rand() % 10000;
       
   178     if(r < 3000) { // 30%
       
   179         // Random
       
   180         r = 0;
       
   181     } else if(r < 5250) { // 22.5%
       
   182         // Maze
       
   183         if(exp <= 3)
       
   184             r = 0;
       
   185         else
       
   186             r = 1;
       
   187     } else if(r < 7490) { // 22.4%
       
   188         // Perlin
       
   189         if(exp <= 7)
       
   190             r = 1;
       
   191         else
       
   192             r = 2;
       
   193     } else if(r < 7500 && exp >= 5) { // 0.1%
       
   194         // Floating Flowers (just for fun)
       
   195         r = 5;
       
   196     } else if(r < 8750) { // 12.5%
       
   197         // Image map
       
   198         r = 3;
       
   199     } else { // 12.5%
       
   200         // Forts
       
   201         r = 4;
       
   202     }
       
   203     switch(r)
       
   204     {
       
   205         // Random map
       
   206         default:
       
   207         case 0: {
       
   208             r = rand() % 3;
       
   209             if(r == 0)
       
   210             {
       
   211                 // small island
       
   212                 HWProto::addStringToBuffer(teamscfg, "e$template_filter 1");
       
   213                 minhogs = 3;
       
   214                 maxhogs = 4;
       
   215             }
       
   216             else if(r == 1 || exp <= 6)
       
   217             {
       
   218                 // medium island
       
   219                 HWProto::addStringToBuffer(teamscfg, "e$template_filter 2");
       
   220                 minhogs = 4;
       
   221                 maxhogs = 5;
       
   222             }
       
   223             else
       
   224             {
       
   225                 // cave (locked at low experience because these maps can be huge)
       
   226                 HWProto::addStringToBuffer(teamscfg, "e$template_filter 4");
       
   227                 minhogs = 4;
       
   228                 maxhogs = 6;
       
   229             }
       
   230             HWProto::addStringToBuffer(teamscfg, "e$feature_size "+QString::number(rand()%18+4));
       
   231             break;
       
   232         }
       
   233         // Maze
       
   234         case 1: {
       
   235             minhogs = 4;
       
   236             maxhogs = 6;
       
   237             HWProto::addStringToBuffer(teamscfg, "e$mapgen 1");
       
   238             HWProto::addStringToBuffer(teamscfg, "e$template_filter "+QString::number(rand()%6));
       
   239             HWProto::addStringToBuffer(teamscfg, "e$feature_size "+QString::number(rand()%16+6));
       
   240             break;
       
   241         }
       
   242         // Perlin
       
   243         case 2: {
       
   244             minhogs = 4;
       
   245             maxhogs = 6;
       
   246             HWProto::addStringToBuffer(teamscfg, "e$mapgen 2");
       
   247             HWProto::addStringToBuffer(teamscfg, "e$template_filter "+QString::number(rand()%6));
       
   248             HWProto::addStringToBuffer(teamscfg, "e$feature_size "+QString::number(rand()%18+4));
       
   249             break;
       
   250         }
       
   251         // Image map
       
   252         case 3: {
       
   253             minhogs = 4;
       
   254             maxhogs = 6;
       
   255             HWProto::addStringToBuffer(teamscfg, "e$mapgen 3");
       
   256             // Select map from hardcoded list.
       
   257             // TODO: find a more dynamic solution.
       
   258             r = rand() % cQuickGameMaps.count();
       
   259             HWProto::addStringToBuffer(teamscfg, "e$map " + cQuickGameMaps[r]);
       
   260             break;
       
   261         }
       
   262         // Forts
       
   263         case 4: {
       
   264             minhogs = 4;
       
   265             maxhogs = 6;
       
   266             HWProto::addStringToBuffer(teamscfg, "e$mapgen 4");
       
   267             HWProto::addStringToBuffer(teamscfg, "e$feature_size "+QString::number(rand()%20+1));
       
   268             break;
       
   269         }
       
   270         // Floating Flowers
       
   271         // (actually empty map; this forces the engine to generate fallback structures to have
       
   272         // something for hogs to stand on)
       
   273         case 5: {
       
   274             minhogs = 4;
       
   275             maxhogs = 8;
       
   276             HWProto::addStringToBuffer(teamscfg, "e$mapgen 3");
       
   277             HWProto::addStringToBuffer(teamscfg, "e$feature_size "+QString::number(rand()%4+3));
       
   278             break;
       
   279         }
       
   280     }
       
   281 
       
   282     // Theme
   146     HWProto::addStringToBuffer(teamscfg, QString("etheme %1")
   283     HWProto::addStringToBuffer(teamscfg, QString("etheme %1")
   147                                .arg((themeModel->rowCount() > 0) ? themeModel->index(rand() % themeModel->rowCount(), 0).data(ThemeModel::ActualNameRole).toString() : "Nature"));
   284         .arg((themeModel->rowCount() > 0) ? themeModel->index(rand() % themeModel->rowCount(), 0).data(ThemeModel::ActualNameRole).toString() : "Nature"));
   148     HWProto::addStringToBuffer(teamscfg, "eseed " + QUuid::createUuid().toString());
   285 
   149 
   286     int hogs = minhogs + rand() % (maxhogs-minhogs+1);
   150     HWProto::addStringToBuffer(teamscfg, "e$template_filter 2");
   287     // Cap hog count at low experience
   151     HWProto::addStringToBuffer(teamscfg, "e$feature_size "+QString::number(rand()%18+4));
   288     if((exp <= 8) && (hogs > 5))
   152 
   289         hogs = 5;
       
   290     else if((exp <= 5) && (hogs > 4))
       
   291         hogs = 4;
       
   292 
       
   293     // Teams
       
   294     // Player team
   153     HWTeam team1;
   295     HWTeam team1;
   154     team1.setDifficulty(0);
   296     team1.setDifficulty(0);
   155     team1.setColor(0);
   297     team1.setColor(0);
   156     team1.setNumHedgehogs(4);
   298     team1.setNumHedgehogs(hogs);
   157     HWNamegen::teamRandomEverything(team1);
   299     HWNamegen::teamRandomEverything(team1);
   158     team1.setVoicepack("Default");
   300     team1.setVoicepack("Default_qau");
   159     HWProto::addStringListToBuffer(teamscfg,
   301 
   160                                    team1.teamGameConfig(100));
   302     // Computer team
   161 
       
   162     HWTeam team2;
   303     HWTeam team2;
   163     team2.setDifficulty(4);
   304     // Random difficulty.
       
   305     // Max. possible difficulty is capped at low experience levels.
       
   306     if(exp >= 15) // very easy to very hard (full range)
       
   307         r = 5 - rand() % 5;
       
   308     else if(exp >= 9) // very easy to hard
       
   309         r = 5 - rand() % 4;
       
   310     else if(exp >= 6) // very easy to medium
       
   311         r = 5 - rand() % 3;
       
   312     else if(exp >= 2) // very easy to easy
       
   313         r = 5 - rand() % 2;
       
   314     else // very easy
       
   315         r = 5;
       
   316     team2.setDifficulty(r);
   164     team2.setColor(1);
   317     team2.setColor(1);
   165     team2.setNumHedgehogs(4);
   318     team2.setNumHedgehogs(hogs);
       
   319     // Make sure the team names are not equal
   166     do
   320     do
   167         HWNamegen::teamRandomEverything(team2);
   321         HWNamegen::teamRandomEverything(team2);
   168     while(!team2.name().compare(team1.name()) || !team2.hedgehog(0).Hat.compare(team1.hedgehog(0).Hat));
   322     while(!team2.name().compare(team1.name()) || !team2.hedgehog(0).Hat.compare(team1.hedgehog(0).Hat));
   169     team2.setVoicepack("Default");
   323     team2.setVoicepack("Default_qau");
   170     HWProto::addStringListToBuffer(teamscfg,
   324 
   171                                    team2.teamGameConfig(100));
   325     // Team play order
   172 
   326     r = rand() % 2;
       
   327     if(r == 0 || exp <= 4) // player plays first
       
   328     {
       
   329         HWProto::addStringListToBuffer(teamscfg, team1.teamGameConfig(100));
       
   330         HWProto::addStringListToBuffer(teamscfg, team2.teamGameConfig(100));
       
   331     }
       
   332     else // computer plays first
       
   333     {
       
   334         HWProto::addStringListToBuffer(teamscfg, team2.teamGameConfig(100));
       
   335         HWProto::addStringListToBuffer(teamscfg, team1.teamGameConfig(100));
       
   336     }
       
   337 
       
   338     // Ammo scheme "Default"
       
   339     // TODO: Random schemes
   173     HWProto::addStringToBuffer(teamscfg, QString("eammloadt %1").arg(cDefaultAmmoStore->mid(0, cAmmoNumber)));
   340     HWProto::addStringToBuffer(teamscfg, QString("eammloadt %1").arg(cDefaultAmmoStore->mid(0, cAmmoNumber)));
   174     HWProto::addStringToBuffer(teamscfg, QString("eammprob %1").arg(cDefaultAmmoStore->mid(cAmmoNumber, cAmmoNumber)));
   341     HWProto::addStringToBuffer(teamscfg, QString("eammprob %1").arg(cDefaultAmmoStore->mid(cAmmoNumber, cAmmoNumber)));
   175     HWProto::addStringToBuffer(teamscfg, QString("eammdelay %1").arg(cDefaultAmmoStore->mid(2 * cAmmoNumber, cAmmoNumber)));
   342     HWProto::addStringToBuffer(teamscfg, QString("eammdelay %1").arg(cDefaultAmmoStore->mid(2 * cAmmoNumber, cAmmoNumber)));
   176     HWProto::addStringToBuffer(teamscfg, QString("eammreinf %1").arg(cDefaultAmmoStore->mid(3 * cAmmoNumber, cAmmoNumber)));
   343     HWProto::addStringToBuffer(teamscfg, QString("eammreinf %1").arg(cDefaultAmmoStore->mid(3 * cAmmoNumber, cAmmoNumber)));
   177     HWProto::addStringToBuffer(teamscfg, QString("eammstore"));
   344     HWProto::addStringToBuffer(teamscfg, QString("eammstore"));
   182 
   349 
   183 void HWGame::SendTrainingConfig()
   350 void HWGame::SendTrainingConfig()
   184 {
   351 {
   185     QByteArray traincfg;
   352     QByteArray traincfg;
   186     HWProto::addStringToBuffer(traincfg, "TL");
   353     HWProto::addStringToBuffer(traincfg, "TL");
       
   354 
       
   355     HWTeam missionTeam = HWTeam();
       
   356     missionTeam.setName(config->Form->ui.pageTraining->CBTeam->currentText());
       
   357     missionTeam.loadFromFile();
       
   358     missionTeam.setNumHedgehogs(HEDGEHOGS_PER_TEAM);
       
   359     missionTeam.setMissionTeam(true);
       
   360     HWProto::addStringListToBuffer(traincfg, missionTeam.teamGameConfig(100));
       
   361 
   187     HWProto::addStringToBuffer(traincfg, "eseed " + QUuid::createUuid().toString());
   362     HWProto::addStringToBuffer(traincfg, "eseed " + QUuid::createUuid().toString());
   188     HWProto::addStringToBuffer(traincfg, "escript " + training);
   363     HWProto::addStringToBuffer(traincfg, "escript " + trainingScript);
   189 
   364 
   190     RawSendIPC(traincfg);
   365     RawSendIPC(traincfg);
   191 }
   366 }
   192 
   367 
   193 void HWGame::SendCampaignConfig()
   368 void HWGame::SendCampaignConfig()
   194 {
   369 {
   195     QByteArray campaigncfg;
   370     QByteArray campaigncfg;
   196     HWProto::addStringToBuffer(campaigncfg, "TL");
   371     HWProto::addStringToBuffer(campaigncfg, "TL");
       
   372 
       
   373     HWTeam missionTeam = HWTeam();
       
   374     missionTeam.setName(config->Form->ui.pageCampaign->CBTeam->currentText());
       
   375     missionTeam.loadFromFile();
       
   376     missionTeam.setNumHedgehogs(HEDGEHOGS_PER_TEAM);
       
   377     missionTeam.setMissionTeam(true);
       
   378     HWProto::addStringListToBuffer(campaigncfg, missionTeam.teamGameConfig(100));
       
   379 
   197     HWProto::addStringToBuffer(campaigncfg, "eseed " + QUuid::createUuid().toString());
   380     HWProto::addStringToBuffer(campaigncfg, "eseed " + QUuid::createUuid().toString());
   198 
       
   199     HWProto::addStringToBuffer(campaigncfg, "escript " + campaignScript);
   381     HWProto::addStringToBuffer(campaigncfg, "escript " + campaignScript);
   200 
   382 
   201     RawSendIPC(campaigncfg);
   383     RawSendIPC(campaigncfg);
   202 }
   384 }
   203 
   385 
   275         case 'q':
   457         case 'q':
   276         {
   458         {
   277             SetGameState(gsFinished);
   459             SetGameState(gsFinished);
   278             break;
   460             break;
   279         }
   461         }
       
   462         case 'm':
       
   463         {
       
   464             SetDemoPresence(false);
       
   465             break;
       
   466         }
   280         case 'H':
   467         case 'H':
   281         {
   468         {
   282             SetGameState(gsHalted);
   469             SetGameState(gsHalted);
   283             break;
   470             break;
   284         }
   471         }
   305                 sendCampaignVar(msg.right(msg.size() - 3));
   492                 sendCampaignVar(msg.right(msg.size() - 3));
   306             else if (msg.at(2) == '!')
   493             else if (msg.at(2) == '!')
   307                 writeCampaignVar(msg.right(msg.size() - 3));
   494                 writeCampaignVar(msg.right(msg.size() - 3));
   308             break;
   495             break;
   309         }
   496         }
       
   497         case 'v':
       
   498         {
       
   499             if (msg.at(2) == '?')
       
   500                 sendMissionVar(msg.right(msg.size() - 3));
       
   501             else if (msg.at(2) == '!')
       
   502                 writeMissionVar(msg.right(msg.size() - 3));
       
   503             break;
       
   504         }
   310         case 'W':
   505         case 'W':
   311         {
   506         {
   312             // fetch new window resolution via IPC and save it in the settings
   507             // fetch new window resolution via IPC and save it in the settings
   313             int size = msg.size();
   508             int size = msg.size();
   314             QString newResolution = QString().append(msg.mid(2)).left(size - 4);
   509             QString newResolution = QString().append(msg.mid(2)).left(size - 4);
   341 
   536 
   342 void HWGame::FromNetChat(const QString & msg)
   537 void HWGame::FromNetChat(const QString & msg)
   343 {
   538 {
   344     QByteArray buf;
   539     QByteArray buf;
   345     HWProto::addStringToBuffer(buf, 's' + msg + "\x20\x20");
   540     HWProto::addStringToBuffer(buf, 's' + msg + "\x20\x20");
       
   541     RawSendIPC(buf);
       
   542 }
       
   543 
       
   544 void HWGame::FromNetWarning(const QString & msg)
       
   545 {
       
   546     QByteArray buf;
       
   547     HWProto::addStringToBuffer(buf, "s\x00" + msg + "\x20\x20");
       
   548     RawSendIPC(buf);
       
   549 }
       
   550 
       
   551 void HWGame::FromNetError(const QString & msg)
       
   552 {
       
   553     QByteArray buf;
       
   554     HWProto::addStringToBuffer(buf, "s\x05" + msg + "\x20\x20");
   346     RawSendIPC(buf);
   555     RawSendIPC(buf);
   347 }
   556 }
   348 
   557 
   349 void HWGame::onClientRead()
   558 void HWGame::onClientRead()
   350 {
   559 {
   398     arguments << QString::number(resolutions.first.height());
   607     arguments << QString::number(resolutions.first.height());
   399     arguments << "--width";
   608     arguments << "--width";
   400     arguments << QString::number(resolutions.second.width());
   609     arguments << QString::number(resolutions.second.width());
   401     arguments << "--height";
   610     arguments << "--height";
   402     arguments << QString::number(resolutions.second.height());
   611     arguments << QString::number(resolutions.second.height());
       
   612     if (config->zoom() != 100) {
       
   613         arguments << "--zoom";
       
   614         arguments << QString::number(config->zoom());
       
   615     }
   403     arguments << "--raw-quality";
   616     arguments << "--raw-quality";
   404     arguments << QString::number(config->translateQuality());
   617     arguments << QString::number(config->translateQuality());
   405     arguments << "--stereo";
   618     arguments << "--stereo";
   406     arguments << QString::number(config->stereoMode());
   619     arguments << QString::number(config->stereoMode());
   407     if (config->vid_Fullscreen())
   620     if (config->vid_Fullscreen())
   412         arguments << "--altdmg";
   625         arguments << "--altdmg";
   413     if (!config->isSoundEnabled())
   626     if (!config->isSoundEnabled())
   414         arguments << "--nosound";
   627         arguments << "--nosound";
   415     if (!config->isMusicEnabled())
   628     if (!config->isMusicEnabled())
   416         arguments << "--nomusic";
   629         arguments << "--nomusic";
       
   630     if (!config->isAudioDampenEnabled())
       
   631         arguments << "--nodampen";
   417     if (!nick.isEmpty()) {
   632     if (!nick.isEmpty()) {
   418         arguments << "--nick";
   633         arguments << "--nick";
   419         arguments << nick;
   634         arguments << nick;
   420     }
   635     }
   421 
   636 
   425         arguments << "--no-hogtag";
   640         arguments << "--no-hogtag";
   426     if (!config->Form->ui.pageOptions->CBHealthTag->isChecked())
   641     if (!config->Form->ui.pageOptions->CBHealthTag->isChecked())
   427         arguments << "--no-healthtag";
   642         arguments << "--no-healthtag";
   428     if (config->Form->ui.pageOptions->CBTagOpacity->isChecked())
   643     if (config->Form->ui.pageOptions->CBTagOpacity->isChecked())
   429         arguments << "--translucent-tags";
   644         arguments << "--translucent-tags";
       
   645     if (!config->isHolidaySillinessEnabled())
       
   646         arguments << "--no-holiday-silliness";
   430     arguments << "--chat-size";
   647     arguments << "--chat-size";
   431     arguments << QString::number(config->chatSize());
   648     arguments << QString::number(config->chatSize());
   432 
   649 
   433     return arguments;
   650     return arguments;
   434 }
   651 }
   451     demo.clear();
   668     demo.clear();
   452     Start(false);
   669     Start(false);
   453     SetGameState(gsStarted);
   670     SetGameState(gsStarted);
   454 }
   671 }
   455 
   672 
       
   673 void HWGame::PlayOfficialServerDemo()
       
   674 {
       
   675     // TODO: Use gtDemo so fast-forward is available.
       
   676     // Needs engine support first.
       
   677     lastGameStartArgs.clear();
       
   678     lastGameType = gtLocal;
       
   679 
       
   680     gameType = gtLocal;
       
   681     demo.clear();
       
   682     Start(false);
       
   683     SetGameState(gsStarted);
       
   684 }
       
   685 
   456 void HWGame::StartNet()
   686 void HWGame::StartNet()
   457 {
   687 {
   458     lastGameStartArgs.clear();
   688     lastGameStartArgs.clear();
   459     lastGameType = gtNet;
   689     lastGameType = gtNet;
   460 
   690 
   484     demo.clear();
   714     demo.clear();
   485     Start(false);
   715     Start(false);
   486     SetGameState(gsStarted);
   716     SetGameState(gsStarted);
   487 }
   717 }
   488 
   718 
   489 void HWGame::StartTraining(const QString & file, const QString & subFolder)
   719 void HWGame::StartTraining(const QString & file, const QString & subFolder, const QString & trainTeam)
   490 {
   720 {
   491     lastGameStartArgs.clear();
   721     lastGameStartArgs.clear();
   492     lastGameStartArgs.append(file);
   722     lastGameStartArgs.append(file);
       
   723     lastGameStartArgs.append(subFolder);
       
   724     lastGameStartArgs.append(trainTeam);
   493     lastGameType = gtTraining;
   725     lastGameType = gtTraining;
   494     lastTrainingSubFolder = subFolder;
       
   495 
   726 
   496     gameType = gtTraining;
   727     gameType = gtTraining;
   497 
   728 
   498     training = "Missions/" + subFolder + "/" + file + ".lua";
   729     trainingScript  = "Missions/" + subFolder + "/" + file + ".lua";
       
   730     trainingName = file;
       
   731     trainingTeam = trainTeam;
   499     demo.clear();
   732     demo.clear();
   500     Start(false);
   733     Start(false);
   501     SetGameState(gsStarted);
   734     SetGameState(gsStarted);
   502 }
   735 }
   503 
   736 
   522 {
   755 {
   523     gameState = state;
   756     gameState = state;
   524     emit GameStateChanged(state);
   757     emit GameStateChanged(state);
   525     if (gameType == gtCampaign)
   758     if (gameType == gtCampaign)
   526     {
   759     {
   527       emit CampStateChanged(1);
   760         emit CampStateChanged(state);
   528     }
   761     }
       
   762     else if (gameType == gtTraining)
       
   763     {
       
   764         emit TrainingStateChanged(1);
       
   765     }
       
   766 }
       
   767 
       
   768 void HWGame::SetDemoPresence(bool hasDemo)
       
   769 {
       
   770     emit DemoPresenceChanged(hasDemo);
   529 }
   771 }
   530 
   772 
   531 void HWGame::abort()
   773 void HWGame::abort()
   532 {
   774 {
   533     QByteArray buf;
   775     QByteArray buf;
   534     HWProto::addStringToBuffer(buf, QString("efinish"));
   776     HWProto::addStringToBuffer(buf, QString("eforcequit"));
   535     RawSendIPC(buf);
   777     RawSendIPC(buf);
   536 }
   778 }
   537 
   779 
   538 void HWGame::sendCampaignVar(const QByteArray &varToSend)
   780 void HWGame::sendCampaignVar(const QByteArray &varToSend)
   539 {
   781 {
   558     QSettings teamfile(QString(cfgdir->absolutePath() + "/Teams/%1.hwt").arg(campaignTeam), QSettings::IniFormat, 0);
   800     QSettings teamfile(QString(cfgdir->absolutePath() + "/Teams/%1.hwt").arg(campaignTeam), QSettings::IniFormat, 0);
   559     teamfile.setIniCodec("UTF-8");
   801     teamfile.setIniCodec("UTF-8");
   560     teamfile.setValue("Campaign " + campaign + "/" + varToWrite, varValue);
   802     teamfile.setValue("Campaign " + campaign + "/" + varToWrite, varValue);
   561 }
   803 }
   562 
   804 
       
   805 void HWGame::sendMissionVar(const QByteArray &varToSend)
       
   806 {
       
   807     QString varToFind = QString::fromUtf8(varToSend);
       
   808     QSettings teamfile(QString(cfgdir->absolutePath() + "/Teams/%1.hwt").arg(trainingTeam), QSettings::IniFormat, 0);
       
   809     teamfile.setIniCodec("UTF-8");
       
   810     QString varValue = teamfile.value("Mission " + trainingName + "/" + varToFind, "").toString();
       
   811     QByteArray command;
       
   812     HWProto::addStringToBuffer(command, "v." + varValue);
       
   813     RawSendIPC(command);
       
   814 }
       
   815 
       
   816 void HWGame::writeMissionVar(const QByteArray & varVal)
       
   817 {
       
   818     int i = varVal.indexOf(" ");
       
   819     if(i < 0)
       
   820         return;
       
   821 
       
   822     QString varToWrite = QString::fromUtf8(varVal.left(i));
       
   823     QString varValue = QString::fromUtf8(varVal.mid(i + 1));
       
   824 
       
   825     QSettings teamfile(QString(cfgdir->absolutePath() + "/Teams/%1.hwt").arg(trainingTeam), QSettings::IniFormat, 0);
       
   826     teamfile.setIniCodec("UTF-8");
       
   827     teamfile.setValue("Mission " + trainingName + "/" + varToWrite, varValue);
       
   828 }
       
   829