mirror of
https://github.com/vcmi/vcmi.git
synced 2025-05-13 22:06:58 +02:00
Team alignments implemented
This commit is contained in:
parent
4f5fab702e
commit
b1f2c7aed4
@ -55,7 +55,6 @@ void InterfaceObjectConfigurable::init(const JsonNode &config)
|
|||||||
: item["name"].String();
|
: item["name"].String();
|
||||||
widgets[name] = buildWidget(item);
|
widgets[name] = buildWidget(item);
|
||||||
}
|
}
|
||||||
variables = config["variables"];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const JsonNode & InterfaceObjectConfigurable::variable(const std::string & name) const
|
const JsonNode & InterfaceObjectConfigurable::variable(const std::string & name) const
|
||||||
@ -94,6 +93,16 @@ Point InterfaceObjectConfigurable::readPosition(const JsonNode & config) const
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rect InterfaceObjectConfigurable::readRect(const JsonNode & config) const
|
||||||
|
{
|
||||||
|
Rect p;
|
||||||
|
p.x = config["x"].Integer();
|
||||||
|
p.y = config["y"].Integer();
|
||||||
|
p.w = config["w"].Integer();
|
||||||
|
p.h = config["h"].Integer();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
ETextAlignment InterfaceObjectConfigurable::readTextAlignment(const JsonNode & config) const
|
ETextAlignment InterfaceObjectConfigurable::readTextAlignment(const JsonNode & config) const
|
||||||
{
|
{
|
||||||
if(!config.isNull())
|
if(!config.isNull())
|
||||||
@ -275,6 +284,45 @@ std::shared_ptr<CSlider> InterfaceObjectConfigurable::buildSlider(const JsonNode
|
|||||||
return std::make_shared<CSlider>(position, length, callbacks.at(config["callback"].String()), itemsVisible, itemsTotal, value, horizontal, style);
|
return std::make_shared<CSlider>(position, length, callbacks.at(config["callback"].String()), itemsVisible, itemsTotal, value, horizontal, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<CAnimImage> InterfaceObjectConfigurable::buildImage(const JsonNode & config) const
|
||||||
|
{
|
||||||
|
auto position = readPosition(config["position"]);
|
||||||
|
auto image = config["image"].String();
|
||||||
|
int group = config["group"].isNull() ? 0 : config["group"].Integer();
|
||||||
|
int frame = config["frame"].isNull() ? 0 : config["frame"].Integer();
|
||||||
|
return std::make_shared<CAnimImage>(image, frame, group, position.x, position.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<CFilledTexture> InterfaceObjectConfigurable::buildTexture(const JsonNode & config) const
|
||||||
|
{
|
||||||
|
auto image = config["image"].String();
|
||||||
|
auto rect = readRect(config);
|
||||||
|
return std::make_shared<CFilledTexture>(image, rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<CShowableAnim> InterfaceObjectConfigurable::buildAnimation(const JsonNode & config) const
|
||||||
|
{
|
||||||
|
auto position = readPosition(config["position"]);
|
||||||
|
auto image = config["image"].String();
|
||||||
|
ui8 flags = 0;
|
||||||
|
if(!config["repeat"].Bool())
|
||||||
|
flags |= CShowableAnim::EFlags::PLAY_ONCE;
|
||||||
|
|
||||||
|
int group = config["group"].isNull() ? 0 : config["group"].Integer();
|
||||||
|
auto anim = std::make_shared<CShowableAnim>(position.x, position.y, image, flags, 4, group);
|
||||||
|
if(!config["alpha"].isNull())
|
||||||
|
anim->setAlpha(config["alpha"].Integer());
|
||||||
|
if(!config["callback"].isNull())
|
||||||
|
anim->callback = std::bind(callbacks.at(config["callback"].String()), 0);
|
||||||
|
if(!config["frames"].isNull())
|
||||||
|
{
|
||||||
|
auto b = config["frames"]["start"].Integer();
|
||||||
|
auto e = config["frames"]["end"].Integer();
|
||||||
|
anim->set(group, b, e);
|
||||||
|
}
|
||||||
|
return anim;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<CIntObject> InterfaceObjectConfigurable::buildWidget(const JsonNode & config) const
|
std::shared_ptr<CIntObject> InterfaceObjectConfigurable::buildWidget(const JsonNode & config) const
|
||||||
{
|
{
|
||||||
assert(!config.isNull());
|
assert(!config.isNull());
|
||||||
@ -283,6 +331,18 @@ std::shared_ptr<CIntObject> InterfaceObjectConfigurable::buildWidget(const JsonN
|
|||||||
{
|
{
|
||||||
return buildPicture(config);
|
return buildPicture(config);
|
||||||
}
|
}
|
||||||
|
if(type == "image")
|
||||||
|
{
|
||||||
|
return buildImage(config);
|
||||||
|
}
|
||||||
|
if(type == "texture")
|
||||||
|
{
|
||||||
|
return buildTexture(config);
|
||||||
|
}
|
||||||
|
if(type == "animation")
|
||||||
|
{
|
||||||
|
return buildAnimation(config);
|
||||||
|
}
|
||||||
if(type == "label")
|
if(type == "label")
|
||||||
{
|
{
|
||||||
return buildLabel(config);
|
return buildLabel(config);
|
||||||
|
@ -21,6 +21,9 @@ class CToggleButton;
|
|||||||
class CButton;
|
class CButton;
|
||||||
class CLabelGroup;
|
class CLabelGroup;
|
||||||
class CSlider;
|
class CSlider;
|
||||||
|
class CAnimImage;
|
||||||
|
class CShowableAnim;
|
||||||
|
class CFilledTexture;
|
||||||
|
|
||||||
class InterfaceObjectConfigurable: public CIntObject
|
class InterfaceObjectConfigurable: public CIntObject
|
||||||
{
|
{
|
||||||
@ -47,6 +50,7 @@ protected:
|
|||||||
|
|
||||||
//basic serializers
|
//basic serializers
|
||||||
Point readPosition(const JsonNode &) const;
|
Point readPosition(const JsonNode &) const;
|
||||||
|
Rect readRect(const JsonNode &) const;
|
||||||
ETextAlignment readTextAlignment(const JsonNode &) const;
|
ETextAlignment readTextAlignment(const JsonNode &) const;
|
||||||
SDL_Color readColor(const JsonNode &) const;
|
SDL_Color readColor(const JsonNode &) const;
|
||||||
EFonts readFont(const JsonNode &) const;
|
EFonts readFont(const JsonNode &) const;
|
||||||
@ -61,6 +65,10 @@ protected:
|
|||||||
std::shared_ptr<CButton> buildButton(const JsonNode &) const;
|
std::shared_ptr<CButton> buildButton(const JsonNode &) const;
|
||||||
std::shared_ptr<CLabelGroup> buildLabelGroup(const JsonNode &) const;
|
std::shared_ptr<CLabelGroup> buildLabelGroup(const JsonNode &) const;
|
||||||
std::shared_ptr<CSlider> buildSlider(const JsonNode &) const;
|
std::shared_ptr<CSlider> buildSlider(const JsonNode &) const;
|
||||||
|
std::shared_ptr<CAnimImage> buildImage(const JsonNode &) const;
|
||||||
|
std::shared_ptr<CShowableAnim> buildAnimation(const JsonNode &) const;
|
||||||
|
std::shared_ptr<CFilledTexture> buildTexture(const JsonNode &) const;
|
||||||
|
|
||||||
|
|
||||||
//composite widgets
|
//composite widgets
|
||||||
virtual std::shared_ptr<CIntObject> buildCustomWidget(const JsonNode & config);
|
virtual std::shared_ptr<CIntObject> buildCustomWidget(const JsonNode & config);
|
||||||
|
@ -155,6 +155,7 @@ void RandomMapTab::updateMapInfoByHost()
|
|||||||
|
|
||||||
mapInfo->mapHeader->howManyTeams = playersToGen;
|
mapInfo->mapHeader->howManyTeams = playersToGen;
|
||||||
|
|
||||||
|
std::set<TeamID> occupiedTeams;
|
||||||
for(int i = 0; i < playersToGen; ++i)
|
for(int i = 0; i < playersToGen; ++i)
|
||||||
{
|
{
|
||||||
PlayerInfo player;
|
PlayerInfo player;
|
||||||
@ -168,11 +169,25 @@ void RandomMapTab::updateMapInfoByHost()
|
|||||||
{
|
{
|
||||||
player.canHumanPlay = true;
|
player.canHumanPlay = true;
|
||||||
}
|
}
|
||||||
player.team = TeamID(i);
|
auto team = mapGenOptions->getPlayersSettings().at(PlayerColor(i)).getTeam();
|
||||||
|
player.team = team;
|
||||||
|
occupiedTeams.insert(team);
|
||||||
player.hasMainTown = true;
|
player.hasMainTown = true;
|
||||||
player.generateHeroAtMainTown = true;
|
player.generateHeroAtMainTown = true;
|
||||||
mapInfo->mapHeader->players.push_back(player);
|
mapInfo->mapHeader->players.push_back(player);
|
||||||
}
|
}
|
||||||
|
for(auto & player : mapInfo->mapHeader->players)
|
||||||
|
{
|
||||||
|
for(int i = 0; player.team == TeamID::NO_TEAM; ++i)
|
||||||
|
{
|
||||||
|
TeamID team(i);
|
||||||
|
if(!occupiedTeams.count(team))
|
||||||
|
{
|
||||||
|
player.team = team;
|
||||||
|
occupiedTeams.insert(team);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mapInfoChanged(mapInfo, mapGenOptions);
|
mapInfoChanged(mapInfo, mapGenOptions);
|
||||||
}
|
}
|
||||||
@ -456,13 +471,67 @@ TeamAlignmentsWidget::TeamAlignmentsWidget(RandomMapTab & randomMapTab):
|
|||||||
{
|
{
|
||||||
OBJ_CONSTRUCTION;
|
OBJ_CONSTRUCTION;
|
||||||
|
|
||||||
pos.w = 300;
|
int humanPlayers = randomMapTab.obtainMapGenOptions().getPlayerCount();
|
||||||
pos.h = 300;
|
int cpuPlayers = randomMapTab.obtainMapGenOptions().getCompOnlyPlayerCount();
|
||||||
|
int totalPlayers = humanPlayers == CMapGenOptions::RANDOM_SIZE || cpuPlayers == CMapGenOptions::RANDOM_SIZE
|
||||||
|
? PlayerColor::PLAYER_LIMIT_I : humanPlayers + cpuPlayers;
|
||||||
|
assert(totalPlayers <= PlayerColor::PLAYER_LIMIT_I);
|
||||||
|
auto settings = randomMapTab.obtainMapGenOptions().getPlayersSettings();
|
||||||
|
|
||||||
|
pos.w = 80 + totalPlayers * 32;
|
||||||
|
pos.h = 80 + totalPlayers * 32;
|
||||||
background = std::make_shared<CFilledTexture>("Bl3DCvex", pos);
|
background = std::make_shared<CFilledTexture>("Bl3DCvex", pos);
|
||||||
center(pos);
|
center(pos);
|
||||||
|
|
||||||
buttonOk = std::make_shared<CButton>(Point(43, 240), "MUBCHCK.DEF", CGI->generaltexth->zelp[560], [](){});
|
for(int plId = 0; plId < totalPlayers; ++plId)
|
||||||
buttonCancel = std::make_shared<CButton>(Point(193, 240), "MUBCANC.DEF", CGI->generaltexth->zelp[561], [&]()
|
{
|
||||||
|
players.push_back(std::make_shared<CToggleGroup>([&, totalPlayers, plId](int sel)
|
||||||
|
{
|
||||||
|
SObjectConstruction obj__i(players[plId].get());
|
||||||
|
for(int teamId = 0; teamId < totalPlayers; ++teamId)
|
||||||
|
{
|
||||||
|
auto button = std::dynamic_pointer_cast<CToggleButton>(players[plId]->buttons[teamId]);
|
||||||
|
assert(button);
|
||||||
|
if(sel == teamId)
|
||||||
|
{
|
||||||
|
button->addOverlay(std::make_shared<CAnimImage>("ITGFLAGS", plId, 0, 8, 8));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button->addOverlay(std::make_shared<CPicture>("TeamPlSl"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
SObjectConstruction obj__i(players.back().get());
|
||||||
|
for(int teamId = 0; teamId < totalPlayers; ++teamId)
|
||||||
|
{
|
||||||
|
Point p(40 + plId * 32, 20 + teamId * 32);
|
||||||
|
placeholders.push_back(std::make_shared<CPicture>("TeamPlSl", p.x, p.y));
|
||||||
|
auto button = std::make_shared<CToggleButton>(p, "TeamPlSl", std::pair<std::string, std::string>{"", ""});
|
||||||
|
button->pos.w = 32;
|
||||||
|
button->pos.h = 32;
|
||||||
|
players.back()->addToggle(teamId, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto team = settings.at(PlayerColor(plId)).getTeam();
|
||||||
|
if(team == TeamID::NO_TEAM)
|
||||||
|
players.back()->setSelected(plId);
|
||||||
|
else
|
||||||
|
players.back()->setSelected(team.getNum());
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonOk = std::make_shared<CButton>(Point(40, 40 + totalPlayers * 32), "MUBCHCK.DEF", CGI->generaltexth->zelp[560], [&]()
|
||||||
|
{
|
||||||
|
for(int plId = 0; plId < players.size(); ++plId)
|
||||||
|
{
|
||||||
|
randomMapTab.obtainMapGenOptions().setPlayerTeam(PlayerColor(plId), TeamID(players[plId]->getSelected()));
|
||||||
|
}
|
||||||
|
randomMapTab.updateMapInfoByHost();
|
||||||
|
assert(GH.topInt().get() == this);
|
||||||
|
GH.popInt(GH.topInt());
|
||||||
|
});
|
||||||
|
buttonCancel = std::make_shared<CButton>(Point(120, 40 + totalPlayers * 32), "MUBCANC.DEF", CGI->generaltexth->zelp[561], [&]()
|
||||||
{
|
{
|
||||||
assert(GH.topInt().get() == this);
|
assert(GH.topInt().get() == this);
|
||||||
GH.popInt(GH.topInt());
|
GH.popInt(GH.topInt());
|
||||||
|
@ -26,6 +26,7 @@ class CToggleButton;
|
|||||||
class CLabel;
|
class CLabel;
|
||||||
class CLabelGroup;
|
class CLabelGroup;
|
||||||
class CSlider;
|
class CSlider;
|
||||||
|
class CPicture;
|
||||||
|
|
||||||
class RandomMapTab : public InterfaceObjectConfigurable
|
class RandomMapTab : public InterfaceObjectConfigurable
|
||||||
{
|
{
|
||||||
@ -35,6 +36,7 @@ public:
|
|||||||
void updateMapInfoByHost();
|
void updateMapInfoByHost();
|
||||||
void setMapGenOptions(std::shared_ptr<CMapGenOptions> opts);
|
void setMapGenOptions(std::shared_ptr<CMapGenOptions> opts);
|
||||||
void setTemplate(const CRmgTemplate *);
|
void setTemplate(const CRmgTemplate *);
|
||||||
|
CMapGenOptions & obtainMapGenOptions() {return *mapGenOptions;}
|
||||||
|
|
||||||
CFunctionList<void(std::shared_ptr<CMapInfo>, std::shared_ptr<CMapGenOptions>)> mapInfoChanged;
|
CFunctionList<void(std::shared_ptr<CMapInfo>, std::shared_ptr<CMapGenOptions>)> mapInfoChanged;
|
||||||
|
|
||||||
@ -97,5 +99,6 @@ private:
|
|||||||
std::shared_ptr<CFilledTexture> background;
|
std::shared_ptr<CFilledTexture> background;
|
||||||
std::shared_ptr<CLabelGroup> labels;
|
std::shared_ptr<CLabelGroup> labels;
|
||||||
std::shared_ptr<CButton> buttonOk, buttonCancel;
|
std::shared_ptr<CButton> buttonOk, buttonCancel;
|
||||||
std::vector<std::shared_ptr<CToggleGroup>> teams;
|
std::vector<std::shared_ptr<CToggleGroup>> players;
|
||||||
|
std::vector<std::shared_ptr<CPicture>> placeholders;
|
||||||
};
|
};
|
||||||
|
@ -449,6 +449,11 @@ void CToggleGroup::selectionChanged(int to)
|
|||||||
parent->redraw();
|
parent->redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CToggleGroup::getSelected() const
|
||||||
|
{
|
||||||
|
return selectedID;
|
||||||
|
}
|
||||||
|
|
||||||
CVolumeSlider::CVolumeSlider(const Point & position, const std::string & defName, const int value, const std::pair<std::string, std::string> * const help)
|
CVolumeSlider::CVolumeSlider(const Point & position, const std::string & defName, const int value, const std::pair<std::string, std::string> * const help)
|
||||||
: CIntObject(LCLICK | RCLICK | WHEEL),
|
: CIntObject(LCLICK | RCLICK | WHEEL),
|
||||||
value(value),
|
value(value),
|
||||||
|
@ -185,6 +185,7 @@ public:
|
|||||||
/// in some cases, e.g. LoadGame difficulty selection, after refreshing the UI, the ToggleGroup should
|
/// in some cases, e.g. LoadGame difficulty selection, after refreshing the UI, the ToggleGroup should
|
||||||
/// reset all of it's child buttons to BLOCK state, then make selection again
|
/// reset all of it's child buttons to BLOCK state, then make selection again
|
||||||
void setSelectedOnly(int id);
|
void setSelectedOnly(int id);
|
||||||
|
int getSelected() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A typical slider for volume with an animated indicator
|
/// A typical slider for volume with an animated indicator
|
||||||
|
@ -56,7 +56,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// area filled with specific texture
|
/// area filled with specific texture
|
||||||
class CFilledTexture : CIntObject
|
class CFilledTexture : public CIntObject
|
||||||
{
|
{
|
||||||
SDL_Surface * texture;
|
SDL_Surface * texture;
|
||||||
|
|
||||||
|
@ -121,10 +121,7 @@
|
|||||||
"defaultTemplate": "default",
|
"defaultTemplate": "default",
|
||||||
"templateLabel": "Template",
|
"templateLabel": "Template",
|
||||||
"teamAlignmentsButton": "Setup...",
|
"teamAlignmentsButton": "Setup...",
|
||||||
"teamAlignmentsLabel": "Team alignments",
|
"teamAlignmentsLabel": "Team alignments"
|
||||||
"dirtRoad": "Dirt",
|
|
||||||
"gravelRoad": "Gravel",
|
|
||||||
"cobblestoneRoad": "Stone"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,12 +136,14 @@ void CMapGenOptions::resetPlayersMap()
|
|||||||
{
|
{
|
||||||
|
|
||||||
std::map<PlayerColor, TFaction> rememberTownTypes;
|
std::map<PlayerColor, TFaction> rememberTownTypes;
|
||||||
|
std::map<PlayerColor, TeamID> rememberTeam;
|
||||||
|
|
||||||
for (auto p : players)
|
for (auto p : players)
|
||||||
{
|
{
|
||||||
auto town = p.second.getStartingTown();
|
auto town = p.second.getStartingTown();
|
||||||
if (town != RANDOM_SIZE)
|
if (town != RANDOM_SIZE)
|
||||||
rememberTownTypes[p.first] = town;
|
rememberTownTypes[p.first] = town;
|
||||||
|
rememberTeam[p.first] = p.second.getTeam();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -169,6 +171,7 @@ void CMapGenOptions::resetPlayersMap()
|
|||||||
playerType = EPlayerType::COMP_ONLY;
|
playerType = EPlayerType::COMP_ONLY;
|
||||||
}
|
}
|
||||||
player.setPlayerType(playerType);
|
player.setPlayerType(playerType);
|
||||||
|
player.setTeam(rememberTeam[pc]);
|
||||||
players[pc] = player;
|
players[pc] = player;
|
||||||
|
|
||||||
if (vstd::contains(rememberTownTypes, pc))
|
if (vstd::contains(rememberTownTypes, pc))
|
||||||
|
@ -188,6 +188,7 @@ void CMapGenerator::addPlayerInfo()
|
|||||||
|
|
||||||
enum ETeams {CPHUMAN = 0, CPUONLY = 1, AFTER_LAST = 2};
|
enum ETeams {CPHUMAN = 0, CPUONLY = 1, AFTER_LAST = 2};
|
||||||
std::array<std::list<int>, 2> teamNumbers;
|
std::array<std::list<int>, 2> teamNumbers;
|
||||||
|
std::set<int> teamsTotal;
|
||||||
|
|
||||||
int teamOffset = 0;
|
int teamOffset = 0;
|
||||||
int playerCount = 0;
|
int playerCount = 0;
|
||||||
@ -258,11 +259,11 @@ void CMapGenerator::addPlayerInfo()
|
|||||||
player.team = TeamID(*itTeam);
|
player.team = TeamID(*itTeam);
|
||||||
teamNumbers[j].erase(itTeam);
|
teamNumbers[j].erase(itTeam);
|
||||||
}
|
}
|
||||||
|
teamsTotal.insert(player.team.getNum());
|
||||||
map->map().players[pSettings.getColor().getNum()] = player;
|
map->map().players[pSettings.getColor().getNum()] = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
map->map().howManyTeams = (mapGenOptions.getTeamCount() == 0 ? mapGenOptions.getPlayerCount() : mapGenOptions.getTeamCount())
|
map->map().howManyTeams = teamsTotal.size();
|
||||||
+ (mapGenOptions.getCompOnlyTeamCount() == 0 ? mapGenOptions.getCompOnlyPlayerCount() : mapGenOptions.getCompOnlyTeamCount());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapGenerator::genZones()
|
void CMapGenerator::genZones()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user