From ff47d28870243ac97e0fa8a8e3f043be0fe8cca5 Mon Sep 17 00:00:00 2001 From: suhrke Date: Wed, 5 Jul 2017 16:00:22 -0700 Subject: [PATCH 1/2] encapsulate constants for EC --- ReflexToQ3/includes/EntityConverter.cpp | 180 ++++++++++++------------ ReflexToQ3/includes/EntityConverter.hpp | 78 +++++----- ReflexToQ3/test/catch.cpp | 8 +- 3 files changed, 138 insertions(+), 128 deletions(-) diff --git a/ReflexToQ3/includes/EntityConverter.cpp b/ReflexToQ3/includes/EntityConverter.cpp index dff0036..d3b6c10 100644 --- a/ReflexToQ3/includes/EntityConverter.cpp +++ b/ReflexToQ3/includes/EntityConverter.cpp @@ -24,26 +24,13 @@ #include #include -// shifts the position of an entity in a given axis. -// for discrepancies between origin points between games. -#define OFFSET_PLAYER 32 // in reflex is origin the feet; in quake it's the center -#define OFFSET_PICKUP 2 // reflex items are on-ground, while quake's are floating -std::string offset(std::string axis, float amount) { - std::istringstream iss(axis); - float c; - iss >> c; - c += amount; - std::stringstream ss; - ss << std::fixed << std::setprecision(5) << c; - return ss.str(); -} /*----------------------------------------------------------------------------- * PUBLIC *-----------------------------------------------------------------------------*/ -EntityConverter::EntityConverter(std::string entityMapFile) +EntityConverter::EntityConverter(std::string entityMapFile) : OFFSET_PLAYER(32.0), OFFSET_PICKUP(2.0) { //MUST RUN matchRelated method after this constructor areEntitiesMatched_ = false; @@ -52,7 +39,7 @@ EntityConverter::EntityConverter(std::string entityMapFile) -EntityConverter::EntityConverter(std::string entityMapFile, std::string reflexMapFile) +EntityConverter::EntityConverter(std::string entityMapFile, std::string reflexMapFile) : OFFSET_PLAYER(32.0), OFFSET_PICKUP(2.0) { mapEntities(entityMapFile); @@ -169,79 +156,8 @@ EntityConverter::convert(std::vector lines) /*----------------------------------------------------------------------------- - * PRIVATE + * PROTECTED *-----------------------------------------------------------------------------*/ - -std::string -EntityConverter::getAttributeType(std::string line) -{ - std::string type; - std::string dataType; - std::istringstream iss(line); - if ( ! (iss >> dataType >> type )) { - return std::string(); - } - - return type; -} - - - -void -EntityConverter::mapEntities(std::string mapFile) -{ - std::ifstream fin; - fin.open(mapFile); - - if ( fin.is_open() ) { - //Read .ent contents into pickup map - std::string line; - while (std::getline(fin, line)) { - std::istringstream iss(line); - // Reflex ID corresponds to xonotic pickup name - int id; - std::string pickup; - if ( ! (iss >> id >> pickup)) { - throw std::runtime_error( "format error in .ent file" ); - } - pickupMapping_.insert ( std::pair(id, pickup) ); - } - } - else { - throw std::ios::failure( "Error: EntityConverter failed to open .ent file" ); - } - fin.close(); - -} - - - -void -EntityConverter::addIfRelated(std::string &line, std::istream &is) -{ - std::string trash; - std::string targetName; - if ( line.find("type Teleporter") != std::string::npos) { - std::getline(is, line); - std::istringstream iss(line); - if ( ! (iss >> trash >> trash >> targetName)) { - throw std::runtime_error( "format error in .map file"); - } - targetMap_.insert ( std::pair(targetName, "Teleporter") ); - } - else if ( line.find("type JumpPad") != std::string::npos) { - std::getline(is, line); - std::istringstream iss(line); - if ( ! (iss >> trash >> trash >> targetName)) { - throw std::runtime_error( "format error in .map file"); - } - targetMap_.insert ( std::pair(targetName, "JumpPad") ); - } - -} - - - std::vector EntityConverter::convertPickup(std::vector &lines) { @@ -552,6 +468,96 @@ EntityConverter::convertRaceFinish(std::vector &lines) return convertedLines; } + + + +/*----------------------------------------------------------------------------- + * PRIVATE + *-----------------------------------------------------------------------------*/ +std::string +EntityConverter::getAttributeType(std::string line) +{ + std::string type; + std::string dataType; + std::istringstream iss(line); + if ( ! (iss >> dataType >> type )) { + return std::string(); + } + + return type; +} + + + +void +EntityConverter::mapEntities(std::string mapFile) +{ + std::ifstream fin; + fin.open(mapFile); + + if ( fin.is_open() ) { + //Read .ent contents into pickup map + std::string line; + while (std::getline(fin, line)) { + std::istringstream iss(line); + // Reflex ID corresponds to xonotic pickup name + int id; + std::string pickup; + if ( ! (iss >> id >> pickup)) { + throw std::runtime_error( "format error in .ent file" ); + } + pickupMapping_.insert ( std::pair(id, pickup) ); + } + } + else { + throw std::ios::failure( "Error: EntityConverter failed to open .ent file" ); + } + fin.close(); + +} + + + +void +EntityConverter::addIfRelated(std::string &line, std::istream &is) +{ + std::string trash; + std::string targetName; + if ( line.find("type Teleporter") != std::string::npos) { + std::getline(is, line); + std::istringstream iss(line); + if ( ! (iss >> trash >> trash >> targetName)) { + throw std::runtime_error( "format error in .map file"); + } + targetMap_.insert ( std::pair(targetName, "Teleporter") ); + } + else if ( line.find("type JumpPad") != std::string::npos) { + std::getline(is, line); + std::istringstream iss(line); + if ( ! (iss >> trash >> trash >> targetName)) { + throw std::runtime_error( "format error in .map file"); + } + targetMap_.insert ( std::pair(targetName, "JumpPad") ); + } + +} + + + +std::string EntityConverter::offset(std::string value, float amount) { + std::istringstream iss(value); + float c; + iss >> c; + c += amount; + + std::stringstream ss; + ss << std::fixed << std::setprecision(5) << c; + return ss.str(); +} + + + + // DEBUG void EntityConverter::printMapping() diff --git a/ReflexToQ3/includes/EntityConverter.hpp b/ReflexToQ3/includes/EntityConverter.hpp index dba947d..ce6145d 100644 --- a/ReflexToQ3/includes/EntityConverter.hpp +++ b/ReflexToQ3/includes/EntityConverter.hpp @@ -31,15 +31,9 @@ #include #include -/* - *-------------------------------------------------------------------------------------- - * Description: Reflex coordinates place entities at the ground and Xonotic entities - * are at about center of player height. Offset accordingly. - * Paramater: string coordinate, float value passed as string - * Return: string, float value passed as string - *-------------------------------------------------------------------------------------- - */ -std::string offset(std::string coordinate); + + + class EntityConverter { @@ -95,20 +89,40 @@ class EntityConverter protected: + + + /* + *-------------------------------------------------------------------------------------- + * Class: EntityConverter + * Method: EntityConverter :: convert~EntityName~ + * Description: Multiple methods to convert entity from reflex to xonotic format + * Parameter: vector of strings entity, multi-lined entity + * Return: vector of strings, the converted entity + *-------------------------------------------------------------------------------------- + */ + std::vector convertPickup(std::vector &entity); + std::vector convertPlayerSpawn(std::vector &entity); + std::vector convertJumpPad(std::vector &entity); + std::vector convertTeleporter(std::vector &entity); + std::vector convertTarget(std::vector &entity); + std::vector convertRaceStart(std::vector &entity); + std::vector convertRaceFinish(std::vector &entity); + + + + // Related entities must be matched prior to entity conversion + bool areEntitiesMatched_; + // Map Reflex pickup IDs to Xonotic pickup identifiers + std::map pickupMapping_; + // Map targets (by name) to their source type + std::map targetMap_; + // Offsets for item/spawn height + const float OFFSET_PLAYER; + const float OFFSET_PICKUP; private: - - /* - *-------------------------------------------------------------------------------------- - * Class: EntityConverter - * Method: EntityConverter :: getOffsetHeight - * Description: Returns a constant - *-------------------------------------------------------------------------------------- - */ - float getHeightOffset() { return 32.0; } - /* *-------------------------------------------------------------------------------------- * Class: EntityConverter @@ -139,34 +153,24 @@ class EntityConverter *-------------------------------------------------------------------------------------- */ void addIfRelated(std::string &line, std::istream &is); - /* *-------------------------------------------------------------------------------------- * Class: EntityConverter - * Method: EntityConverter :: convert~EntityName~ - * Description: Multiple methods to convert entity from reflex to xonotic format - * Parameter: vector of strings entity, multi-lined entity - * Return: vector of strings, the converted entity + * Method: EntityConverter :: offset + * Description: Reflex coordinates place entities at the ground and Xonotic entities + * are at about center of player height. Offset accordingly. + * Paramater: string value, float value passed as string + * Parameter: float offset, amount to add to value + * Return: string, float value passed as string *-------------------------------------------------------------------------------------- */ - std::vector convertPickup(std::vector &entity); - std::vector convertPlayerSpawn(std::vector &entity); - std::vector convertJumpPad(std::vector &entity); - std::vector convertTeleporter(std::vector &entity); - std::vector convertTarget(std::vector &entity); - std::vector convertRaceStart(std::vector &entity); - std::vector convertRaceFinish(std::vector &entity); + std::string offset(std::string value, float offset); + void printMapping(); //DEBUG void printTargetSources(); //DEBUG - // Related entities must be matched prior to entity conversion - bool areEntitiesMatched_; - // Map Reflex pickup IDs to Xonotic pickup identifiers - std::map pickupMapping_; - // Map targets (by name) to their source type - std::map targetMap_; }; #endif //ENTITY_CONVERTER_HPP diff --git a/ReflexToQ3/test/catch.cpp b/ReflexToQ3/test/catch.cpp index 22690e1..cada5d2 100644 --- a/ReflexToQ3/test/catch.cpp +++ b/ReflexToQ3/test/catch.cpp @@ -78,7 +78,7 @@ TEST_CASE( "r2x: a single Pickup entity can be converted", "[EntityConverter]" ) REQUIRE( converted[0] == "\"classname\" \"weapon_grenadelauncher\"\n" ); - // The z (vertical) is offset + // The z (vertical) is offset by +2 std::istringstream iss(converted[1]); std::string attribute; std::string coords[2]; @@ -88,7 +88,7 @@ TEST_CASE( "r2x: a single Pickup entity can be converted", "[EntityConverter]" ) REQUIRE( attribute == "\"origin\"" ); REQUIRE( coords[0] == "\"-216.00000" ); REQUIRE( coords[1] == "-1488.000488" ); - REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA ); + REQUIRE( fabs(-130.00000 - offsetCoord) <= DELTA ); } @@ -119,7 +119,7 @@ TEST_CASE( "r2x: a single PlayerSpawn (teamA) entity can be converted", "[Entity REQUIRE( converted[0] == "\"classname\" \"info_player_team1\"\n" ); REQUIRE( converted[2] == "\"angle\" \"180.00000\"\n" ); - // The z (vertical) is offset + // The z (vertical) is offset by +32 std::istringstream iss(converted[1]); std::string attribute; std::string coords[2]; @@ -219,7 +219,7 @@ TEST_CASE( "r2x: a single Teleporter and related Target can be converted", "[Ent REQUIRE( converted2[0] == "\"classname\" \"misc_teleporter_dest\"\n" ); REQUIRE( converted2[2] == "\"targetname\" \"tp1\"\n" ); // - // The z (vertical) is offset + // The z (vertical) is offset by +32 std::istringstream iss(converted2[1]); std::string attribute; std::string coords[2]; From 0e61e02259bfeb871eaf20d12b1f5c8491f119ca Mon Sep 17 00:00:00 2001 From: suhrke Date: Wed, 5 Jul 2017 16:14:17 -0700 Subject: [PATCH 2/2] EC: fixed malformed race spawn conversion, issue #33 --- ReflexToQ3/includes/EntityConverter.cpp | 6 ++-- ReflexToQ3/test/catch.cpp | 48 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/ReflexToQ3/includes/EntityConverter.cpp b/ReflexToQ3/includes/EntityConverter.cpp index d3b6c10..da3e24e 100644 --- a/ReflexToQ3/includes/EntityConverter.cpp +++ b/ReflexToQ3/includes/EntityConverter.cpp @@ -286,11 +286,11 @@ EntityConverter::convertPlayerSpawn(std::vector &lines) } else { - convertedLines.push_back ( "\"classname\" \"info_player_race\"" ); + convertedLines.push_back ( "\"classname\" \"info_player_race\"\n" ); // Reflex maps have only start and finish, point to start on spawn - convertedLines.push_back ( "\"target\" \"cp1\"" ); + convertedLines.push_back ( "\"target\" \"cp1\"\n" ); // Reflex maps are only cts, set spawn to cts-only type - convertedLines.push_back ( "\"race_place\" \"-1\"" ); + convertedLines.push_back ( "\"race_place\" \"-1\"\n" ); } std::stringstream oss; diff --git a/ReflexToQ3/test/catch.cpp b/ReflexToQ3/test/catch.cpp index cada5d2..5d247a0 100644 --- a/ReflexToQ3/test/catch.cpp +++ b/ReflexToQ3/test/catch.cpp @@ -93,6 +93,54 @@ TEST_CASE( "r2x: a single Pickup entity can be converted", "[EntityConverter]" ) +TEST_CASE( "r2x: a single PlayerSpawn (race) entity can be converted", "[EntityConverter]" ) { + + // Instantiate object + EntityConverter ec (PICKUP_FILENAME); + + // Mock up entity + std::vector 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"); + entity.push_back(" Bool8 teamA 0"); + entity.push_back(" Bool8 teamB 0"); + entity.push_back(" Bool8 modeCTF 0"); + entity.push_back(" Bool8 modeFFA 0"); + entity.push_back(" Bool8 modeTDM 0"); + entity.push_back(" Bool8 mode1v1 0"); + + // Mock up entity queue + std::queue> q; + q.push( entity ); + + // Match related entities (none) + ec.matchRelated( q ); + + // Convert a single entity + std::vector converted = ec.convert(entity); + + REQUIRE( converted[0] == "\"classname\" \"info_player_race\"\n" ); + REQUIRE( converted[1] == "\"target\" \"cp1\"\n" ); + REQUIRE( converted[2] == "\"race_place\" \"-1\"\n" ); + REQUIRE( converted[4] == "\"angle\" \"180.00000\"\n" ); + + // The z (vertical) is offset by +32 + std::istringstream iss(converted[3]); + 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 PlayerSpawn (teamA) entity can be converted", "[EntityConverter]" ) { // Instantiate object