added PlayerSpawn conversion (will break if race and regular spawns present)

This commit is contained in:
suhrke 2017-07-02 23:41:59 -07:00
parent 16fe71b008
commit 0c5d5d1899
3 changed files with 132 additions and 19 deletions

View File

@ -5,5 +5,12 @@
*.log *.log
# git merge backups
*_BACKUP*
*_BASE*
*_LOCAL*
*_REMOTE*
*.orig
# executables # executables
reflex2q3 reflex2q3

View File

@ -83,6 +83,24 @@ EntityConverter::EntityConverter(std::string entityMapFile, std::string reflexMa
/*
*--------------------------------------------------------------------------------------
* !-- Not sure if this is used the same way as the pre-scan was --!
*--------------------------------------------------------------------------------------
*/
void
matchRelated(std::queue<std::vector<std::string>> entities)
{
if( areEntitiesMatched_ ) {
std::cerr << "Related entities are already matched, doing nothing" << std::endl;
}
else {
//Same as pre-scan or convert and pass back all converted entities?
}
}
std::vector<std::string> std::vector<std::string>
EntityConverter::convert(std::vector<std::string> lines) EntityConverter::convert(std::vector<std::string> lines)
{ {
@ -102,7 +120,7 @@ EntityConverter::convert(std::vector<std::string> lines)
} }
if ( type == "Pickup" ) { if ( type == "Pickup" ) {
return convertPickup(lines); return convertPickup(lines);
} }
else if ( type == "PlayerSpawn" ) { else if ( type == "PlayerSpawn" ) {
@ -183,16 +201,16 @@ std::vector<std::string>
EntityConverter::convertPickup(std::vector<std::string> &lines) EntityConverter::convertPickup(std::vector<std::string> &lines)
{ {
std::vector<std::string> convertedLines; std::vector<std::string> convertedLines;
//can ignore angle of pickups in xonotic format
std::string coords[3]; std::string coords[3];
int pickupID;
std::string trash; std::string trash;
bool havePosition = false;
bool havePickupID = false;
if ( lines.size() < 3 ) { if ( lines.size() < 3 ) {
throw std::runtime_error("error: Pickup entity requires at least 3 lines"); throw std::runtime_error("error: Pickup entity requires at least 3 lines");
} }
//can ignore angle of pickups in xonotic format
int pickupID;
bool havePosition = false;
bool havePickupID = false;
for (int i = 1; i < lines.size(); i++) { for (int i = 1; i < lines.size(); i++) {
std::string type = getAttributeType(lines[i]); std::string type = getAttributeType(lines[i]);
@ -233,11 +251,88 @@ EntityConverter::convertPickup(std::vector<std::string> &lines)
/*
*--------------------------------------------------------------------------------------
* Class: EntityConverter
* Method: EntityConverter :: convertPlayerSpawn
* Notes: REFLEX
* -Optionally includes angle, team indicator, and 0 or more game
* mode indicators (defaults to all modes enabled so this line
* is used to disable a mode. eg Bool8 modeRace 0)
* *mode indicators cause problem with maps that support race
* and other modes because Xonotic doesn't handle spawns this
* way
*--------------------------------------------------------------------------------------
*/
std::vector<std::string> std::vector<std::string>
EntityConverter::convertPlayerSpawn(std::vector<std::string> &lines) EntityConverter::convertPlayerSpawn(std::vector<std::string> &lines)
{ {
//minimum of 3 lines, max of ? lines std::vector<std::string> convertedLines;
//Requires position coordinate
std::string coords[3];
//Requires an angle so if no reflex one is given, use 0
std::string angle("0");
int team = 0; // 1-2 for corresponding team, 0 for deathmatch spawn
std::string trash;
bool havePosition = false;
if ( lines.size() < 2 ) {
throw std::runtime_error("error: PlayerSpawn entity requires at least 2 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: PlayerSpawn entity requires position coordinates");
}
havePosition = true;
}
else if ( type == "angles" ) {
std::istringstream iss(lines[i]);
// UInt8 pickupType ID
if ( ! (iss >> trash >> trash >> angle ) {
throw std::runtime_error("error: Pickup entity requires Pickup ID");
}
}
else if ( type == "teamA" ) {
team = 2; // Bool8 teamA 0 indicates teamB only
}
else ef ( type == "teamB" ) {
team = 1; // Bool8 teamB 0 indicates teamA only
}
}
if ( havePosition ) {
switch (team) {
case 0:
convertedLines.push_back ( "\"classname\" \"info_player_deathmatch\"" );
break;
case 1:
convertedLines.push_back ( "\"classname\" \"info_player_team1\"" );
break;
case 2:
convertedLines.push_back ( "\"classname\" \"info_player_team2\"" );
break;
}
std::stringstream oss;
// coordinates reordered to x, z, y
oss << "\"origin\" \"" << coords[0] << " " << coords[2] << " " <<
coords[1] << "\"" << std::endl;
convertedLines.push_back ( oss.str() );
std::stringstream oss2;
oss2 << "\"angle\" \"" << angle << "\"" << endl;
convertedLines.push_back ( oss2.str() );
return convertedLines;
}
else {
throw std::runtime_error("error: PlayerSpawn entity requires position coordinates");
}
} }
@ -246,13 +341,13 @@ std::vector<std::string>
EntityConverter::convertJumpPad(std::vector<std::string> &lines) EntityConverter::convertJumpPad(std::vector<std::string> &lines)
{ {
std::vector<std::string> convertedLines; std::vector<std::string> convertedLines;
std::string targetName;
std::string trash; std::string trash;
if ( lines.size() < 2 ) { if ( lines.size() < 2 ) {
throw std::runtime_error("error: JumpPad entity requires at least 2 lines"); throw std::runtime_error("error: JumpPad entity requires at least 2 lines");
} }
std::istringstream iss(lines[1]); std::istringstream iss(lines[1]);
std::string targetName;
// String32 target targetName // String32 target targetName
if ( ! (iss >> trash >> trash >> targetName) ) { if ( ! (iss >> trash >> trash >> targetName) ) {
throw std::runtime_error("error: JumpPad entity requires target name"); throw std::runtime_error("error: JumpPad entity requires target name");
@ -271,13 +366,13 @@ std::vector<std::string>
EntityConverter::convertTeleporter(std::vector<std::string> &lines) EntityConverter::convertTeleporter(std::vector<std::string> &lines)
{ {
std::vector<std::string> convertedLines; std::vector<std::string> convertedLines;
std::string targetName;
std::string trash; std::string trash;
if ( lines.size() < 2 ) { if ( lines.size() < 2 ) {
throw std::runtime_error("error: Teleport entity requires at least 2 lines"); throw std::runtime_error("error: Teleport entity requires at least 2 lines");
} }
std::istringstream iss(lines[1]); std::istringstream iss(lines[1]);
std::string targetName;
// String32 target targetName // String32 target targetName
if ( ! (iss >> trash >> trash >> targetName) ) { if ( ! (iss >> trash >> trash >> targetName) ) {
throw std::runtime_error( "error: Teleport entity requires target name" ); throw std::runtime_error( "error: Teleport entity requires target name" );
@ -285,7 +380,7 @@ EntityConverter::convertTeleporter(std::vector<std::string> &lines)
convertedLines.push_back ( "\"classname\" \"trigger_teleport\"\n" ); convertedLines.push_back ( "\"classname\" \"trigger_teleport\"\n" );
std::stringstream oss; std::stringstream oss;
oss << "\"target\" \"" << targetName << std::endl; oss << "\"target\" \"" << targetName << "\"" << std::endl;
convertedLines.push_back ( oss.str() ); convertedLines.push_back ( oss.str() );
return convertedLines; return convertedLines;
} }
@ -296,18 +391,18 @@ std::vector<std::string>
EntityConverter::convertTarget(std::vector<std::string> &lines) EntityConverter::convertTarget(std::vector<std::string> &lines)
{ {
std::vector<std::string> convertedLines; std::vector<std::string> convertedLines;
//position and name required, angles optional
std::string coords[3]; std::string coords[3];
std::string targetName;
std::string angle;
std::string trash; std::string trash;
bool havePosition = false;
bool haveName = false;
bool haveAngle = false;
if ( lines.size() < 3 ) { if ( lines.size() < 3 ) {
throw std::runtime_error("error: Target entity requires at least 3 lines"); throw std::runtime_error("error: Target entity requires at least 3 lines");
} }
//position and name required, angles optional
std::string targetName;
std::string angle;
bool havePosition = false;
bool haveName = false;
bool haveAngle = false;
for (int i = 1; i < lines.size(); i++) { for (int i = 1; i < lines.size(); i++) {
std::string type = getAttributeType(lines[i]); std::string type = getAttributeType(lines[i]);
@ -329,9 +424,9 @@ EntityConverter::convertTarget(std::vector<std::string> &lines)
haveName = true; haveName = true;
} }
else if ( type == "angles" ) { else if ( type == "angles" ) {
std::istringstream iss2(lines[i]); std::istringstream iss(lines[i]);
// Vector3 angles angle notapplicable notapplicable // Vector3 angles angle notapplicable notapplicable
if ( ! (iss2 >> trash >> trash >> angle) ) { if ( ! (iss >> trash >> trash >> angle) ) {
throw std::runtime_error( "error: Target entity requires target angle if specified" ); throw std::runtime_error( "error: Target entity requires target angle if specified" );
} }
haveAngle = true; haveAngle = true;

View File

@ -105,13 +105,24 @@ class EntityConverter
* Class: EntityConverter * Class: EntityConverter
* Method: EntityConverter :: convert * Method: EntityConverter :: convert
* Description: Converts a single entity from reflex to xonotic format * Description: Converts a single entity from reflex to xonotic format
* Parameter: vector of strings "lines", lines that comprise a single entity * Parameter: vector of strings lines, lines that comprise a single entity
* Return: vector of strings, single entity in the converted format * Return: vector of strings, single entity in the converted format
* THROWS: runtime_error on malformed .map file * THROWS: runtime_error on malformed .map file
* THROWS: runtime_error when called before related entitios are matched * THROWS: runtime_error when called before related entities are matched
*-------------------------------------------------------------------------------------- *--------------------------------------------------------------------------------------
*/ */
std::vector<std::string> convert(std::vector<std::string> lines); std::vector<std::string> convert(std::vector<std::string> lines);
/*
*--------------------------------------------------------------------------------------
* Class: EntityConverter
* Method: EntityConverter :: matchRelated
* Description: Finds related entities (targets of teleports, etc), call after parsing
* the entire .map
* Parameter: queue of vector of string entities, ALL entities in a .map file
* THROWS: runtime_error when encountering malformed entity
*--------------------------------------------------------------------------------------
*/
void matchRelated(std::queue<std::vector<std::string>> entities);