QTfrontend/game.cpp
changeset 2948 3f21a9dc93d0
parent 2786 85f6425a4d74
child 3011 73c8f618fd8b
equal deleted inserted replaced
2947:803b277e4894 2948:3f21a9dc93d0
    35 HWGame::HWGame(GameUIConfig * config, GameCFGWidget * gamecfg, QString ammo, TeamSelWidget* pTeamSelWidget) :
    35 HWGame::HWGame(GameUIConfig * config, GameCFGWidget * gamecfg, QString ammo, TeamSelWidget* pTeamSelWidget) :
    36   TCPBase(true),
    36   TCPBase(true),
    37   ammostr(ammo),
    37   ammostr(ammo),
    38   m_pTeamSelWidget(pTeamSelWidget)
    38   m_pTeamSelWidget(pTeamSelWidget)
    39 {
    39 {
    40 	this->config = config;
    40     this->config = config;
    41 	this->gamecfg = gamecfg;
    41     this->gamecfg = gamecfg;
    42 	TeamCount = 0;
    42     TeamCount = 0;
    43 }
    43 }
    44 
    44 
    45 HWGame::~HWGame()
    45 HWGame::~HWGame()
    46 {
    46 {
    47 	SetGameState(gsDestroyed);
    47     SetGameState(gsDestroyed);
    48 }
    48 }
    49 
    49 
    50 void HWGame::onClientDisconnect()
    50 void HWGame::onClientDisconnect()
    51 {
    51 {
    52 	switch (gameType) {
    52     switch (gameType) {
    53 		case gtDemo: break;
    53         case gtDemo: break;
    54 		case gtNet:
    54         case gtNet:
    55 			emit HaveRecord(true, demo);
    55             emit HaveRecord(true, demo);
    56 			break;
    56             break;
    57 		default:
    57         default:
    58 			if (gameState == gsInterrupted) emit HaveRecord(false, demo);
    58             if (gameState == gsInterrupted) emit HaveRecord(false, demo);
    59 			else if (gameState == gsFinished) emit HaveRecord(true, demo);
    59             else if (gameState == gsFinished) emit HaveRecord(true, demo);
    60 	}
    60     }
    61 	SetGameState(gsStopped);
    61     SetGameState(gsStopped);
    62 }
    62 }
    63 
    63 
    64 void HWGame::commonConfig()
    64 void HWGame::commonConfig()
    65 {
    65 {
    66 	QByteArray buf;
    66     QByteArray buf;
    67 	QString gt;
    67     QString gt;
    68 	switch (gameType) {
    68     switch (gameType) {
    69 		case gtDemo:
    69         case gtDemo:
    70 			gt = "TD";
    70             gt = "TD";
    71 			break;
    71             break;
    72 		case gtNet:
    72         case gtNet:
    73 			gt = "TN";
    73             gt = "TN";
    74 			break;
    74             break;
    75 		default:
    75         default:
    76 			gt = "TL";
    76             gt = "TL";
    77 	}
    77     }
    78 	HWProto::addStringToBuffer(buf, gt);
    78     HWProto::addStringToBuffer(buf, gt);
    79 
    79 
    80 	HWProto::addStringListToBuffer(buf, gamecfg->getFullConfig());
    80     HWProto::addStringListToBuffer(buf, gamecfg->getFullConfig());
    81 
    81 
    82 	if (m_pTeamSelWidget)
    82     if (m_pTeamSelWidget)
    83 	{
    83     {
    84 		QList<HWTeam> teams = m_pTeamSelWidget->getPlayingTeams();
    84         QList<HWTeam> teams = m_pTeamSelWidget->getPlayingTeams();
    85 		for(QList<HWTeam>::iterator it = teams.begin(); it != teams.end(); ++it)
    85         for(QList<HWTeam>::iterator it = teams.begin(); it != teams.end(); ++it)
    86 		{
    86         {
    87 			HWProto::addStringListToBuffer(buf,
    87             HWProto::addStringListToBuffer(buf,
    88 				(*it).TeamGameConfig(gamecfg->getInitHealth()));
    88                 (*it).TeamGameConfig(gamecfg->getInitHealth()));
    89 			HWProto::addStringToBuffer(buf, QString("eammstore %1").arg(ammostr));
    89             HWProto::addStringToBuffer(buf, QString("eammstore %1").arg(ammostr));
    90 		}
    90         }
    91 	}
    91     }
    92 	RawSendIPC(buf);
    92     RawSendIPC(buf);
    93 }
    93 }
    94 
    94 
    95 void HWGame::SendConfig()
    95 void HWGame::SendConfig()
    96 {
    96 {
    97 	commonConfig();
    97     commonConfig();
    98 }
    98 }
    99 
    99 
   100 void HWGame::SendQuickConfig()
   100 void HWGame::SendQuickConfig()
   101 {
   101 {
   102 	QByteArray teamscfg;
   102     QByteArray teamscfg;
   103 
   103 
   104 	HWProto::addStringToBuffer(teamscfg, "TL");
   104     HWProto::addStringToBuffer(teamscfg, "TL");
   105 	HWProto::addStringToBuffer(teamscfg, QString("etheme %1")
   105     HWProto::addStringToBuffer(teamscfg, QString("etheme %1")
   106 			.arg((Themes->size() > 0) ? Themes->at(rand() % Themes->size()) : "steel"));
   106             .arg((Themes->size() > 0) ? Themes->at(rand() % Themes->size()) : "steel"));
   107 	HWProto::addStringToBuffer(teamscfg, "eseed " + QUuid::createUuid().toString());
   107     HWProto::addStringToBuffer(teamscfg, "eseed " + QUuid::createUuid().toString());
   108 
   108 
   109 	HWNamegen namegen;
   109     HWNamegen namegen;
   110 
   110 
   111 	HWTeam * team1;
   111     HWTeam * team1;
   112 	team1 = new HWTeam;
   112     team1 = new HWTeam;
   113 	team1->difficulty = 0;
   113     team1->difficulty = 0;
   114 	team1->teamColor = *color1;
   114     team1->teamColor = *color1;
   115 	team1->numHedgehogs = 4;
   115     team1->numHedgehogs = 4;
   116 	namegen.TeamRandomNames(team1,TRUE);
   116     namegen.TeamRandomNames(team1,TRUE);
   117 	HWProto::addStringListToBuffer(teamscfg,
   117     HWProto::addStringListToBuffer(teamscfg,
   118 			team1->TeamGameConfig(100));
   118             team1->TeamGameConfig(100));
   119 
   119 
   120 	HWTeam * team2;
   120     HWTeam * team2;
   121 	team2 = new HWTeam;
   121     team2 = new HWTeam;
   122 	team2->difficulty = 4;
   122     team2->difficulty = 4;
   123 	team2->teamColor = *color2;
   123     team2->teamColor = *color2;
   124 	team2->numHedgehogs = 4;
   124     team2->numHedgehogs = 4;
   125 	namegen.TeamRandomNames(team2,TRUE);
   125     namegen.TeamRandomNames(team2,TRUE);
   126 	HWProto::addStringListToBuffer(teamscfg,
   126     HWProto::addStringListToBuffer(teamscfg,
   127 			team2->TeamGameConfig(100));
   127             team2->TeamGameConfig(100));
   128 
   128 
   129 	HWProto::addStringToBuffer(teamscfg, "eammstore " + *cDefaultAmmoStore);
   129     HWProto::addStringToBuffer(teamscfg, "eammstore " + *cDefaultAmmoStore);
   130 	HWProto::addStringToBuffer(teamscfg, "eammstore " + *cDefaultAmmoStore);
   130     HWProto::addStringToBuffer(teamscfg, "eammstore " + *cDefaultAmmoStore);
   131 	RawSendIPC(teamscfg);
   131     RawSendIPC(teamscfg);
   132 }
   132 }
   133 
   133 
   134 void HWGame::SendTrainingConfig()
   134 void HWGame::SendTrainingConfig()
   135 {
   135 {
   136 	QByteArray traincfg;
   136     QByteArray traincfg;
   137 	HWProto::addStringToBuffer(traincfg, "TL");
   137     HWProto::addStringToBuffer(traincfg, "TL");
   138 
   138 
   139 	HWProto::addStringToBuffer(traincfg, "escript " + datadir->absolutePath() + "/Missions/" + training + ".hwt");
   139     HWProto::addStringToBuffer(traincfg, "escript " + datadir->absolutePath() + "/Missions/" + training + ".hwt");
   140 
   140 
   141 	RawSendIPC(traincfg);
   141     RawSendIPC(traincfg);
   142 }
   142 }
   143 
   143 
   144 void HWGame::SendNetConfig()
   144 void HWGame::SendNetConfig()
   145 {
   145 {
   146 	commonConfig();
   146     commonConfig();
   147 }
   147 }
   148 
   148 
   149 void HWGame::ParseMessage(const QByteArray & msg)
   149 void HWGame::ParseMessage(const QByteArray & msg)
   150 {
   150 {
   151 	switch(msg.at(1)) {
   151     switch(msg.at(1)) {
   152 		case '?': {
   152         case '?': {
   153 			SendIPC("!");
   153             SendIPC("!");
   154 			break;
   154             break;
   155 		}
   155         }
   156 		case 'C': {
   156         case 'C': {
   157 			switch (gameType) {
   157             switch (gameType) {
   158 				case gtLocal: {
   158                 case gtLocal: {
   159 					SendConfig();
   159                     SendConfig();
   160 					break;
   160                     break;
   161 				}
   161                 }
   162 				case gtQLocal: {
   162                 case gtQLocal: {
   163 					SendQuickConfig();
   163                     SendQuickConfig();
   164 					break;
   164                     break;
   165 				}
   165                 }
   166 				case gtDemo: break;
   166                 case gtDemo: break;
   167 				case gtNet: {
   167                 case gtNet: {
   168 					SendNetConfig();
   168                     SendNetConfig();
   169 					break;
   169                     break;
   170 				}
   170                 }
   171 				case gtTraining: {
   171                 case gtTraining: {
   172 					SendTrainingConfig();
   172                     SendTrainingConfig();
   173 					break;
   173                     break;
   174 				}
   174                 }
   175 			}
   175             }
   176 			break;
   176             break;
   177 		}
   177         }
   178 		case 'E': {
   178         case 'E': {
   179 			int size = msg.size();
   179             int size = msg.size();
   180 			emit ErrorMessage(QString("Last two engine messages:\n") + QString().append(msg.mid(2)).left(size - 4));
   180             emit ErrorMessage(QString("Last two engine messages:\n") + QString().append(msg.mid(2)).left(size - 4));
   181 			return;
   181             return;
   182 		}
   182         }
   183 		case 'K': {
   183         case 'K': {
   184 			ulong kb = msg.mid(2).toULong();
   184             ulong kb = msg.mid(2).toULong();
   185 			if (kb==1) {
   185             if (kb==1) {
   186 			  qWarning("%s", KBMessages[kb - 1].toLocal8Bit().constData());
   186               qWarning("%s", KBMessages[kb - 1].toLocal8Bit().constData());
   187 			  return;
   187               return;
   188 			}
   188             }
   189 			if (kb && kb <= KBmsgsCount)
   189             if (kb && kb <= KBmsgsCount)
   190 			{
   190             {
   191 				emit ErrorMessage(KBMessages[kb - 1]);
   191                 emit ErrorMessage(KBMessages[kb - 1]);
   192 			}
   192             }
   193 			return;
   193             return;
   194 		}
   194         }
   195 		case 'i': {
   195         case 'i': {
   196 			emit GameStats(msg.at(2), QString::fromUtf8(msg.mid(3)));
   196             emit GameStats(msg.at(2), QString::fromUtf8(msg.mid(3)));
   197 			break;
   197             break;
   198 		}
   198         }
   199 		case 'Q': {
   199         case 'Q': {
   200 			SetGameState(gsInterrupted);
   200             SetGameState(gsInterrupted);
   201 			break;
   201             break;
   202 		}
   202         }
   203 		case 'q': {
   203         case 'q': {
   204 			SetGameState(gsFinished);
   204             SetGameState(gsFinished);
   205 			break;
   205             break;
   206 		}
   206         }
   207 		case 's': {
   207         case 's': {
   208 			int size = msg.size();
   208             int size = msg.size();
   209 			QString msgbody = QString::fromUtf8(msg.mid(2).left(size - 4));
   209             QString msgbody = QString::fromUtf8(msg.mid(2).left(size - 4));
   210 			emit SendChat(msgbody);
   210             emit SendChat(msgbody);
   211 			// FIXME: /me command doesn't work here
   211             // FIXME: /me command doesn't work here
   212 			QByteArray buf;
   212             QByteArray buf;
   213 			HWProto::addStringToBuffer(buf, "s" + HWProto::formatChatMsg(config->netNick(), msgbody) + "\x20\x20");
   213             HWProto::addStringToBuffer(buf, "s" + HWProto::formatChatMsg(config->netNick(), msgbody) + "\x20\x20");
   214 			demo.append(buf);
   214             demo.append(buf);
   215 			break;
   215             break;
   216 		}
   216         }
   217 		case 'b': {
   217         case 'b': {
   218 			int size = msg.size();
   218             int size = msg.size();
   219 			QString msgbody = QString::fromUtf8(msg.mid(2).left(size - 4));
   219             QString msgbody = QString::fromUtf8(msg.mid(2).left(size - 4));
   220 			emit SendTeamMessage(msgbody);
   220             emit SendTeamMessage(msgbody);
   221 			break;
   221             break;
   222 		}
   222         }
   223 		default: {
   223         default: {
   224 			if (gameType == gtNet)
   224             if (gameType == gtNet)
   225 			{
   225             {
   226 				emit SendNet(msg);
   226                 emit SendNet(msg);
   227 			}
   227             }
   228 		if (msg.at(1) != 's')
   228         if (msg.at(1) != 's')
   229 			demo.append(msg);
   229             demo.append(msg);
   230 		}
   230         }
   231 	}
   231     }
   232 }
   232 }
   233 
   233 
   234 void HWGame::FromNet(const QByteArray & msg)
   234 void HWGame::FromNet(const QByteArray & msg)
   235 {
   235 {
   236 	RawSendIPC(msg);
   236     RawSendIPC(msg);
   237 }
   237 }
   238 
   238 
   239 void HWGame::FromNetChat(const QString & msg)
   239 void HWGame::FromNetChat(const QString & msg)
   240 {
   240 {
   241 	QByteArray buf;
   241     QByteArray buf;
   242 	HWProto::addStringToBuffer(buf, 's' + msg + "\x20\x20");
   242     HWProto::addStringToBuffer(buf, 's' + msg + "\x20\x20");
   243 	RawSendIPC(buf);
   243     RawSendIPC(buf);
   244 }
   244 }
   245 
   245 
   246 void HWGame::onClientRead()
   246 void HWGame::onClientRead()
   247 {
   247 {
   248 	quint8 msglen;
   248     quint8 msglen;
   249 	quint32 bufsize;
   249     quint32 bufsize;
   250 	while (!readbuffer.isEmpty() && ((bufsize = readbuffer.size()) > 0) &&
   250     while (!readbuffer.isEmpty() && ((bufsize = readbuffer.size()) > 0) &&
   251 			((msglen = readbuffer.data()[0]) < bufsize))
   251             ((msglen = readbuffer.data()[0]) < bufsize))
   252 	{
   252     {
   253 		QByteArray msg = readbuffer.left(msglen + 1);
   253         QByteArray msg = readbuffer.left(msglen + 1);
   254 		readbuffer.remove(0, msglen + 1);
   254         readbuffer.remove(0, msglen + 1);
   255 		ParseMessage(msg);
   255         ParseMessage(msg);
   256 	}
   256     }
   257 }
   257 }
   258 
   258 
   259 QStringList HWGame::setArguments()
   259 QStringList HWGame::setArguments()
   260 {
   260 {
   261 	QStringList arguments;
   261     QStringList arguments;
   262 	QRect resolution = config->vid_Resolution();
   262     QRect resolution = config->vid_Resolution();
   263 	arguments << cfgdir->absolutePath();
   263     arguments << cfgdir->absolutePath();
   264 	arguments << QString::number(resolution.width());
   264     arguments << QString::number(resolution.width());
   265 	arguments << QString::number(resolution.height());
   265     arguments << QString::number(resolution.height());
   266 	arguments << QString::number(config->bitDepth()); // bpp
   266     arguments << QString::number(config->bitDepth()); // bpp
   267 	arguments << QString("%1").arg(ipc_port);
   267     arguments << QString("%1").arg(ipc_port);
   268 	arguments << (config->vid_Fullscreen() ? "1" : "0");
   268     arguments << (config->vid_Fullscreen() ? "1" : "0");
   269 	arguments << (config->isSoundEnabled() ? "1" : "0");
   269     arguments << (config->isSoundEnabled() ? "1" : "0");
   270 #ifdef _WIN32
   270 #ifdef _WIN32
   271 	arguments << (config->isSoundHardware() ? "1" : "0");
   271     arguments << (config->isSoundHardware() ? "1" : "0");
   272 #else
   272 #else
   273 	arguments << "0";
   273     arguments << "0";
   274 #endif
   274 #endif
   275 	arguments << (config->isWeaponTooltip() ? "1" : "0");
   275     arguments << (config->isWeaponTooltip() ? "1" : "0");
   276 	arguments << tr("en.txt");
   276     arguments << tr("en.txt");
   277 	arguments << QString::number(config->volume()); // sound volume
   277     arguments << QString::number(config->volume()); // sound volume
   278 	arguments << QString::number(config->timerInterval());
   278     arguments << QString::number(config->timerInterval());
   279 	arguments << datadir->absolutePath();
   279     arguments << datadir->absolutePath();
   280 	arguments << (config->isShowFPSEnabled() ? "1" : "0");
   280     arguments << (config->isShowFPSEnabled() ? "1" : "0");
   281 	arguments << (config->isAltDamageEnabled() ? "1" : "0");
   281     arguments << (config->isAltDamageEnabled() ? "1" : "0");
   282 	arguments << config->netNick().toUtf8().toBase64();
   282     arguments << config->netNick().toUtf8().toBase64();
   283 	arguments << (config->isMusicEnabled() ? "1" : "0");
   283     arguments << (config->isMusicEnabled() ? "1" : "0");
   284 	arguments << (config->isReducedQuality() ? "1" : "0");
   284     arguments << (config->isReducedQuality() ? "1" : "0");
   285 	return arguments;
   285     return arguments;
   286 }
   286 }
   287 
   287 
   288 void HWGame::AddTeam(const QString & teamname)
   288 void HWGame::AddTeam(const QString & teamname)
   289 {
   289 {
   290 	if (TeamCount == 5) return;
   290     if (TeamCount == 5) return;
   291 	teams[TeamCount] = teamname;
   291     teams[TeamCount] = teamname;
   292 	TeamCount++;
   292     TeamCount++;
   293 }
   293 }
   294 
   294 
   295 void HWGame::PlayDemo(const QString & demofilename)
   295 void HWGame::PlayDemo(const QString & demofilename)
   296 {
   296 {
   297 	gameType = gtDemo;
   297     gameType = gtDemo;
   298 	QFile demofile(demofilename);
   298     QFile demofile(demofilename);
   299 	if (!demofile.open(QIODevice::ReadOnly))
   299     if (!demofile.open(QIODevice::ReadOnly))
   300 	{
   300     {
   301 		emit ErrorMessage(tr("Cannot open demofile %1").arg(demofilename));
   301         emit ErrorMessage(tr("Cannot open demofile %1").arg(demofilename));
   302 		return ;
   302         return ;
   303 	}
   303     }
   304 
   304 
   305 	// read demo
   305     // read demo
   306 	toSendBuf = demofile.readAll();
   306     toSendBuf = demofile.readAll();
   307 
   307 
   308 	// run engine
   308     // run engine
   309 	demo.clear();
   309     demo.clear();
   310 	Start();
   310     Start();
   311 	SetGameState(gsStarted);
   311     SetGameState(gsStarted);
   312 }
   312 }
   313 
   313 
   314 void HWGame::StartNet()
   314 void HWGame::StartNet()
   315 {
   315 {
   316 	gameType = gtNet;
   316     gameType = gtNet;
   317 	demo.clear();
   317     demo.clear();
   318 	Start();
   318     Start();
   319 	SetGameState(gsStarted);
   319     SetGameState(gsStarted);
   320 }
   320 }
   321 
   321 
   322 void HWGame::StartLocal()
   322 void HWGame::StartLocal()
   323 {
   323 {
   324 	gameType = gtLocal;
   324     gameType = gtLocal;
   325 	demo.clear();
   325     demo.clear();
   326 	Start();
   326     Start();
   327 	SetGameState(gsStarted);
   327     SetGameState(gsStarted);
   328 }
   328 }
   329 
   329 
   330 void HWGame::StartQuick()
   330 void HWGame::StartQuick()
   331 {
   331 {
   332 	gameType = gtQLocal;
   332     gameType = gtQLocal;
   333 	demo.clear();
   333     demo.clear();
   334 	Start();
   334     Start();
   335 	SetGameState(gsStarted);
   335     SetGameState(gsStarted);
   336 }
   336 }
   337 
   337 
   338 void HWGame::StartTraining(const QString & file)
   338 void HWGame::StartTraining(const QString & file)
   339 {
   339 {
   340 	gameType = gtTraining;
   340     gameType = gtTraining;
   341 	training = file;
   341     training = file;
   342 	demo.clear();
   342     demo.clear();
   343 	Start();
   343     Start();
   344 	SetGameState(gsStarted);
   344     SetGameState(gsStarted);
   345 }
   345 }
   346 
   346 
   347 void HWGame::SetGameState(GameState state)
   347 void HWGame::SetGameState(GameState state)
   348 {
   348 {
   349 	gameState = state;
   349     gameState = state;
   350 	emit GameStateChanged(state);
   350     emit GameStateChanged(state);
   351 }
   351 }