Split quest flags into two separate boolean values

This commit is contained in:
2023-01-22 18:14:04 -05:00
parent b19356757d
commit b03c34396d
10 changed files with 28 additions and 23 deletions

View File

@@ -476,14 +476,14 @@ static void readQuestFromXml(ticpp::Element& data, cQuest& quest) {
std::string type, name, val, fname;
data.GetDocument()->GetValue(&fname);
data.GetValue(&type);
quest.flags = 0;
quest.deadline_is_relative = quest.auto_start = false;
Iterator<Attribute> attr;
for(attr = attr.begin(&data); attr != attr.end(); attr++) {
attr->GetName(&name);
if(name == "start-with") {
attr->GetValue(&val);
if(val == "true")
quest.flags += 10;
quest.auto_start = true;
} else throw xBadAttr(type, name, attr->Row(), attr->Column(), fname);
}
std::set<std::string> reqs = {"name", "description"};
@@ -498,7 +498,7 @@ static void readQuestFromXml(ticpp::Element& data, cQuest& quest) {
if(name == "relative") {
attr->GetValue(&val);
if(val == "true")
quest.flags += 1;
quest.deadline_is_relative = true;
} else if(name == "waive-if")
attr->GetValue(&quest.event);
else throw xBadAttr(type, name, attr->Row(), attr->Column(), fname);

View File

@@ -657,7 +657,7 @@ static void fill_job_bank(cDialog& me, job_bank_t& bank, std::string) {
cQuest& quest = univ.scenario.quests[bank.jobs[i]];
std::string description = quest.descr;
if(quest.deadline > 0) {
if(quest.flags % 10 == 1)
if(quest.deadline_is_relative)
description += " Must be completed in " + std::to_string(quest.deadline) + " days.";
else description += " Must be completed by day " + std::to_string(quest.deadline) + ".";
}

View File

@@ -670,7 +670,7 @@ void put_quest_info(short which_i) {
int start = univ.party.active_quests[which_i].start;
quest_dlg["start"].setText("Day " + std::to_string(start));
if(quest.deadline > 0)
quest_dlg["chop"].setText("Day " + std::to_string(quest.deadline + (quest.flags % 10) * start));
quest_dlg["chop"].setText("Day " + std::to_string(quest.deadline + int(quest.deadline_is_relative) * start));
else quest_dlg["chop"].setText("None");
if(quest.gold > 0)
quest_dlg["pay"].setText(std::to_string(quest.gold) + " gold");

View File

@@ -1814,7 +1814,7 @@ void special_increase_age(long length, bool queue) {
cQuest& quest = univ.scenario.quests[p.first];
if(quest.deadline <= 0)
continue;
bool is_relative = quest.flags % 10;
bool is_relative = quest.deadline_is_relative;
int deadline = quest.deadline + is_relative * p.second.start;
if(day_reached(deadline + 1, quest.event)) {
p.second.status = eQuestStatus::FAILED;
@@ -1824,7 +1824,7 @@ void special_increase_age(long length, bool queue) {
if(bank >= univ.party.job_banks.size())
univ.party.job_banks.resize(bank + 1);
int add_anger = 1;
if(quest.flags % 10 == 1) {
if(quest.deadline_is_relative) {
if(quest.deadline < 20)
add_anger++;
if(quest.deadline < 10)

View File

@@ -13,7 +13,8 @@ enum class eQuestStatus {AVAILABLE, STARTED, COMPLETED, FAILED};
class cQuest {
public:
short flags = 0; // 0 - absolute deadline, 1 - relative to when quest started, +10 - start quest when scenario starts
bool deadline_is_relative = false;
bool auto_start = false;
short deadline = -1;
short event = -1; // if this event occurs before the deadline, then the deadline is waived
short xp = 0, gold = 0; // automatically award this much XP and gold to the party when the quest is marked complete

View File

@@ -2078,8 +2078,8 @@ static void put_quest_in_dlog(cDialog& me, const cQuest& quest, size_t which_que
me["bank1"].setTextToNum(quest.bank1);
me["bank2"].setTextToNum(quest.bank2);
dynamic_cast<cLed&>(me["rel"]).setState(quest.flags % 10 == 1 ? led_red : led_off);
dynamic_cast<cLed&>(me["start"]).setState(quest.flags >= 10 ? led_red : led_off);
dynamic_cast<cLed&>(me["rel"]).setState(quest.deadline_is_relative ? led_red : led_off);
dynamic_cast<cLed&>(me["start"]).setState(quest.auto_start ? led_red : led_off);
dynamic_cast<cLed&>(me["inbank"]).setState(quest.bank1 >= 0 || quest.bank2 >= 0 ? led_red : led_off);
if(quest.bank1 < 0 && quest.bank2 < 0) {
me["bank1"].hide();
@@ -2100,9 +2100,8 @@ static bool save_quest_from_dlog(cDialog& me, cQuest& quest, size_t which_quest,
quest.xp = me["xp"].getTextAsNum();
quest.gold = me["gold"].getTextAsNum();
quest.flags = dynamic_cast<cLed&>(me["rel"]).getState() == led_red;
if(dynamic_cast<cLed&>(me["start"]).getState() == led_red)
quest.flags += 10;
quest.deadline_is_relative = dynamic_cast<cLed&>(me["rel"]).getState() == led_red;
quest.auto_start = dynamic_cast<cLed&>(me["start"]).getState() == led_red;
if(dynamic_cast<cLed&>(me["inbank"]).getState() == led_red) {
quest.bank1 = me["bank1"].getTextAsNum();
quest.bank2 = me["bank2"].getTextAsNum();

View File

@@ -203,10 +203,10 @@ void writeScenarioToXml(ticpp::Printer&& data, cScenario& scenario) {
for(size_t i = 0; i < scenario.quests.size(); i++) {
cQuest& quest = scenario.quests[i];
data.OpenElement("quest");
data.PushAttribute("start-with", boolstr(quest.flags / 10));
data.PushAttribute("start-with", boolstr(quest.auto_start));
if(quest.deadline >= 0) {
data.OpenElement("deadline");
data.PushAttribute("relative", boolstr(quest.flags % 10));
data.PushAttribute("relative", boolstr(quest.deadline_is_relative));
if(quest.event >= 0)
data.PushAttribute("waive-if", quest.event);
data.PushText(quest.deadline);

View File

@@ -1430,7 +1430,7 @@ void cUniverse::enter_scenario(const std::string& name) {
party.spec_items.insert(i);
}
for(short i = 0; i < scenario.quests.size(); i++) {
if(scenario.quests[i].flags >= 10) {
if(scenario.quests[i].auto_start) {
party.active_quests[i] = cJob(1);
}
}

View File

@@ -330,7 +330,8 @@ TEST_CASE("Loading a new-format scenario record") {
REQUIRE(scen.quests.size() == 1);
CHECK(scen.quests[0].name == "My Silly Quest");
CHECK(scen.quests[0].descr == " It is! The best quest! ");
CHECK(scen.quests[0].flags == 0);
CHECK_FALSE(scen.quests[0].deadline_is_relative);
CHECK_FALSE(scen.quests[0].auto_start);
CHECK(scen.quests[0].gold == 0);
CHECK(scen.quests[0].xp == 0);
CHECK(scen.quests[0].bank1 == -1);

View File

@@ -132,34 +132,38 @@ TEST_CASE("Saving a scenario record") {
}
SECTION("With a quest") {
scen.quests.resize(3);
scen.quests[0].flags = 11;
scen.quests[0].deadline_is_relative = true;
scen.quests[0].auto_start = true;
scen.quests[0].bank1 = 2;
scen.quests[0].deadline = 12;
scen.quests[0].event = 3;
scen.quests[0].xp = 5200;
scen.quests[0].name = "Test Quest";
scen.quests[0].descr = "This is a quest description! It has an absolute deadline which is waived by an event, and an XP reward. It's also in a job bank.";
scen.quests[1].flags = 10;
scen.quests[1].auto_start = true;
scen.quests[1].gold = 220;
scen.quests[1].name = "Test Quest 2";
scen.quests[1].descr = "This is another quest description! It has no deadline, and a monetary reward.";
scen.quests[2].flags = 1;
scen.quests[2].deadline_is_relative = true;
scen.quests[2].deadline = 12;
scen.quests[2].bank2 = 4;
scen.quests[2].name = "Test Quest 3";
scen.quests[2].descr = "And now another quest description! This one has a relative deadline and no reward, but it's in a job bank.";
in_and_out("quest", scen);
REQUIRE(scen.quests.size() == 3);
CHECK(scen.quests[0].flags == 11);
CHECK(scen.quests[0].deadline_is_relative);
CHECK(scen.quests[0].auto_start);
CHECK(scen.quests[0].bank1 == 2);
CHECK(scen.quests[0].deadline == 12);
CHECK(scen.quests[0].event == 3);
CHECK(scen.quests[0].xp == 5200);
CHECK(scen.quests[0].name == "Test Quest");
CHECK(scen.quests[1].flags == 10);
CHECK_FALSE(scen.quests[1].deadline_is_relative);
CHECK(scen.quests[1].auto_start);
CHECK(scen.quests[1].gold == 220);
CHECK(scen.quests[1].name == "Test Quest 2");
CHECK(scen.quests[2].flags == 1);
CHECK(scen.quests[2].deadline_is_relative);
CHECK_FALSE(scen.quests[2].auto_start);
CHECK(scen.quests[2].deadline == 12);
CHECK(scen.quests[2].bank1 == 4); // bank2 moves into bank1
CHECK(scen.quests[2].bank2 == -1);