Consolidate active quest data into a single map
This commit is contained in:
@@ -638,9 +638,7 @@ static void show_job_bank(int which_bank, std::string title) {
|
||||
int which = hit[4] - '1';
|
||||
me["prompt"].setText("Job accepted.");
|
||||
job_bank_t& bank = univ.party.job_banks[which_bank];
|
||||
univ.party.quest_status[bank.jobs[which]] = eQuestStatus::STARTED;
|
||||
univ.party.quest_source[bank.jobs[which]] = store_personality;
|
||||
univ.party.quest_start[bank.jobs[which]] = univ.party.calc_day();
|
||||
univ.party.active_quests[bank.jobs[which]] = cJob(univ.party.calc_day(), store_personality);
|
||||
// Now, if there are spare jobs available, fill in. Otherwise, clear space.
|
||||
if(bank.jobs[4] >= 0)
|
||||
std::swap(bank.jobs[which], bank.jobs[4]);
|
||||
@@ -977,11 +975,9 @@ void handle_talk_event(location p) {
|
||||
showError("Tried to give a nonexistent quest!");
|
||||
return;
|
||||
}
|
||||
switch(univ.party.quest_status[a]) {
|
||||
switch(univ.party.active_quests[a].status) {
|
||||
case eQuestStatus::AVAILABLE:
|
||||
univ.party.quest_status[a] = eQuestStatus::STARTED;
|
||||
univ.party.quest_source[a] = -1;
|
||||
univ.party.quest_start[a] = univ.party.calc_day();
|
||||
univ.party.active_quests[a] = cJob(univ.party.calc_day());
|
||||
break;
|
||||
case eQuestStatus::STARTED:
|
||||
break;
|
||||
|
@@ -675,7 +675,7 @@ void put_quest_info(short which_i) {
|
||||
cDialog quest_dlg("quest-info");
|
||||
quest_dlg["name"].setText(quest.name);
|
||||
quest_dlg["descr"].setText(quest.descr);
|
||||
int start = univ.party.quest_start[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));
|
||||
|
@@ -495,9 +495,9 @@ static bool display_item_event_filter(cDialog& me, std::string id, size_t& first
|
||||
univ.party.spec_items.insert(item.item_level);
|
||||
set_item_flag(&item);
|
||||
} else if(item.variety == eItemType::QUEST) {
|
||||
univ.party.quest_status[item.item_level] = eQuestStatus::STARTED;
|
||||
univ.party.quest_start[item.item_level] = univ.party.calc_day();
|
||||
univ.party.quest_source[item.item_level] = -1;
|
||||
univ.party.active_quests[item.item_level].status = eQuestStatus::STARTED;
|
||||
univ.party.active_quests[item.item_level].start = univ.party.calc_day();
|
||||
univ.party.active_quests[item.item_level].source = -1;
|
||||
set_item_flag(&item);
|
||||
} else {
|
||||
if(!allow_overload && item.item_weight() > univ.party[current_getting_pc].free_weight()) {
|
||||
|
@@ -1806,18 +1806,18 @@ void special_increase_age(long length, bool queue) {
|
||||
trigger_loc = univ.party.out_loc;
|
||||
}
|
||||
|
||||
for(auto& p : univ.party.quest_status) {
|
||||
if(p.second != eQuestStatus::STARTED)
|
||||
for(auto& p : univ.party.active_quests) {
|
||||
if(p.second.status != eQuestStatus::STARTED)
|
||||
continue;
|
||||
cQuest& quest = univ.scenario.quests[p.first];
|
||||
if(quest.deadline <= 0)
|
||||
continue;
|
||||
bool is_relative = quest.flags % 10;
|
||||
int deadline = quest.deadline + is_relative * univ.party.quest_start[p.first];
|
||||
int deadline = quest.deadline + is_relative * p.second.start;
|
||||
if(day_reached(deadline + 1, quest.event)) {
|
||||
p.second = eQuestStatus::FAILED;
|
||||
if(univ.party.quest_source[p.first] >= 0) {
|
||||
int bank = univ.party.quest_source[p.first];
|
||||
p.second.status = eQuestStatus::FAILED;
|
||||
if(p.second.source >= 0) {
|
||||
int bank = p.second.source;
|
||||
// Safety valve in case it was given by a special node
|
||||
if(bank >= univ.party.job_banks.size())
|
||||
univ.party.job_banks.resize(bank + 1);
|
||||
@@ -1829,7 +1829,7 @@ void special_increase_age(long length, bool queue) {
|
||||
add_anger++;
|
||||
if(quest.deadline < 5)
|
||||
add_anger++;
|
||||
} else if(quest.deadline - univ.party.quest_start[p.first] > 20)
|
||||
} else if(quest.deadline - p.second.start > 20)
|
||||
add_anger++;
|
||||
univ.party.job_banks[bank].anger += add_anger;
|
||||
}
|
||||
@@ -2460,7 +2460,7 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
*next_spec = -1;
|
||||
break;
|
||||
}
|
||||
case eSpecType::UPDATE_QUEST:
|
||||
case eSpecType::UPDATE_QUEST: {
|
||||
check_mess = true;
|
||||
if(spec.ex1a < 0 || spec.ex1a >= univ.scenario.quests.size()) {
|
||||
showError("The scenario tried to update a non-existent quest.");
|
||||
@@ -2470,33 +2470,36 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
showError("Invalid quest status (range 0 .. 3).");
|
||||
break;
|
||||
}
|
||||
if(spec.ex1b == int(eQuestStatus::STARTED) && univ.party.quest_status[spec.ex1a] != eQuestStatus::STARTED) {
|
||||
univ.party.quest_start[spec.ex1a] = univ.party.calc_day();
|
||||
univ.party.quest_source[spec.ex1a] = max(-1,spec.ex2a);
|
||||
if(univ.party.quest_source[spec.ex1a] >= univ.party.job_banks.size())
|
||||
univ.party.job_banks.resize(univ.party.quest_source[spec.ex1a] + 1);
|
||||
auto& job = univ.party.active_quests[spec.ex1a];
|
||||
auto& quest = univ.scenario.quests[spec.ex1a];
|
||||
if(spec.ex1b == int(eQuestStatus::STARTED) && job.status != eQuestStatus::STARTED) {
|
||||
job.start = univ.party.calc_day();
|
||||
job.source = max(-1,spec.ex2a);
|
||||
if(job.source >= univ.party.job_banks.size())
|
||||
univ.party.job_banks.resize(job.source + 1);
|
||||
}
|
||||
univ.party.quest_status[spec.ex1a] = eQuestStatus(spec.ex1b);
|
||||
switch(univ.party.quest_status[spec.ex1a]) {
|
||||
job.status = eQuestStatus(spec.ex1b);
|
||||
switch(job.status) {
|
||||
case eQuestStatus::STARTED: add_string_to_buf("You have received a quest."); break;
|
||||
case eQuestStatus::AVAILABLE: break; // TODO: Should this award XP/gold if the quest was previously started?
|
||||
case eQuestStatus::FAILED:
|
||||
add_string_to_buf("You have failed to complete a quest.");
|
||||
if(univ.party.quest_source[spec.ex1a] >= 0 && univ.party.quest_source[spec.ex1a] < univ.party.job_banks.size())
|
||||
univ.party.job_banks[univ.party.quest_source[spec.ex1a]].anger += spec.ex2a < 0 ? 1 : spec.ex2a;
|
||||
if(job.source >= 0 && job.source < univ.party.job_banks.size())
|
||||
univ.party.job_banks[job.source].anger += spec.ex2a < 0 ? 1 : spec.ex2a;
|
||||
break;
|
||||
case eQuestStatus::COMPLETED:
|
||||
add_string_to_buf("You have completed a quest!");
|
||||
if(univ.scenario.quests[spec.ex1a].gold > 0) {
|
||||
int gold = univ.scenario.quests[spec.ex1a].gold;
|
||||
if(quest.gold > 0) {
|
||||
int gold = quest.gold;
|
||||
add_string_to_buf(" Received " + std::to_string(gold) + " as a reward.");
|
||||
give_gold(gold, true);
|
||||
}
|
||||
if(univ.scenario.quests[spec.ex1a].xp > 0)
|
||||
award_party_xp(univ.scenario.quests[spec.ex1a].xp);
|
||||
if(quest.xp > 0)
|
||||
award_party_xp(quest.xp);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
showError("Special node type \"" + (*cur_node.type).name() + "\" is either miscategorized or unimplemented!");
|
||||
break;
|
||||
@@ -3738,7 +3741,7 @@ void ifthen_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
showError("Invalid quest status (range 0 .. 3).");
|
||||
break;
|
||||
}
|
||||
if(univ.party.quest_status[spec.ex1a] == eQuestStatus(spec.ex1b))
|
||||
if(univ.party.active_quests[spec.ex1a].status == eQuestStatus(spec.ex1b))
|
||||
*next_spec = spec.ex1c;
|
||||
break;
|
||||
case eSpecType::IF_CONTEXT:
|
||||
|
@@ -573,13 +573,13 @@ void set_stat_window(short new_stat) {
|
||||
case ITEM_WIN_QUESTS:
|
||||
std::fill(spec_item_array.begin(), spec_item_array.end(), -1);
|
||||
for(short i = 0; i < univ.scenario.quests.size(); i++)
|
||||
if(univ.party.quest_status[i] == eQuestStatus::STARTED) {
|
||||
if(univ.party.active_quests[i].status == eQuestStatus::STARTED) {
|
||||
spec_item_array.push_back(i);
|
||||
array_pos++;
|
||||
} else if(univ.party.quest_status[i] == eQuestStatus::COMPLETED) {
|
||||
} else if(univ.party.active_quests[i].status == eQuestStatus::COMPLETED) {
|
||||
spec_item_array.push_back(i + 10000);
|
||||
array_pos++;
|
||||
} else if(univ.party.quest_status[i] == eQuestStatus::FAILED) {
|
||||
} else if(univ.party.active_quests[i].status == eQuestStatus::FAILED) {
|
||||
spec_item_array.push_back(i + 20000);
|
||||
array_pos++;
|
||||
}
|
||||
|
@@ -377,7 +377,7 @@ void start_town_mode(short which_town, short entry_dir) {
|
||||
continue;
|
||||
}
|
||||
// Don't place quest items if party already started
|
||||
if(item.variety == eItemType::QUEST && univ.party.quest_status[item.item_level] != eQuestStatus::AVAILABLE) {
|
||||
if(item.variety == eItemType::QUEST && univ.party.active_quests[item.item_level].status != eQuestStatus::AVAILABLE) {
|
||||
univ.town.items.pop_back();
|
||||
continue;
|
||||
}
|
||||
|
@@ -22,6 +22,15 @@ public:
|
||||
std::string descr;
|
||||
};
|
||||
|
||||
class cJob {
|
||||
public:
|
||||
cJob() : status(eQuestStatus::AVAILABLE), start(0), source(-1) {}
|
||||
explicit cJob(int start, int source = -1) : status(eQuestStatus::STARTED), start(start), source(source) {}
|
||||
eQuestStatus status;
|
||||
int start; // the day the quest was started; used for quests with relative deadlines
|
||||
int source; // if gotten from a job board, this is the number of the job board; otherwise -1
|
||||
};
|
||||
|
||||
std::istream& operator>>(std::istream& in, eQuestStatus& type);
|
||||
std::ostream& operator<<(std::ostream& out, eQuestStatus type);
|
||||
|
||||
|
@@ -86,9 +86,7 @@ cParty::cParty(const cParty& other)
|
||||
, special_notes(other.special_notes)
|
||||
, talk_save(other.talk_save)
|
||||
, status(other.status)
|
||||
, quest_status(other.quest_status)
|
||||
, quest_start(other.quest_start)
|
||||
, quest_source(other.quest_source)
|
||||
, active_quests(other.active_quests)
|
||||
, left_at(other.left_at)
|
||||
, left_in(other.left_in)
|
||||
, direction(other.direction)
|
||||
@@ -158,9 +156,7 @@ void cParty::swap(cParty& other) {
|
||||
std::swap(special_notes, other.special_notes);
|
||||
std::swap(talk_save, other.talk_save);
|
||||
std::swap(status, other.status);
|
||||
std::swap(quest_status, other.quest_status);
|
||||
std::swap(quest_start, other.quest_start);
|
||||
std::swap(quest_source, other.quest_source);
|
||||
std::swap(active_quests, other.active_quests);
|
||||
std::swap(left_at, other.left_at);
|
||||
std::swap(left_in, other.left_in);
|
||||
std::swap(direction, other.direction);
|
||||
@@ -741,8 +737,8 @@ void cParty::writeTo(std::ostream& file, const cScenario& scen) const {
|
||||
file << "SCENARIO " << scen_name << '\n';
|
||||
file << "WON " << scen_won << '\n';
|
||||
file << "PLAYED " << scen_played << '\n';
|
||||
for(auto p : quest_status)
|
||||
file << "QUEST " << p.first << ' ' << p.second << ' ' << quest_start.at(p.first) << ' ' << quest_source.at(p.first) << '\n';
|
||||
for(auto p : active_quests)
|
||||
file << "QUEST " << p.first << ' ' << p.second.status << ' ' << p.second.start << ' ' << p.second.source << '\n';
|
||||
for(auto p : store_limited_stock) {
|
||||
for(auto p2 : p.second) {
|
||||
file << "SHOPSTOCK " << p.first << p2.first << p2.second;
|
||||
@@ -990,7 +986,7 @@ void cParty::readFrom(std::istream& file, cScenario& scen){
|
||||
} else if(cur == "QUEST") {
|
||||
int i;
|
||||
sin >> i;
|
||||
sin >> quest_status[i] >> quest_start[i] >> quest_source[i];
|
||||
sin >> active_quests[i].status >> active_quests[i].start >> active_quests[i].source;
|
||||
} else if(cur == "SHOPSTOCK") {
|
||||
int i, j;
|
||||
sin >> i >> j >> store_limited_stock[i][j];
|
||||
|
@@ -111,10 +111,7 @@ public:
|
||||
std::vector<cEncNote> special_notes;
|
||||
std::vector<cConvers> talk_save;
|
||||
std::map<ePartyStatus,short> status;
|
||||
// Quest stuff
|
||||
std::map<int, eQuestStatus> quest_status;
|
||||
std::map<int, int> quest_start; // the day the quest was started; used for quests with relative deadlines
|
||||
std::map<int, int> quest_source; // if gotten from a job board, this is the number of the job board; otherwise -1
|
||||
std::map<int, cJob> active_quests;
|
||||
location left_at;
|
||||
size_t left_in;
|
||||
eDirection direction;
|
||||
|
@@ -465,9 +465,7 @@ bool cPlayer::give_item(cItem item, int flags) {
|
||||
}
|
||||
if(item.variety == eItemType::QUEST) {
|
||||
if(!party) return false;
|
||||
party->quest_status[item.item_level] = eQuestStatus::STARTED;
|
||||
party->quest_start[item.item_level] = party->calc_day();
|
||||
party->quest_source[item.item_level] = -1;
|
||||
party->active_quests[item.item_level] = cJob(party->calc_day());
|
||||
if(do_print && print_result)
|
||||
print_result("You get a quest.");
|
||||
return true;
|
||||
@@ -832,7 +830,7 @@ eBuyStatus cPlayer::ok_to_buy(short cost,cItem item) const {
|
||||
if(party->spec_items.count(item.item_level))
|
||||
return eBuyStatus::HAVE_LOTS;
|
||||
} else if(item.variety == eItemType::QUEST) {
|
||||
if(party->quest_status[item.item_level] != eQuestStatus::AVAILABLE)
|
||||
if(party->active_quests[item.item_level].status != eQuestStatus::AVAILABLE)
|
||||
return eBuyStatus::HAVE_LOTS;
|
||||
} else if(item.variety != eItemType::GOLD && item.variety != eItemType::FOOD) {
|
||||
for(int i = 0; i < items.size(); i++)
|
||||
|
@@ -1369,9 +1369,7 @@ void cUniverse::enter_scenario(const std::string& name) {
|
||||
}
|
||||
for(short i = 0; i < scenario.quests.size(); i++) {
|
||||
if(scenario.quests[i].flags >= 10) {
|
||||
party.quest_status[i] = eQuestStatus::STARTED;
|
||||
party.quest_start[i] = 1;
|
||||
party.quest_source[i] = -1;
|
||||
party.active_quests[i] = cJob(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1397,7 +1395,7 @@ void cUniverse::generate_job_bank(int which, job_bank_t& bank) {
|
||||
for(size_t i = 0; iSlot < 4 && i < scenario.quests.size(); i++) {
|
||||
if(scenario.quests[i].bank1 != which && scenario.quests[i].bank2 != which)
|
||||
continue;
|
||||
if(party.quest_status[i] != eQuestStatus::AVAILABLE)
|
||||
if(party.active_quests[i].status != eQuestStatus::AVAILABLE)
|
||||
continue;
|
||||
if(get_ran(1,1,100) <= 50 - bank.anger)
|
||||
bank.jobs[iSlot++] = i;
|
||||
|
Reference in New Issue
Block a user