Make some things dynamically sized

- Also, this fixes events being completely broken
This commit is contained in:
2015-02-07 11:19:45 -05:00
parent 220c8bf76c
commit 7d65dba686
11 changed files with 53 additions and 48 deletions

View File

@@ -91,7 +91,7 @@ extern sf::RenderWindow mainPtr;
extern short which_item_page[6];
extern short store_spell_target,pc_casting;
extern eSpell store_mage, store_priest;
extern short spec_item_array[60];
extern std::vector<int> spec_item_array;
extern cUniverse univ;
extern std::vector<word_rect_t> talk_words;
extern bool talk_end_forced;

View File

@@ -945,7 +945,7 @@ void handle_talk_event(location p) {
can_save_talk = false;
break;
case eTalkNode::BUY_SPEC_ITEM:
if(univ.party.spec_items[a]) {
if(univ.party.spec_items.count(a)) {
save_talk_str1 = "You already have it.";
can_save_talk = false;
}
@@ -955,7 +955,7 @@ void handle_talk_event(location p) {
else {
univ.party.gold -= b;
put_pc_screen();
univ.party.spec_items[a] = true;
univ.party.spec_items.insert(a);
}
save_talk_str2 = "";
break;

View File

@@ -543,7 +543,7 @@ static bool display_item_event_filter(cDialog& me, std::string id, size_t& first
set_item_flag(&item);
play_sound(62); // formerly force_play_sound
} else if(item.variety == eItemType::SPECIAL) {
univ.party.spec_items[item.item_level] = true;
univ.party.spec_items.insert(item.item_level);
set_item_flag(&item);
} else {
if(!allow_overload && item.item_weight() > univ.party[current_getting_pc].free_weight()) {

View File

@@ -68,7 +68,7 @@ bool belt_present = false;
/* Display globals */
short combat_posing_monster = -1, current_working_monster = -1; // 0-5 PC 100 + x - monster x
short fast_bang = false; // Note: This mostly behaves as a boolean variable, but values other than 1 are assigned to it, so I made it a short
short spec_item_array[60];
std::vector<int> spec_item_array;
short current_spell_range;
eGameMode overall_mode = MODE_STARTUP;
bool first_update = true,anim_onscreen = false,frills_on = true,changed_display_mode = false;

View File

@@ -165,8 +165,10 @@ static void init_party_scen_data() {
for(i = 0; i < 20; i++)
univ.party.key_times[i] = 30000;
univ.party.party_event_timers.clear();
for(i = 0; i < univ.scenario.special_items.size(); i++)
univ.party.spec_items[i] = univ.scenario.special_items[i].flags >= 10;
for(i = 0; i < univ.scenario.special_items.size(); i++) {
if(univ.scenario.special_items[i].flags >= 10)
univ.party.spec_items.insert(i);
}
for(i = 0; i < univ.scenario.quests.size(); i++) {
if(univ.scenario.quests[i].flags >= 10) {
univ.party.quest_status[i] = eQuestStatus::STARTED;

View File

@@ -2192,7 +2192,7 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
check_mess = true;
if(spec.ex1a != minmax(1,10,spec.ex1a))
giveError("Event code out of range.");
else if(univ.party.key_times[spec.ex1a] == 30000)
else if(univ.party.key_times.count(spec.ex1a) == 0)
univ.party.key_times[spec.ex1a] = calc_day();
break;
case eSpecType::FORCED_GIVE:
@@ -2505,9 +2505,9 @@ void oneshot_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
giveError("Special item is out of range.");
set_sd = false;
}
else {
univ.party.spec_items[spec.ex1a] = spec.ex1b == 0;
}
else if(spec.ex1b == 0)
univ.party.spec_items.insert(spec.ex1a);
else univ.party.spec_items.erase(spec.ex1a);
if(stat_window == ITEM_WIN_SPECIAL)
set_stat_window(ITEM_WIN_SPECIAL);
*redraw = 1;
@@ -2573,9 +2573,9 @@ void oneshot_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
give_gold(spec.ex1b,true);
give_food(spec.ex2a,true);
if((spec.m3 >= 0) && (spec.m3 < 50)) {
if(!univ.party.spec_items[spec.m3])
if(!univ.party.spec_items.count(spec.m3))
ASB("You get a special item.");
univ.party.spec_items[spec.m3] = true;
univ.party.spec_items.insert(spec.m3);
*redraw = true;
if(stat_window == ITEM_WIN_SPECIAL)
set_stat_window(ITEM_WIN_SPECIAL);
@@ -3198,7 +3198,7 @@ void ifthen_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
if(spec.ex1a != minmax(0,49,spec.ex1a)) {
giveError("Special item is out of range.");
}
else if(univ.party.spec_items[spec.ex1a] > 0)
else if(univ.party.spec_items.count(spec.ex1a) > 0)
*next_spec = spec.ex1b;
break;
case eSpecType::IF_SDF_COMPARE:

View File

@@ -69,7 +69,7 @@ extern rectangle pc_buttons[6][5];
extern bool item_area_button_active[8][6];
extern bool pc_area_button_active[6][5];
extern rectangle item_screen_button_rects[9];
extern short spec_item_array[60];
extern std::vector<int> spec_item_array;
extern std::map<eItemAbil, short> abil_chart;
// combat globals
extern short item_bottom_button_active[9];
@@ -244,8 +244,7 @@ void put_item_screen(short screen_num,short suppress_buttons) {
style.colour = sf::Color::Black;
for(i = 0; i < 8; i++) {
i_num = i + item_offset;
if(spec_item_array[i_num] >= 0) {
// 2nd condition above is quite kludgy, in case it gets here with array all 0's
if(i_num < spec_item_array.size()) {
win_draw_string(item_stats_gworld,item_buttons[i][0],univ.scenario.special_items[spec_item_array[i_num]].name,eTextMode::WRAP,style);
place_item_button(3,i,4,0);
@@ -262,8 +261,7 @@ void put_item_screen(short screen_num,short suppress_buttons) {
style.colour = sf::Color::Black;
for(i = 0; i < 8; i++) {
i_num = i + item_offset;
if(spec_item_array[i_num] >= 0) {
// 2nd condition above is quite kludgy, in case it gets here with array all 0's
if(i_num < spec_item_array.size()) {
win_draw_string(item_stats_gworld,item_buttons[i][0],univ.scenario.quests[spec_item_array[i_num]].name,eTextMode::WRAP,style);
place_item_button(3,i,4,0);
@@ -516,24 +514,23 @@ void set_stat_window(short new_stat) {
if(stat_window < ITEM_WIN_SPECIAL && univ.party[stat_window].main_status != eMainStatus::ALIVE)
stat_window = first_active_pc();
item_sbar->setPageSize(8);
spec_item_array.clear();
switch(stat_window) {
case ITEM_WIN_SPECIAL:
for(i = 0; i < 60; i++)
spec_item_array[i] = -1;
for(i = 0; i < 50; i++) ////
if(univ.party.spec_items[i]) {
spec_item_array[array_pos] = i;
std::fill(spec_item_array.begin(), spec_item_array.end(), -1);
for(i = 0; i < univ.scenario.special_items.size(); i++)
if(univ.party.spec_items.count(i)) {
spec_item_array.push_back(i);
array_pos++;
}
array_pos = max(0,array_pos - 8);
item_sbar->setMaximum(array_pos);
break;
case ITEM_WIN_QUESTS:
for(i = 0; i < 60; i++)
spec_item_array[i] = -1;
for(i = 0; i < 50; i++)
std::fill(spec_item_array.begin(), spec_item_array.end(), -1);
for(i = 0; i < univ.scenario.quests.size(); i++)
if(univ.party.quest_status[i] == eQuestStatus::STARTED) {
spec_item_array[array_pos] = i;
spec_item_array.push_back(i);
array_pos++;
}
array_pos = max(0,array_pos - 8);
@@ -1147,10 +1144,12 @@ bool day_reached(unsigned short which_day, unsigned short which_event) {
// Windows version unconditionally added 20 days for no reason at all.
// Instead, let's add 10 days, but only if easy mode enabled.
if(PSD[SDF_EASY_MODE]) which_day += 10;
if(which_event > 10)
return false;
if((which_event > 0) && (univ.party.key_times[which_event] < which_day))
return false;
if(which_event > 0) {
if(univ.party.key_times.find(which_event) == univ.party.key_times.end())
return false;
if(univ.party.key_times[which_event] < which_day)
return false;
}
if(calc_day() >= which_day)
return true;
else return false;

View File

@@ -236,6 +236,8 @@ void start_town_mode(short which_town, short entry_dir) {
}
break;
case eMonstTime::APPEAR_WHEN_EVENT:
if(univ.party.key_times.find(univ.town.monst[j].time_code) == univ.party.key_times.end())
break; // Event hasn't happened yet
if(calc_day() >= univ.party.key_times[univ.town.monst[j].time_code]){ //calc_day is used because of the "definition" of univ.party.key_times
univ.town.monst[j].active = 1;
univ.town.monst[j].time_flag = eMonstTime::ALWAYS;
@@ -243,6 +245,8 @@ void start_town_mode(short which_town, short entry_dir) {
break;
case eMonstTime::DISAPPEAR_WHEN_EVENT:
if(univ.party.key_times.find(univ.town.monst[j].time_code) == univ.party.key_times.end())
break; // Event hasn't happened yet
if(calc_day() >= univ.party.key_times[univ.town.monst[j].time_code]){
univ.town.monst[j].active = 0;
univ.town.monst[j].time_flag = eMonstTime::ALWAYS;
@@ -306,11 +310,15 @@ void start_town_mode(short which_town, short entry_dir) {
}
break;
case eMonstTime::APPEAR_WHEN_EVENT:
if(calc_day() < univ.party.key_times[univ.town.monst[i].time_code])
univ.town.monst[i].active = 0;
if(univ.party.key_times.find(univ.town.monst[j].time_code) == univ.party.key_times.end())
univ.town.monst[i].active = 0; // Event hasn't happened yet
else if(calc_day() < univ.party.key_times[univ.town.monst[i].time_code])
univ.town.monst[i].active = 0; // This would only be reached if the time was set back (or in a legacy save)
break;
case eMonstTime::DISAPPEAR_WHEN_EVENT:
if(univ.party.key_times.find(univ.town.monst[j].time_code) == univ.party.key_times.end())
break; // Event hasn't happened yet
if(calc_day() >= univ.party.key_times[univ.town.monst[i].time_code])
univ.town.monst[i].active = 0;
break;
@@ -402,7 +410,7 @@ void start_town_mode(short which_town, short entry_dir) {
// place the preset item, if party hasn't gotten it already
univ.town.items.push_back(get_stored_item(univ.town->preset_items[i].code));
// Don't place special items if already in the party's possession
if(univ.town.items[j].variety == eItemType::SPECIAL && univ.party.spec_items[univ.town.items[j].item_level])
if(univ.town.items[j].variety == eItemType::SPECIAL && univ.party.spec_items.count(univ.town.items[j].item_level))
break;
univ.town.items[j].item_loc = univ.town->preset_items[i].loc;

View File

@@ -39,8 +39,6 @@ cParty::cParty(cUniverse& univ, long party_preset) : univ(univ) {
for(int i = 0; i < 5; i++)
for(int j = 0; j < 10; j++)
magic_store_items[i][j].variety = eItemType::NO_ITEM;
// Original code set all key times 30000. I felt this was more appropriate.
std::fill(key_times, key_times + 20, std::numeric_limits<short>::max());
for(int i = 0; i < 6; i++)
adven[i] = new cPlayer(*this, party_preset, i);
@@ -556,12 +554,10 @@ void cParty::writeTo(std::ostream& file) const {
for(int i = 0; i < 200; i++)
if(can_find_town[i])
file << "TOWNVISIBLE " << i << '\n';
for(int i = 0; i < 100; i++)
if(key_times[i])
file << "EVENT " << i << ' ' << key_times[i] << '\n';
for(int i = 0; i < 50; i++)
if(spec_items[i])
file << "ITEM " << i << '\n';
for(auto key : key_times)
file << "EVENT " << key.first << ' ' << key.second << '\n';
for(int i : spec_items)
file << "ITEM " << i << '\n';
for(int i : help_received)
file << "HELP " << i << '\n';
for(int i = 0; i < 200; i++)
@@ -786,7 +782,7 @@ void cParty::readFrom(std::istream& file){
}else if(cur == "ITEM"){
int i;
sin >> i;
spec_items[i] = true;
spec_items.insert(i);
}else if(cur == "HELP"){
int i;
sin >> i;

View File

@@ -107,9 +107,9 @@ public:
short at_which_save_slot;
bool alchemy[20];
bool can_find_town[200];
short key_times[100];
std::map<int,int> key_times;
std::vector<cTimer> party_event_timers;
std::array<bool,50> spec_items;
std::set<int> spec_items;
std::set<int> help_received;
short m_killed[200]; // monsters killed per town, I think
long long total_m_killed, total_dam_done, total_xp_gained, total_dam_taken;

View File

@@ -427,7 +427,7 @@ bool cPlayer::give_item(cItem item, bool do_print, bool allow_overload) {
return true;
}
if(item.variety == eItemType::SPECIAL) {
party.spec_items[item.item_level] = true;
party.spec_items.insert(item.item_level);
if(do_print && print_result)
print_result("You get a special item.");
return true;
@@ -571,7 +571,7 @@ short cPlayer::skill(eSkill skill) const {
eBuyStatus cPlayer::ok_to_buy(short cost,cItem item) const {
if(item.variety == eItemType::SPECIAL) {
if(party.spec_items[item.item_level])
if(party.spec_items.count(item.item_level))
return eBuyStatus::HAVE_LOTS;
} else if(item.variety != eItemType::GOLD && item.variety != eItemType::FOOD) {
for(int i = 0; i < 24; i++)