A feature flag denotes whether a scenario uses the new or old format for its metadata. With the old format (legacy scenarios and openBoE scenarios created prior to this PR) everything displays in the scenario picker as before, and scenario designers get 2 text fields to display however they want, and 2 text fields that are pretty much useless.
With the new format, Author and Contact info are formatted onto the first line in the scenario picker display. The scenario designer gets 1 line to write a teaser. Fix #593 Also fix a bug where scenario ratings were appearing as integers ingame instead of the correct "G", "PG", etc.
This commit is contained in:
@@ -271,7 +271,7 @@ bool load_scenario_v1(fs::path file_to_load, cScenario& scenario, bool only_head
|
||||
temp_str[len] = 0;
|
||||
if(i == 0) scenario.scen_name = temp_str;
|
||||
else if(i == 1 || i == 2)
|
||||
scenario.who_wrote[i-1] = temp_str;
|
||||
scenario.teaser_text[i-1] = temp_str;
|
||||
else if(i == 3)
|
||||
scenario.contact_info[1] = temp_str;
|
||||
else if(i >= 4 && i < 10)
|
||||
@@ -781,7 +781,7 @@ void readScenarioFromXml(ticpp::Document&& data, cScenario& scenario) {
|
||||
if(type == "teaser") {
|
||||
if(found_teasers >= 2)
|
||||
throw xBadNode(type,info->Row(),info->Column(),fname);
|
||||
info->GetText(&scenario.who_wrote[found_teasers], false);
|
||||
info->GetText(&scenario.teaser_text[found_teasers], false);
|
||||
found_teasers++;
|
||||
} else if(type == "icon") {
|
||||
info->GetText(&scenario.intro_mess_pic);
|
||||
|
@@ -1580,8 +1580,8 @@ class cChooseScenario {
|
||||
sout << '.' << int(scen_headers[page * 3 + i].ver[2]);
|
||||
sout << " - | Difficulty: " << difficulty[scen_headers[page * 3 + i].difficulty];
|
||||
sout << ", Rating: " << scen_headers[page * 3 + i].rating;
|
||||
sout << " |" << scen_headers[page * 3 + i].who1;
|
||||
sout << " |" << scen_headers[page * 3 + i].who2;
|
||||
sout << " |" << scen_headers[page * 3 + i].teaser1;
|
||||
sout << " |" << scen_headers[page * 3 + i].teaser2;
|
||||
me["desc" + n].setText(sout.str());
|
||||
me["start" + n].show();
|
||||
} else {
|
||||
|
@@ -357,11 +357,12 @@ std::vector<scen_header_type> build_scen_headers() {
|
||||
scen_headers.push_back(scen_head);
|
||||
}else{
|
||||
scen_header_type missing_scen;
|
||||
missing_scen.intro_pic = missing_scen.rating = missing_scen.difficulty = 0;
|
||||
missing_scen.intro_pic = missing_scen.difficulty = 0;
|
||||
missing_scen.rating = eContentRating::G;
|
||||
for(int i=0; i<3; ++i)
|
||||
missing_scen.ver[i] = missing_scen.prog_make_ver[i] = 0;
|
||||
missing_scen.name = scen_file;
|
||||
missing_scen.who1 = missing_scen.who2 = missing_scen.file = "";
|
||||
missing_scen.teaser1 = missing_scen.teaser2 = missing_scen.file = "";
|
||||
scen_headers.push_back(missing_scen);
|
||||
}
|
||||
}
|
||||
@@ -446,8 +447,26 @@ bool load_scenario_header(fs::path file,scen_header_type& scen_head){
|
||||
return false;
|
||||
|
||||
scen_head.name = temp_scenario.scen_name;
|
||||
scen_head.who1 = temp_scenario.who_wrote[0];
|
||||
scen_head.who2 = temp_scenario.who_wrote[1];
|
||||
// Legacy scenario meta display: Teaser 1/2 are mixed with credits, other fields hidden.
|
||||
if(!temp_scenario.has_feature_flag("scenario-meta-format")){
|
||||
scen_head.teaser1 = temp_scenario.teaser_text[0];
|
||||
scen_head.teaser2 = temp_scenario.teaser_text[1];
|
||||
}
|
||||
// V2 meta display: By {Author}, Contact: {Contact}|{Teaser!}
|
||||
else{
|
||||
if(!temp_scenario.contact_info[0].empty()){
|
||||
scen_head.teaser1 = "By " + temp_scenario.contact_info[0];
|
||||
}
|
||||
if(!temp_scenario.contact_info[1].empty()){
|
||||
if(!scen_head.teaser1.empty()) scen_head.teaser1 += ", ";
|
||||
|
||||
scen_head.teaser1 += "Contact: " + temp_scenario.contact_info[1];
|
||||
}
|
||||
if(scen_head.teaser1.empty())
|
||||
scen_head.teaser1 = temp_scenario.teaser_text[0];
|
||||
else
|
||||
scen_head.teaser2 = temp_scenario.teaser_text[0];
|
||||
}
|
||||
scen_head.file = fname == "header.exs" ? file.parent_path().filename().string() : fname;
|
||||
scen_head.intro_pic = temp_scenario.intro_pic;
|
||||
scen_head.rating = temp_scenario.rating;
|
||||
|
@@ -20,8 +20,10 @@ const int NUM_FACE_G = 80;
|
||||
const int NUM_DLOG_G = 28;
|
||||
|
||||
struct scen_header_type{
|
||||
int intro_pic, rating, difficulty, ver[3], prog_make_ver[3];
|
||||
std::string name, who1, who2, file;
|
||||
int intro_pic;
|
||||
eContentRating rating;
|
||||
int difficulty, ver[3], prog_make_ver[3];
|
||||
std::string name, teaser1, teaser2, file;
|
||||
};
|
||||
|
||||
struct effect_pat_type {
|
||||
|
@@ -78,10 +78,10 @@ cScenario::cScenario() {
|
||||
scenario_timers[i].node = -1;
|
||||
}
|
||||
scen_name = "Scen name";
|
||||
who_wrote[0] = "Who wrote 1";
|
||||
who_wrote[1] = "Who wrote 2";
|
||||
contact_info[0] = "Name not given";
|
||||
contact_info[1] = "Contact info";
|
||||
teaser_text[0] = "An exciting adventure!";
|
||||
teaser_text[1] = "";
|
||||
contact_info[0] = "Author";
|
||||
contact_info[1] = "";
|
||||
}
|
||||
|
||||
cScenario::cScenario(const cScenario& other)
|
||||
@@ -131,8 +131,8 @@ cScenario::cScenario(const cScenario& other)
|
||||
, outdoors(other.outdoors.width(), other.outdoors.height())
|
||||
{
|
||||
// MSVC 12 doesn't like arrays in the initializer list. :(
|
||||
who_wrote[0] = other.who_wrote[0];
|
||||
who_wrote[1] = other.who_wrote[1];
|
||||
teaser_text[0] = other.teaser_text[0];
|
||||
teaser_text[1] = other.teaser_text[1];
|
||||
contact_info[0] = other.contact_info[0];
|
||||
contact_info[1] = other.contact_info[1];
|
||||
// Copy towns and sectors
|
||||
@@ -189,8 +189,8 @@ void swap(cScenario& lhs, cScenario& rhs) {
|
||||
swap(lhs.campaign_id, rhs.campaign_id);
|
||||
swap(lhs.scen_items, rhs.scen_items);
|
||||
swap(lhs.scen_name, rhs.scen_name);
|
||||
swap(lhs.who_wrote[0], rhs.who_wrote[0]);
|
||||
swap(lhs.who_wrote[1], rhs.who_wrote[1]);
|
||||
swap(lhs.teaser_text[0], rhs.teaser_text[0]);
|
||||
swap(lhs.teaser_text[1], rhs.teaser_text[1]);
|
||||
swap(lhs.contact_info[0], rhs.contact_info[0]);
|
||||
swap(lhs.contact_info[1], rhs.contact_info[1]);
|
||||
swap(lhs.intro_strs, rhs.intro_strs);
|
||||
|
@@ -92,8 +92,10 @@ public:
|
||||
std::string campaign_id; // A hopefully unique identifier to specify the campaign this scenario is a part of.
|
||||
std::vector<cItem> scen_items;
|
||||
std::string scen_name;
|
||||
std::string who_wrote[2];
|
||||
|
||||
std::string teaser_text[2];
|
||||
std::string contact_info[2];
|
||||
|
||||
std::array<std::string, 6> intro_strs;
|
||||
std::vector<std::string> journal_strs;
|
||||
std::vector<std::string> spec_strs;
|
||||
|
@@ -2796,12 +2796,45 @@ static bool save_scen_details(cDialog& me, std::string, eKeyMod) {
|
||||
case '4': scenario.rating = eContentRating::NC17; break;
|
||||
}
|
||||
}
|
||||
scenario.adjust_diff = dynamic_cast<cLed&>(me["adjust"]).getState() != led_red;
|
||||
scenario.scen_name = me["title"].getText();
|
||||
for(short i = 0; i < 3; i++)
|
||||
scenario.format.ver[i] = me["ver" + std::to_string(i + 1)].getTextAsNum();
|
||||
scenario.who_wrote[0] = me["who1"].getText().substr(0, 100);
|
||||
scenario.who_wrote[1] = me["who2"].getText().substr(0, 100);
|
||||
scenario.contact_info[1] = me["contact"].getText().substr(0, 256);
|
||||
scenario.teaser_text[0] = me["teaser1"].getText();
|
||||
scenario.teaser_text[1] = me["teaser2"].getText();
|
||||
scenario.contact_info[0] = me["author"].getText();
|
||||
scenario.contact_info[1] = me["contact"].getText();
|
||||
return true;
|
||||
}
|
||||
|
||||
static void put_scen_details_in_dlog(cDialog& me) {
|
||||
me["title"].setText(scenario.scen_name);
|
||||
dynamic_cast<cLedGroup&>(me["difficulty"]).setSelected("lvl" + std::to_string(scenario.difficulty + 1));
|
||||
dynamic_cast<cLedGroup&>(me["rating"]).setSelected("rate" + std::to_string(scenario.rating + 1));
|
||||
for(int i = 0; i < 3; i++)
|
||||
me["ver" + std::to_string(i + 1)].setTextToNum(scenario.format.ver[i]);
|
||||
// Legacy meta text labels:
|
||||
if(!scenario.has_feature_flag("scenario-meta-format")){
|
||||
me["teaser1-text"].setText("Credits/Teaser Part 1:");
|
||||
me["teaser2-text"].setText("Credits/Teaser Part 2:");
|
||||
me["author-text"].setText("Author|(not displayed):");
|
||||
me["contact-text"].setText("Contact info|(not displayed):");
|
||||
}else{
|
||||
// Updated meta text labels:
|
||||
me["teaser2-text"].hide();
|
||||
me["teaser2"].hide();
|
||||
}
|
||||
|
||||
me["teaser1"].setText(scenario.teaser_text[0]);
|
||||
me["teaser2"].setText(scenario.teaser_text[1]);
|
||||
me["author"].setText(scenario.contact_info[0]);
|
||||
me["contact"].setText(scenario.contact_info[1]);
|
||||
}
|
||||
|
||||
static bool save_scen_adv_details(cDialog& me, std::string, eKeyMod) {
|
||||
if(!me.toast(true)) return true;
|
||||
|
||||
scenario.adjust_diff = dynamic_cast<cLed&>(me["adjust"]).getState() != led_red;
|
||||
|
||||
scenario.campaign_id = me["cpnid"].getText();
|
||||
scenario.bg_out = boost::lexical_cast<int>(me["bg-out"].getText().substr(10));
|
||||
scenario.bg_town = boost::lexical_cast<int>(me["bg-town"].getText().substr(10));
|
||||
@@ -2811,15 +2844,9 @@ static bool save_scen_details(cDialog& me, std::string, eKeyMod) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void put_scen_details_in_dlog(cDialog& me) {
|
||||
dynamic_cast<cLedGroup&>(me["difficulty"]).setSelected("lvl" + std::to_string(scenario.difficulty + 1));
|
||||
dynamic_cast<cLedGroup&>(me["rating"]).setSelected("rate" + std::to_string(scenario.rating + 1));
|
||||
|
||||
static void put_scen_adv_details_in_dlog(cDialog& me) {
|
||||
dynamic_cast<cLed&>(me["adjust"]).setState(scenario.adjust_diff ? led_red : led_off);
|
||||
for(int i = 0; i < 3; i++)
|
||||
me["ver" + std::to_string(i + 1)].setTextToNum(scenario.format.ver[i]);
|
||||
me["who1"].setText(scenario.who_wrote[0]);
|
||||
me["who2"].setText(scenario.who_wrote[1]);
|
||||
me["contact"].setText(scenario.contact_info[1]);
|
||||
me["cpnid"].setText(scenario.campaign_id);
|
||||
me["bg-out"].setText("Outdoors: " + std::to_string(scenario.bg_out));
|
||||
me["bg-town"].setText("In towns: " + std::to_string(scenario.bg_town));
|
||||
@@ -2863,14 +2890,22 @@ static bool edit_scen_default_bgs(cDialog& me, std::string which, eKeyMod) {
|
||||
void edit_scen_details() {
|
||||
cDialog info_dlg(*ResMgr::dialogs.get("edit-scenario-details"));
|
||||
info_dlg["okay"].attachClickHandler(save_scen_details);
|
||||
info_dlg.attachClickHandlers(edit_scen_default_bgs, {"bg-out", "bg-town", "bg-dungeon", "bg-fight"});
|
||||
info_dlg["pickinit"].attachClickHandler(edit_scen_init_spec);
|
||||
|
||||
put_scen_details_in_dlog(info_dlg);
|
||||
|
||||
info_dlg.run();
|
||||
}
|
||||
|
||||
void edit_scen_adv_details() {
|
||||
cDialog info_dlg(*ResMgr::dialogs.get("edit-scenario-advanced"));
|
||||
info_dlg["okay"].attachClickHandler(save_scen_adv_details);
|
||||
info_dlg.attachClickHandlers(edit_scen_default_bgs, {"bg-out", "bg-town", "bg-dungeon", "bg-fight"});
|
||||
info_dlg["pickinit"].attachClickHandler(edit_scen_init_spec);
|
||||
|
||||
put_scen_adv_details_in_dlog(info_dlg);
|
||||
info_dlg.run();
|
||||
}
|
||||
|
||||
bool edit_make_scen_1(std::string& author,std::string& title,bool& grass) {
|
||||
cDialog new_dlog(*ResMgr::dialogs.get("make-scenario1"));
|
||||
new_dlog["okay"].attachClickHandler(std::bind(&cDialog::toast, &new_dlog, true));
|
||||
@@ -2960,7 +2995,9 @@ bool build_scenario() {
|
||||
scenario.contact_info[0] = author;
|
||||
scenario.default_ground = grass ? 2 : 0;
|
||||
|
||||
scenario.feature_flags = {};
|
||||
scenario.feature_flags = {
|
||||
{"scenario-meta-format", "V2"}
|
||||
};
|
||||
|
||||
fs::path basePath = progDir/"Blades of Exile Base"/"bladbase.boes";
|
||||
if(!fs::exists(basePath)) {
|
||||
|
@@ -16,6 +16,7 @@ void edit_save_rects();
|
||||
void edit_add_town();
|
||||
void edit_item_placement();
|
||||
void edit_scen_details();
|
||||
void edit_scen_adv_details();
|
||||
bool edit_make_scen_2(short& out_w, short& out_h, short& town_l, short& town_m, short& town_s, bool& def_town);
|
||||
bool edit_make_scen_1(std::string& filename,std::string& title,bool& grass);
|
||||
void edit_scenario_events();
|
||||
|
@@ -139,8 +139,8 @@ void writeScenarioToXml(ticpp::Printer&& data, cScenario& scenario) {
|
||||
}
|
||||
data.CloseElement("feature-flags");
|
||||
data.OpenElement("text");
|
||||
data.PushElement("teaser", scenario.who_wrote[0]);
|
||||
data.PushElement("teaser", scenario.who_wrote[1]);
|
||||
data.PushElement("teaser", scenario.teaser_text[0]);
|
||||
data.PushElement("teaser", scenario.teaser_text[1]);
|
||||
if(scenario.intro_pic != scenario.intro_mess_pic)
|
||||
data.PushElement("icon", scenario.intro_mess_pic);
|
||||
{
|
||||
@@ -1209,8 +1209,8 @@ void scen_text_dump(){
|
||||
std::ofstream fout((scenario.scen_file.parent_path()/(scenario.scen_name + " Text.txt")).string().c_str());
|
||||
fout << "Scenario text for " << scenario.scen_name << ':' << endl << endl;
|
||||
fout << "Scenario Text:" << endl;
|
||||
fout << "Who Wrote 1: " << scenario.who_wrote[0] << endl;
|
||||
fout << "Who Wrote 2: " << scenario.who_wrote[1] << endl;
|
||||
fout << "Teaser 1: " << scenario.teaser_text[0] << endl;
|
||||
fout << "Teaser 2: " << scenario.teaser_text[1] << endl;
|
||||
fout << "Contact Info: " << scenario.contact_info[0] << " " << scenario.contact_info[1] << endl;
|
||||
for(short i = 0; i < scenario.intro_strs.size(); i++)
|
||||
if(scenario.intro_strs[i][0] != '*')
|
||||
|
@@ -553,6 +553,10 @@ void handle_menu_choice(eMenu item_hit) {
|
||||
edit_scen_details();
|
||||
change_made = true;
|
||||
break;
|
||||
case eMenu::SCEN_ADV_DETAILS:
|
||||
edit_scen_adv_details();
|
||||
change_made = true;
|
||||
break;
|
||||
case eMenu::SCEN_INTRO:
|
||||
edit_scen_intro();
|
||||
change_made = true;
|
||||
|
@@ -59,6 +59,7 @@ void OpenBoESceneditMenu::add_persistent_menu_items(tgui::MenuBar::Ptr& menubar)
|
||||
{ { "Scenario", "Advanced", "Edit Special Nodes" }, eMenu::SCEN_SPECIALS },
|
||||
{ { "Scenario", "Advanced", "Edit Scenario Text" }, eMenu::SCEN_TEXT },
|
||||
{ { "Scenario", "Advanced", "Edit Journal Entries" }, eMenu::SCEN_JOURNALS },
|
||||
{ { "Scenario", "Advanced", "Advanced Scenario Details" }, eMenu::SCEN_ADV_DETAILS },
|
||||
{ { "Scenario", "Advanced", "Import Town" }, eMenu::TOWN_IMPORT },
|
||||
{ { "Scenario", "Advanced", "Import Outdoor Sector" }, eMenu::OUT_IMPORT },
|
||||
{ { "Scenario", "Advanced", "Edit Saved Item Rectangles" }, eMenu::SCEN_SAVE_ITEM_RECTS },
|
||||
|
@@ -19,7 +19,8 @@ enum class eMenu {
|
||||
EDIT_UNDO, EDIT_REDO, EDIT_CUT, EDIT_COPY, EDIT_PASTE, EDIT_DELETE, EDIT_SELECT_ALL,
|
||||
HELP_TOC, HELP_START, HELP_TEST, HELP_DIST, HELP_CONTEST,
|
||||
// Scenario menu
|
||||
LAUNCH_HERE, LAUNCH_START, LAUNCH_ENTRANCE, TOWN_CREATE, OUT_RESIZE, SCEN_DETAILS, SCEN_INTRO, TOWN_START,
|
||||
LAUNCH_HERE, LAUNCH_START, LAUNCH_ENTRANCE, TOWN_CREATE, OUT_RESIZE,
|
||||
SCEN_DETAILS, SCEN_ADV_DETAILS, SCEN_INTRO, TOWN_START,
|
||||
SCEN_SPECIALS, SCEN_TEXT, SCEN_JOURNALS, TOWN_IMPORT, OUT_IMPORT,
|
||||
SCEN_SAVE_ITEM_RECTS,
|
||||
TOWN_VARYING, SCEN_TIMERS, SCEN_ITEM_SHORTCUTS, TOWN_DELETE,
|
||||
|
@@ -59,7 +59,7 @@ void init_menubar() {
|
||||
eMenu::LAUNCH_HERE, eMenu::LAUNCH_START, eMenu::LAUNCH_ENTRANCE, eMenu::NONE,
|
||||
eMenu::TOWN_CREATE, eMenu::OUT_RESIZE, eMenu::NONE,
|
||||
eMenu::SCEN_DETAILS, eMenu::SCEN_INTRO, eMenu::SCEN_SHEETS, eMenu::SCEN_PICS, eMenu::SCEN_SNDS, eMenu::NONE, eMenu::NONE,
|
||||
eMenu::SCEN_SPECIALS, eMenu::SCEN_TEXT, eMenu::SCEN_JOURNALS, eMenu::TOWN_IMPORT, eMenu::OUT_IMPORT, eMenu::SCEN_SAVE_ITEM_RECTS,
|
||||
eMenu::SCEN_SPECIALS, eMenu::SCEN_TEXT, eMenu::SCEN_JOURNALS, eMenu::SCEN_ADV_DETAILS, eMenu::TOWN_IMPORT, eMenu::OUT_IMPORT, eMenu::SCEN_SAVE_ITEM_RECTS,
|
||||
eMenu::TOWN_VARYING, eMenu::SCEN_TIMERS, eMenu::SCEN_ITEM_SHORTCUTS,
|
||||
eMenu::TOWN_DELETE, eMenu::SCEN_DATA_DUMP, eMenu::SCEN_TEXT_DUMP,
|
||||
};
|
||||
|
@@ -79,7 +79,8 @@ void init_menubar() {
|
||||
eMenu::LAUNCH_HERE, eMenu::LAUNCH_START, eMenu::LAUNCH_ENTRANCE, eMenu::NONE,
|
||||
eMenu::TOWN_CREATE, eMenu::OUT_RESIZE, eMenu::NONE,
|
||||
eMenu::SCEN_DETAILS, eMenu::SCEN_INTRO, eMenu::SCEN_SHEETS, eMenu::SCEN_PICS, eMenu::SCEN_SNDS, eMenu::NONE, eMenu::NONE,
|
||||
eMenu::SCEN_SPECIALS, eMenu::SCEN_TEXT, eMenu::SCEN_JOURNALS, eMenu::TOWN_IMPORT, eMenu::OUT_IMPORT, eMenu::SCEN_SAVE_ITEM_RECTS,
|
||||
eMenu::SCEN_SPECIALS, eMenu::SCEN_TEXT, eMenu::SCEN_JOURNALS, eMenu::SCEN_ADV_DETAILS,
|
||||
eMenu::TOWN_IMPORT, eMenu::OUT_IMPORT, eMenu::SCEN_SAVE_ITEM_RECTS,
|
||||
eMenu::TOWN_VARYING, eMenu::SCEN_TIMERS, eMenu::SCEN_ITEM_SHORTCUTS,
|
||||
eMenu::TOWN_DELETE, eMenu::SCEN_DATA_DUMP, eMenu::SCEN_TEXT_DUMP,
|
||||
};
|
||||
|
Reference in New Issue
Block a user