1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-15 20:03:15 +02:00

Initial implementation of new team settings format

This commit is contained in:
AlexVinS
2015-11-13 04:01:14 +03:00
parent 6f203fb7e2
commit 8493d0cded
3 changed files with 113 additions and 30 deletions

View File

@@ -145,6 +145,6 @@ public:
/**
* Saves the VCMI/H3 map file.
*
*/
*/
virtual void saveMap(const std::unique_ptr<CMap> & map) = 0;
};

View File

@@ -109,6 +109,14 @@ namespace TerrainDetail
};
}
namespace MapHeaderDetail
{
static const std::array<std::string, PlayerColor::PLAYER_LIMIT_I> playerColorNames =
{
"red", "blue", "tan", "green", "orange", "purple", "teal", "pink"
};
}
///CMapFormatJson
const int CMapFormatJson::VERSION_MAJOR = 1;
const int CMapFormatJson::VERSION_MINOR = 0;
@@ -213,7 +221,7 @@ CMapLoaderJson::CMapLoaderJson(CInputOutputStream * stream):
si32 CMapLoaderJson::getIdentifier(const std::string& type, const std::string& name)
{
boost::optional<si32> res = VLC->modh->identifiers.getIdentifier("core", type, name, false);
if(!res)
{
throw new std::runtime_error("Map load failed. Identifier not resolved.");
@@ -297,6 +305,7 @@ void CMapLoaderJson::readHeader()
readTriggeredEvents(header);
readPlayerInfo(header);
readTeams(header);
//TODO: readHeader
}
@@ -319,7 +328,6 @@ void CMapLoaderJson::readPlayerInfo(const JsonNode & input)
else
{
readPlayerInfo(info, playerSrc);
vstd::amax(howManyTeams, info.team.getNum()+1);
}
}
mapHeader->howManyTeams = howManyTeams;
@@ -328,28 +336,63 @@ void CMapLoaderJson::readPlayerInfo(const JsonNode & input)
void CMapLoaderJson::readPlayerInfo(PlayerInfo& info, const JsonNode& input)
{
//allowed factions
info.isFactionRandom = input["randomFaction"].Bool();
info.canComputerPlay = input["canComputerPlay"].Bool();
info.canComputerPlay = input["canComputerPlay"].Bool();
info.canHumanPlay = input["canHumanPlay"].Bool();
//plasedHeroes
//placedHeroes
//mainTown
info.generateHeroAtMainTown = input["generateHeroAtMainTown"].Bool();
info.hasRandomHero = input["randomHero"].Bool();
//mainHero
//mainHeroPortrait
info.mainCustomHeroName = input["mainHeroName"].String();
info.team = TeamID(input["team"].Float());
}
void CMapLoaderJson::readTeams(const JsonNode& input)
{
const JsonNode & src = input["teams"];
if(src.getType() != JsonNode::DATA_VECTOR)
{
// No alliances
if(src.getType() != JsonNode::DATA_NULL)
logGlobal->errorStream() << "Invalid teams field type";
mapHeader->howManyTeams = 0;
for(int i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++)
{
if(mapHeader->players[i].canComputerPlay || mapHeader->players[i].canHumanPlay)
{
mapHeader->players[i].team = TeamID(mapHeader->howManyTeams++);
}
}
}
else
{
const JsonVector & srcVector = src.Vector();
mapHeader->howManyTeams = srcVector.size();
for(int team = 0; team < mapHeader->howManyTeams; team++)
{
for(const JsonNode & playerData : srcVector[team].Vector())
{
PlayerColor player = PlayerColor(vstd::find_pos(MapHeaderDetail::playerColorNames, playerData.String()));
if(player.isValidPlayer())
{
map->players[player.getNum()].team = TeamID(team);
}
}
}
}
}
void CMapLoaderJson::readTerrainTile(const std::string& src, TerrainTile& tile)
{
@@ -476,7 +519,6 @@ void CMapLoaderJson::readTerrainLevel(const JsonNode& src, const int index)
}
}
void CMapLoaderJson::readTerrain()
{
{
@@ -567,6 +609,8 @@ void CMapSaverJson::writeHeader()
writePlayerInfo(header);
writeTeams(header);
//todo: allowedHeroes;
//todo: placeholdedHeroes;
@@ -577,11 +621,11 @@ void CMapSaverJson::writePlayerInfo(JsonNode & output)
{
JsonNode & dest = output["players"];
dest.setType(JsonNode::DATA_STRUCT);
for(int player = 0; player < PlayerColor::PLAYER_LIMIT_I; player++)
{
const PlayerInfo & info = map->players[player];
if(info.canAnyonePlay())
writePlayerInfo(info, dest[GameConstants::PLAYER_COLOR_NAMES[player]]);
}
@@ -590,27 +634,62 @@ void CMapSaverJson::writePlayerInfo(JsonNode & output)
void CMapSaverJson::writePlayerInfo(const PlayerInfo & info, JsonNode & output)
{
//allowed factions
output["randomFaction"].Bool() = info.isFactionRandom;
output["canComputerPlay"].Bool() = info.canComputerPlay;
output["canHumanPlay"].Bool() = info.canHumanPlay;
//plasedHeroes
//mainTown
output["generateHeroAtMainTown"].Bool() = info.generateHeroAtMainTown;
output["randomHero"].Bool() = info.hasRandomHero;
//mainHero
//mainHeroPortrait
output["mainHeroName"].String() = info.mainCustomHeroName;
output["team"].Float() = info.team.getNum();
}
void CMapSaverJson::writeTeams(JsonNode& output)
{
JsonNode & dest = output["teams"];
std::vector<std::set<PlayerColor>> teamsData;
teamsData.resize(map->howManyTeams);
//get raw data
for(int idx = 0; idx < map->players.size(); idx++)
{
const PlayerInfo & player = map->players.at(idx);
int team = player.team.getNum();
if(vstd::isbetween(team, 0, map->howManyTeams-1))
teamsData.at(team).insert(PlayerColor(idx));
}
//remove single-member teams
vstd::erase_if(teamsData, [](std::set<PlayerColor> & elem) -> bool
{
return elem.size() <= 1;
});
dest.setType(JsonNode::DATA_VECTOR);
for(const std::set<PlayerColor> & teamData : teamsData)
{
JsonNode team(JsonNode::DATA_VECTOR);
for(const PlayerColor & player : teamData)
{
JsonNode member(JsonNode::DATA_STRING);
member.String() = GameConstants::PLAYER_COLOR_NAMES[player.getNum()];
team.Vector().push_back(std::move(member));
}
dest.Vector().push_back(std::move(team));
}
}
const std::string CMapSaverJson::writeTerrainTile(const TerrainTile & tile)

View File

@@ -143,6 +143,8 @@ private:
*/
void readPlayerInfo(PlayerInfo & info, const JsonNode & input);
void readTeams(const JsonNode & input);
void readTerrainTile(const std::string & src, TerrainTile & tile);
void readTerrainLevel(const JsonNode & src, const int index);
@@ -189,7 +191,9 @@ private:
* Save one player info
* @param output empty object
*/
void writePlayerInfo(const PlayerInfo & info, JsonNode & output);
void writePlayerInfo(const PlayerInfo & info, JsonNode & output);
void writeTeams(JsonNode & output);
const std::string writeTerrainTile(const TerrainTile & tile);