mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Merge pull request #2887 from Laserlicht/campaign_improvement
campaign improvements
This commit is contained in:
commit
ec582328b4
@ -683,12 +683,19 @@ void CServerHandler::startCampaignScenario(std::shared_ptr<CampaignState> cs)
|
||||
auto & epilogue = ourCampaign->scenario(*ourCampaign->lastScenario()).epilog;
|
||||
auto finisher = [=]()
|
||||
{
|
||||
if(!ourCampaign->isCampaignFinished())
|
||||
if(ourCampaign->campaignSet != "")
|
||||
{
|
||||
GH.windows().pushWindow(CMM);
|
||||
GH.windows().pushWindow(CMM->menu);
|
||||
CMM->openCampaignLobby(ourCampaign);
|
||||
Settings entry = persistentStorage.write["completedCampaigns"][ourCampaign->getFilename()];
|
||||
entry->Bool() = true;
|
||||
}
|
||||
|
||||
GH.windows().pushWindow(CMM);
|
||||
GH.windows().pushWindow(CMM->menu);
|
||||
|
||||
if(!ourCampaign->isCampaignFinished())
|
||||
CMM->openCampaignLobby(ourCampaign);
|
||||
else
|
||||
CMM->openCampaignScreen(ourCampaign->campaignSet);
|
||||
};
|
||||
if(epilogue.hasPrologEpilog)
|
||||
{
|
||||
|
@ -47,12 +47,12 @@
|
||||
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
CCampaignScreen::CCampaignScreen(const JsonNode & config)
|
||||
: CWindowObject(BORDERED)
|
||||
CCampaignScreen::CCampaignScreen(const JsonNode & config, std::string name)
|
||||
: CWindowObject(BORDERED), campaignSet(name)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||
|
||||
for(const JsonNode & node : config["images"].Vector())
|
||||
for(const JsonNode & node : config[name]["images"].Vector())
|
||||
images.push_back(CMainMenu::createPicture(node));
|
||||
|
||||
if(!images.empty())
|
||||
@ -63,14 +63,14 @@ CCampaignScreen::CCampaignScreen(const JsonNode & config)
|
||||
pos = images[0]->pos; // fix height\width of this window
|
||||
}
|
||||
|
||||
if(!config["exitbutton"].isNull())
|
||||
if(!config[name]["exitbutton"].isNull())
|
||||
{
|
||||
buttonBack = createExitButton(config["exitbutton"]);
|
||||
buttonBack = createExitButton(config[name]["exitbutton"]);
|
||||
buttonBack->hoverable = true;
|
||||
}
|
||||
|
||||
for(const JsonNode & node : config["items"].Vector())
|
||||
campButtons.push_back(std::make_shared<CCampaignButton>(node));
|
||||
for(const JsonNode & node : config[name]["items"].Vector())
|
||||
campButtons.push_back(std::make_shared<CCampaignButton>(node, config, campaignSet));
|
||||
}
|
||||
|
||||
void CCampaignScreen::activate()
|
||||
@ -89,7 +89,8 @@ std::shared_ptr<CButton> CCampaignScreen::createExitButton(const JsonNode & butt
|
||||
return std::make_shared<CButton>(Point((int)button["x"].Float(), (int)button["y"].Float()), AnimationPath::fromJson(button["name"]), help, [=](){ close();}, EShortcut::GLOBAL_CANCEL);
|
||||
}
|
||||
|
||||
CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode & config)
|
||||
CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode & config, const JsonNode & parentConfig, std::string campaignSet)
|
||||
: campaignSet(campaignSet)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||
|
||||
@ -101,11 +102,27 @@ CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode & config)
|
||||
campFile = config["file"].String();
|
||||
video = VideoPath::fromJson(config["video"]);
|
||||
|
||||
status = config["open"].Bool() ? CCampaignScreen::ENABLED : CCampaignScreen::DISABLED;
|
||||
status = CCampaignScreen::ENABLED;
|
||||
|
||||
auto header = CampaignHandler::getHeader(campFile);
|
||||
hoverText = header->getName();
|
||||
|
||||
if(persistentStorage["completedCampaigns"][header->getFilename()].Bool())
|
||||
status = CCampaignScreen::COMPLETED;
|
||||
|
||||
for(const JsonNode & node : parentConfig[campaignSet]["items"].Vector())
|
||||
{
|
||||
for(const JsonNode & requirement : config["requires"].Vector())
|
||||
{
|
||||
if(node["id"].Integer() == requirement.Integer())
|
||||
if(!persistentStorage["completedCampaigns"][node["file"].String()].Bool())
|
||||
status = CCampaignScreen::DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
if(persistentStorage["unlockAllCampaigns"].Bool())
|
||||
status = CCampaignScreen::ENABLED;
|
||||
|
||||
if(status != CCampaignScreen::DISABLED)
|
||||
{
|
||||
addUsedEvents(LCLICK | HOVER);
|
||||
@ -134,7 +151,7 @@ void CCampaignScreen::CCampaignButton::show(Canvas & to)
|
||||
void CCampaignScreen::CCampaignButton::clickReleased(const Point & cursorPosition)
|
||||
{
|
||||
CCS->videoh->close();
|
||||
CMainMenu::openCampaignLobby(campFile);
|
||||
CMainMenu::openCampaignLobby(campFile, campaignSet);
|
||||
}
|
||||
|
||||
void CCampaignScreen::CCampaignButton::hover(bool on)
|
||||
|
@ -40,14 +40,18 @@ private:
|
||||
VideoPath video; // the resource name of the video
|
||||
std::string hoverText;
|
||||
|
||||
std::string campaignSet;
|
||||
|
||||
void clickReleased(const Point & cursorPosition) override;
|
||||
void hover(bool on) override;
|
||||
|
||||
public:
|
||||
CCampaignButton(const JsonNode & config);
|
||||
CCampaignButton(const JsonNode & config, const JsonNode & parentConfig, std::string campaignSet);
|
||||
void show(Canvas & to) override;
|
||||
};
|
||||
|
||||
std::string campaignSet;
|
||||
|
||||
std::vector<std::shared_ptr<CCampaignButton>> campButtons;
|
||||
std::vector<std::shared_ptr<CPicture>> images;
|
||||
std::shared_ptr<CButton> buttonBack;
|
||||
@ -55,9 +59,7 @@ private:
|
||||
std::shared_ptr<CButton> createExitButton(const JsonNode & button);
|
||||
|
||||
public:
|
||||
enum CampaignSet {ROE, AB, SOD, WOG};
|
||||
|
||||
CCampaignScreen(const JsonNode & config);
|
||||
CCampaignScreen(const JsonNode & config, std::string campaignSet);
|
||||
|
||||
void activate() override;
|
||||
};
|
||||
|
@ -349,9 +349,10 @@ void CMainMenu::openLobby(ESelectionScreen screenType, bool host, const std::vec
|
||||
GH.windows().createAndPushWindow<CSimpleJoinScreen>(host);
|
||||
}
|
||||
|
||||
void CMainMenu::openCampaignLobby(const std::string & campaignFileName)
|
||||
void CMainMenu::openCampaignLobby(const std::string & campaignFileName, std::string campaignSet)
|
||||
{
|
||||
auto ourCampaign = CampaignHandler::getCampaign(campaignFileName);
|
||||
ourCampaign->campaignSet = campaignSet;
|
||||
openCampaignLobby(ourCampaign);
|
||||
}
|
||||
|
||||
@ -367,7 +368,7 @@ void CMainMenu::openCampaignScreen(std::string name)
|
||||
{
|
||||
if(vstd::contains(CMainMenuConfig::get().getCampaigns().Struct(), name))
|
||||
{
|
||||
GH.windows().createAndPushWindow<CCampaignScreen>(CMainMenuConfig::get().getCampaigns()[name]);
|
||||
GH.windows().createAndPushWindow<CCampaignScreen>(CMainMenuConfig::get().getCampaigns(), name);
|
||||
return;
|
||||
}
|
||||
logGlobal->error("Unknown campaign set: %s", name);
|
||||
|
@ -149,7 +149,7 @@ public:
|
||||
void onScreenResize() override;
|
||||
void update() override;
|
||||
static void openLobby(ESelectionScreen screenType, bool host, const std::vector<std::string> * names, ELoadMode loadMode);
|
||||
static void openCampaignLobby(const std::string & campaignFileName);
|
||||
static void openCampaignLobby(const std::string & campaignFileName, std::string campaignSet = "");
|
||||
static void openCampaignLobby(std::shared_ptr<CampaignState> campaign);
|
||||
static void startTutorial();
|
||||
void openCampaignScreen(std::string name);
|
||||
|
@ -5,13 +5,13 @@
|
||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN" },
|
||||
"items":
|
||||
[
|
||||
{ "x":90, "y":72, "file":"DATA/GOOD1.H3C", "image":"CAMPGD1S", "video":"CGOOD1", "open": true },
|
||||
{ "x":539, "y":72, "file":"DATA/EVIL1.H3C", "image":"CAMPEV1S", "video":"CEVIL1", "open": true },
|
||||
{ "x":43, "y":245, "file":"DATA/GOOD2.H3C", "image":"CAMPGD2S", "video":"CGOOD2", "open": true },
|
||||
{ "x":313, "y":244, "file":"DATA/NEUTRAL1.H3C", "image":"CAMPNEUS", "video":"CNEUTRAL", "open": true },
|
||||
{ "x":586, "y":246, "file":"DATA/EVIL2.H3C", "image":"CAMPEV2S", "video":"CEVIL2", "open": true },
|
||||
{ "x":34, "y":417, "file":"DATA/GOOD3.H3C", "image":"CAMPGD3S", "video":"CGOOD3", "open": true },
|
||||
{ "x":404, "y":414, "file":"DATA/SECRET1.H3C", "image":"CAMPSCTS", "video":"CSECRET", "open": true }
|
||||
{ "id": 1, "x":90, "y":72, "file":"DATA/GOOD1", "image":"CAMPGD1S", "video":"CGOOD1", "requires": [] },
|
||||
{ "id": 2, "x":539, "y":72, "file":"DATA/EVIL1", "image":"CAMPEV1S", "video":"CEVIL1", "requires": [] },
|
||||
{ "id": 3, "x":43, "y":245, "file":"DATA/GOOD2", "image":"CAMPGD2S", "video":"CGOOD2", "requires": [1, 2, 4] },
|
||||
{ "id": 4, "x":313, "y":244, "file":"DATA/NEUTRAL1", "image":"CAMPNEUS", "video":"CNEUTRAL", "requires": [] },
|
||||
{ "id": 5, "x":586, "y":246, "file":"DATA/EVIL2", "image":"CAMPEV2S", "video":"CEVIL2", "requires": [1, 2, 4] },
|
||||
{ "id": 6, "x":34, "y":417, "file":"DATA/GOOD3", "image":"CAMPGD3S", "video":"CGOOD3", "requires": [3, 5] },
|
||||
{ "id": 7, "x":404, "y":414, "file":"DATA/SECRET1", "image":"CAMPSCTS", "video":"CSECRET", "requires": [6] }
|
||||
]
|
||||
},
|
||||
"ab" :
|
||||
@ -25,12 +25,12 @@
|
||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN" },
|
||||
"items":
|
||||
[
|
||||
{ "x":90, "y":72, "file":"DATA/AB.H3C", "image":"CAMP1AB7", "video":"C1ab7", "open": true },
|
||||
{ "x":539, "y":72, "file":"DATA/BLOOD.H3C", "image":"CAMP1DB2", "video":"C1db2", "open": true },
|
||||
{ "x":43, "y":245, "file":"DATA/SLAYER.H3C", "image":"CAMP1DS1", "video":"C1ds1", "open": true },
|
||||
{ "x":313, "y":244, "file":"DATA/FESTIVAL.H3C", "image":"CAMP1FL3", "video":"C1fl3", "open": true },
|
||||
{ "x":586, "y":246, "file":"DATA/FIRE.H3C", "image":"CAMP1PF2", "video":"C1pf2", "open": true },
|
||||
{ "x":34, "y":417, "file":"DATA/FOOL.H3C", "image":"CAMP1FW1", "video":"C1fw1", "open": true }
|
||||
{ "id": 1, "x":90, "y":72, "file":"DATA/AB", "image":"CAMP1AB7", "video":"C1ab7", "requires": [] },
|
||||
{ "id": 2, "x":539, "y":72, "file":"DATA/BLOOD", "image":"CAMP1DB2", "video":"C1db2", "requires": [] },
|
||||
{ "id": 3, "x":43, "y":245, "file":"DATA/SLAYER", "image":"CAMP1DS1", "video":"C1ds1", "requires": [] },
|
||||
{ "id": 4, "x":313, "y":244, "file":"DATA/FESTIVAL", "image":"CAMP1FL3", "video":"C1fl3", "requires": [] },
|
||||
{ "id": 5, "x":586, "y":246, "file":"DATA/FIRE", "image":"CAMP1PF2", "video":"C1pf2", "requires": [] },
|
||||
{ "id": 6, "x":34, "y":417, "file":"DATA/FOOL", "image":"CAMP1FW1", "video":"C1fw1", "requires": [1, 2, 3, 4, 5] }
|
||||
]
|
||||
},
|
||||
"sod":
|
||||
@ -39,26 +39,13 @@
|
||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN" },
|
||||
"items":
|
||||
[
|
||||
{ "x":90, "y":72, "file":"DATA/GEM.H3C", "image":"CAMPNB1", "video":"NEW", "open": true },
|
||||
{ "x":539, "y":72, "file":"DATA/GELU.H3C", "image":"CAMPEL1", "video":"ELIXIR", "open": true },
|
||||
{ "x":43, "y":245, "file":"DATA/CRAG.H3C", "image":"CAMPHS1", "video":"HACK", "open": true },
|
||||
{ "x":313, "y":244, "file":"DATA/SANDRO.H3C", "image":"CAMPRN1", "video":"RISE", "open": true },
|
||||
{ "x":586, "y":246, "file":"DATA/YOG.H3C", "image":"CAMPBB1", "video":"BIRTH", "open": true },
|
||||
{ "x":34, "y":417, "file":"DATA/FINAL.H3C", "image":"CAMPUA1", "video":"UNHOLY", "open": true },
|
||||
{ "x":404, "y":414, "file":"DATA/SECRET.H3C", "image":"CAMPSP1", "video":"SPECTRE", "open": true }
|
||||
{ "id": 1, "x":90, "y":72, "file":"DATA/GEM", "image":"CAMPNB1", "video":"NEW", "requires": [] },
|
||||
{ "id": 2, "x":539, "y":72, "file":"DATA/GELU", "image":"CAMPEL1", "video":"ELIXIR", "requires": [] },
|
||||
{ "id": 3, "x":43, "y":245, "file":"DATA/CRAG", "image":"CAMPHS1", "video":"HACK", "requires": [] },
|
||||
{ "id": 4, "x":313, "y":244, "file":"DATA/SANDRO", "image":"CAMPRN1", "video":"RISE", "requires": [1, 2, 3, 5] },
|
||||
{ "id": 5, "x":586, "y":246, "file":"DATA/YOG", "image":"CAMPBB1", "video":"BIRTH", "requires": [] },
|
||||
{ "id": 6, "x":34, "y":417, "file":"DATA/FINAL", "image":"CAMPUA1", "video":"UNHOLY", "requires": [4] },
|
||||
{ "id": 7, "x":404, "y":414, "file":"DATA/SECRET", "image":"CAMPSP1", "video":"SPECTRE", "requires": [6] }
|
||||
]
|
||||
}
|
||||
// "wog" :
|
||||
// {
|
||||
// /// wog campaigns, currently has no assigned button in campaign screen and thus unused
|
||||
// "images" : [ {"x": 0, "y": 0, "name":"CAMPZALL"} ],
|
||||
// "exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
||||
// "items":
|
||||
// [
|
||||
// { "x":90, "y":72, "file":"DATA/ZC1.H3C", "image":"CAMPZ01", "open": true},
|
||||
// { "x":539, "y":72, "file":"DATA/ZC2.H3C", "image":"CAMPZ02", "open": true},
|
||||
// { "x":43, "y":245, "file":"DATA/ZC3.H3C", "image":"CAMPZ03", "open": true},
|
||||
// { "x":311, "y":242, "file":"DATA/ZC4.H3C", "image":"CAMPZ04", "open": true}
|
||||
// ]
|
||||
// }
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ void MainWindow::load()
|
||||
QDir::addSearchPath("icons", pathToQString(VCMIDirs::get().userDataPath() / "launcher" / "icons"));
|
||||
#endif
|
||||
|
||||
settings.init();
|
||||
settings.init("config/settings.json", "vcmi:settings");
|
||||
}
|
||||
|
||||
void MainWindow::computeSidePanelSizes()
|
||||
|
@ -17,6 +17,7 @@
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
SettingsStorage settings;
|
||||
SettingsStorage persistentStorage;
|
||||
|
||||
template<typename Accessor>
|
||||
SettingsStorage::NodeAccessor<Accessor>::NodeAccessor(SettingsStorage & _parent, std::vector<std::string> _path):
|
||||
@ -53,18 +54,24 @@ SettingsStorage::SettingsStorage():
|
||||
{
|
||||
}
|
||||
|
||||
void SettingsStorage::init()
|
||||
void SettingsStorage::init(const std::string & dataFilename, const std::string & schema)
|
||||
{
|
||||
JsonPath confName = JsonPath::builtin("config/settings.json");
|
||||
this->dataFilename = dataFilename;
|
||||
this->schema = schema;
|
||||
|
||||
JsonPath confName = JsonPath::builtin(dataFilename);
|
||||
|
||||
JsonUtils::assembleFromFiles(confName.getOriginalName()).swap(config);
|
||||
|
||||
// Probably new install. Create config file to save settings to
|
||||
if (!CResourceHandler::get("local")->existsResource(confName))
|
||||
CResourceHandler::get("local")->createResource("config/settings.json");
|
||||
CResourceHandler::get("local")->createResource(dataFilename);
|
||||
|
||||
JsonUtils::maximize(config, "vcmi:settings");
|
||||
JsonUtils::validate(config, "vcmi:settings", "settings");
|
||||
if(!schema.empty())
|
||||
{
|
||||
JsonUtils::maximize(config, schema);
|
||||
JsonUtils::validate(config, schema, "settings");
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsStorage::invalidateNode(const std::vector<std::string> &changedPath)
|
||||
@ -74,9 +81,10 @@ void SettingsStorage::invalidateNode(const std::vector<std::string> &changedPath
|
||||
|
||||
JsonNode savedConf = config;
|
||||
savedConf.Struct().erase("session");
|
||||
JsonUtils::minimize(savedConf, "vcmi:settings");
|
||||
if(!schema.empty())
|
||||
JsonUtils::minimize(savedConf, schema);
|
||||
|
||||
std::fstream file(CResourceHandler::get()->getResourceName(JsonPath::builtin("config/settings.json"))->c_str(), std::ofstream::out | std::ofstream::trunc);
|
||||
std::fstream file(CResourceHandler::get()->getResourceName(JsonPath::builtin(dataFilename))->c_str(), std::ofstream::out | std::ofstream::trunc);
|
||||
file << savedConf.toJson();
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,9 @@ class DLL_LINKAGE SettingsStorage
|
||||
std::set<SettingsListener*> listeners;
|
||||
JsonNode config;
|
||||
|
||||
std::string dataFilename;
|
||||
std::string schema;
|
||||
|
||||
JsonNode & getNode(const std::vector<std::string> & path);
|
||||
|
||||
// Calls all required listeners
|
||||
@ -45,7 +48,7 @@ class DLL_LINKAGE SettingsStorage
|
||||
public:
|
||||
// Initialize config structure
|
||||
SettingsStorage();
|
||||
void init();
|
||||
void init(const std::string & dataFilename, const std::string & schema);
|
||||
|
||||
// Get write access to config node at path
|
||||
const NodeAccessor<Settings> write;
|
||||
@ -113,5 +116,6 @@ public:
|
||||
};
|
||||
|
||||
extern DLL_LINKAGE SettingsStorage settings;
|
||||
extern DLL_LINKAGE SettingsStorage persistentStorage;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -52,7 +52,8 @@ DLL_LINKAGE void preinitDLL(CConsoleHandler * Console, bool onlyEssential, bool
|
||||
console = Console;
|
||||
VLC = new LibClasses();
|
||||
VLC->loadFilesystem(extractArchives);
|
||||
settings.init();
|
||||
settings.init("config/settings.json", "vcmi:settings");
|
||||
persistentStorage.init("config/persistentStorage.json", "");
|
||||
VLC->loadModFilesystem(onlyEssential);
|
||||
|
||||
}
|
||||
|
@ -293,6 +293,8 @@ public:
|
||||
static JsonNode crossoverSerialize(CGHeroInstance * hero);
|
||||
static CGHeroInstance * crossoverDeserialize(const JsonNode & node, CMap * map);
|
||||
|
||||
std::string campaignSet;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<Campaign&>(*this);
|
||||
@ -302,6 +304,7 @@ public:
|
||||
h & mapsConquered;
|
||||
h & currentMap;
|
||||
h & chosenCampaignBonuses;
|
||||
h & campaignSet;
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user