2015-02-02 08:11:03 +05:30
|
|
|
//
|
|
|
|
// Author: Michael Cameron
|
|
|
|
// Email: chronokun@hotmail.com
|
|
|
|
//
|
2017-04-12 12:48:29 +05:30
|
|
|
#include <vector>
|
|
|
|
#include <string>
|
|
|
|
#include <sstream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <iostream>
|
2017-07-13 15:54:02 +05:30
|
|
|
#include <exception>
|
2017-05-06 08:03:26 +05:30
|
|
|
|
2017-07-03 08:52:09 +05:30
|
|
|
#include "cxxopts.hpp"
|
2017-06-18 20:14:42 +05:30
|
|
|
|
2017-05-06 08:03:26 +05:30
|
|
|
#include "oopless-parser.hpp"
|
2017-04-11 20:57:10 +05:30
|
|
|
#include "brushdef.hpp"
|
2015-02-02 08:11:03 +05:30
|
|
|
|
2017-04-11 02:59:47 +05:30
|
|
|
using namespace std;
|
|
|
|
|
2017-07-01 05:03:32 +05:30
|
|
|
//ease of reading function pointer
|
|
|
|
typedef void (*brushdef) (std::stringstream &,
|
|
|
|
const std::vector<TPlanePoints> &);
|
|
|
|
|
|
|
|
#define ARG_INPUT_SHORTALIAS "i"
|
|
|
|
#define ARG_OUTPUT_SHORTALIAS "o"
|
|
|
|
#define ARG_BRUSHFORMAT "gtk"
|
2017-06-18 20:14:42 +05:30
|
|
|
cxxopts::Options arguments(int ac, char ** av) {
|
|
|
|
vector<string> parg = {"input", "output"};
|
|
|
|
cxxopts::Options o("reflex2q3",
|
|
|
|
"A tool to convert Reflex maps to idTech 3 maps.");
|
|
|
|
o.add_options()
|
|
|
|
("h,help", "displays help")
|
|
|
|
("i,input",
|
|
|
|
"required, input map file, from Reflex",
|
|
|
|
cxxopts::value<string>(), "FILE")
|
|
|
|
("o,output",
|
|
|
|
"required, output map file, for idTech 3 or similar map editors",
|
|
|
|
cxxopts::value<string>(), "FILE")
|
2017-07-01 05:03:32 +05:30
|
|
|
(ARG_BRUSHFORMAT,
|
2017-06-18 20:14:42 +05:30
|
|
|
"optional, output in GTK Radiant's brush definition format")
|
|
|
|
("e,ent",
|
|
|
|
"optional, convert game entities given a table of equivalents",
|
|
|
|
cxxopts::value<string>(), "FILE")
|
|
|
|
;
|
|
|
|
o.parse_positional(parg);
|
|
|
|
o.parse(ac, av);
|
|
|
|
if (o.count("help")) {
|
|
|
|
cout << o.help() << endl;
|
|
|
|
}
|
|
|
|
if (o.count(ARG_INPUT_SHORTALIAS) < 1 ||
|
|
|
|
o.count(ARG_OUTPUT_SHORTALIAS) < 1) {
|
|
|
|
cerr << "error: no input or output file given" << endl;
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
return o;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool convert_worldspawn(const cxxopts::Options &o,
|
2017-07-07 02:22:31 +05:30
|
|
|
vector<vector<string> > &q) {
|
2017-06-18 20:14:42 +05:30
|
|
|
bool is_ok = false;
|
|
|
|
brushdef fn = &brushdef_net;
|
2017-07-01 05:03:32 +05:30
|
|
|
if (o.count(ARG_BRUSHFORMAT)) {
|
2017-06-18 20:14:42 +05:30
|
|
|
fn = &brushdef_gtk;
|
|
|
|
}
|
2017-06-17 16:04:19 +05:30
|
|
|
try {
|
2017-06-18 20:14:42 +05:30
|
|
|
is_ok = convertmap(
|
|
|
|
o[ARG_INPUT_SHORTALIAS].as<string>().c_str(), // in file
|
|
|
|
o[ARG_OUTPUT_SHORTALIAS].as<string>().c_str(), // out file
|
|
|
|
fn, // brush definition
|
|
|
|
q); // queue of entities
|
2017-06-17 16:04:19 +05:30
|
|
|
} catch (exception &e) {
|
|
|
|
cout << e.what() << endl;
|
2017-06-18 20:14:42 +05:30
|
|
|
cout << "exception encountered while converting map geometry"
|
|
|
|
" - unrecoverable failure" << endl;
|
2017-06-17 16:04:19 +05:30
|
|
|
}
|
2017-06-18 20:14:42 +05:30
|
|
|
if (is_ok) {
|
2017-06-17 01:38:46 +05:30
|
|
|
cout << "Successfully converted map "
|
2017-06-18 20:14:42 +05:30
|
|
|
<< o[ARG_INPUT_SHORTALIAS].as<string>()
|
2017-06-17 01:38:46 +05:30
|
|
|
<< " to "
|
2017-06-18 20:14:42 +05:30
|
|
|
<< o[ARG_OUTPUT_SHORTALIAS].as<string>()
|
2017-06-17 01:38:46 +05:30
|
|
|
<< endl;
|
|
|
|
} else {
|
|
|
|
cout << "Failed to convert map." << endl;
|
|
|
|
}
|
2017-06-18 20:14:42 +05:30
|
|
|
return is_ok;
|
|
|
|
}
|
|
|
|
|
2017-07-07 02:22:31 +05:30
|
|
|
void print_entities(vector<vector<string> > &q) {
|
2017-07-01 05:03:32 +05:30
|
|
|
vector<string> entity;
|
2017-06-18 20:14:42 +05:30
|
|
|
do {
|
|
|
|
entity = q.front();
|
2017-07-01 05:03:32 +05:30
|
|
|
cout << "--------------------------" << endl;
|
2017-06-18 20:14:42 +05:30
|
|
|
for (const string &s : entity) {
|
|
|
|
cout << s << endl;
|
|
|
|
}
|
2017-07-01 05:03:32 +05:30
|
|
|
cout << "--------------------------" << endl;
|
|
|
|
} while (!q.empty());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-07 06:23:43 +05:30
|
|
|
void convert_entities(const cxxopts::Options &o, const vector<vector<string> > &q) {
|
2017-07-01 05:03:32 +05:30
|
|
|
string entfile = o["e"].as<string>();
|
|
|
|
if (entfile.empty()) {
|
|
|
|
cout << "No entity data file given"
|
|
|
|
"- skipping entity conversion" << endl;
|
|
|
|
return;
|
|
|
|
}
|
2017-07-07 06:23:43 +05:30
|
|
|
EntityConverter e(entfile);
|
|
|
|
e.extractMapInfo(q);
|
2017-07-01 05:03:32 +05:30
|
|
|
ofstream fout(o[ARG_OUTPUT_SHORTALIAS].as<string>(), ios::app);
|
|
|
|
brushdef fn = &brushdef_net;
|
|
|
|
vector<string> entity;
|
|
|
|
if (o.count(ARG_BRUSHFORMAT)) {
|
|
|
|
fn = &brushdef_gtk;
|
|
|
|
}
|
2017-07-07 02:22:31 +05:30
|
|
|
for (const vector<string> &entity : q) {
|
2017-07-13 15:54:02 +05:30
|
|
|
try {
|
|
|
|
write(entity, fout, fn, e);
|
|
|
|
} catch (exception &e) {
|
|
|
|
cerr << e.what() << endl;
|
|
|
|
}
|
2017-07-07 02:22:31 +05:30
|
|
|
}
|
2017-06-18 20:14:42 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char** argv)
|
|
|
|
{
|
|
|
|
cxxopts::Options p = arguments(argc, argv);
|
|
|
|
|
2017-07-07 02:22:31 +05:30
|
|
|
vector<vector<string> > entities;
|
2017-06-18 20:14:42 +05:30
|
|
|
bool is_ok = convert_worldspawn(p, entities);
|
2017-07-01 05:03:32 +05:30
|
|
|
// print_entities(entities);
|
2017-06-18 20:14:42 +05:30
|
|
|
convert_entities(p, entities);
|
2015-02-02 08:11:03 +05:30
|
|
|
return(0);
|
2017-06-17 01:38:46 +05:30
|
|
|
}
|