Skip to content

Commit

Permalink
A feature flag denotes whether a scenario uses the new or old format …
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
NQNStudios authored and CelticMinstrel committed Mar 2, 2025
1 parent 0f4b112 commit 0afed5d
Show file tree
Hide file tree
Showing 22 changed files with 195 additions and 83 deletions.
35 changes: 35 additions & 0 deletions rsrc/dialogs/edit-scenario-advanced.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!-- NOTE: This file should be updated to use relative positioning the next time it changes. -->
<?xml-stylesheet href="dialog.xsl" type="text/xsl"?>
<dialog defbtn='okay'>
<pict type='dlog' num='16' top='8' left='8'/>
<text size='large' top='6' left='50' width='256' height='17'>Scenario Advanced Details</text>

<text top='23' left='50' width='372' height='20'>
You can use this window to edit some of the more esoteric details for your scenario.
</text>

<led name='adjust' top='56' left='50' size='small'>Adjust difficulty if played by a party stronger than recommended</led>

<text top='79' left='50' width='120' height='14'>Special on Start:</text>
<field name='oninit' top='78' left='181' width='100' height='16'/>
<button name='pickinit' type='large' top='74' left='290'>Create/Edit</button>

<text top='107' left='50' width='120' height='14'>Campaign ID:</text>
<field name='cpnid' top='106' left='181' width='100' height='16'/>
<text top='130' left='50' width='400' height='44'>
If your scenario is part of a campaign of several scenarios,
the ID specified here makes it easy to carry information from one scenario to the next.
It should be the same in each scenario in the series.
</text>

<text top='184' left='50' width='120' height='60'>Default backgrounds:<br/>
Set the default patterns to be shown behind the game screen.
</text>
<button name='bg-out' type='tiny' top='184' left='180'>Outdoors:</button>
<button name='bg-town' type='tiny' top='201' left='180'>In towns:</button>
<button name='bg-dungeon' type='tiny' top='218' left='180'>In dungeons:</button>
<button name='bg-fight' type='tiny' top='235' left='180'>In combat:</button>

<button name='okay' type='regular' top='304' left='395'>OK</button>
</dialog>
55 changes: 24 additions & 31 deletions rsrc/dialogs/edit-scenario-details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,39 @@
<!-- NOTE: This file should be updated to use relative positioning the next time it changes. -->
<?xml-stylesheet href="dialog.xsl" type="text/xsl"?>
<dialog defbtn='okay'>
<field name='ver1' type='uint' top='80' left='181' width='43' height='16'/>
<field name='ver2' type='uint' top='80' left='234' width='43' height='16'/>
<field name='ver3' type='uint' top='80' left='287' width='43' height='16'/>
<field name='who1' top='104' left='181' width='243' height='47'/>
<field name='who2' top='159' left='181' width='243' height='47'/>
<field name='contact' top='214' left='181' width='243' height='65'/>
<button name='okay' type='regular' top='528' left='395'>OK</button>
<pict type='dlog' num='16' top='8' left='8'/>
<text size='large' top='6' left='50' width='256' height='17'>Scenario Details</text>

<text top='23' left='50' width='372' height='53'>
This is where you can define the various pieces of information the user will see when deciding whether or not to play your scenario.
The meanings of all these fields are given in the documentation.
</text>
<text size='large' top='6' left='50' width='256' height='17'>Scenario Details</text>
<text top='81' left='50' width='120' height='14'>Version number:</text>
<text top='102' left='50' width='120' height='14'>Credits, Part 1:</text>
<text top='150' left='50' width='120' height='14'>Credits, Part 2:</text>
<text top='213' left='50' width='120' height='14'>Contact Information:</text>

<text name='title-label' top='65' left='50' width='120' height='14'>Title:</text>
<field name='title' relative='pos-in pos-in' rel-anchor='prev' top='0' left='131' width='243' height='16' max-chars='30'/>

<text name='version-label' relative='pos-in pos-in' anchor='title-label' top='20' left='0' width='120' height='14'>Version number:</text>
<field name='ver1' relative='pos-in neg' rel-anchor='prev' type='uint' top='1' left='131' width='43' height='16'/>
<field name='ver2' relative='pos-in' rel-anchor='prev' type='uint' top='0' left='53' width='43' height='16'/>
<field name='ver3' relative='pos-in' rel-anchor='prev' type='uint' top='0' left='53' width='43' height='16'/>

<text name='teaser1-label' top='102' left='50' width='120' height='14'>Teaser:</text>
<field name='teaser1' top='104' left='181' width='243' height='47'/>
<text name='teaser2-label' top='150' left='50' width='120' height='14'></text>
<field name='teaser2' top='159' left='181' width='243' height='47'/>
<text name='author-label' top='212' left='50' width='160' height='14'>Author:</text>
<field name='author' top='214' left='181' width='243' height='16'/>
<text name='contact-label' top='233' left='50' width='160' height='14'>Contact Information<br/>(optional):</text>
<field name='contact' top='234' left='181' width='243' height='35'/>

<text top='285' left='50' width='50' height='14'>Rating:</text>
<group name='rating'>
<led name='rate1' state='off' top='288' left='107'>G</led>
<led name='rate2' state='off' top='305' left='107'>PG</led>
<led name='rate3' state='off' top='322' left='107'>R</led>
<led name='rate4' state='off' top='339' left='107'>NC-17</led>
</group>

