Merge branch 'master' of https://git.teknik.io/scuti/reflex2q3
This commit is contained in:
commit
9f32ca0568
@ -4,7 +4,7 @@ CFLAGS=-std=c++11 -I"./includes" -I"./includes/Catch/single_include" -I"./includ
|
|||||||
TESTEX=test/test-parser
|
TESTEX=test/test-parser
|
||||||
UNITEX=test/catch
|
UNITEX=test/catch
|
||||||
|
|
||||||
all: main
|
all: main unittest
|
||||||
|
|
||||||
main: planes.o brushdef.o oopless-parser.o EntityConverter.o
|
main: planes.o brushdef.o oopless-parser.o EntityConverter.o
|
||||||
$(CC) $^ main.cpp $(CFLAGS) -o $(EX) 2>error8.log
|
$(CC) $^ main.cpp $(CFLAGS) -o $(EX) 2>error8.log
|
||||||
|
@ -25,25 +25,42 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
* PUBLIC
|
* PUBLIC
|
||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
EntityConverter::EntityConverter(std::string entityMapFile) : OFFSET_PLAYER(32.0), OFFSET_PICKUP(2.0)
|
EntityConverter::EntityConverter(const std::string &entityMapFile) :
|
||||||
|
OFFSET_PLAYER(32.0), OFFSET_PICKUP(2.0), BRIGHTNESS_ADJUST(50.0)
|
||||||
{
|
{
|
||||||
//MUST RUN matchRelated method after this constructor
|
//MUST RUN extractMapInfo method after this constructor
|
||||||
areEntitiesMatched_ = false;
|
haveMapInfo_ = false;
|
||||||
|
// game modes default to enabled
|
||||||
|
ws_.cts = true;
|
||||||
|
ws_.ctf = true;
|
||||||
|
ws_.ffa = true;
|
||||||
|
ws_.tdm = true;
|
||||||
|
ws_.duel = true;
|
||||||
|
|
||||||
mapEntities(entityMapFile);
|
mapEntities(entityMapFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EntityConverter::EntityConverter(std::string entityMapFile, std::string reflexMapFile) : OFFSET_PLAYER(32.0), OFFSET_PICKUP(2.0)
|
EntityConverter::EntityConverter(const std::string &entityMapFile,
|
||||||
|
const std::string &reflexMapFile) : OFFSET_PLAYER(32.0),
|
||||||
|
OFFSET_PICKUP(2.0), BRIGHTNESS_ADJUST(50.0)
|
||||||
{
|
{
|
||||||
|
haveMapInfo_ = false;
|
||||||
|
// game modes default to enabled
|
||||||
|
ws_.cts = true;
|
||||||
|
ws_.ctf = true;
|
||||||
|
ws_.ffa = true;
|
||||||
|
ws_.tdm = true;
|
||||||
|
ws_.duel = true;
|
||||||
|
|
||||||
mapEntities(entityMapFile);
|
mapEntities(entityMapFile);
|
||||||
|
|
||||||
// Pre-scan for related entities
|
// Pre-scan for info needed by converter
|
||||||
std::ifstream fin;
|
std::ifstream fin;
|
||||||
fin.open(reflexMapFile);
|
fin.open(reflexMapFile);
|
||||||
|
|
||||||
@ -51,14 +68,14 @@ EntityConverter::EntityConverter(std::string entityMapFile, std::string reflexMa
|
|||||||
//Extract the source type of targets (teleporters or jump pads)
|
//Extract the source type of targets (teleporters or jump pads)
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(fin, line)) {
|
while (std::getline(fin, line)) {
|
||||||
addIfRelated(line, fin);
|
extractFromEntity(line, fin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw std::ios::failure( "Error: EntityConverter failed to open .map file" );
|
throw std::ios::failure( "Error: EntityConverter failed to open .map file" );
|
||||||
}
|
}
|
||||||
fin.close();
|
fin.close();
|
||||||
areEntitiesMatched_ = true;
|
haveMapInfo_ = true;
|
||||||
|
|
||||||
//DEBUG
|
//DEBUG
|
||||||
//printMapping();
|
//printMapping();
|
||||||
@ -67,24 +84,15 @@ EntityConverter::EntityConverter(std::string entityMapFile, std::string reflexMa
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
*--------------------------------------------------------------------------------------
|
|
||||||
* Class: EntityConverter
|
|
||||||
* Method: EntityConverter :: matchRelated
|
|
||||||
* Description: Read through entities, matching related as necessary
|
|
||||||
* Note: For now, accomplishes the same goal as the pre-scan
|
|
||||||
* constructor
|
|
||||||
*--------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
EntityConverter::matchRelated(std::queue<std::vector<std::string>> entities)
|
EntityConverter::extractMapInfo(std::queue<std::vector<std::string>> entities)
|
||||||
{
|
{
|
||||||
if( areEntitiesMatched_ ) {
|
if( haveMapInfo_ ) {
|
||||||
std::cerr << "Related entities are already matched, doing nothing" << std::endl;
|
std::cerr << "Map info already extracted, doing nothing" << std::endl;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while ( ! entities.empty() ) {
|
while ( ! entities.empty() ) {
|
||||||
std::vector<std::string> entity = entities.front();
|
std::vector<std::string> entity( entities.front() );
|
||||||
entities.pop();
|
entities.pop();
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@ -93,20 +101,47 @@ EntityConverter::matchRelated(std::queue<std::vector<std::string>> entities)
|
|||||||
|
|
||||||
std::string nextLine;
|
std::string nextLine;
|
||||||
if ( getline(ss, nextLine )) {
|
if ( getline(ss, nextLine )) {
|
||||||
addIfRelated(nextLine, ss);
|
extractFromEntity(nextLine, ss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
areEntitiesMatched_ = true;
|
haveMapInfo_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
EntityConverter::extractMapInfo(const std::vector<std::vector<std::string>> &entities)
|
||||||
|
{
|
||||||
|
if( haveMapInfo_ ) {
|
||||||
|
std::cerr << "Map info already extracted, doing nothing" << std::endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::vector<std::vector<std::string>>::const_iterator it;
|
||||||
|
for ( it=entities.begin(); it!=entities.end(); ++it ) {
|
||||||
|
std::vector<std::string> entity( *it );
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
std::copy(entity.begin(), entity.end(),
|
||||||
|
std::ostream_iterator<std::string>(ss, "\n"));
|
||||||
|
|
||||||
|
std::string nextLine;
|
||||||
|
if ( getline(ss, nextLine )) {
|
||||||
|
extractFromEntity(nextLine, ss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
haveMapInfo_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
EntityConverter::convert(std::vector<std::string> lines)
|
EntityConverter::convert(const std::vector<std::string> &lines)
|
||||||
{
|
{
|
||||||
if ( areEntitiesMatched_ )
|
if ( haveMapInfo_ )
|
||||||
{
|
{
|
||||||
std::string attribute;
|
std::string attribute;
|
||||||
std::string trash; //unused tokens
|
std::string trash; //unused tokens
|
||||||
@ -121,8 +156,37 @@ EntityConverter::convert(std::vector<std::string> lines)
|
|||||||
throw std::runtime_error("error: type is required");
|
throw std::runtime_error("error: type is required");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If worldspawn, first reenable all gamemodes
|
||||||
|
// then check worldspawn for disabled modes
|
||||||
|
// then RETURN EMPTY VECTOR
|
||||||
|
if ( type == "WorldSpawn" ) {
|
||||||
|
ws_.cts = true;
|
||||||
|
ws_.ctf = true;
|
||||||
|
ws_.ffa = true;
|
||||||
|
ws_.tdm = true;
|
||||||
|
ws_.duel = true;
|
||||||
|
|
||||||
if ( type == "Pickup" ) {
|
// Each worldspawn can specify modes enabled/disabled
|
||||||
|
for ( int i = 1; i < lines.size(); ++i ) {
|
||||||
|
if ( lines[i].find("modeRace 0") != std::string::npos) {
|
||||||
|
ws_.cts = false;
|
||||||
|
}
|
||||||
|
else if ( lines[i].find("modeCTF 0") != std::string::npos) {
|
||||||
|
ws_.ctf = false;
|
||||||
|
}
|
||||||
|
else if ( lines[i].find("modeFFA 0") != std::string::npos) {
|
||||||
|
ws_.ffa = false;
|
||||||
|
}
|
||||||
|
else if ( lines[i].find("modeTDM 0") != std::string::npos) {
|
||||||
|
ws_.tdm = false;
|
||||||
|
}
|
||||||
|
else if ( lines[i].find("mode1v1 0") != std::string::npos) {
|
||||||
|
ws_.duel = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if ( type == "Pickup" ) {
|
||||||
return convertPickup(lines);
|
return convertPickup(lines);
|
||||||
}
|
}
|
||||||
else if ( type == "PlayerSpawn" ) {
|
else if ( type == "PlayerSpawn" ) {
|
||||||
@ -143,9 +207,12 @@ EntityConverter::convert(std::vector<std::string> lines)
|
|||||||
else if ( type == "RaceFinish" ) {
|
else if ( type == "RaceFinish" ) {
|
||||||
return convertRaceFinish(lines);
|
return convertRaceFinish(lines);
|
||||||
}
|
}
|
||||||
|
else if ( type == "PointLight" ) {
|
||||||
|
return convertPointLight(lines);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw std::runtime_error( "error: related entities must be matched prior to conversion" );
|
throw std::runtime_error( "error: Map info must be extracted prior to conversion" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// If unsupported entity, return empty vector
|
// If unsupported entity, return empty vector
|
||||||
@ -159,7 +226,7 @@ EntityConverter::convert(std::vector<std::string> lines)
|
|||||||
* PROTECTED
|
* PROTECTED
|
||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
EntityConverter::convertPickup(std::vector<std::string> &lines)
|
EntityConverter::convertPickup(const std::vector<std::string> &lines) const
|
||||||
{
|
{
|
||||||
std::vector<std::string> convertedLines;
|
std::vector<std::string> convertedLines;
|
||||||
//can ignore angle of pickups in xonotic format
|
//can ignore angle of pickups in xonotic format
|
||||||
@ -195,14 +262,14 @@ EntityConverter::convertPickup(std::vector<std::string> &lines)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( havePosition && havePickupID ) {
|
if ( havePosition && havePickupID ) {
|
||||||
std::stringstream oss;
|
std::stringstream pickupStream;
|
||||||
oss << "\"classname\" \"" << pickupMapping_[pickupID] << "\"" << std::endl;
|
pickupStream << "\"classname\" \"" << pickupMapping_.find(pickupID)->second << "\"" << std::endl;
|
||||||
convertedLines.push_back ( oss.str() );
|
convertedLines.push_back ( pickupStream.str() );
|
||||||
// coordinates reordered to x, z, y
|
// coordinates reordered to x, z, y
|
||||||
std::stringstream oss2;
|
std::stringstream positionStream;
|
||||||
oss2 << "\"origin\" \"" << coords[0] << " " << coords[2] << " " <<
|
positionStream << "\"origin\" \"" << coords[0] << " " << coords[2] << " " <<
|
||||||
offset(coords[1], OFFSET_PICKUP) << "\"" << std::endl;
|
offset(coords[1], OFFSET_PICKUP) << "\"" << std::endl;
|
||||||
convertedLines.push_back ( oss2.str() );
|
convertedLines.push_back ( positionStream.str() );
|
||||||
return convertedLines;
|
return convertedLines;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -223,7 +290,7 @@ EntityConverter::convertPickup(std::vector<std::string> &lines)
|
|||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
EntityConverter::convertPlayerSpawn(std::vector<std::string> &lines)
|
EntityConverter::convertPlayerSpawn(const std::vector<std::string> &lines) const
|
||||||
{
|
{
|
||||||
std::vector<std::string> convertedLines;
|
std::vector<std::string> convertedLines;
|
||||||
// Requires position coordinate
|
// Requires position coordinate
|
||||||
@ -234,7 +301,11 @@ EntityConverter::convertPlayerSpawn(std::vector<std::string> &lines)
|
|||||||
int team = 0;
|
int team = 0;
|
||||||
std::string trash;
|
std::string trash;
|
||||||
bool havePosition = false;
|
bool havePosition = false;
|
||||||
bool isModeRace = true;
|
bool isModeRace = ws_.cts;
|
||||||
|
bool isModeCtf = ws_.ctf;
|
||||||
|
bool isModeTdm = ws_.tdm;
|
||||||
|
bool isModeFfa = ws_.ffa;
|
||||||
|
bool isModeDuel = ws_.duel;
|
||||||
|
|
||||||
|
|
||||||
if ( lines.size() < 2 ) {
|
if ( lines.size() < 2 ) {
|
||||||
@ -259,9 +330,22 @@ EntityConverter::convertPlayerSpawn(std::vector<std::string> &lines)
|
|||||||
throw std::runtime_error("error: Pickup entity requires Pickup ID");
|
throw std::runtime_error("error: Pickup entity requires Pickup ID");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Bool8 modeX 0 indicates this spawn is not for game mode X
|
||||||
else if ( type == "modeRace" ) {
|
else if ( type == "modeRace" ) {
|
||||||
isModeRace = false;
|
isModeRace = false;
|
||||||
}
|
}
|
||||||
|
else if ( type == "modeCTF" ) {
|
||||||
|
isModeCtf = false;
|
||||||
|
}
|
||||||
|
else if ( type == "modeTDM" ) {
|
||||||
|
isModeTdm = false;
|
||||||
|
}
|
||||||
|
else if ( type == "modeFFA" ) {
|
||||||
|
isModeFfa = false;
|
||||||
|
}
|
||||||
|
else if ( type == "mode1v1" ) {
|
||||||
|
isModeDuel = false;
|
||||||
|
}
|
||||||
else if ( type == "teamA" ) {
|
else if ( type == "teamA" ) {
|
||||||
team = 2; // Bool8 teamA 0 indicates teamB only
|
team = 2; // Bool8 teamA 0 indicates teamB only
|
||||||
}
|
}
|
||||||
@ -271,7 +355,8 @@ EntityConverter::convertPlayerSpawn(std::vector<std::string> &lines)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( havePosition ) {
|
if ( havePosition ) {
|
||||||
if ( ! isModeRace ) {
|
// Will convert all race points to dm/team spawns on maps that support race AND others
|
||||||
|
if ( isModeCtf || isModeTdm || isModeFfa || isModeDuel ) {
|
||||||
switch (team) {
|
switch (team) {
|
||||||
case 0:
|
case 0:
|
||||||
convertedLines.push_back ( "\"classname\" \"info_player_deathmatch\"\n" );
|
convertedLines.push_back ( "\"classname\" \"info_player_deathmatch\"\n" );
|
||||||
@ -283,7 +368,6 @@ EntityConverter::convertPlayerSpawn(std::vector<std::string> &lines)
|
|||||||
convertedLines.push_back ( "\"classname\" \"info_player_team2\"\n" );
|
convertedLines.push_back ( "\"classname\" \"info_player_team2\"\n" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
convertedLines.push_back ( "\"classname\" \"info_player_race\"\n" );
|
convertedLines.push_back ( "\"classname\" \"info_player_race\"\n" );
|
||||||
@ -293,14 +377,14 @@ EntityConverter::convertPlayerSpawn(std::vector<std::string> &lines)
|
|||||||
convertedLines.push_back ( "\"race_place\" \"-1\"\n" );
|
convertedLines.push_back ( "\"race_place\" \"-1\"\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::stringstream oss;
|
std::stringstream positionStream;
|
||||||
// coordinates reordered to x, z, y
|
// coordinates reordered to x, z, y
|
||||||
oss << "\"origin\" \"" << coords[0] << " " << coords[2] << " " <<
|
positionStream << "\"origin\" \"" << coords[0] << " " << coords[2] << " " <<
|
||||||
offset(coords[1], OFFSET_PLAYER) << "\"" << std::endl;
|
offset(coords[1], OFFSET_PLAYER) << "\"" << std::endl;
|
||||||
convertedLines.push_back ( oss.str() );
|
convertedLines.push_back ( positionStream.str() );
|
||||||
std::stringstream oss2;
|
std::stringstream angleStream;
|
||||||
oss2 << "\"angle\" \"" << angle << "\"" << std::endl;
|
angleStream << "\"angle\" \"" << angle << "\"" << std::endl;
|
||||||
convertedLines.push_back ( oss2.str() );
|
convertedLines.push_back (angleStream.str() );
|
||||||
return convertedLines;
|
return convertedLines;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -311,7 +395,7 @@ EntityConverter::convertPlayerSpawn(std::vector<std::string> &lines)
|
|||||||
|
|
||||||
|
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
EntityConverter::convertJumpPad(std::vector<std::string> &lines)
|
EntityConverter::convertJumpPad(const std::vector<std::string> &lines) const
|
||||||
{
|
{
|
||||||
std::vector<std::string> convertedLines;
|
std::vector<std::string> convertedLines;
|
||||||
std::string targetName;
|
std::string targetName;
|
||||||
@ -336,7 +420,7 @@ EntityConverter::convertJumpPad(std::vector<std::string> &lines)
|
|||||||
|
|
||||||
|
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
EntityConverter::convertTeleporter(std::vector<std::string> &lines)
|
EntityConverter::convertTeleporter(const std::vector<std::string> &lines) const
|
||||||
{
|
{
|
||||||
std::vector<std::string> convertedLines;
|
std::vector<std::string> convertedLines;
|
||||||
std::string targetName;
|
std::string targetName;
|
||||||
@ -361,7 +445,7 @@ EntityConverter::convertTeleporter(std::vector<std::string> &lines)
|
|||||||
|
|
||||||
|
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
EntityConverter::convertTarget(std::vector<std::string> &lines)
|
EntityConverter::convertTarget(const std::vector<std::string> &lines) const
|
||||||
{
|
{
|
||||||
std::vector<std::string> convertedLines;
|
std::vector<std::string> convertedLines;
|
||||||
//position and name required, angles optional
|
//position and name required, angles optional
|
||||||
@ -409,7 +493,7 @@ EntityConverter::convertTarget(std::vector<std::string> &lines)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( havePosition && haveName) {
|
if ( havePosition && haveName) {
|
||||||
if ( targetMap_[targetName] == "Teleporter") {
|
if ( targetMap_.find(targetName)->second == "Teleporter") {
|
||||||
convertedLines.push_back ( "\"classname\" \"misc_teleporter_dest\"\n" );
|
convertedLines.push_back ( "\"classname\" \"misc_teleporter_dest\"\n" );
|
||||||
// coordinates reordered to x, z, y
|
// coordinates reordered to x, z, y
|
||||||
// teleporter height is OFFSET
|
// teleporter height is OFFSET
|
||||||
@ -418,7 +502,7 @@ EntityConverter::convertTarget(std::vector<std::string> &lines)
|
|||||||
offset(coords[1], OFFSET_PLAYER) << "\"" << std::endl;
|
offset(coords[1], OFFSET_PLAYER) << "\"" << std::endl;
|
||||||
convertedLines.push_back ( oss.str() );
|
convertedLines.push_back ( oss.str() );
|
||||||
}
|
}
|
||||||
else if ( targetMap_[targetName] == "JumpPad") {
|
else if ( targetMap_.find(targetName)->second == "JumpPad") {
|
||||||
convertedLines.push_back ( "\"classname\" \"target_position\"\n" );
|
convertedLines.push_back ( "\"classname\" \"target_position\"\n" );
|
||||||
// coordinates reordered to x, z, y
|
// coordinates reordered to x, z, y
|
||||||
std::stringstream oss;
|
std::stringstream oss;
|
||||||
@ -426,15 +510,15 @@ EntityConverter::convertTarget(std::vector<std::string> &lines)
|
|||||||
coords[1] << "\"" << std::endl;
|
coords[1] << "\"" << std::endl;
|
||||||
convertedLines.push_back ( oss.str() );
|
convertedLines.push_back ( oss.str() );
|
||||||
}
|
}
|
||||||
std::stringstream oss;
|
std::stringstream targetStream;
|
||||||
oss << "\"targetname\" \"" << targetName << "\"" << std::endl;
|
targetStream << "\"targetname\" \"" << targetName << "\"" << std::endl;
|
||||||
convertedLines.push_back ( oss.str() );
|
convertedLines.push_back ( targetStream.str() );
|
||||||
|
|
||||||
// Write angle only if position and name exist
|
// Write angle only if position and name exist
|
||||||
if ( haveAngle ) {
|
if ( haveAngle ) {
|
||||||
std::stringstream oss2;
|
std::stringstream angleStream;
|
||||||
oss2 << "\"angle\" \"" << angle << "\"" << std::endl;
|
angleStream << "\"angle\" \"" << angle << "\"" << std::endl;
|
||||||
convertedLines.push_back (oss2.str() );
|
convertedLines.push_back( angleStream.str() );
|
||||||
}
|
}
|
||||||
return convertedLines;
|
return convertedLines;
|
||||||
}
|
}
|
||||||
@ -447,7 +531,7 @@ EntityConverter::convertTarget(std::vector<std::string> &lines)
|
|||||||
|
|
||||||
|
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
EntityConverter::convertRaceStart(std::vector<std::string> &lines)
|
EntityConverter::convertRaceStart(const std::vector<std::string> &lines) const
|
||||||
{
|
{
|
||||||
std::vector<std::string> convertedLines;
|
std::vector<std::string> convertedLines;
|
||||||
convertedLines.push_back ("\"classname\" \"trigger_race_checkpoint\"\n");
|
convertedLines.push_back ("\"classname\" \"trigger_race_checkpoint\"\n");
|
||||||
@ -459,7 +543,7 @@ EntityConverter::convertRaceStart(std::vector<std::string> &lines)
|
|||||||
|
|
||||||
|
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
EntityConverter::convertRaceFinish(std::vector<std::string> &lines)
|
EntityConverter::convertRaceFinish(const std::vector<std::string> &lines) const
|
||||||
{
|
{
|
||||||
std::vector<std::string> convertedLines;
|
std::vector<std::string> convertedLines;
|
||||||
convertedLines.push_back ("\"classname\" \"trigger_race_checkpoint\"\n");
|
convertedLines.push_back ("\"classname\" \"trigger_race_checkpoint\"\n");
|
||||||
@ -470,12 +554,91 @@ EntityConverter::convertRaceFinish(std::vector<std::string> &lines)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<std::string>
|
||||||
|
EntityConverter::convertPointLight(const std::vector<std::string> &lines) const
|
||||||
|
{
|
||||||
|
std::vector<std::string> convertedLines;
|
||||||
|
//position and intensity required, color optional
|
||||||
|
std::string coords[3];
|
||||||
|
std::string intensity;
|
||||||
|
//color is hex 8 digits
|
||||||
|
std::string color;
|
||||||
|
std::string trash;
|
||||||
|
bool havePosition = false;
|
||||||
|
bool haveIntensity = false;
|
||||||
|
bool haveColor = false;
|
||||||
|
|
||||||
|
|
||||||
|
if ( lines.size() < 3 ) {
|
||||||
|
throw std::runtime_error("error: PointLight entity requires at least 3 lines");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < lines.size(); i++) {
|
||||||
|
std::string type = getAttributeType(lines[i]);
|
||||||
|
if ( type == "position" ) {
|
||||||
|
std::istringstream iss(lines[i]);
|
||||||
|
// Vector3 position coord0 coord1 coord2
|
||||||
|
if ( ! (iss >> trash >> trash >>
|
||||||
|
coords[0] >> coords[1] >> coords[2])) {
|
||||||
|
throw std::runtime_error( "error: PointLight entity requires position coordinates" );
|
||||||
|
}
|
||||||
|
havePosition = true;
|
||||||
|
}
|
||||||
|
else if ( type == "intensity" ) {
|
||||||
|
std::istringstream iss(lines[i]);
|
||||||
|
// Float intensity validFloat
|
||||||
|
if ( ! (iss >> trash >> trash >> intensity) ) {
|
||||||
|
throw std::runtime_error( "error: PointLight entity requires intensity value" );
|
||||||
|
}
|
||||||
|
haveIntensity = true;
|
||||||
|
}
|
||||||
|
else if ( type == "color" ) {
|
||||||
|
std::istringstream iss(lines[i]);
|
||||||
|
// ColourXRGB32 color eightDigitHexValue
|
||||||
|
if ( ! (iss >> trash >> trash >> color) ) {
|
||||||
|
throw std::runtime_error( "error: PointLight entity requires valid float value if specified" );
|
||||||
|
}
|
||||||
|
haveColor = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( havePosition && haveIntensity) {
|
||||||
|
convertedLines.push_back ( "\"classname\" \"light\"\n" );
|
||||||
|
// coordinates reordered to x, z, y
|
||||||
|
std::stringstream positionStream;
|
||||||
|
positionStream << "\"origin\" \"" << coords[0] << " " << coords[2] << " " <<
|
||||||
|
coords[1] << "\"" << std::endl;
|
||||||
|
convertedLines.push_back ( positionStream.str() );
|
||||||
|
// convert intensity
|
||||||
|
std::stringstream intensityStream;
|
||||||
|
intensityStream << "\"light\" \"" << adjustBrightness(intensity) << "\"\n";
|
||||||
|
convertedLines.push_back ( intensityStream.str() );
|
||||||
|
|
||||||
|
if ( haveColor ) {
|
||||||
|
std::stringstream colorStream;
|
||||||
|
float red;
|
||||||
|
float green;
|
||||||
|
float blue;
|
||||||
|
// Convert 32bit hex value into RGB values
|
||||||
|
hexToRGB(color, red, green, blue);
|
||||||
|
colorStream << "\"_color\" \"" << red << " " << green << " " << blue << "\"" << std::endl;
|
||||||
|
convertedLines.push_back (colorStream.str() );
|
||||||
|
}
|
||||||
|
return convertedLines;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw std::runtime_error("error: Target entity requires position coordinates and targetname");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
* PRIVATE
|
* PRIVATE
|
||||||
*-----------------------------------------------------------------------------*/
|
*-----------------------------------------------------------------------------*/
|
||||||
std::string
|
std::string
|
||||||
EntityConverter::getAttributeType(std::string line)
|
EntityConverter::getAttributeType(const std::string &line) const
|
||||||
{
|
{
|
||||||
std::string type;
|
std::string type;
|
||||||
std::string dataType;
|
std::string dataType;
|
||||||
@ -490,7 +653,7 @@ EntityConverter::getAttributeType(std::string line)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EntityConverter::mapEntities(std::string mapFile)
|
EntityConverter::mapEntities(const std::string &mapFile)
|
||||||
{
|
{
|
||||||
std::ifstream fin;
|
std::ifstream fin;
|
||||||
fin.open(mapFile);
|
fin.open(mapFile);
|
||||||
@ -519,32 +682,34 @@ EntityConverter::mapEntities(std::string mapFile)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EntityConverter::addIfRelated(std::string &line, std::istream &is)
|
EntityConverter::extractFromEntity(const std::string &line, std::istream &is)
|
||||||
{
|
{
|
||||||
std::string trash;
|
std::string trash;
|
||||||
std::string targetName;
|
std::string targetName;
|
||||||
|
std::string nextLine;
|
||||||
if ( line.find("type Teleporter") != std::string::npos) {
|
if ( line.find("type Teleporter") != std::string::npos) {
|
||||||
std::getline(is, line);
|
std::getline(is, nextLine);
|
||||||
std::istringstream iss(line);
|
std::istringstream iss(nextLine);
|
||||||
if ( ! (iss >> trash >> trash >> targetName)) {
|
if ( ! (iss >> trash >> trash >> targetName)) {
|
||||||
throw std::runtime_error( "format error in .map file");
|
throw std::runtime_error( "format error in .map file");
|
||||||
}
|
}
|
||||||
targetMap_.insert ( std::pair<std::string, std::string>(targetName, "Teleporter") );
|
targetMap_.insert ( std::pair<std::string, std::string>(targetName, "Teleporter") );
|
||||||
}
|
}
|
||||||
else if ( line.find("type JumpPad") != std::string::npos) {
|
else if ( line.find("type JumpPad") != std::string::npos) {
|
||||||
std::getline(is, line);
|
std::getline(is, nextLine);
|
||||||
std::istringstream iss(line);
|
std::istringstream iss(nextLine);
|
||||||
if ( ! (iss >> trash >> trash >> targetName)) {
|
if ( ! (iss >> trash >> trash >> targetName)) {
|
||||||
throw std::runtime_error( "format error in .map file");
|
throw std::runtime_error( "format error in .map file");
|
||||||
}
|
}
|
||||||
targetMap_.insert ( std::pair<std::string, std::string>(targetName, "JumpPad") );
|
targetMap_.insert ( std::pair<std::string, std::string>(targetName, "JumpPad") );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string EntityConverter::offset(std::string value, float amount) {
|
std::string
|
||||||
|
EntityConverter::offset(const std::string &value, const float amount) const
|
||||||
|
{
|
||||||
std::istringstream iss(value);
|
std::istringstream iss(value);
|
||||||
float c;
|
float c;
|
||||||
iss >> c;
|
iss >> c;
|
||||||
@ -557,21 +722,50 @@ std::string EntityConverter::offset(std::string value, float amount) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
EntityConverter::hexToRGB(const std::string &hex, float &r, float &g, float &b) const
|
||||||
|
{
|
||||||
|
unsigned int value;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::hex << hex;
|
||||||
|
ss >> value;
|
||||||
|
|
||||||
|
// get the necessary components from the top 3 bytes
|
||||||
|
r = ((value >> 16) & 0xFF) / 255.0;
|
||||||
|
g = ((value >> 8) & 0xFF) / 255.0;
|
||||||
|
b = ((value) & 0xFF) / 255.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
EntityConverter::adjustBrightness(const std::string &value) const
|
||||||
|
{
|
||||||
|
float inputBright;
|
||||||
|
std::stringstream ss(value);
|
||||||
|
ss >> inputBright;
|
||||||
|
|
||||||
|
return static_cast<int>(inputBright * BRIGHTNESS_ADJUST);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
void
|
void
|
||||||
EntityConverter::printMapping()
|
EntityConverter::printMapping() const
|
||||||
{
|
{
|
||||||
std::map<int, std::string>::iterator it;
|
std::cout << std::endl << "Reflex pickup ID mapped to Xonotic pickup names: " << std::endl;
|
||||||
|
std::map<int, std::string>::const_iterator it;
|
||||||
for ( it=pickupMapping_.begin(); it!=pickupMapping_.end(); ++it )
|
for ( it=pickupMapping_.begin(); it!=pickupMapping_.end(); ++it )
|
||||||
std::cout << it->first << " => " << it->second << std::endl;
|
std::cout << it->first << " => " << it->second << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
void
|
void
|
||||||
EntityConverter::printTargetSources()
|
EntityConverter::printTargetSources() const
|
||||||
{
|
{
|
||||||
std::map<std::string, std::string>::iterator it;
|
std::cout << std::endl << "Target and Sources: " << std::endl;
|
||||||
|
std::map<std::string, std::string>::const_iterator it;
|
||||||
for ( it=targetMap_.begin(); it!=targetMap_.end(); ++it )
|
for ( it=targetMap_.begin(); it!=targetMap_.end(); ++it )
|
||||||
std::cout << it->first << " => " << it->second << std::endl;
|
std::cout << it->first << " => " << it->second << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,19 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct WorldSpawn
|
||||||
|
{
|
||||||
|
bool cts;
|
||||||
|
bool ctf;
|
||||||
|
bool ffa;
|
||||||
|
bool tdm;
|
||||||
|
bool duel;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class EntityConverter
|
class EntityConverter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -43,24 +56,24 @@ class EntityConverter
|
|||||||
* Class: EntityConverter
|
* Class: EntityConverter
|
||||||
* Method: Constructor
|
* Method: Constructor
|
||||||
* Description: Creates entity format mapping
|
* Description: Creates entity format mapping
|
||||||
* CAUTION: Requires matchRelated method to be called after this
|
* CAUTION: Requires extractMapInfo method to be called after this
|
||||||
* Requires: .ent filename for mapping entities from reflex format to xonotic format
|
* Requires: .ent filename for mapping entities from reflex format to xonotic format
|
||||||
* THROWS: runtime_error on .ent format error
|
* THROWS: runtime_error on .ent format error
|
||||||
* THROWS: std::ios::failure on IO failure
|
* THROWS: std::ios::failure on IO failure
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
EntityConverter(std::string entityMapFile);
|
EntityConverter(const std::string &entityMapFile);
|
||||||
/* *--------------------------------------------------------------------------------------
|
/* *--------------------------------------------------------------------------------------
|
||||||
* Class: EntityConverter
|
* Class: EntityConverter
|
||||||
* Method: Constructor
|
* Method: Constructor
|
||||||
* Description: Creates entity format mapping and pre-scans for related entities
|
* Description: Creates entity format mapping and pre-scans for map info
|
||||||
* Parameter: string entityMapFile, file maps source to target entity formats
|
* Parameter: string entityMapFile, file maps source to target entity formats
|
||||||
* Parameter: string reflexMapFile, for pre-scan
|
* Parameter: string reflexMapFile, for pre-scan
|
||||||
* THROWS: runtime_error on .ent format error
|
* THROWS: runtime_error on .ent format error
|
||||||
* THROWS: std::ios::failure on IO failure
|
* THROWS: std::ios::failure on IO failure
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
EntityConverter(std::string entityMapFile, std::string reflexMapFile);
|
EntityConverter(const std::string &entityMapFile, const std::string &reflexMapFile);
|
||||||
/*
|
/*
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
* Class: EntityConverter
|
* Class: EntityConverter
|
||||||
@ -70,21 +83,32 @@ class EntityConverter
|
|||||||
* Return: vector of strings, single entity in the converted format
|
* Return: vector of strings, single entity in the converted format
|
||||||
* *IF entity is not supported, returns EMPTY vector
|
* *IF entity is not supported, returns EMPTY vector
|
||||||
* THROWS: runtime_error on malformed .map file
|
* THROWS: runtime_error on malformed .map file
|
||||||
* THROWS: runtime_error when called before related entities are matched
|
* THROWS: runtime_error when called before map info has been extracted
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
std::vector<std::string> convert(std::vector<std::string> lines);
|
std::vector<std::string> convert(const std::vector<std::string> &lines);
|
||||||
/*
|
/*
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
* Class: EntityConverter
|
* Class: EntityConverter
|
||||||
* Method: EntityConverter :: matchRelated
|
* Method: EntityConverter :: extractMapInfo
|
||||||
* Description: Finds related entities (targets of teleports, etc), call after parsing
|
* Description: Get information needed by the converter that can't be obtained
|
||||||
* the entire .map
|
* in entity-by-entity conversion (teleport and jump pad
|
||||||
* Parameter: queue of vector of string entities, ALL entities in a .map file
|
* Parameter: queue of vector of string entities, ALL entities in a .map file
|
||||||
* THROWS: runtime_error when encountering malformed entity
|
* THROWS: runtime_error when encountering malformed entity
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
void matchRelated(std::queue<std::vector<std::string>> entities);
|
void extractMapInfo(std::queue<std::vector<std::string>> entities);
|
||||||
|
/*
|
||||||
|
*--------------------------------------------------------------------------------------
|
||||||
|
* Class: EntityConverter
|
||||||
|
* Method: EntityConverter :: extractMapInfo
|
||||||
|
* Description: Get information needed by the converter that can't be obtained
|
||||||
|
* in entity-by-entity conversion (teleport and jump pad
|
||||||
|
* Parameter: vector of vector of string entities, ALL entities in a .map file
|
||||||
|
* THROWS: runtime_error when encountering malformed entity
|
||||||
|
*--------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void extractMapInfo(const std::vector<std::vector<std::string>> &entities);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -96,29 +120,34 @@ class EntityConverter
|
|||||||
* Class: EntityConverter
|
* Class: EntityConverter
|
||||||
* Method: EntityConverter :: convert~EntityName~
|
* Method: EntityConverter :: convert~EntityName~
|
||||||
* Description: Multiple methods to convert entity from reflex to xonotic format
|
* Description: Multiple methods to convert entity from reflex to xonotic format
|
||||||
* Parameter: vector of strings entity, multi-lined entity
|
* Parameter: vector of strings lines, multi-lined entity
|
||||||
* Return: vector of strings, the converted entity
|
* Return: vector of strings, the converted entity
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
std::vector<std::string> convertPickup(std::vector<std::string> &entity);
|
std::vector<std::string> convertPickup(const std::vector<std::string> &lines) const;
|
||||||
std::vector<std::string> convertPlayerSpawn(std::vector<std::string> &entity);
|
std::vector<std::string> convertPlayerSpawn(const std::vector<std::string> &lines) const;
|
||||||
std::vector<std::string> convertJumpPad(std::vector<std::string> &entity);
|
std::vector<std::string> convertJumpPad(const std::vector<std::string> &lines) const;
|
||||||
std::vector<std::string> convertTeleporter(std::vector<std::string> &entity);
|
std::vector<std::string> convertTeleporter(const std::vector<std::string> &lines) const;
|
||||||
std::vector<std::string> convertTarget(std::vector<std::string> &entity);
|
std::vector<std::string> convertTarget(const std::vector<std::string> &lines) const;
|
||||||
std::vector<std::string> convertRaceStart(std::vector<std::string> &entity);
|
std::vector<std::string> convertRaceStart(const std::vector<std::string> &lines) const;
|
||||||
std::vector<std::string> convertRaceFinish(std::vector<std::string> &entity);
|
std::vector<std::string> convertRaceFinish(const std::vector<std::string> &lines) const;
|
||||||
|
std::vector<std::string> convertPointLight(const std::vector<std::string> &lines) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Related entities must be matched prior to entity conversion
|
|
||||||
bool areEntitiesMatched_;
|
|
||||||
// Map Reflex pickup IDs to Xonotic pickup identifiers
|
// Map Reflex pickup IDs to Xonotic pickup identifiers
|
||||||
std::map<int, std::string> pickupMapping_;
|
std::map<int, std::string> pickupMapping_;
|
||||||
// Map targets (by name) to their source type
|
// Map targets (by name) to their source type
|
||||||
std::map<std::string, std::string> targetMap_;
|
std::map<std::string, std::string> targetMap_;
|
||||||
|
// Related entities must be matched prior to entity conversion
|
||||||
|
bool haveMapInfo_;
|
||||||
|
WorldSpawn ws_;
|
||||||
|
|
||||||
// Offsets for item/spawn height
|
// Offsets for item/spawn height
|
||||||
const float OFFSET_PLAYER;
|
const float OFFSET_PLAYER;
|
||||||
const float OFFSET_PICKUP;
|
const float OFFSET_PICKUP;
|
||||||
|
// Brightness adjustment factor
|
||||||
|
const float BRIGHTNESS_ADJUST;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -131,7 +160,7 @@ class EntityConverter
|
|||||||
* Parameter: string "line", entity keyword followed by the type
|
* Parameter: string "line", entity keyword followed by the type
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
std::string getAttributeType(std::string line);
|
std::string getAttributeType(const std::string &line) const;
|
||||||
/*
|
/*
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
* Class: EntityConverter
|
* Class: EntityConverter
|
||||||
@ -141,18 +170,18 @@ class EntityConverter
|
|||||||
* Return: true if no error, false if error
|
* Return: true if no error, false if error
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
void mapEntities(std::string mapFile);
|
void mapEntities(const std::string &mapFile);
|
||||||
/*
|
/*
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
* Class: EntityConverter
|
* Class: EntityConverter
|
||||||
* Method: EntityConverter :: addIfRelated
|
* Method: EntityConverter :: extractFromEntity
|
||||||
* Description: If the entity contains a related target/etc, add to map
|
* Description: Get map info from a single entity
|
||||||
* Paramater: string line, the previous line (contains entity type)
|
* Paramater: string line, the previous line (contains entity type)
|
||||||
* Parameter: istream is, an ifstream or a stringstream containing a
|
* Parameter: istream is, an ifstream or a stringstream containing a
|
||||||
* single entity
|
* single entity
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
void addIfRelated(std::string &line, std::istream &is);
|
void extractFromEntity(const std::string &line, std::istream &is);
|
||||||
/*
|
/*
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
* Class: EntityConverter
|
* Class: EntityConverter
|
||||||
@ -164,12 +193,33 @@ class EntityConverter
|
|||||||
* Return: string, float value passed as string
|
* Return: string, float value passed as string
|
||||||
*--------------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
std::string offset(std::string value, float offset);
|
std::string offset(const std::string &value, const float offset) const;
|
||||||
|
/*
|
||||||
|
*--------------------------------------------------------------------------------------
|
||||||
|
* Class: EntityConverter
|
||||||
|
* Method: EntityConverter :: hexToRGB
|
||||||
|
* Description: Convert 8 digit hex value into separate red, green, and blue values
|
||||||
|
* Parameter: string hex, inputted hex value
|
||||||
|
* Parameter: float r, RETURN BY REFERENCE: converted red value
|
||||||
|
* Parameter: float g, RETURN BY REFERENCE: converted green value
|
||||||
|
* Parameter: float b, RETURN BY REFERENCE: converted blue value
|
||||||
|
*--------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void hexToRGB(const std::string &hex, float &r, float &g, float &b) const;
|
||||||
|
/*
|
||||||
|
*--------------------------------------------------------------------------------------
|
||||||
|
* Class: EntityConverter
|
||||||
|
* Method: EntityConverter :: adjustBrightness
|
||||||
|
* Description: Reflex uses significantly smaller values than Xonotic -> adjust
|
||||||
|
* Parameter: string value, original brightness value
|
||||||
|
*--------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
int adjustBrightness(const std::string &value) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void printMapping(); //DEBUG
|
void printMapping() const; //DEBUG
|
||||||
void printTargetSources(); //DEBUG
|
void printTargetSources() const; //DEBUG
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
40 item_health_small
|
40 item_health_small
|
||||||
41 item_health_medium
|
41 item_health_medium
|
||||||
42 item_health_large
|
42 item_health_big
|
||||||
43 item_health_mega
|
43 item_health_mega
|
||||||
50 item_armor_small
|
50 item_armor_small
|
||||||
51 item_armor_medium
|
51 item_armor_medium
|
||||||
52 item_armor_large
|
52 item_armor_big
|
||||||
53 item_armor_big
|
53 item_armor_mega
|
||||||
1 weapon_uzi
|
1 weapon_uzi
|
||||||
2 weapon_grenadelauncher
|
2 weapon_grenadelauncher
|
||||||
3 weapon_hagar
|
3 weapon_hagar
|
||||||
|
@ -37,14 +37,14 @@ TEST_CASE( "r2x: Unsupported entity types cause return of empty vector", "[Entit
|
|||||||
|
|
||||||
// Mock up entity
|
// Mock up entity
|
||||||
std::vector<std::string> entity;
|
std::vector<std::string> entity;
|
||||||
entity.push_back(" type Worldspawn");
|
entity.push_back(" type NotAType");
|
||||||
|
|
||||||
// Mock up entity queue
|
// Mock up entity queue
|
||||||
std::queue<std::vector<std::string>> q;
|
std::queue<std::vector<std::string>> q;
|
||||||
q.push( entity );
|
q.push( entity );
|
||||||
|
|
||||||
// Match related entities (none)
|
// Match related entities (none)
|
||||||
ec.matchRelated( q );
|
ec.extractMapInfo( q );
|
||||||
|
|
||||||
// Convert a single entity
|
// Convert a single entity
|
||||||
std::vector<std::string> converted = ec.convert(entity);
|
std::vector<std::string> converted = ec.convert(entity);
|
||||||
@ -71,7 +71,7 @@ TEST_CASE( "r2x: a single Pickup entity can be converted", "[EntityConverter]" )
|
|||||||
q.push( entity );
|
q.push( entity );
|
||||||
|
|
||||||
// Match related entities (none)
|
// Match related entities (none)
|
||||||
ec.matchRelated( q );
|
ec.extractMapInfo( q );
|
||||||
|
|
||||||
// Convert a single entity
|
// Convert a single entity
|
||||||
std::vector<std::string> converted = ec.convert(entity);
|
std::vector<std::string> converted = ec.convert(entity);
|
||||||
@ -98,6 +98,16 @@ TEST_CASE( "r2x: a single PlayerSpawn (race) entity can be converted", "[EntityC
|
|||||||
// Instantiate object
|
// Instantiate object
|
||||||
EntityConverter ec (PICKUP_FILENAME);
|
EntityConverter ec (PICKUP_FILENAME);
|
||||||
|
|
||||||
|
// Mock up WorldSpawn entity
|
||||||
|
// (needed for mode info)
|
||||||
|
std::vector<std::string> worldspawn;
|
||||||
|
worldspawn.push_back(" type WorldSpawn");
|
||||||
|
worldspawn.push_back(" Bool8 modeCTF 0");
|
||||||
|
worldspawn.push_back(" Bool8 modeFFA 0");
|
||||||
|
worldspawn.push_back(" Bool8 modeTDM 0");
|
||||||
|
worldspawn.push_back(" Bool8 mode1v1 0");
|
||||||
|
|
||||||
|
|
||||||
// Mock up entity
|
// Mock up entity
|
||||||
std::vector<std::string> entity;
|
std::vector<std::string> entity;
|
||||||
entity.push_back(" type PlayerSpawn");
|
entity.push_back(" type PlayerSpawn");
|
||||||
@ -112,12 +122,15 @@ TEST_CASE( "r2x: a single PlayerSpawn (race) entity can be converted", "[EntityC
|
|||||||
|
|
||||||
// Mock up entity queue
|
// Mock up entity queue
|
||||||
std::queue<std::vector<std::string>> q;
|
std::queue<std::vector<std::string>> q;
|
||||||
|
q.push( worldspawn );
|
||||||
q.push( entity );
|
q.push( entity );
|
||||||
|
|
||||||
// Match related entities (none)
|
// Match related entities (none)
|
||||||
ec.matchRelated( q );
|
ec.extractMapInfo( q );
|
||||||
|
|
||||||
// Convert a single entity
|
// Convert a single entity (worldspawn conversion returns empty vector
|
||||||
|
// BUT sets the supported game modes for entities in that worldspawn
|
||||||
|
std::vector<std::string> unused = ec.convert(worldspawn);
|
||||||
std::vector<std::string> converted = ec.convert(entity);
|
std::vector<std::string> converted = ec.convert(entity);
|
||||||
|
|
||||||
REQUIRE( converted[0] == "\"classname\" \"info_player_race\"\n" );
|
REQUIRE( converted[0] == "\"classname\" \"info_player_race\"\n" );
|
||||||
@ -136,6 +149,20 @@ TEST_CASE( "r2x: a single PlayerSpawn (race) entity can be converted", "[EntityC
|
|||||||
REQUIRE( coords[0] == "\"-216.00000" );
|
REQUIRE( coords[0] == "\"-216.00000" );
|
||||||
REQUIRE( coords[1] == "-1488.000488" );
|
REQUIRE( coords[1] == "-1488.000488" );
|
||||||
REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA );
|
REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA );
|
||||||
|
|
||||||
|
SECTION( "Encountering a new worldspawn reenables all modes" ) {
|
||||||
|
std::vector<std::string> basicWorldspawn;
|
||||||
|
basicWorldspawn.push_back(" type WorldSpawn");
|
||||||
|
|
||||||
|
std::vector<std::string> e;
|
||||||
|
e.push_back(" type PlayerSpawn");
|
||||||
|
e.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488");
|
||||||
|
e.push_back(" Vector3 angles 180.00000 0.00000 0.00000");
|
||||||
|
|
||||||
|
std::vector<std::string> u = ec.convert(basicWorldspawn);
|
||||||
|
std::vector<std::string> c = ec.convert(e);
|
||||||
|
REQUIRE( c[0] == "\"classname\" \"info_player_deathmatch\"\n" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -159,7 +186,7 @@ TEST_CASE( "r2x: a single PlayerSpawn (teamA) entity can be converted", "[Entity
|
|||||||
q.push( entity );
|
q.push( entity );
|
||||||
|
|
||||||
// Match related entities (none)
|
// Match related entities (none)
|
||||||
ec.matchRelated( q );
|
ec.extractMapInfo( q );
|
||||||
|
|
||||||
// Convert a single entity
|
// Convert a single entity
|
||||||
std::vector<std::string> converted = ec.convert(entity);
|
std::vector<std::string> converted = ec.convert(entity);
|
||||||
@ -182,6 +209,46 @@ TEST_CASE( "r2x: a single PlayerSpawn (teamA) entity can be converted", "[Entity
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE( "r2x: a single PlayerSpawn (non-team) entity can be converted", "[EntityConverter]" ) {
|
||||||
|
|
||||||
|
// Instantiate object
|
||||||
|
EntityConverter ec (PICKUP_FILENAME);
|
||||||
|
|
||||||
|
// Mock up entity
|
||||||
|
std::vector<std::string> entity;
|
||||||
|
entity.push_back(" type PlayerSpawn");
|
||||||
|
entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488");
|
||||||
|
entity.push_back(" Vector3 angles 180.00000 0.00000 0.00000");
|
||||||
|
|
||||||
|
// Mock up entity queue
|
||||||
|
std::queue<std::vector<std::string>> q;
|
||||||
|
q.push( entity );
|
||||||
|
|
||||||
|
// Match related entities (none)
|
||||||
|
ec.extractMapInfo( q );
|
||||||
|
|
||||||
|
// Convert a single entity
|
||||||
|
std::vector<std::string> converted = ec.convert(entity);
|
||||||
|
|
||||||
|
REQUIRE( converted[0] == "\"classname\" \"info_player_deathmatch\"\n" );
|
||||||
|
REQUIRE( converted[2] == "\"angle\" \"180.00000\"\n" );
|
||||||
|
|
||||||
|
// The z (vertical) is offset by +32
|
||||||
|
std::istringstream iss(converted[1]);
|
||||||
|
std::string attribute;
|
||||||
|
std::string coords[2];
|
||||||
|
float offsetCoord;
|
||||||
|
iss >> attribute >> coords[0] >> coords[1] >> offsetCoord;
|
||||||
|
|
||||||
|
REQUIRE( attribute == "\"origin\"" );
|
||||||
|
REQUIRE( coords[0] == "\"-216.00000" );
|
||||||
|
REQUIRE( coords[1] == "-1488.000488" );
|
||||||
|
REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE( "r2x: a single RaceStart entity can be converted", "[EntityConverter]" ) {
|
TEST_CASE( "r2x: a single RaceStart entity can be converted", "[EntityConverter]" ) {
|
||||||
|
|
||||||
// Instantiate object
|
// Instantiate object
|
||||||
@ -196,7 +263,7 @@ TEST_CASE( "r2x: a single RaceStart entity can be converted", "[EntityConverter]
|
|||||||
q.push( entity );
|
q.push( entity );
|
||||||
|
|
||||||
// Match related entities (none)
|
// Match related entities (none)
|
||||||
ec.matchRelated( q );
|
ec.extractMapInfo( q );
|
||||||
|
|
||||||
// Convert a single entity
|
// Convert a single entity
|
||||||
std::vector<std::string> converted = ec.convert(entity);
|
std::vector<std::string> converted = ec.convert(entity);
|
||||||
@ -222,7 +289,7 @@ TEST_CASE( "r2x: a single RaceFinish entity can be converted", "[EntityConverter
|
|||||||
q.push( entity );
|
q.push( entity );
|
||||||
|
|
||||||
// Match related entities (none)
|
// Match related entities (none)
|
||||||
ec.matchRelated( q );
|
ec.extractMapInfo( q );
|
||||||
|
|
||||||
// Convert a single entity
|
// Convert a single entity
|
||||||
std::vector<std::string> converted = ec.convert(entity);
|
std::vector<std::string> converted = ec.convert(entity);
|
||||||
@ -256,7 +323,7 @@ TEST_CASE( "r2x: a single Teleporter and related Target can be converted", "[Ent
|
|||||||
q.push( entity2 );
|
q.push( entity2 );
|
||||||
|
|
||||||
// Match related entities (one pair)
|
// Match related entities (one pair)
|
||||||
ec.matchRelated( q );
|
ec.extractMapInfo( q );
|
||||||
|
|
||||||
// Convert two entities
|
// Convert two entities
|
||||||
std::vector<std::string> converted = ec.convert(entity);
|
std::vector<std::string> converted = ec.convert(entity);
|
||||||
@ -274,7 +341,7 @@ TEST_CASE( "r2x: a single Teleporter and related Target can be converted", "[Ent
|
|||||||
float offsetCoord;
|
float offsetCoord;
|
||||||
iss >> attribute >> coords[0] >> coords[1] >> offsetCoord;
|
iss >> attribute >> coords[0] >> coords[1] >> offsetCoord;
|
||||||
|
|
||||||
// first test fails without busy wait
|
// next REQUIRE fails without busy wait
|
||||||
for( int i = 0; i < 10000000; i++ )
|
for( int i = 0; i < 10000000; i++ )
|
||||||
int x = i;
|
int x = i;
|
||||||
|
|
||||||
@ -308,7 +375,7 @@ TEST_CASE( "r2x: a single JumpPad and related Target can be converted", "[Entity
|
|||||||
q.push( entity2 );
|
q.push( entity2 );
|
||||||
|
|
||||||
// Match related entities (one pair)
|
// Match related entities (one pair)
|
||||||
ec.matchRelated( q );
|
ec.extractMapInfo( q );
|
||||||
|
|
||||||
// Convert two entities
|
// Convert two entities
|
||||||
std::vector<std::string> converted = ec.convert(entity);
|
std::vector<std::string> converted = ec.convert(entity);
|
||||||
@ -323,6 +390,52 @@ TEST_CASE( "r2x: a single JumpPad and related Target can be converted", "[Entity
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE( "r2x: a single PointLight entity can be converted", "[EntityConverter]" ) {
|
||||||
|
|
||||||
|
// Instantiate object
|
||||||
|
EntityConverter ec (PICKUP_FILENAME);
|
||||||
|
|
||||||
|
// Mock up entity
|
||||||
|
std::vector<std::string> entity;
|
||||||
|
entity.push_back(" type PointLight");
|
||||||
|
entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488");
|
||||||
|
entity.push_back(" ColourXRGB32 color ffffc400");
|
||||||
|
entity.push_back(" Float intensity 1.500000");
|
||||||
|
entity.push_back(" Float nearAttenuation 32.000000");
|
||||||
|
entity.push_back(" Float farAttenuation 160.000000");
|
||||||
|
|
||||||
|
// Mock up entity queue
|
||||||
|
std::queue<std::vector<std::string>> q;
|
||||||
|
q.push( entity );
|
||||||
|
|
||||||
|
// Match related entities (none)
|
||||||
|
ec.extractMapInfo( q );
|
||||||
|
|
||||||
|
// Convert a single entity
|
||||||
|
std::vector<std::string> converted = ec.convert(entity);
|
||||||
|
|
||||||
|
REQUIRE( converted[0] == "\"classname\" \"light\"\n" );
|
||||||
|
REQUIRE( converted[1] == "\"origin\" \"-216.00000 -1488.000488 -132.00000\"\n" );
|
||||||
|
REQUIRE( converted[2] == "\"light\" \"75\"\n" );
|
||||||
|
|
||||||
|
INFO( converted[3] );
|
||||||
|
std::istringstream iss(converted[3]);
|
||||||
|
std::string attribute;
|
||||||
|
std::string r;
|
||||||
|
float red;
|
||||||
|
float green;
|
||||||
|
float blue;
|
||||||
|
iss >> attribute >> r >> green >> blue;
|
||||||
|
r.erase(r.begin()); //removing preceding quote is necessary
|
||||||
|
std::stringstream redStream(r);
|
||||||
|
redStream >> red;
|
||||||
|
|
||||||
|
REQUIRE( attribute == "\"_color\"" );
|
||||||
|
|
||||||
|
REQUIRE( fabs(1.0 - red) <= DELTA );
|
||||||
|
REQUIRE( fabs(0.768627 - green) <= DELTA );
|
||||||
|
REQUIRE( fabs(0.0 - blue) <= DELTA );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user