예제 #1
0
int LuaArchive::GetAvailableAIs(lua_State* L)
{
	const std::string gameArchivePath = GetFileName(luaL_optsstring(L, 1, ""));
	const std::string mapArchivePath = GetFileName(luaL_optsstring(L, 2, ""));

	// load selected archives to get lua ais
	if (!gameArchivePath.empty()) {
		vfsHandler->AddArchive(gameArchivePath, false);
	}
	if (!mapArchivePath.empty()) {
		vfsHandler->AddArchive(mapArchivePath, false);
	}

	const IAILibraryManager::T_skirmishAIKeys& skirmishAIKeys = aiLibManager->GetSkirmishAIKeys();
	std::vector< std::vector<InfoItem> > luaAIInfos = luaAIImplHandler.LoadInfos();	

	lua_createtable(L, skirmishAIKeys.size() + luaAIInfos.size(), 0);
	unsigned int count = 0;

	for(int i=0; i<luaAIInfos.size(); i++) {
		lua_newtable(L); {
			for (int j=0; j<luaAIInfos[i].size(); j++) {
				if (luaAIInfos[i][j].key==SKIRMISH_AI_PROPERTY_SHORT_NAME) {
					HSTR_PUSH_STRING(L, "shortName", luaAIInfos[i][j].GetValueAsString());
				} else if (luaAIInfos[i][j].key==SKIRMISH_AI_PROPERTY_VERSION) {
					HSTR_PUSH_STRING(L, "version", luaAIInfos[i][j].GetValueAsString());
				}
			}
		}
		lua_rawseti(L, -2, ++count);
	}
	
	// close archives
	if (!mapArchivePath.empty()) {
		vfsHandler->RemoveArchive(mapArchivePath);
	}
	if (!gameArchivePath.empty()) {
		vfsHandler->RemoveArchive(gameArchivePath);
	}
	
	IAILibraryManager::T_skirmishAIKeys::const_iterator i = skirmishAIKeys.begin();
	IAILibraryManager::T_skirmishAIKeys::const_iterator e = skirmishAIKeys.end();

	for (; i != e; ++i) {
		lua_newtable(L); {
			HSTR_PUSH_STRING(L, "shortName", i->GetShortName());
			HSTR_PUSH_STRING(L, "version", i->GetVersion());
		}
		lua_rawseti(L, -2, ++count);
	}
	
	return 1;
}
예제 #2
0
void CTeamHandler::LoadFromSetup(const CGameSetup* setup)
{
	const bool useLuaGaia = CLuaGaia::SetConfigString(setup->luaGaiaStr);

	assert(setup->numTeams <= MAX_TEAMS);
	teams.resize(setup->numTeams);

	for (size_t i = 0; i < teams.size(); ++i) {
		// TODO: this loop body could use some more refactoring
		CTeam* team = Team(i);
		*team = setup->teamStartingData[i];
		team->teamNum = i;
		team->metalIncome = team->metal; // for the endgame statistics

		team->energyIncome = setup->startEnergy;

		SetAllyTeam(i, team->teamAllyteam);

		const SkirmishAIData* skirmishAIData = setup->GetSkirmishAIDataForTeam(i);

		if (skirmishAIData != NULL) {
			bool isLuaAI = true;
			const IAILibraryManager::T_skirmishAIKeys& skirmishAIKeys = IAILibraryManager::GetInstance()->GetSkirmishAIKeys();
			IAILibraryManager::T_skirmishAIKeys::const_iterator skirmAiImpl;

			for (skirmAiImpl = skirmishAIKeys.begin();
				skirmAiImpl != skirmishAIKeys.end(); ++skirmAiImpl) {
				if (skirmishAIData->shortName == skirmAiImpl->GetShortName()) {
					isLuaAI = false;
					logOutput.Print("Skirmish AI (%s) for team %i is no Lua AI", skirmishAIData->shortName.c_str(), skirmishAIData->team);
					break;
				}
			}

			if (isLuaAI) {
				team->luaAI = skirmishAIData->shortName;
				team->isAI = true;
			} else {
				if (setup->hostDemo) {
					// CPreGame always adds the name of the demo
					// file to the internal setup script before
					// CGameSetup is inited, therefore hostDemo
					// tells us if we're watching a replay
					// if so, then we do NOT want to load any AI
					// libs, and therefore we must make sure each
					// team's skirmishAIKey is left "unspecified"
					//
					// however, flag this team as an AI anyway so
					// the original AI team's orders are not seen
					// as invalid and we don't desync the demo
					team->skirmishAIKey = SkirmishAIKey(); // unspecified AI Key
					team->isAI = true;
				} else {
					const char* sn = skirmishAIData->shortName.c_str();
					const char* v = skirmishAIData->version.c_str();

					SkirmishAIKey spec = SkirmishAIKey(sn, v);
					SkirmishAIKey fittingKey =
							IAILibraryManager::GetInstance()->ResolveSkirmishAIKey(spec);

					if (!fittingKey.IsUnspecified()) {
						team->skirmishAIKey = fittingKey;
						team->skirmishAIOptions = skirmishAIData->options;
						team->isAI = true;
					} else {
						// a missing AI lib is only a problem for
						// the player who is supposed to load it
						if (gu->myPlayerNum == skirmishAIData->hostPlayerNum) {
							const int MAX_MSG_LENGTH = 511;
							char s_msg[MAX_MSG_LENGTH + 1];
							SNPRINTF(s_msg, MAX_MSG_LENGTH,
									"Specified Skirmish AI could not be found: %s (version: %s)",
									spec.GetShortName().c_str(), spec.GetVersion() != "" ? spec.GetVersion().c_str() : "<not specified>");
							handleerror(NULL, s_msg, "Team Handler Error", MBF_OK | MBF_EXCL);
						}
					}
				}
			}
		}
	}

	allyTeams = setup->allyStartingData;
	assert(setup->numAllyTeams <= MAX_TEAMS);
	if (useLuaGaia) {
		// Gaia adjustments
		gaiaTeamID = static_cast<int>(teams.size());
		gaiaAllyTeamID = static_cast<int>(allyTeams.size());

		// Setup the gaia team
		CTeam team;
		team.color[0] = 255;
		team.color[1] = 255;
		team.color[2] = 255;
		team.color[3] = 255;
		team.gaia = true;
		team.teamNum = gaiaTeamID;
		team.StartposMessage(float3(0.0, 0.0, 0.0), true);
		team.teamAllyteam = gaiaAllyTeamID;
		teams.push_back(team);

		for (std::vector< ::AllyTeam >::iterator it = allyTeams.begin(); it != allyTeams.end(); ++it)
		{
			it->allies.push_back(false); // enemy to everyone
		}
		::AllyTeam allyteam;
		allyteam.allies.resize(allyTeams.size()+1,false); // everyones enemy
		allyteam.allies[gaiaTeamID] = true; // peace with itself
		allyTeams.push_back(allyteam);
	}
}