Merge all the town classes and remove the unimplemented templated towns

This also adds a common superclass shared by towns and outdoor sectors, and
enables towns of arbitrary sizes.
This commit is contained in:
2016-09-03 02:50:29 -04:00
parent 5c3a96c69c
commit 88d6afce27
41 changed files with 566 additions and 1165 deletions

View File

@@ -6,6 +6,9 @@
*
*/
#ifndef BOE_FILEIO_HPP
#define BOE_FILEIO_HPP
#include <string>
#include <vector>
#include <sstream>
@@ -28,9 +31,19 @@ void check_for_intel();
std::string read_maybe_quoted_string(std::istream& from);
std::string maybe_quote_string(std::string which);
template<typename T, int D>
void writeArray(std::ostream& to, const T(* array)[D], int width, int height) {
using int_type = decltype(T() + 1);
template<typename T>
struct array_value_type{
using type = typename T::value_type;
};
template<typename T, int D1, int D2>
struct array_value_type<T[D1][D2]> {
using type = T;
};
template<typename T>
void writeArray(std::ostream& to, const T& array, int width, int height) {
using int_type = decltype(typename array_value_type<T>::type() + 1);
for(int y = 0; y < height; y++) {
to << array[0][y];
for(int x = 1; x < width; x++)
@@ -40,9 +53,9 @@ void writeArray(std::ostream& to, const T(* array)[D], int width, int height) {
to << '\f';
}
template<typename T, int D>
void readArray(std::istream& from, T(* array)[D], int width, int height) {
using int_type = decltype(T() + 1);
template<typename T>
void readArray(std::istream& from, T& array, int width, int height) {
using int_type = decltype(typename array_value_type<T>::type() + 1);
from >> std::ws;
std::string arrayContents;
getline(from, arrayContents, '\f');
@@ -88,3 +101,5 @@ public:
return pos;
}
};
#endif

View File

@@ -248,8 +248,8 @@ bool load_party_v1(fs::path file_to_load, cUniverse& real_univ, bool town_restor
univ.import_legacy(o_maps);
univ.town.import_legacy(sfx, misc_i);
if(town_restore) // Check items in crates/barrels
for(int i = 0; i < univ.town->max_dim(); i++) {
for(int j = 0; j < univ.town->max_dim(); j++) {
for(int i = 0; i < univ.town->max_dim; i++) {
for(int j = 0; j < univ.town->max_dim; j++) {
if(univ.town.is_barrel(i,j) || univ.town.is_crate(i,j)) {
for(cItem item : univ.town.items) {
if(item.item_loc == loc(i,j) && item.contained)

View File

@@ -15,7 +15,7 @@
#include "strdlog.hpp"
#include "scenario.hpp"
#include "regtown.hpp"
#include "town.hpp"
#include "map_parse.hpp"
#include "special_parse.hpp"
#include "graphtool.hpp"
@@ -26,6 +26,10 @@
#include "porting.hpp"
#include "restypes.hpp"
// Because the full template definition needs to be visible in this file
// Also, for some reason, it's not found in the include paths, so use a relative path
#include "../classes/town_import.tpp"
bool cur_scen_is_mac = true;
extern cCustomGraphics spec_scen_g;
extern fs::path tempDir;
@@ -218,9 +222,9 @@ bool load_scenario_v1(fs::path file_to_load, cScenario& scenario, bool only_head
scenario.towns.resize(scenario.format.num_towns);
for(int i = 0; i < scenario.format.num_towns; i++) {
switch(temp_scenario->town_size[i]) {
case 0: scenario.towns[i] = new cBigTown(scenario); break;
case 1: scenario.towns[i] = new cMedTown(scenario); break;
case 2: scenario.towns[i] = new cTinyTown(scenario); break;
case 0: scenario.towns[i] = new cTown(scenario, AREA_LARGE); break;
case 1: scenario.towns[i] = new cTown(scenario, AREA_MEDIUM); break;
case 2: scenario.towns[i] = new cTown(scenario, AREA_SMALL); break;
}
load_town_v1(scenario.scen_file, i, *scenario.towns[i], *temp_scenario, shops);
}
@@ -1478,7 +1482,7 @@ void readOutdoorsFromXml(ticpp::Document&& data, cOutdoors& out) {
for(elem = elem.begin(data.FirstChildElement()); elem != elem.end(); elem++) {
elem->GetValue(&type);
if(type == "name") {
elem->GetText(&out.out_name, false);
elem->GetText(&out.name, false);
found_name = true;
} else if(type == "comment") {
elem->GetText(&out.comment, false);
@@ -1555,10 +1559,10 @@ void readOutdoorsFromXml(ticpp::Document&& data, cOutdoors& out) {
out.sign_locs.resize(sign + 1);
elem->GetText(&out.sign_locs[sign].text, false);
} else if(type == "area") {
if(num_rects >= out.info_rect.size())
out.info_rect.resize(num_rects + 1);
static_cast<rectangle&>(out.info_rect[num_rects]) = readRectFromXml(*elem);
elem->GetText(&out.info_rect[num_rects].descr, false);
if(num_rects >= out.area_desc.size())
out.area_desc.resize(num_rects + 1);
static_cast<rectangle&>(out.area_desc[num_rects]) = readRectFromXml(*elem);
elem->GetText(&out.area_desc[num_rects].descr, false);
num_rects++;
} else if(type == "string") {
int str;
@@ -1588,19 +1592,16 @@ void readTownFromXml(ticpp::Document&& data, cTown*& town, cScenario& scen) {
elem->GetValue(&type);
reqs.erase(type);
if(type == "size") {
elem->GetText(&val);
if(val == "32") {
town = new cTinyTown(scen);
} else if(val == "48") {
town = new cMedTown(scen);
} else if(val == "64") {
town = new cBigTown(scen);
} else throw xBadVal(type, xBadVal::CONTENT, val, elem->Row(), elem->Column(), fname);
size_t dim;
elem->GetText(&dim);
if(dim < 24)
throw xBadVal(type, xBadVal::CONTENT, val, elem->Row(), elem->Column(), fname);
else town = new cTown(scen, dim);
found_size = true;
} else if(!found_size) {
throw xBadNode(type, elem->Row(), elem->Column(), fname);
} else if(type == "name") {
elem->GetText(&town->town_name, false);
elem->GetText(&town->name, false);
} else if(type == "comment") {
if(num_cmt >= 3)
throw xBadNode(type, elem->Row(), elem->Column(), fname);
@@ -1771,10 +1772,10 @@ void readTownFromXml(ticpp::Document&& data, cTown*& town, cScenario& scen) {
if(!reqs.empty())
throw xMissingElem("creature", *reqs.begin(), elem->Row(), elem->Column(), fname);
} else if(type == "area") {
if(num_rects >= town->room_rect.size())
town->room_rect.resize(num_rects + 1);
static_cast<rectangle&>(town->room_rect[num_rects]) = readRectFromXml(*elem);
elem->GetText(&town->room_rect[num_rects].descr, false);
if(num_rects >= town->area_desc.size())
town->area_desc.resize(num_rects + 1);
static_cast<rectangle&>(town->area_desc[num_rects]) = readRectFromXml(*elem);
elem->GetText(&town->area_desc[num_rects].descr, false);
num_rects++;
} else throw xBadNode(type, elem->Row(), elem->Column(), fname);
}
@@ -1926,8 +1927,8 @@ void loadOutMapData(map_data&& data, location which, cScenario& scen) {
void loadTownMapData(map_data&& data, int which, cScenario& scen) {
cTown& town = *scen.towns[which];
for(int x = 0; x < town.max_dim(); x++) {
for(int y = 0; y < town.max_dim(); y++) {
for(int x = 0; x < town.max_dim; x++) {
for(int y = 0; y < town.max_dim; y++) {
town.terrain(x,y) = data.get(x,y);
auto features = data.getFeatures(x,y);
for(auto feat : features) {
@@ -2242,14 +2243,14 @@ bool load_town_v1(fs::path scen_file, short which_town, cTown& the_town, legacy:
the_town.spec_strs.resize(100);
the_town.sign_locs.resize(20);
the_town.room_rect.resize(16);
the_town.area_desc.resize(16);
for(short i = 0; i < 140; i++) {
len = (long) (store_town.strlens[i]);
fread(temp_str, len, 1, file_id);
temp_str[len] = 0;
if(i == 0) the_town.town_name = temp_str;
if(i == 0) the_town.name = temp_str;
else if(i >= 1 && i < 17)
the_town.room_rect[i-1].descr = temp_str;
the_town.area_desc[i-1].descr = temp_str;
else if(i >= 17 && i < 20)
the_town.comment[i-17] = temp_str;
else if(i >= 20 && i < 120)
@@ -2352,14 +2353,14 @@ bool load_outdoors_v1(fs::path scen_file, location which_out,cOutdoors& the_out,
the_out.import_legacy(store_out);
the_out.spec_strs.resize(90);
the_out.sign_locs.resize(8);
the_out.info_rect.resize(8);
the_out.area_desc.resize(8);
for(short i = 0; i < 108; i++) {
len = (long) (store_out.strlens[i]);
fread(temp_str, len, 1, file_id);
temp_str[len] = 0;
if(i == 0) the_out.out_name = temp_str;
if(i == 0) the_out.name = temp_str;
else if(i == 9) the_out.comment = temp_str;
else if(i < 9) the_out.info_rect[i-1].descr = temp_str;
else if(i < 9) the_out.area_desc[i-1].descr = temp_str;
else if(i >= 10 && i < 100)
the_out.spec_strs[i-10] = temp_str;
else if(i >= 100 && i < 108)

View File

@@ -22,6 +22,7 @@ template<typename Type, typename Alloc = std::allocator<Type>> class vector2d {
std::vector<Type, Alloc> data;
size_t w, h;
public:
using value_type = Type;
class row_ref {
friend class vector2d<Type, Alloc>;
vector2d<Type, Alloc>& ref;
@@ -120,6 +121,12 @@ public:
const_row_ref row(size_t x) const {
return const_row_ref(*this, x);
}
Type& operator()(size_t x, size_t y) {
return (*this)[x][y];
}
const Type& operator()(size_t x, size_t y) const {
return (*this)[x][y];
}
size_t width() const {
return w;
}
@@ -162,7 +169,9 @@ public:
return data.empty();
}
vector2d() : w(0), h(0) {}
vector2d(size_t w, size_t h) : w(w), h(h) {}
vector2d(size_t w, size_t h) : w(w), h(h) {
resize(w,h);
}
};
#endif