150 lines
4.7 KiB
C++
150 lines
4.7 KiB
C++
#include "oopless-parser.hpp"
|
|
#include "brushdef.hpp"
|
|
#include <sstream>
|
|
#include <iostream>
|
|
#include <iterator>
|
|
using namespace std;
|
|
|
|
bool is_ebrush(std::vector<std::string> input) {
|
|
#define KEYWORD_ENTBRUSH1 "type Teleporter"
|
|
#define KEYWORD_ENTBRUSH2 "type JumpPad"
|
|
for (const string &str : input) {
|
|
if (str.find(KEYWORD_ENTBRUSH1) != string::npos ||
|
|
str.find(KEYWORD_ENTBRUSH2) != string::npos) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// place holding functions to test proper control flow.
|
|
bool write(const struct TBrush &geometry,
|
|
ofstream &fout,
|
|
void (*b) (stringstream &, const vector<TPlanePoints> &)) {
|
|
bool ok = true;
|
|
if (geometry.m_Vertices.size() < 1) {
|
|
cerr << "error: geometry has no vertices" << endl;
|
|
ok = false;
|
|
}
|
|
if (geometry.m_Faces.size() < 1) {
|
|
cerr << "error: geometry has no faces"<< endl;
|
|
ok = false;
|
|
}
|
|
if (ok) {
|
|
fout << GetBrushString(geometry, b);
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
void write(const vector<string> &entity,
|
|
ofstream &fo,
|
|
void (*b) (stringstream &, const vector<TPlanePoints> &),
|
|
EntityConverter &e) {
|
|
/* Likely inefficient.
|
|
Current process for the entities:
|
|
1. It acquires the lines.
|
|
2. Searches through and splits the vector.
|
|
3. Recombines the brush vector.
|
|
(4. Sends the vector to parse the brush through again.)*/
|
|
bool brushent = false;
|
|
unsigned int i;
|
|
for (i = 0; i < entity.size(); ++i) {
|
|
if (entity[i].find(KEYWORD_BRUSH) != string::npos) {
|
|
brushent = true;
|
|
break;
|
|
}
|
|
}
|
|
vector<string> brush(entity.size() - i);
|
|
if (brushent) {
|
|
// entity.begin() + i = vector that begins with KEYWORD_BRUSH
|
|
// parsing functions will expect only the contents underneath the keyword.
|
|
move((entity.begin() + i), entity.end(), brush.begin());
|
|
}
|
|
vector<string> converted = e.convert(entity);
|
|
if (converted.empty()) {
|
|
return;
|
|
}
|
|
fo << "{" << endl;
|
|
for (const string &s : converted) {
|
|
fo << s;
|
|
}
|
|
if (brushent) {
|
|
stringstream ss;
|
|
string line;
|
|
copy(brush.begin(), brush.end(), ostream_iterator<string>(ss, "\n"));
|
|
getline(ss, line); // this both discards the brush keyboard and prevents a crash
|
|
write(parse_brush<stringstream>(ss), fo, b);
|
|
}
|
|
fo << "}" << endl;
|
|
}
|
|
|
|
// entities will vary widely depending on their type and available flags.
|
|
// for now, acquire entity data, and handle their conversion in the write methods.
|
|
vector<string> get_entity(ifstream &f) {
|
|
vector<string> output;
|
|
string line;
|
|
unsigned int pos = f.tellg();
|
|
while (getline(f, line)) {
|
|
// stop when
|
|
// entity or a prefab keyword
|
|
// brush keyword and the entity is not of the type teleporter or jumppad.
|
|
if ((line.find(KEYWORD_ENTITY) != string::npos ||
|
|
line.find(KEYWORD_PREFAB) != string::npos) || (
|
|
line.find(KEYWORD_BRUSH) != string::npos && !is_ebrush(output))) {
|
|
f.seekg(pos);
|
|
return output;
|
|
} else {
|
|
output.push_back(line);
|
|
}
|
|
pos = f.tellg();
|
|
}
|
|
}
|
|
|
|
void parse_prefab(ifstream &f,
|
|
ofstream &out,
|
|
void (*b) (stringstream &, const vector<TPlanePoints> &),
|
|
queue<vector<string> > &entities) {
|
|
string l;
|
|
getline(f, l);
|
|
if (l.find(KEYWORD_BRUSH) != string::npos) {
|
|
write(parse_brush<ifstream>(f), out, b);
|
|
} else if (l.find(KEYWORD_ENTITY) != string::npos) {
|
|
entities.push(get_entity(f));
|
|
}
|
|
}
|
|
|
|
bool convertmap(const char * const infile,
|
|
const char * const outfile,
|
|
void (*brushdef) (stringstream &, const vector<TPlanePoints> &),
|
|
queue<vector<string> > &entities) {
|
|
ifstream fin;
|
|
fin.open(infile);
|
|
if (!fin.good()){
|
|
cerr << "error: failed to open input file" << endl;
|
|
return false;
|
|
}
|
|
ofstream fout;
|
|
fout.open(outfile);
|
|
if (!fout.good()) {
|
|
cerr << "error: failed to open output file" << endl;
|
|
return false;
|
|
}
|
|
fout << "{\n"
|
|
<< "\"classname\" \"worldspawn\"" << endl;
|
|
string line;
|
|
while (getline(fin, line)) {
|
|
if (line.find(KEYWORD_PREFAB) != string::npos ||
|
|
line.find(KEYWORD_GLOBAL) != string::npos) {
|
|
parse_prefab(fin, fout, brushdef, entities);
|
|
} else if (line.find(KEYWORD_ENTITY) != string::npos) {
|
|
entities.push(get_entity(fin));
|
|
} else if (line.find(KEYWORD_BRUSH) != string::npos) {
|
|
write(parse_brush<ifstream>(fin), fout, brushdef);
|
|
}
|
|
}
|
|
fout << "}" << endl;
|
|
fin.close();
|
|
fout.close();
|
|
return true;
|
|
}
|