<text top='285' left='199' width='71' height='14'>Difficulty:</text>
<!--
TODO: Isn't there a level cap? If so, this should probably say "30-cap" (with cap replaced with the actual cap) rather than 30+.
Expand All @@ -36,22 +45,6 @@
<led name='lvl3' state='off' top='322' left='281'>High Level (19-30)</led>
<led name='lvl4' state='off' top='339' left='281'>Very High Level (30+)</led>
</group>
<led name='adjust' top='356' left='50' size='small'>Adjust difficulty if played by a party stronger than recommended</led>
<text top='379' left='50' width='120' height='14'>Special on Start:</text>
<field name='oninit' top='378' left='181' width='100' height='16'/>
<button name='pickinit' type='large' top='374' left='290'>Create/Edit</button>
<text top='407' left='50' width='120' height='14'>Campaign ID:</text>
<field name='cpnid' top='406' left='181' width='100' height='16'/>
<text top='430' left='50' width='400' height='44'>
If your scenario is part of a campaign of several scenarios,
the ID specified here makes it easy to carry information from one scenario to the next.
It should be the same in each scenario in the series.
</text>
<text top='484' left='50' width='120' height='60'>Default backgrounds:<br/>
Set the default patterns to be shown behind the game screen.
</text>
<button name='bg-out' type='tiny' top='484' left='180'>Outdoors:</button>
<button name='bg-town' type='tiny' top='501' left='180'>In towns:</button>
<button name='bg-dungeon' type='tiny' top='518' left='180'>In dungeons:</button>
<button name='bg-fight' type='tiny' top='535' left='180'>In combat:</button>
</dialog>

<button name='okay' type='regular' top='354' left='395'>OK</button>
</dialog>
2 changes: 1 addition & 1 deletion rsrc/dialogs/make-scenario1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
Examples: 'Hammer of Thor', 'Dragon's Quest'<br/>
(max. length 30 characters)
</text>
<field name='name' top='34' left='351' width='125' height='32'>Scenario name</field>
<field name='name' top='34' left='351' width='125' height='32' max-chars='30'>Scenario name</field>

<text top='96' left='52' width='292' height='56'>
What is your name or handle, for crediting purposes?
Expand Down
1 change: 1 addition & 0 deletions rsrc/menus/ScenEditor.rc
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ BEGIN
MENUITEM " Edit Special &Nodes", IDM_SCEN_ADV_SPECIALS
MENUITEM " Edit Scenario &Text", IDM_SCEN_ADV_TEXT
MENUITEM " Edit Journal Entries", IDM_SCEN_ADV_JOURNAL
MENUITEM " Advanced Scenario Details", IDM_SCEN_ADV_DETAILS
MENUITEM " &Import Town", IDM_SCEN_ADV_IMPORT_TOWN
MENUITEM " Import Outdoor Sector", IDM_SCEN_ADV_IMPORT_OUT
MENUITEM " Edit Saved Item &Rectangles", IDM_SCEN_ADV_SAVE_RECTS
Expand Down
14 changes: 14 additions & 0 deletions rsrc/menus/scenedit.xib
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,14 @@
<reference key="NSOnImage" ref="229763992"/>
<reference key="NSMixedImage" ref="909111550"/>
</object>
<object class="NSMenuItem" id="788000513">
<reference key="NSMenu" ref="399390342"/>
<string key="NSTitle"> Advanced Scenario Details</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="229763992"/>
<reference key="NSMixedImage" ref="909111550"/>
</object>
<object class="NSMenuItem" id="800006778">
<reference key="NSMenu" ref="399390342"/>
<string key="NSTitle"> Import Town</string>
Expand Down Expand Up @@ -1289,6 +1297,7 @@
<reference ref="726312118"/>
<reference ref="926133930"/>
<reference ref="788000512"/>
<reference ref="788000513"/>
<reference ref="637087210"/>
<reference ref="878691898"/>
<reference ref="800006778"/>
Expand Down Expand Up @@ -1425,6 +1434,11 @@
<reference key="object" ref="788000512"/>
<reference key="parent" ref="399390342"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">893</int>
<reference key="object" ref="788000513"/>
<reference key="parent" ref="399390342"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">817</int>
<reference key="object" ref="637087210"/>
Expand Down
1 change: 1 addition & 0 deletions rsrc/menus/scenresource.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
#define IDM_SCEN_LAUNCH_START 171
#define IDM_SCEN_LAUNCH_ENTRANCE 172
#define ID_FILE_PREFERENCES 173
#define IDM_SCEN_ADV_DETAILS 174

// Next default values for new objects
//
Expand Down
4 changes: 2 additions & 2 deletions src/fileio/fileio_scen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/game/boe.dlgutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
27 changes: 23 additions & 4 deletions src/game/boe.fileio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions src/game/boe.global.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
16 changes: 8 additions & 8 deletions src/scenario/scenario.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion src/scenario/scenario.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ class cScenario {
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;
Expand Down
Loading

0 comments on commit 0afed5d

Please sign in to comment.