Move town-specific daved game data into the town record
Als, use bitsets for item_taken and maps.
This commit is contained in:
@@ -163,16 +163,6 @@ void init_screen_locs() {
|
||||
startup_top.left = 5;
|
||||
startup_top.right = startup_button[STARTBTN_JOIN].right;
|
||||
|
||||
for(short i = 0; i < 200; i++)
|
||||
for(short j = 0; j < 8; j++)
|
||||
for(short k = 0; k < 64; k++)
|
||||
univ.town_maps[i][j][k] = 0;
|
||||
|
||||
for(short i = 0; i < 100; i++)
|
||||
for(short k = 0; k < 6; k++)
|
||||
for(short l = 0; l < 48; l++)
|
||||
univ.out_maps[i][k][l] = 0;
|
||||
|
||||
// name, use, give, drip, info, sell/id each one 13 down
|
||||
item_buttons[0][ITEMBTN_NAME].top = 17;
|
||||
item_buttons[0][ITEMBTN_NAME].bottom = item_buttons[0][ITEMBTN_NAME].top + 12;
|
||||
|
@@ -999,7 +999,7 @@ void handle_talk_event(location p) {
|
||||
save_talk_str2 = "";
|
||||
break;
|
||||
case eTalkNode::BUY_TOWN_LOC:
|
||||
if(univ.party.can_find_town[b]) {
|
||||
if(univ.scenario.towns[b]->can_find) {
|
||||
// TODO: Uh, is something supposed to happen here?
|
||||
}
|
||||
else if(univ.party.gold < a) {
|
||||
@@ -1008,7 +1008,7 @@ void handle_talk_event(location p) {
|
||||
else {
|
||||
univ.party.gold -= a;
|
||||
put_pc_screen();
|
||||
univ.party.can_find_town[b] = true;
|
||||
univ.scenario.towns[b]->can_find = true;
|
||||
}
|
||||
save_talk_str2 = "";
|
||||
break;
|
||||
|
@@ -291,71 +291,33 @@ void build_outdoors() {
|
||||
|
||||
}
|
||||
|
||||
short onm(char x_sector,char y_sector) {
|
||||
short i;
|
||||
|
||||
i = y_sector * univ.scenario.outdoors.width() + x_sector;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// This adds the current outdoor map info to the saved outdoor map info
|
||||
void save_outdoor_maps() {
|
||||
location corner = univ.party.outdoor_corner;
|
||||
for(short i = 0; i < 48; i++)
|
||||
for(short j = 0; j < 48; j++) {
|
||||
if(univ.out.out_e[i][j] > 0)
|
||||
univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y)][i / 8][j] =
|
||||
univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y)][i / 8][j] |
|
||||
(char) (1 << i % 8);
|
||||
if(univ.party.outdoor_corner.x + 1 < univ.scenario.outdoors.width()) {
|
||||
if(univ.out.out_e[i + 48][j] > 0)
|
||||
univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y)][i / 8][j] =
|
||||
univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y)][i / 8][j] |
|
||||
(char) (1 << i % 8);
|
||||
}
|
||||
if(univ.party.outdoor_corner.y + 1 < univ.scenario.outdoors.height()) {
|
||||
if(univ.out.out_e[i][j + 48] > 0)
|
||||
univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y + 1)][i / 8][j] =
|
||||
univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y + 1)][i / 8][j] |
|
||||
(char) (1 << i % 8);
|
||||
}
|
||||
if((univ.party.outdoor_corner.y + 1 < univ.scenario.outdoors.height()) &&
|
||||
(univ.party.outdoor_corner.x + 1 < univ.scenario.outdoors.width())) {
|
||||
if(univ.out.out_e[i + 48][j + 48] > 0)
|
||||
univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y + 1)][i / 8][j] =
|
||||
univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y + 1)][i / 8][j] |
|
||||
(char) (1 << i % 8);
|
||||
}
|
||||
univ.scenario.outdoors[corner.x][corner.y]->maps[j][i] = univ.out.out_e[i][j];
|
||||
if(corner.x + 1 < univ.scenario.outdoors.width())
|
||||
univ.scenario.outdoors[corner.x + 1][corner.y]->maps[j][i] = univ.out.out_e[i + 48][j];
|
||||
if(corner.y + 1 < univ.scenario.outdoors.height())
|
||||
univ.scenario.outdoors[corner.x][corner.y + 1]->maps[j][i] = univ.out.out_e[i][j + 48];
|
||||
if(corner.y + 1 < univ.scenario.outdoors.height() && corner.x + 1 < univ.scenario.outdoors.width())
|
||||
univ.scenario.outdoors[corner.x + 1][corner.y + 1]->maps[j][i] = univ.out.out_e[i + 48][j + 48];
|
||||
}
|
||||
}
|
||||
|
||||
void add_outdoor_maps() { // This takes the existing outdoor map info and supplements it with the saved map info
|
||||
// This takes the existing outdoor map info and supplements it with the saved map info
|
||||
void add_outdoor_maps() {
|
||||
location corner = univ.party.outdoor_corner;
|
||||
for(short i = 0; i < 48; i++)
|
||||
for(short j = 0; j < 48; j++) {
|
||||
if((univ.out.out_e[i][j] == 0) &&
|
||||
((univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y)][i / 8][j] &
|
||||
(char) (1 << i % 8)) != 0))
|
||||
univ.out.out_e[i][j] = 1;
|
||||
if(univ.party.outdoor_corner.x + 1 < univ.scenario.outdoors.width()) {
|
||||
if((univ.out.out_e[i + 48][j] == 0) &&
|
||||
((univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y)][i / 8][j] &
|
||||
(char) (1 << i % 8)) != 0))
|
||||
univ.out.out_e[i + 48][j] = 1;
|
||||
}
|
||||
if(univ.party.outdoor_corner.y + 1 < univ.scenario.outdoors.height()) {
|
||||
if((univ.out.out_e[i][j + 48] == 0) &&
|
||||
((univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y + 1)][i / 8][j] &
|
||||
(char) (1 << i % 8)) != 0))
|
||||
univ.out.out_e[i][j + 48] = 1;
|
||||
}
|
||||
if((univ.party.outdoor_corner.y + 1 < univ.scenario.outdoors.height()) &&
|
||||
(univ.party.outdoor_corner.x + 1 < univ.scenario.outdoors.width())) {
|
||||
if((univ.out.out_e[i + 48][j + 48] == 0) &&
|
||||
((univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y + 1)][i / 8][j] &
|
||||
(char) (1 << i % 8)) != 0))
|
||||
univ.out.out_e[i + 48][j + 48] = 1;
|
||||
}
|
||||
univ.out.out_e[i][j] = univ.scenario.outdoors[corner.x][corner.y]->maps[j][i];
|
||||
if(corner.x + 1 < univ.scenario.outdoors.width())
|
||||
univ.out.out_e[i + 48][j] = univ.scenario.outdoors[corner.x + 1][corner.y]->maps[j][i];
|
||||
if(corner.y + 1 < univ.scenario.outdoors.height())
|
||||
univ.out.out_e[i][j + 48] = univ.scenario.outdoors[corner.x][corner.y + 1]->maps[j][i];
|
||||
if(corner.y + 1 < univ.scenario.outdoors.height() && corner.x + 1 < univ.scenario.outdoors.width())
|
||||
univ.out.out_e[i + 48][j + 48] = univ.scenario.outdoors[corner.x + 1][corner.y + 1]->maps[j][i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -251,12 +251,11 @@ short dist_from_party(location where) {
|
||||
return store;
|
||||
}
|
||||
|
||||
// TODO: I have no idea what is going on here, other than that it seems to have something to do items being picked up in town
|
||||
// This marks the item as taken so that it won't show up again when the party returns to this town
|
||||
void set_item_flag(cItem* item) {
|
||||
if((item->is_special > 0) && (item->is_special < 65)) {
|
||||
item->is_special--;
|
||||
univ.party.item_taken[univ.party.town_num][item->is_special / 8] =
|
||||
univ.party.item_taken[univ.party.town_num][item->is_special / 8] | (1 << item->is_special % 8);
|
||||
univ.town->item_taken.set(item->is_special);
|
||||
item->is_special = 0;
|
||||
}
|
||||
}
|
||||
|
@@ -54,7 +54,7 @@ void create_wand_monst() {
|
||||
place_outd_wand_monst(univ.out->wandering_locs[r2], univ.out->wandering[r1],0);
|
||||
}
|
||||
} else if(!univ.town->wandering[r1].isNull() && univ.town.countMonsters() <= 50
|
||||
&& !univ.town->is_cleaned_out(univ.party.m_killed[univ.party.town_num])) {
|
||||
&& !univ.town->is_cleaned_out()) {
|
||||
// won't place wandering if more than 50 monsters
|
||||
r2 = get_ran(1,0,univ.town->wandering.size() - 1);
|
||||
while(point_onscreen(univ.town->wandering_locs[r2],univ.party.town_loc) &&
|
||||
|
@@ -144,6 +144,13 @@ static void init_party_scen_data() {
|
||||
}
|
||||
}
|
||||
}
|
||||
for(short j = 0; j < 6; j++) {
|
||||
univ.party[j].status.clear();
|
||||
if(isSplit(univ.party[j].main_status))
|
||||
univ.party[j].main_status -= eMainStatus::SPLIT;
|
||||
univ.party[j].cur_health = univ.party[j].max_health;
|
||||
univ.party[j].cur_sp = univ.party[j].max_sp;
|
||||
}
|
||||
univ.party.in_boat = -1;
|
||||
univ.party.in_horse = -1;
|
||||
for(auto& pop : univ.party.creature_save)
|
||||
@@ -153,22 +160,20 @@ static void init_party_scen_data() {
|
||||
for(short i = 0; i < 5; i++)
|
||||
for(short j = 0; j < 10; j++)
|
||||
univ.party.magic_store_items[i][j].variety = eItemType::NO_ITEM;
|
||||
// for(short i = 0; i < 50; i++)
|
||||
// univ.party.journal_str[i] = -1;
|
||||
// for(short i = 0; i < 140; i++)
|
||||
// for(short j = 0; j < 2; j++)
|
||||
// univ.party.special_notes_str[i][j] = 0;
|
||||
// for(short i = 0; i < 120; i++)
|
||||
// univ.party.talk_save[i].personality = -1;
|
||||
// TODO: The journal at least should persist across scenarios; the special and talk notes, maybe, maybe not
|
||||
// TODO: Now uncertain if the journal should really persist
|
||||
// univ.party.journal.clear();
|
||||
univ.party.special_notes.clear();
|
||||
univ.party.talk_save.clear();
|
||||
|
||||
univ.party.direction = DIR_N;
|
||||
univ.party.at_which_save_slot = 0;
|
||||
univ.party.can_find_town.resize(univ.scenario.towns.size());
|
||||
for(short i = 0; i < univ.scenario.towns.size(); i++)
|
||||
univ.party.can_find_town[i] = !univ.scenario.towns[i]->is_hidden;
|
||||
for(auto town : univ.scenario.towns) {
|
||||
town->can_find = !town->is_hidden;
|
||||
town->m_killed = 0;
|
||||
town->item_taken.reset();
|
||||
for(auto& m : town->maps)
|
||||
m.reset();
|
||||
}
|
||||
for(short i = 0; i < 20; i++)
|
||||
univ.party.key_times[i] = 30000;
|
||||
univ.party.party_event_timers.clear();
|
||||
@@ -184,13 +189,6 @@ static void init_party_scen_data() {
|
||||
}
|
||||
}
|
||||
|
||||
univ.party.m_killed.clear();
|
||||
univ.party.m_killed.resize(univ.scenario.towns.size());
|
||||
|
||||
for(short i = 0; i < 200; i++)
|
||||
for(short j = 0; j < 8; j++)
|
||||
univ.party.item_taken[i][j] = 0;
|
||||
|
||||
|
||||
refresh_store_items();
|
||||
|
||||
@@ -216,10 +214,9 @@ static void init_party_scen_data() {
|
||||
for(short i = 0; i < 3;i++)
|
||||
univ.party.stored_items[i].clear();
|
||||
|
||||
for(short i = 0; i < 100; i++)
|
||||
for(short k = 0; k < 6; k++)
|
||||
for(short l = 0; l < 48; l++)
|
||||
univ.out_maps[i][k][l] = 0;
|
||||
for(auto sector : univ.scenario.outdoors)
|
||||
for(auto& m : sector->maps)
|
||||
m.reset();
|
||||
|
||||
}
|
||||
|
||||
@@ -234,14 +231,6 @@ void put_party_in_scen(std::string scen_name) {
|
||||
univ.ghost_mode = false;
|
||||
univ.node_step_through = false;
|
||||
|
||||
for(short j = 0; j < 6; j++) {
|
||||
univ.party[j].status.clear();
|
||||
if(isSplit(univ.party[j].main_status))
|
||||
univ.party[j].main_status -= eMainStatus::SPLIT;
|
||||
univ.party[j].cur_health = univ.party[j].max_health;
|
||||
univ.party[j].cur_sp = univ.party[j].max_sp;
|
||||
}
|
||||
// TODO: The above probably belongs in init_party_scen_data
|
||||
for(short j = 0; j < 6; j++)
|
||||
for(short i = 23; i >= 0; i--) {
|
||||
cItem& thisItem = univ.party[j].items[i];
|
||||
@@ -268,10 +257,6 @@ void put_party_in_scen(std::string scen_name) {
|
||||
}
|
||||
if(item_took)
|
||||
cChoiceDlog("removed-special-items").show();
|
||||
univ.party.age = 0;
|
||||
univ.party.m_killed.clear();
|
||||
univ.party.m_killed.resize(univ.scenario.towns.size());
|
||||
univ.party.party_event_timers.clear();
|
||||
|
||||
fs::path path = locate_scenario(scen_name);
|
||||
if(path.empty()) {
|
||||
|
@@ -1652,7 +1652,7 @@ void kill_monst(cCreature& which_m,short who_killed,eMainStatus type) {
|
||||
}
|
||||
|
||||
if((is_town() || which_combat_type == 1) && which_m.summon_time == 0) {
|
||||
univ.party.m_killed[univ.party.town_num]++;
|
||||
univ.town->m_killed++;
|
||||
}
|
||||
|
||||
which_m.spec1 = 0; // make sure, if this is a spec. activated monster, it won't come back
|
||||
@@ -2227,7 +2227,7 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
check_mess = true;
|
||||
if(spec.ex1a != minmax(0,univ.scenario.towns.size() - 1,spec.ex1a))
|
||||
showError("Town out of range.");
|
||||
else univ.party.can_find_town[spec.ex1a] = spec.ex2a;
|
||||
else univ.scenario.towns[spec.ex1a]->can_find = spec.ex2a;
|
||||
*redraw = true;
|
||||
break;
|
||||
case eSpecType::MAJOR_EVENT_OCCURRED:
|
||||
|
@@ -679,7 +679,7 @@ void print_party_stats() {
|
||||
add_string_to_buf("PARTY STATS:");
|
||||
add_string_to_buf(" Number of kills: " + std::to_string(univ.party.total_m_killed));
|
||||
if((is_town()) || ((is_combat()) && (which_combat_type == 1))) {
|
||||
add_string_to_buf(" Kills in this town: " + std::to_string(univ.party.m_killed[univ.party.town_num]));
|
||||
add_string_to_buf(" Kills in this town: " + std::to_string(univ.town->m_killed));
|
||||
}
|
||||
add_string_to_buf(" Total experience: " + std::to_string(univ.party.total_xp_gained));
|
||||
add_string_to_buf(" Total damage done: " + std::to_string(univ.party.total_dam_done));
|
||||
|
@@ -127,7 +127,7 @@ void start_town_mode(short which_town, short entry_dir) {
|
||||
// Set up map, using stored map
|
||||
for(short i = 0; i < univ.town->max_dim(); i++)
|
||||
for(short j = 0; j < univ.town->max_dim(); j++) {
|
||||
if(univ.town_maps[univ.party.town_num][i / 8][j] & (char)(1 << i % 8))
|
||||
if(univ.town->maps[j][i])
|
||||
make_explored(i,j);
|
||||
|
||||
if(univ.town->terrain(i,j) == 0)
|
||||
@@ -218,7 +218,7 @@ void start_town_mode(short which_town, short entry_dir) {
|
||||
// TODO: Should these two cases be separated?
|
||||
if(univ.town->town_chop_time > 0 && day_reached(univ.town->town_chop_time,univ.town->town_chop_key))
|
||||
univ.town.monst[j].active += 10;
|
||||
else if(univ.town->is_cleaned_out(univ.party.m_killed[univ.party.town_num]))
|
||||
else if(univ.town->is_cleaned_out())
|
||||
univ.town.monst[j].active += 10;
|
||||
else univ.town.monst[j].active = 0;
|
||||
if(univ.town.monst[j].active >= 10)
|
||||
@@ -290,7 +290,7 @@ void start_town_mode(short which_town, short entry_dir) {
|
||||
// TODO: Should these two cases be separated?
|
||||
if(univ.town->town_chop_time > 0 && day_reached(univ.town->town_chop_time,univ.town->town_chop_key))
|
||||
univ.town.monst[i].active += 10;
|
||||
else if(univ.town->is_cleaned_out(univ.party.m_killed[univ.party.town_num]))
|
||||
else if(univ.town->is_cleaned_out())
|
||||
univ.town.monst[i].active += 10;
|
||||
else univ.town.monst[i].active = 0;
|
||||
break;
|
||||
@@ -319,7 +319,7 @@ void start_town_mode(short which_town, short entry_dir) {
|
||||
|
||||
|
||||
// Thrash town?
|
||||
if(univ.town->is_cleaned_out(univ.party.m_killed[univ.party.town_num])) {
|
||||
if(univ.town->is_cleaned_out()) {
|
||||
town_toast = true;
|
||||
add_string_to_buf("Area has been cleaned out.");
|
||||
}
|
||||
@@ -373,7 +373,7 @@ void start_town_mode(short which_town, short entry_dir) {
|
||||
|
||||
for(short i = 0; i < univ.town->preset_items.size(); i++)
|
||||
if((univ.town->preset_items[i].code >= 0)
|
||||
&& (((univ.party.item_taken[univ.party.town_num][i / 8] & (1 << i % 8)) == 0) ||
|
||||
&& (!univ.town->item_taken[i] ||
|
||||
(univ.town->preset_items[i].always_there))) {
|
||||
// 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));
|
||||
@@ -571,8 +571,7 @@ location end_town_mode(short switching_level,location destination) { // returns
|
||||
for(short i = 0; i < univ.town->max_dim(); i++)
|
||||
for(short j = 0; j < univ.town->max_dim(); j++)
|
||||
if(is_explored(i,j)) {
|
||||
univ.town_maps[univ.party.town_num][i / 8][j] = univ.town_maps[univ.party.town_num][i / 8][j] |
|
||||
(char) (1 << i % 8);
|
||||
univ.town->maps[j].set(i);
|
||||
}
|
||||
|
||||
to_return = univ.party.out_loc;
|
||||
@@ -1268,11 +1267,11 @@ void erase_out_specials() {
|
||||
(sector.city_locs[k].y == minmax(0,47,sector.city_locs[k].y))) {
|
||||
if(sector.city_locs[k].spec < 0 || sector.city_locs[k].spec >= univ.scenario.towns.size())
|
||||
continue;
|
||||
if(!univ.party.can_find_town[sector.city_locs[k].spec]) {
|
||||
if(!univ.scenario.towns[sector.city_locs[k].spec]->can_find) {
|
||||
univ.out[48 * i + sector.city_locs[k].x][48 * j + sector.city_locs[k].y] =
|
||||
univ.scenario.ter_types[sector.terrain[sector.city_locs[k].x][sector.city_locs[k].y]].flag1;
|
||||
}
|
||||
else if(univ.party.can_find_town[sector.city_locs[k].spec]) {
|
||||
else if(univ.scenario.towns[sector.city_locs[k].spec]->can_find) {
|
||||
univ.out[48 * i + sector.city_locs[k].x][48 * j + sector.city_locs[k].y] =
|
||||
sector.terrain[sector.city_locs[k].x][sector.city_locs[k].y];
|
||||
|
||||
|
@@ -78,6 +78,8 @@ public:
|
||||
eAmbientSound ambient_sound;
|
||||
snd_num_t out_sound;
|
||||
int bg_out, bg_fight, bg_town, bg_dungeon;
|
||||
// Persistent data for saved games
|
||||
std::array<std::bitset<48>, 48> maps;
|
||||
|
||||
explicit cOutdoors(cScenario& scenario);
|
||||
void append(legacy::outdoor_record_type& old);
|
||||
|
@@ -53,16 +53,13 @@ cParty::~cParty() {
|
||||
}
|
||||
}
|
||||
|
||||
void cParty::append(legacy::party_record_type& old, const cScenario& scen){
|
||||
void cParty::append(legacy::party_record_type& old, cUniverse& univ){
|
||||
age = old.age;
|
||||
gold = old.gold;
|
||||
food = old.food;
|
||||
for(short i = 0; i < 310; i++)
|
||||
for(short j = 0; j < 10; j++)
|
||||
stuff_done[i][j] = old.stuff_done[i][j];
|
||||
for(short i = 0; i < 200; i++)
|
||||
for(short j = 0; j < 8; j++)
|
||||
item_taken[i][j] = old.item_taken[i][j];
|
||||
light_level = old.light_level;
|
||||
if(stuff_done[305][0] > 0)
|
||||
status[ePartyStatus::STEALTH] = stuff_done[305][0];
|
||||
@@ -108,26 +105,18 @@ void cParty::append(legacy::party_record_type& old, const cScenario& scen){
|
||||
for(short i = 0; i < 256; i++)
|
||||
if(old.m_seen[i])
|
||||
m_noted.insert(i);
|
||||
journal.reserve(50);
|
||||
// The journal wasn't used before, so let's not bother converting it
|
||||
// for(short i = 0; i < 50; i++){
|
||||
// cJournal j;
|
||||
// j.day = old.journal_day[i];
|
||||
// journal.push_back(j);
|
||||
// spec_items[i] = old.spec_items[i];
|
||||
// }
|
||||
if(!scen_name.empty()) {
|
||||
special_notes.reserve(140);
|
||||
for(short i = 0; i < 140; i++){
|
||||
if(old.special_notes_str[i][0] <= 0) continue;
|
||||
cEncNote n;
|
||||
n.append(old.special_notes_str[i], scen);
|
||||
n.append(old.special_notes_str[i], univ.scenario);
|
||||
special_notes.push_back(n);
|
||||
}
|
||||
talk_save.reserve(120);
|
||||
for(short i = 0; i < 120; i++){
|
||||
cConvers t;
|
||||
t.append(old.talk_save[i], scen);
|
||||
t.append(old.talk_save[i], univ.scenario);
|
||||
talk_save.push_back(t);
|
||||
}
|
||||
}
|
||||
@@ -135,11 +124,11 @@ void cParty::append(legacy::party_record_type& old, const cScenario& scen){
|
||||
at_which_save_slot = old.at_which_save_slot;
|
||||
for(short i = 0; i < 20 ; i++)
|
||||
alchemy[i] = old.alchemy[i];
|
||||
can_find_town.resize(200);
|
||||
m_killed.resize(200);
|
||||
for(short i = 0; i < 200; i++){
|
||||
can_find_town[i] = old.can_find_town[i];
|
||||
m_killed[i] = old.m_killed[i];
|
||||
for(short i = 0; i < univ.scenario.towns.size(); i++){
|
||||
univ.scenario.towns[i]->can_find = old.can_find_town[i];
|
||||
univ.scenario.towns[i]->m_killed = old.m_killed[i];
|
||||
for(short j = 0; j < 64; j++)
|
||||
univ.scenario.towns[i]->item_taken[j] = old.item_taken[i][j / 8] & (1 << j % 8);
|
||||
}
|
||||
for(short i = 0; i < 100; i++)
|
||||
key_times[i] = old.key_times[i];
|
||||
@@ -538,7 +527,7 @@ bool cParty::start_timer(short time, short node, short type){
|
||||
return(true);
|
||||
}
|
||||
|
||||
void cParty::writeTo(std::ostream& file) const {
|
||||
void cParty::writeTo(std::ostream& file, const cScenario& scen) const {
|
||||
file << "CREATEVERSION " << std::hex << OBOE_CURRENT_VERSION << std::dec << '\n';
|
||||
file << "AGE " << age << '\n';
|
||||
file << "GOLD " << gold << '\n';
|
||||
@@ -555,14 +544,6 @@ void cParty::writeTo(std::ostream& file) const {
|
||||
file << "POINTER " << iter->first << ' ' << iter->second.first << ' ' << iter->second.second << '\n';
|
||||
for(int i = 0; i < magic_ptrs.size(); i++)
|
||||
file << "POINTER " << i << ' ' << int(magic_ptrs[i]) << '\n';
|
||||
for(int i = 0; i < 200; i++)
|
||||
if(item_taken[i][0] > 0 || item_taken[i][1] > 0 || item_taken[i][2] > 0 || item_taken[i][3] > 0 ||
|
||||
item_taken[i][4] > 0 || item_taken[i][5] > 0 || item_taken[i][6] > 0 || item_taken[i][7] > 0) {
|
||||
file << "ITEMTAKEN " << i;
|
||||
for(int j = 0; j < 8; j++)
|
||||
file << ' ' << unsigned(item_taken[i][j]);
|
||||
file << '\n';
|
||||
}
|
||||
file << "LIGHT " << light_level << '\n';
|
||||
file << "OUTCORNER " << outdoor_corner.x << ' ' << outdoor_corner.y << '\n';
|
||||
file << "INWHICHCORNER " << i_w_c.x << ' ' << i_w_c.y << '\n';
|
||||
@@ -594,16 +575,18 @@ void cParty::writeTo(std::ostream& file) const {
|
||||
for(int i = 0; i < alchemy.size(); i++)
|
||||
if(alchemy[i])
|
||||
file << "ALCHEMY " << i << '\n';
|
||||
for(int i = 0; i < can_find_town.size(); i++)
|
||||
if(can_find_town[i])
|
||||
file << "TOWNVISIBLE " << i << '\n';
|
||||
for(int i = 0; i < scen.towns.size(); i++) {
|
||||
if(scen.towns[i]->item_taken.any())
|
||||
file << "ITEMTAKEN " << i << ' ' << scen.towns[i]->item_taken << '\n';
|
||||
if(scen.towns[i]->can_find == scen.towns[i]->is_hidden)
|
||||
file << (scen.towns[i]->can_find ? "TOWNVISIBLE " : "TOWNHIDDEN ") << i << '\n';
|
||||
if(scen.towns[i]->m_killed > 0)
|
||||
file << "TOWNSLAUGHTER " << i << ' ' << scen.towns[i]->m_killed << '\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 = 0; i < m_killed.size(); i++)
|
||||
if(m_killed[i] > 0)
|
||||
file << "TOWNSLAUGHTER " << i << ' ' << m_killed[i] << '\n';
|
||||
file << "KILLS " << total_m_killed << '\n';
|
||||
file << "DAMAGE " << total_dam_done << '\n';
|
||||
file << "WOUNDS " << total_dam_taken << '\n';
|
||||
@@ -728,7 +711,7 @@ void cParty::writeTo(std::ostream& file) const {
|
||||
}
|
||||
}
|
||||
|
||||
void cParty::readFrom(std::istream& file){
|
||||
void cParty::readFrom(std::istream& file, cScenario& scen){
|
||||
// TODO: Error-check input
|
||||
// TODO: Don't call this sin, it's a trig function
|
||||
std::istringstream bin;
|
||||
@@ -787,11 +770,8 @@ void cParty::readFrom(std::istream& file){
|
||||
}else if(cur == "ITEMTAKEN"){
|
||||
int i;
|
||||
sin >> i;
|
||||
for(int j = 0; j < 8; j++) {
|
||||
unsigned int n;
|
||||
sin >> n;
|
||||
item_taken[i][j] = n;
|
||||
}
|
||||
if(i >= 0 && i < scen.towns.size())
|
||||
sin >> scen.towns[i]->item_taken;
|
||||
}else if(cur == "LIGHT")
|
||||
sin >> light_level;
|
||||
else if(cur == "OUTCORNER")
|
||||
@@ -840,9 +820,13 @@ void cParty::readFrom(std::istream& file){
|
||||
} else if(cur == "TOWNVISIBLE") {
|
||||
int i;
|
||||
sin >> i;
|
||||
if(i >= can_find_town.size())
|
||||
can_find_town.resize(i + 1);
|
||||
can_find_town[i] = true;
|
||||
if(i >= 0 && i < scen.towns.size())
|
||||
scen.towns[i]->can_find = true;
|
||||
} else if(cur == "TOWNHIDDEN") {
|
||||
int i;
|
||||
sin >> i;
|
||||
if(i >= 0 && i < scen.towns.size())
|
||||
scen.towns[i]->can_find = false;
|
||||
}else if(cur == "EVENT"){
|
||||
int i;
|
||||
sin >> i;
|
||||
@@ -854,9 +838,8 @@ void cParty::readFrom(std::istream& file){
|
||||
}else if(cur == "TOWNSLAUGHTER"){
|
||||
int i;
|
||||
sin >> i;
|
||||
if(i >= m_killed.size())
|
||||
m_killed.resize(i + 1);
|
||||
sin >> m_killed[i];
|
||||
if(i >= 0 && i < scen.towns.size())
|
||||
sin >> scen.towns[i]->m_killed;
|
||||
} else if(cur == "QUEST") {
|
||||
int i;
|
||||
sin >> i;
|
||||
|
@@ -45,6 +45,7 @@ struct job_bank_t {
|
||||
bool inited = false;
|
||||
};
|
||||
|
||||
class cUniverse;
|
||||
class cItem;
|
||||
|
||||
class cParty : public iLiving {
|
||||
@@ -80,7 +81,6 @@ public:
|
||||
bool easy_mode = false, less_wm = false;
|
||||
// End former magic SDFs
|
||||
std::array<unsigned char,90> magic_ptrs;
|
||||
unsigned char item_taken[200][8];
|
||||
short light_level;
|
||||
location outdoor_corner;
|
||||
location i_w_c;
|
||||
@@ -113,11 +113,9 @@ public:
|
||||
eDirection direction;
|
||||
short at_which_save_slot;
|
||||
std::bitset<20> alchemy;
|
||||
std::vector<bool> can_find_town;
|
||||
std::map<int,int> key_times;
|
||||
std::vector<cTimer> party_event_timers;
|
||||
std::set<int> spec_items;
|
||||
std::vector<long> m_killed;
|
||||
long long total_m_killed, total_dam_done, total_xp_gained, total_dam_taken;
|
||||
std::string scen_name;
|
||||
private:
|
||||
@@ -138,7 +136,7 @@ public:
|
||||
void clear_ptr(unsigned short p);
|
||||
unsigned char get_ptr(unsigned short p);
|
||||
|
||||
void append(legacy::party_record_type& old, const cScenario& scen);
|
||||
void append(legacy::party_record_type& old, cUniverse& univ);
|
||||
void append(legacy::big_tr_type& old);
|
||||
void append(legacy::stored_items_list_type& old,short which_list);
|
||||
void append(legacy::setup_save_type& old);
|
||||
@@ -184,8 +182,8 @@ public:
|
||||
bool start_timer(short time, short node, short type);
|
||||
cPlayer& operator[](unsigned short n);
|
||||
const cPlayer& operator[](unsigned short n) const;
|
||||
void writeTo(std::ostream& file) const;
|
||||
void readFrom(std::istream& file);
|
||||
void writeTo(std::ostream& file, const cScenario& scen) const;
|
||||
void readFrom(std::istream& file, cScenario& scen);
|
||||
|
||||
bool give_item(cItem item,int flags);
|
||||
bool forced_give(cItem item,eItemAbil abil,short dat = -1);
|
||||
|
@@ -173,7 +173,7 @@ bool cTown::cWandering::isNull(){
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cTown::is_cleaned_out(long m_killed) {
|
||||
bool cTown::is_cleaned_out() {
|
||||
if(max_num_monst < 0) return false;
|
||||
return m_killed >= max_num_monst;
|
||||
}
|
||||
|
@@ -91,6 +91,11 @@ public:
|
||||
std::array<std::string,3> comment;
|
||||
std::vector<std::string> spec_strs;
|
||||
cSpeech talking;
|
||||
// Persistent data for saved games
|
||||
std::array<std::bitset<64>, 64> maps;
|
||||
std::bitset<64> item_taken;
|
||||
bool can_find;
|
||||
long m_killed;
|
||||
|
||||
virtual ~cTown(){}
|
||||
virtual void append(legacy::big_tr_type& old, int town_num);
|
||||
@@ -103,7 +108,7 @@ public:
|
||||
void init_start();
|
||||
void set_up_lights();
|
||||
short light_obscurity(short x,short y); // Obscurity function used for calculating lighting
|
||||
bool is_cleaned_out(long m_killed);
|
||||
bool is_cleaned_out();
|
||||
|
||||
explicit cTown(cScenario& scenario);
|
||||
void append(legacy::town_record_type& old);
|
||||
|
@@ -64,16 +64,21 @@ void cCurTown::append(legacy::town_item_list& old){
|
||||
|
||||
void cUniverse::append(legacy::stored_town_maps_type& old){
|
||||
for(int n = 0; n < 200; n++)
|
||||
for(int i = 0; i < 8; i++)
|
||||
for(int i = 0; i < 64; i++)
|
||||
for(int j = 0; j < 64; j++)
|
||||
town_maps[n][i][j] = old.town_maps[n][i][j];
|
||||
scenario.towns[n]->maps[j][i] = old.town_maps[n][i / 8][j] & (1 << (i % 8));
|
||||
}
|
||||
|
||||
static short onm(char x_sector,char y_sector, char w) {
|
||||
return y_sector * w + x_sector;
|
||||
}
|
||||
|
||||
void cUniverse::append(legacy::stored_outdoor_maps_type& old){
|
||||
for(int n = 0; n < 100; n++)
|
||||
for(int i = 0; i < 6; i++)
|
||||
for(int j = 0; j < 48; j++)
|
||||
out_maps[n][i][j] = old.outdoor_maps[n][i][j];
|
||||
for(int x = 0; x < scenario.outdoors.width(); x++)
|
||||
for(int y = 0; y < scenario.outdoors.height(); y++)
|
||||
for(int i = 0; i < 48; i++)
|
||||
for(int j = 0; j < 48; j++)
|
||||
scenario.outdoors[x][y]->maps[i][j] = old.outdoor_maps[onm(x,y,scenario.outdoors.width())][i / 8][j] & (1 << i % 8);
|
||||
}
|
||||
|
||||
void cCurTown::append(unsigned char(& old_sfx)[64][64], unsigned char(& old_misc_i)[64][64]){
|
||||
|
@@ -176,9 +176,7 @@ public:
|
||||
cParty party;
|
||||
std::map<long,cPlayer*> stored_pcs;
|
||||
cCurTown town;
|
||||
unsigned char town_maps[200][8][64]; // formerly stored_town_maps_type
|
||||
cCurOut out;
|
||||
unsigned char out_maps[100][6][48]; // formerly stored_outdoor_maps_type
|
||||
fs::path file;
|
||||
bool debug_mode, ghost_mode, node_step_through;
|
||||
|
||||
|
@@ -285,17 +285,15 @@ void handle_menu_choice(eMenu item_hit) {
|
||||
break;
|
||||
case eMenu::ADD_OUT_MAPS:
|
||||
display_strings(13,15);
|
||||
for(short i = 0; i < 100; i++)
|
||||
for(short j = 0; j < 6; j++)
|
||||
for(short k = 0; k < 48; k++)
|
||||
univ.out_maps[i][j][k] = 255;
|
||||
for(auto sector : univ.scenario.outdoors)
|
||||
for(auto& m : sector->maps)
|
||||
m.set();
|
||||
break;
|
||||
case eMenu::ADD_TOWN_MAPS:
|
||||
display_strings(14,15);
|
||||
for(short i = 0; i < 200; i++)
|
||||
for(short j = 0; j < 8; j++)
|
||||
for(short k = 0; k < 64; k++)
|
||||
univ.town_maps[i][j][k] = 255;
|
||||
for(auto town : univ.scenario.towns)
|
||||
for(auto& m : town->maps)
|
||||
m.set();
|
||||
break;
|
||||
case eMenu::EDIT_MAGE:
|
||||
display_pc(current_active_pc,10,0);
|
||||
|
@@ -233,7 +233,7 @@ bool load_party_v1(fs::path file_to_load, cUniverse& univ, bool town_restore, bo
|
||||
univ.party.scen_name = "";
|
||||
}
|
||||
|
||||
univ.party.append(store_party, univ.scenario);
|
||||
univ.party.append(store_party, univ);
|
||||
univ.party.append(store_setup);
|
||||
univ.party.append(store_pc);
|
||||
if(in_scen){
|
||||
@@ -280,7 +280,7 @@ bool load_party_v2(fs::path file_to_load, cUniverse& univ){
|
||||
showError("Loading Blades of Exile save file failed.");
|
||||
return false;
|
||||
}
|
||||
univ.party.readFrom(fin);
|
||||
univ.party.readFrom(fin, univ.scenario);
|
||||
}
|
||||
|
||||
{ // Then the "setup" array
|
||||
@@ -343,10 +343,9 @@ bool load_party_v2(fs::path file_to_load, cUniverse& univ){
|
||||
|
||||
// Read town maps
|
||||
std::istream& fin2 = partyIn.getFile("save/townmaps.dat");
|
||||
for(int i = 0; i < 200; i++)
|
||||
for(int j = 0; j < 8; j++)
|
||||
for(int k = 0; k < 64; k++)
|
||||
univ.town_maps[i][j][k] = fin2.get();
|
||||
for(int i = 0; i < univ.scenario.towns.size(); i++)
|
||||
for(int j = 0; j < 64; j++)
|
||||
fin2 >> univ.scenario.towns[i]->maps[j];
|
||||
} else univ.party.town_num = 200;
|
||||
|
||||
// Load outdoors data
|
||||
@@ -359,10 +358,10 @@ bool load_party_v2(fs::path file_to_load, cUniverse& univ){
|
||||
|
||||
// Read outdoor maps
|
||||
std::istream& fin2 = partyIn.getFile("save/outmaps.dat");
|
||||
for(int i = 0; i < 100; i++)
|
||||
for(int j = 0; j < 6; j++)
|
||||
for(int k = 0; k < 48; k++)
|
||||
univ.out_maps[i][j][k] = fin2.get();
|
||||
for(int i = 0; i < univ.scenario.outdoors.height(); i++)
|
||||
for(int j = 0; j < 48; j++)
|
||||
for(int k = 0; k < univ.scenario.outdoors.width(); k++)
|
||||
fin2 >> univ.scenario.outdoors[k][i]->maps[j];
|
||||
} else univ.party.scen_name = "";
|
||||
|
||||
if(partyIn.hasFile("save/export.png")) {
|
||||
@@ -391,7 +390,7 @@ bool save_party(fs::path dest_file, const cUniverse& univ) {
|
||||
tarball partyOut;
|
||||
|
||||
// First, write the main party data
|
||||
univ.party.writeTo(partyOut.newFile("save/party.txt"));
|
||||
univ.party.writeTo(partyOut.newFile("save/party.txt"), univ.scenario);
|
||||
{
|
||||
std::ostream& fout = partyOut.newFile("save/setup.dat");
|
||||
static uint16_t magic = 0x0B0E;
|
||||
@@ -423,10 +422,9 @@ bool save_party(fs::path dest_file, const cUniverse& univ) {
|
||||
|
||||
// Write the town map data
|
||||
std::ostream& fout = partyOut.newFile("save/townmaps.dat");
|
||||
for(int i = 0; i < 200; i++)
|
||||
for(int j = 0; j < 8; j++)
|
||||
for(int k = 0; k < 64; k++)
|
||||
fout.put(univ.town_maps[i][j][k]);
|
||||
for(int i = 0; i < univ.scenario.towns.size(); i++)
|
||||
for(int j = 0; j < 64; j++)
|
||||
fout << univ.scenario.towns[i]->maps[j] << '\n';
|
||||
}
|
||||
|
||||
// Write the current outdoors data
|
||||
@@ -434,10 +432,14 @@ bool save_party(fs::path dest_file, const cUniverse& univ) {
|
||||
|
||||
// Write the outdoors map data
|
||||
std::ostream& fout = partyOut.newFile("save/outmaps.dat");
|
||||
for(int i = 0; i < 100; i++)
|
||||
for(int j = 0; j < 6; j++)
|
||||
for(int k = 0; k < 48; k++)
|
||||
fout.put(univ.out_maps[i][j][k]);
|
||||
for(int i = 0; i < univ.scenario.outdoors.height(); i++) {
|
||||
for(int j = 0; j < 48; j++) {
|
||||
for(int k = 0; k < univ.scenario.outdoors.width(); k++)
|
||||
fout << univ.scenario.outdoors[k][i]->maps[j] << ' ';
|
||||
fout << '\n';
|
||||
}
|
||||
fout << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
if(spec_scen_g.party_sheet) {
|
||||
|
Reference in New Issue
Block a user