summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkrzys-h <krzys_h@interia.pl>2014-09-24 22:54:26 +0200
committerkrzys-h <krzys_h@interia.pl>2014-09-24 22:56:19 +0200
commit740036e430d98afe487313bb5be8c5e72968eb94 (patch)
tree3a998518dbf9750a98228fcef35c23ef01ff5768
parent9f2d544b27171c89eceedbb83bfcb26f5702dadb (diff)
downloadcolobot-740036e430d98afe487313bb5be8c5e72968eb94.tar.gz
colobot-740036e430d98afe487313bb5be8c5e72968eb94.tar.bz2
colobot-740036e430d98afe487313bb5be8c5e72968eb94.zip
New level parser
Known issues: * TerrainLevel for some reason doesn't work * %lvl% is not yet implemented everywhere because of hardcoded directories in functions
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/object/level/parser.cpp221
-rw-r--r--src/object/level/parser.h66
-rw-r--r--src/object/level/parserexceptions.cpp40
-rw-r--r--src/object/level/parserexceptions.h49
-rw-r--r--src/object/level/parserline.cpp87
-rw-r--r--src/object/level/parserline.h59
-rw-r--r--src/object/level/parserparam.cpp930
-rw-r--r--src/object/level/parserparam.h133
-rw-r--r--src/object/robotmain.cpp1296
-rw-r--r--src/script/cmdtoken.cpp2
-rw-r--r--src/script/script.cpp1
12 files changed, 2179 insertions, 709 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e02a30b..0440c5f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -122,6 +122,10 @@ object/auto/autosafe.cpp
object/auto/autostation.cpp
object/auto/autotower.cpp
object/brain.cpp
+object/level/parser.cpp
+object/level/parserline.cpp
+object/level/parserparam.cpp
+object/level/parserexceptions.cpp
object/mainmovie.cpp
object/motion/motion.cpp
object/motion/motionant.cpp
diff --git a/src/object/level/parser.cpp b/src/object/level/parser.cpp
new file mode 100644
index 0000000..89059d0
--- /dev/null
+++ b/src/object/level/parser.cpp
@@ -0,0 +1,221 @@
+// * This file is part of the COLOBOT source code
+// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
+// *
+// * This program is free software: you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License as published by
+// * the Free Software Foundation, either version 3 of the License, or
+// * (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+
+#include "object/level/parser.h"
+
+
+#include "app/app.h"
+
+#include "common/resources/inputstream.h"
+
+#include "object/level/parserexceptions.h"
+
+#include <string>
+#include <exception>
+#include <sstream>
+#include <iomanip>
+
+#include <boost/algorithm/string/trim.hpp>
+#include <boost/algorithm/string/replace.hpp>
+
+CLevelParser::CLevelParser()
+{
+ m_filename = "";
+}
+
+CLevelParser::CLevelParser(std::string filename)
+{
+ m_filename = filename;
+}
+
+CLevelParser::CLevelParser(std::string category, int chapter, int rank)
+{
+ m_filename = BuildSceneName(category, chapter, rank);
+}
+
+CLevelParser::~CLevelParser()
+{
+ for(auto line : m_lines)
+ {
+ delete line;
+ }
+}
+
+std::string CLevelParser::BuildSceneName(std::string category, int chapter, int rank, bool sceneFile)
+{
+ std::ostringstream outstream;
+ if(category == "user")
+ {
+ //TODO: Change this to point user dir according to operating system
+ /*rankStream << std::setfill('0') << std::setw(2) << rank%100;
+ filename = m_userDir + "/" + m_userList[rank/100-1] + "/" + rankStream.str() + ".txt";*/
+ assert(false); //TODO: Userlevel support
+ }
+ else if(category == "perso")
+ {
+ outstream << "levels/other/perso.txt";
+ }
+ else if(category == "win" || category == "lost")
+ {
+ outstream << "levels/other/";
+ outstream << category << std::setfill('0') << std::setw(3) << chapter*100+rank << ".txt";
+ }
+ else
+ {
+ outstream << "levels/" << category << "/";
+ outstream << "chapter" << std::setfill('0') << std::setw(3) << chapter;
+ if(rank == 000)
+ {
+ if(sceneFile)
+ {
+ outstream << "/chaptertitle.txt";
+ }
+ }
+ else
+ {
+ outstream << "/level" << std::setfill('0') << std::setw(3) << rank;
+ if(sceneFile)
+ {
+ outstream << "/scene.txt";
+ }
+ }
+ }
+ return outstream.str();
+}
+
+void CLevelParser::Load()
+{
+ CInputStream file;
+ file.open(m_filename);
+ if(!file.is_open())
+ throw CLevelParserException("Failed to open file: "+m_filename);
+
+ char lang = CApplication::GetInstancePointer()->GetLanguageChar();
+
+ std::string line;
+ int lineNumber = 0;
+ std::map<std::string, CLevelParserLine*> translatableLines;
+ while(getline(file,line))
+ {
+ lineNumber++;
+
+ boost::replace_all(line, "\t", " "); // replace tab by space
+
+ // ignore comments
+ std::size_t comment = line.find("//");
+ if(comment != std::string::npos)
+ line = line.substr(0, comment);
+
+ boost::algorithm::trim(line);
+
+ std::size_t pos = line.find_first_of(" \t\n");
+ std::string command = line.substr(0, pos);
+ if(pos != std::string::npos) {
+ line = line.substr(pos+1);
+ boost::algorithm::trim(line);
+ } else {
+ line = "";
+ }
+ if(command.empty()) continue;
+
+ CLevelParserLine* parserLine = new CLevelParserLine(lineNumber, command);
+
+ std::string baseCommand = command;
+ if(command[command.length()-2] == '.') {
+ baseCommand = command.substr(0, command.length()-2);
+ if(command[command.length()-1] == 'E' && translatableLines[baseCommand] == nullptr) {
+ parserLine->SetCommand(baseCommand);
+ translatableLines[baseCommand] = parserLine;
+ } else if(command[command.length()-1] == lang) {
+ if(translatableLines[baseCommand] != nullptr) {
+ m_lines.erase(std::remove(m_lines.begin(), m_lines.end(), translatableLines[baseCommand]), m_lines.end());
+ delete translatableLines[baseCommand];
+ }
+ parserLine->SetCommand(baseCommand);
+ translatableLines[baseCommand] = parserLine;
+ } else {
+ delete parserLine;
+ continue;
+ }
+ }
+
+ while(!line.empty()) {
+ pos = line.find_first_of("=");
+ std::string paramName = line.substr(0, pos);
+ boost::algorithm::trim(paramName);
+ line = line.substr(pos+1);
+ boost::algorithm::trim(line);
+
+ if(line[0] == '\"') {
+ pos = line.find_first_of("\"", 1);
+ if(pos == std::string::npos)
+ throw CLevelParserException("Unclosed \" in "+m_filename+":"+std::to_string(lineNumber));
+ } else if(line[0] == '\'') {
+ pos = line.find_first_of("'", 1);
+ if(pos == std::string::npos)
+ throw CLevelParserException("Unclosed ' in "+m_filename+":"+std::to_string(lineNumber));
+ } else {
+ pos = line.find_first_of("=");
+ if(pos != std::string::npos) {
+ std::size_t pos2 = line.find_last_of(" \t\n", line.find_last_not_of(" \t\n", pos-1));
+ if(pos2 != std::string::npos)
+ pos = pos2;
+ } else {
+ pos = line.length()-1;
+ }
+ }
+ std::string paramValue = line.substr(0, pos+1);
+ boost::algorithm::trim(paramValue);
+
+ parserLine->AddParam(paramName, new CLevelParserParam(paramName, paramValue));
+
+ if(pos == std::string::npos)
+ break;
+ line = line.substr(pos+1);
+ boost::algorithm::trim(line);
+ }
+
+ AddLine(parserLine);
+ }
+
+ file.close();
+}
+
+void CLevelParser::Save(std::string filename)
+{
+ assert(false); //TODO
+}
+
+const std::string& CLevelParser::GetFilename()
+{
+ return m_filename;
+}
+
+std::vector<CLevelParserLine*> CLevelParser::GetLines()
+{
+ return m_lines;
+}
+
+void CLevelParser::AddLine(CLevelParserLine* line)
+{
+ line->SetLevel(this);
+ m_lines.push_back(line);
+}
+
+CLevelParserLine* CLevelParser::Get(std::string command)
+{
+ assert(false); //TODO
+} \ No newline at end of file
diff --git a/src/object/level/parser.h b/src/object/level/parser.h
new file mode 100644
index 0000000..3bae2eb
--- /dev/null
+++ b/src/object/level/parser.h
@@ -0,0 +1,66 @@
+// * This file is part of the COLOBOT source code
+// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
+// *
+// * This program is free software: you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License as published by
+// * the Free Software Foundation, either version 3 of the License, or
+// * (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+
+/**
+ * \file object/level/parser.h
+ * \brief Parser for level files
+ */
+
+#pragma once
+
+#include "object/level/parserline.h"
+#include "object/level/parserparam.h"
+#include "object/level/parserexceptions.h"
+
+#include <string>
+#include <vector>
+
+class CLevelParser
+{
+public:
+ //! Create an empty level file
+ CLevelParser();
+ //! Load level from file
+ CLevelParser(std::string filename);
+ //! Load given level
+ CLevelParser(std::string category, int chapter, int rank);
+
+ ~CLevelParser();
+
+ //! Build level filename
+ static std::string BuildSceneName(std::string category, int chapter, int rank, bool sceneFile = true);
+
+ //! Load file
+ void Load();
+ //! Save file
+ void Save(std::string filename);
+
+ //! Get filename
+ const std::string& GetFilename();
+
+ //! Get all lines from file
+ std::vector<CLevelParserLine*> GetLines();
+ //! Insert new line to file
+ void AddLine(CLevelParserLine* line);
+
+ //! Find first line with given command
+ CLevelParserLine* Get(std::string command);
+
+private:
+
+ std::string m_filename;
+ std::vector<CLevelParserLine*> m_lines;
+}; \ No newline at end of file
diff --git a/src/object/level/parserexceptions.cpp b/src/object/level/parserexceptions.cpp
new file mode 100644
index 0000000..d5c4620
--- /dev/null
+++ b/src/object/level/parserexceptions.cpp
@@ -0,0 +1,40 @@
+// * This file is part of the COLOBOT source code
+// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
+// *
+// * This program is free software: you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License as published by
+// * the Free Software Foundation, either version 3 of the License, or
+// * (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+
+#include "object/level/parserexceptions.h"
+
+
+#include "object/level/parser.h"
+
+CLevelParserException::CLevelParserException(std::string message) noexcept
+{
+ m_message = message;
+}
+
+const char* CLevelParserException::what() const noexcept
+{
+ return m_message.c_str();
+}
+
+CLevelParserExceptionMissingParam::CLevelParserExceptionMissingParam(CLevelParserParam* thisParam) noexcept
+: CLevelParserException("Missing required param "+thisParam->GetName()+" (in "+thisParam->GetLine()->GetLevel()->GetFilename()+":"+std::to_string(thisParam->GetLine()->GetLineNumber())+")")
+{
+}
+
+CLevelParserExceptionBadParam::CLevelParserExceptionBadParam(CLevelParserParam* thisParam, std::string requestedType) noexcept
+: CLevelParserException("Unable to parse '"+thisParam->GetValue()+"' as "+requestedType+" (param '"+thisParam->GetName()+"' in "+thisParam->GetLine()->GetLevel()->GetFilename()+":"+std::to_string(thisParam->GetLine()->GetLineNumber())+")")
+{
+} \ No newline at end of file
diff --git a/src/object/level/parserexceptions.h b/src/object/level/parserexceptions.h
new file mode 100644
index 0000000..813467f
--- /dev/null
+++ b/src/object/level/parserexceptions.h
@@ -0,0 +1,49 @@
+// * This file is part of the COLOBOT source code
+// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
+// *
+// * This program is free software: you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License as published by
+// * the Free Software Foundation, either version 3 of the License, or
+// * (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+
+/**
+ * \file object/level/parserexceptions.h
+ * \brief Exceptions that could be thrown in level parser
+ */
+
+#pragma once
+
+#include <exception>
+#include <string>
+
+class CLevelParserParam;
+
+class CLevelParserException : public std::exception
+{
+public:
+ CLevelParserException(std::string message) noexcept;
+ const char* what() const noexcept;
+
+protected:
+ std::string m_message;
+};
+
+class CLevelParserExceptionMissingParam : public CLevelParserException
+{
+public:
+ CLevelParserExceptionMissingParam(CLevelParserParam* thisParam) noexcept;
+};
+
+class CLevelParserExceptionBadParam : public CLevelParserException
+{
+public:
+ CLevelParserExceptionBadParam(CLevelParserParam* thisParam, std::string requestedType) noexcept;
+}; \ No newline at end of file
diff --git a/src/object/level/parserline.cpp b/src/object/level/parserline.cpp
new file mode 100644
index 0000000..37f6397
--- /dev/null
+++ b/src/object/level/parserline.cpp
@@ -0,0 +1,87 @@
+// * This file is part of the COLOBOT source code
+// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
+// *
+// * This program is free software: you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License as published by
+// * the Free Software Foundation, either version 3 of the License, or
+// * (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+
+#include "object/level/parserline.h"
+
+
+#include "object/level/parser.h"
+#include "common/logger.h"
+
+CLevelParserLine::CLevelParserLine(std::string command)
+{
+ m_command = command;
+ m_lineNumber = 0;
+}
+
+CLevelParserLine::CLevelParserLine(int lineNumber, std::string command)
+{
+ m_command = command;
+ m_lineNumber = lineNumber;
+}
+
+CLevelParserLine::~CLevelParserLine()
+{
+ for(auto param : m_params)
+ {
+ delete param.second;
+ }
+}
+
+std::string CLevelParserLine::GetLine()
+{
+ assert(false); //TODO
+}
+
+int CLevelParserLine::GetLineNumber()
+{
+ return m_lineNumber;
+}
+
+CLevelParser* CLevelParserLine::GetLevel()
+{
+ return m_level;
+}
+
+void CLevelParserLine::SetLevel(CLevelParser* level)
+{
+ m_level = level;
+}
+
+std::string CLevelParserLine::GetCommand()
+{
+ return m_command;
+}
+
+void CLevelParserLine::SetCommand(std::string command)
+{
+ m_command = command;
+}
+
+CLevelParserParam* CLevelParserLine::GetParam(std::string name)
+{
+ if(m_params[name] == nullptr) {
+ CLevelParserParam* param = new CLevelParserParam(name, true);
+ param->SetLine(this);
+ m_params[name] = param;
+ }
+ return m_params[name];
+}
+
+void CLevelParserLine::AddParam(std::string name, CLevelParserParam* value)
+{
+ value->SetLine(this);
+ m_params[name] = value;
+} \ No newline at end of file
diff --git a/src/object/level/parserline.h b/src/object/level/parserline.h
new file mode 100644
index 0000000..e8da34f
--- /dev/null
+++ b/src/object/level/parserline.h
@@ -0,0 +1,59 @@
+// * This file is part of the COLOBOT source code
+// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
+// *
+// * This program is free software: you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License as published by
+// * the Free Software Foundation, either version 3 of the License, or
+// * (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+
+/**
+ * \file object/level/parserline.h
+ * \brief Class for one line from level file
+ */
+
+#pragma once
+
+#include <string>
+#include <map>
+
+class CLevelParser;
+class CLevelParserParam;
+
+class CLevelParserLine
+{
+public:
+ CLevelParserLine(int lineNumber, std::string command);
+ CLevelParserLine(std::string command);
+ ~CLevelParserLine();
+
+ //! Get line to be saved in level file
+ std::string GetLine();
+
+ //! Get line number
+ int GetLineNumber();
+
+ //! Get CLevelParser this line is part of
+ CLevelParser* GetLevel();
+ //! Set CLevelParser this line is part of
+ void SetLevel(CLevelParser* level);
+
+ std::string GetCommand();
+ void SetCommand(std::string command);
+
+ CLevelParserParam* GetParam(std::string name);
+ void AddParam(std::string name, CLevelParserParam* value);
+
+private:
+ CLevelParser* m_level;
+ int m_lineNumber;
+ std::string m_command;
+ std::map<std::string, CLevelParserParam*> m_params;
+}; \ No newline at end of file
diff --git a/src/object/level/parserparam.cpp b/src/object/level/parserparam.cpp
new file mode 100644
index 0000000..ec043b4
--- /dev/null
+++ b/src/object/level/parserparam.cpp
@@ -0,0 +1,930 @@
+// * This file is part of the COLOBOT source code
+// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
+// *
+// * This program is free software: you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License as published by
+// * the Free Software Foundation, either version 3 of the License, or
+// * (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+
+#include "object/level/parserline.h"
+
+
+#include "app/app.h"
+#include "common/logger.h"
+#include "object/level/parser.h"
+#include "object/robotmain.h"
+
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+
+CLevelParserParam::CLevelParserParam(std::string name, std::string value)
+{
+ m_name = name;
+ m_value = value;
+ m_empty = false;
+}
+
+CLevelParserParam::CLevelParserParam(std::string name, bool empty)
+{
+ assert(empty == true); // we need a second argument because we don't want to create param with value "name"
+ m_name = name;
+ m_value = "";
+ m_empty = true;
+}
+
+CLevelParserParam::~CLevelParserParam()
+{
+ for(auto& a : m_array)
+ delete a;
+}
+
+void CLevelParserParam::SetLine(CLevelParserLine* line)
+{
+ m_line = line;
+}
+
+CLevelParserLine* CLevelParserParam::GetLine()
+{
+ return m_line;
+}
+
+std::string CLevelParserParam::GetName()
+{
+ return m_name;
+}
+
+std::string CLevelParserParam::GetValue()
+{
+ return m_value;
+}
+
+bool CLevelParserParam::IsDefined()
+{
+ return !m_empty;
+}
+
+template<typename T>
+T CLevelParserParam::Cast(std::string value, std::string requestedType)
+{
+ try {
+ return boost::lexical_cast<T>(value);
+ }
+ catch(...)
+ {
+ throw CLevelParserExceptionBadParam(this, requestedType);
+ }
+}
+
+template<typename T>
+T CLevelParserParam::Cast(std::string requestedType)
+{
+ return Cast<T>(m_value, requestedType);
+}
+
+
+int CLevelParserParam::AsInt()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+ return Cast<int>("int");
+}
+
+
+int CLevelParserParam::AsInt(int def)
+{
+ if(m_empty)
+ return def;
+ return AsInt();
+}
+
+
+float CLevelParserParam::AsFloat()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+ return Cast<float>("float");
+}
+
+float CLevelParserParam::AsFloat(float def)
+{
+ if(m_empty)
+ return def;
+ return AsFloat();
+}
+
+
+std::string CLevelParserParam::AsString()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+ if((m_value[0] == '\"' && m_value[m_value.length()-1] == '\"') || (m_value[0] == '\'' && m_value[m_value.length()-1] == '\''))
+ {
+ return m_value.substr(1, m_value.length()-2);
+ } else {
+ throw CLevelParserExceptionBadParam(this, "string");
+ }
+}
+
+std::string CLevelParserParam::AsString(std::string def)
+{
+ if(m_empty)
+ return def;
+ return AsString();
+}
+
+
+bool CLevelParserParam::AsBool()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+ std::string value = m_value;
+ boost::to_lower(value);
+ if(value == "true") return true;
+ if(value == "false") return false;
+ return Cast<bool>("bool");
+}
+
+bool CLevelParserParam::AsBool(bool def)
+{
+ if(m_empty)
+ return def;
+ return AsBool();
+}
+
+
+std::string CLevelParserParam::InjectLevelDir(std::string path, const std::string defaultDir)
+{
+ std::string newPath = path;
+ std::string lvlDir = CLevelParser::BuildSceneName(CRobotMain::GetInstancePointer()->GetSceneName(), CRobotMain::GetInstancePointer()->GetSceneRank()/100, CRobotMain::GetInstancePointer()->GetSceneRank()%100, false);
+ boost::replace_all(newPath, "%lvl%", lvlDir);
+ if(newPath == path)
+ {
+ newPath = defaultDir + (!defaultDir.empty() ? "/" : "") + newPath;
+ } else {
+ if(defaultDir == "")
+ throw CLevelParserException("TODO: Param "+m_name+" does not yet support %lvl%! :(");
+ }
+ //TODO: Fallback to English
+ std::string langStr(1, CApplication::GetInstancePointer()->GetLanguageChar());
+ boost::replace_all(newPath, "%lng%", langStr);
+ return newPath;
+}
+
+std::string CLevelParserParam::AsPath(const std::string defaultDir)
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+
+ return InjectLevelDir(AsString(), defaultDir);
+}
+
+std::string CLevelParserParam::AsPath(const std::string defaultDir, std::string def)
+{
+ if(m_empty)
+ return InjectLevelDir(def, defaultDir);
+
+ return InjectLevelDir(AsString(def), defaultDir);
+}
+
+
+Gfx::Color CLevelParserParam::AsColor()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+
+ ParseArray();
+
+ if(m_array.size() == 3) { //RGB
+ return Gfx::Color(m_array[0]->AsFloat(), m_array[1]->AsFloat(), m_array[2]->AsFloat());
+ } else if(m_array.size() == 4) { //RGBA
+ return Gfx::Color(m_array[0]->AsFloat(), m_array[1]->AsFloat(), m_array[2]->AsFloat(), m_array[3]->AsFloat());
+ } else {
+ throw CLevelParserExceptionBadParam(this, "color");
+ }
+}
+
+Gfx::Color CLevelParserParam::AsColor(Gfx::Color def)
+{
+ if(m_empty)
+ return def;
+ return AsColor();
+}
+
+
+Math::Vector CLevelParserParam::AsPoint()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+
+ ParseArray();
+
+ if(m_array.size() == 2) { //XZ
+ return Math::Vector(m_array[0]->AsFloat(), 0.0f, m_array[1]->AsFloat());
+ } else if(m_array.size() == 3) { //XYZ
+ return Math::Vector(m_array[0]->AsFloat(), m_array[1]->AsFloat(), m_array[2]->AsFloat());
+ } else {
+ throw CLevelParserExceptionBadParam(this, "point");
+ }
+}
+
+Math::Vector CLevelParserParam::AsPoint(Math::Vector def)
+{
+ if(m_empty)
+ return def;
+ return AsPoint();
+}
+
+
+ObjectType CLevelParserParam::ToObjectType(std::string value)
+{
+ if(value == "All" ) return OBJECT_NULL;
+ if(value == "Portico" ) return OBJECT_PORTICO;
+ if(value == "SpaceShip" ) return OBJECT_BASE;
+ if(value == "PracticeBot" ) return OBJECT_MOBILEwt;
+ if(value == "WingedGrabber" ) return OBJECT_MOBILEfa;
+ if(value == "TrackedGrabber" ) return OBJECT_MOBILEta;
+ if(value == "WheeledGrabber" ) return OBJECT_MOBILEwa;
+ if(value == "LeggedGrabber" ) return OBJECT_MOBILEia;
+ if(value == "WingedShooter" ) return OBJECT_MOBILEfc;
+ if(value == "TrackedShooter" ) return OBJECT_MOBILEtc;
+ if(value == "WheeledShooter" ) return OBJECT_MOBILEwc;
+ if(value == "LeggedShooter" ) return OBJECT_MOBILEic;
+ if(value == "WingedOrgaShooter" ) return OBJECT_MOBILEfi;
+ if(value == "TrackedOrgaShooter") return OBJECT_MOBILEti;
+ if(value == "WheeledOrgaShooter") return OBJECT_MOBILEwi;
+ if(value == "LeggedOrgaShooter" ) return OBJECT_MOBILEii;
+ if(value == "WingedSniffer" ) return OBJECT_MOBILEfs;
+ if(value == "TrackedSniffer" ) return OBJECT_MOBILEts;
+ if(value == "WheeledSniffer" ) return OBJECT_MOBILEws;
+ if(value == "LeggedSniffer" ) return OBJECT_MOBILEis;
+ if(value == "Thumper" ) return OBJECT_MOBILErt;
+ if(value == "PhazerShooter" ) return OBJECT_MOBILErc;
+ if(value == "Recycler" ) return OBJECT_MOBILErr;
+ if(value == "Shielder" ) return OBJECT_MOBILErs;
+ if(value == "Subber" ) return OBJECT_MOBILEsa;
+ if(value == "TargetBot" ) return OBJECT_MOBILEtg;
+ if(value == "Scribbler" ) return OBJECT_MOBILEdr;
+ if(value == "PowerSpot" ) return OBJECT_MARKPOWER;
+ if(value == "TitaniumSpot" ) return OBJECT_MARKSTONE;
+ if(value == "UraniumSpot" ) return OBJECT_MARKURANIUM;
+ if(value == "PlatinumSpot" ) return OBJECT_MARKURANIUM;
+ if(value == "KeyASpot" ) return OBJECT_MARKKEYa;
+ if(value == "KeyBSpot" ) return OBJECT_MARKKEYb;
+ if(value == "KeyCSpot" ) return OBJECT_MARKKEYc;
+ if(value == "KeyDSpot" ) return OBJECT_MARKKEYd;
+ if(value == "WayPoint" ) return OBJECT_WAYPOINT;
+ if(value == "BlueFlag" ) return OBJECT_FLAGb;
+ if(value == "RedFlag" ) return OBJECT_FLAGr;
+ if(value == "GreenFlag" ) return OBJECT_FLAGg;
+ if(value == "YellowFlag" ) return OBJECT_FLAGy;
+ if(value == "VioletFlag" ) return OBJECT_FLAGv;
+ if(value == "PowerCell" ) return OBJECT_POWER;
+ if(value == "FuelCellPlant" ) return OBJECT_NUCLEAR;
+ if(value == "FuelCell" ) return OBJECT_ATOMIC;
+ if(value == "NuclearCell" ) return OBJECT_ATOMIC;
+ if(value == "TitaniumOre" ) return OBJECT_STONE;
+ if(value == "UraniumOre" ) return OBJECT_URANIUM;
+ if(value == "PlatinumOre" ) return OBJECT_URANIUM;
+ if(value == "Titanium" ) return OBJECT_METAL;
+ if(value == "OrgaMatter" ) return OBJECT_BULLET;
+ if(value == "BlackBox" ) return OBJECT_BBOX;
+ if(value == "KeyA" ) return OBJECT_KEYa;
+ if(value == "KeyB" ) return OBJECT_KEYb;
+ if(value == "KeyC" ) return OBJECT_KEYc;
+ if(value == "KeyD" ) return OBJECT_KEYd;
+ if(value == "TNT" ) return OBJECT_TNT;
+ if(value == "Scrap1" ) return OBJECT_SCRAP1;
+ if(value == "Scrap2" ) return OBJECT_SCRAP2;
+ if(value == "Scrap3" ) return OBJECT_SCRAP3;
+ if(value == "Scrap4" ) return OBJECT_SCRAP4;
+ if(value == "Scrap5" ) return OBJECT_SCRAP5;
+ if(value == "Mine" ) return OBJECT_BOMB;
+ if(value == "Firework" ) return OBJECT_WINFIRE;
+ if(value == "Bag" ) return OBJECT_BAG;
+ if(value == "Greenery0" ) return OBJECT_PLANT0;
+ if(value == "Greenery1" ) return OBJECT_PLANT1;
+ if(value == "Greenery2" ) return OBJECT_PLANT2;
+ if(value == "Greenery3" ) return OBJECT_PLANT3;
+ if(value == "Greenery4" ) return OBJECT_PLANT4;
+ if(value == "Greenery5" ) return OBJECT_PLANT5;
+ if(value == "Greenery6" ) return OBJECT_PLANT6;
+ if(value == "Greenery7" ) return OBJECT_PLANT7;
+ if(value == "Greenery8" ) return OBJECT_PLANT8;
+ if(value == "Greenery9" ) return OBJECT_PLANT9;
+ if(value == "Greenery10" ) return OBJECT_PLANT10;
+ if(value == "Greenery11" ) return OBJECT_PLANT11;
+ if(value == "Greenery12" ) return OBJECT_PLANT12;
+ if(value == "Greenery13" ) return OBJECT_PLANT13;
+ if(value == "Greenery14" ) return OBJECT_PLANT14;
+ if(value == "Greenery15" ) return OBJECT_PLANT15;
+ if(value == "Greenery16" ) return OBJECT_PLANT16;
+ if(value == "Greenery17" ) return OBJECT_PLANT17;
+ if(value == "Greenery18" ) return OBJECT_PLANT18;
+ if(value == "Greenery19" ) return OBJECT_PLANT19;
+ if(value == "Tree0" ) return OBJECT_TREE0;
+ if(value == "Tree1" ) return OBJECT_TREE1;
+ if(value == "Tree2" ) return OBJECT_TREE2;
+ if(value == "Tree3" ) return OBJECT_TREE3;
+ if(value == "Tree4" ) return OBJECT_TREE4;
+ if(value == "Tree5" ) return OBJECT_TREE5;
+ if(value == "Mushroom1" ) return OBJECT_MUSHROOM1;
+ if(value == "Mushroom2" ) return OBJECT_MUSHROOM2;
+ if(value == "Home" ) return OBJECT_HOME1;
+ if(value == "Derrick" ) return OBJECT_DERRICK;
+ if(value == "BotFactory" ) return OBJECT_FACTORY;
+ if(value == "PowerStation" ) return OBJECT_STATION;
+ if(value == "Converter" ) return OBJECT_CONVERT;
+ if(value == "RepairCenter" ) return OBJECT_REPAIR;
+ if(value == "Destroyer" ) return OBJECT_DESTROYER;
+ if(value == "DefenseTower" ) return OBJECT_TOWER;
+ if(value == "AlienNest" ) return OBJECT_NEST;
+ if(value == "ResearchCenter" ) return OBJECT_RESEARCH;
+ if(value == "RadarStation" ) return OBJECT_RADAR;
+ if(value == "ExchangePost" ) return OBJECT_INFO;
+ if(value == "PowerPlant" ) return OBJECT_ENERGY;
+ if(value == "AutoLab" ) return OBJECT_LABO;
+ if(value == "NuclearPlant" ) return OBJECT_NUCLEAR;
+ if(value == "PowerCaptor" ) return OBJECT_PARA;
+ if(value == "Vault" ) return OBJECT_SAFE;
+ if(value == "Houston" ) return OBJECT_HUSTON;
+ if(value == "Target1" ) return OBJECT_TARGET1;
+ if(value == "Target2" ) return OBJECT_TARGET2;
+ if(value == "StartArea" ) return OBJECT_START;
+ if(value == "GoalArea" ) return OBJECT_END;
+ if(value == "AlienQueen" ) return OBJECT_MOTHER;
+ if(value == "AlienEgg" ) return OBJECT_EGG;
+ if(value == "AlienAnt" ) return OBJECT_ANT;
+ if(value == "AlienSpider" ) return OBJECT_SPIDER;
+ if(value == "AlienWasp" ) return OBJECT_BEE;
+ if(value == "AlienWorm" ) return OBJECT_WORM;
+ if(value == "WreckBotw1" ) return OBJECT_RUINmobilew1;
+ if(value == "WreckBotw2" ) return OBJECT_RUINmobilew2;
+ if(value == "WreckBott1" ) return OBJECT_RUINmobilet1;
+ if(value == "WreckBott2" ) return OBJECT_RUINmobilet2;
+ if(value == "WreckBotr1" ) return OBJECT_RUINmobiler1;
+ if(value == "WreckBotr2" ) return OBJECT_RUINmobiler2;
+ if(value == "RuinBotFactory" ) return OBJECT_RUINfactory;
+ if(value == "RuinDoor" ) return OBJECT_RUINdoor;
+ if(value == "RuinSupport" ) return OBJECT_RUINsupport;
+ if(value == "RuinRadar" ) return OBJECT_RUINradar;
+ if(value == "RuinConvert" ) return OBJECT_RUINconvert;
+ if(value == "RuinBaseCamp" ) return OBJECT_RUINbase;
+ if(value == "RuinHeadCamp" ) return OBJECT_RUINhead;
+ if(value == "Barrier0" ) return OBJECT_BARRIER0;
+ if(value == "Barrier1" ) return OBJECT_BARRIER1;
+ if(value == "Barrier2" ) return OBJECT_BARRIER2;
+ if(value == "Barrier3" ) return OBJECT_BARRIER3;
+ if(value == "Teen0" ) return OBJECT_TEEN0;
+ if(value == "Teen1" ) return OBJECT_TEEN1;
+ if(value == "Teen2" ) return OBJECT_TEEN2;
+ if(value == "Teen3" ) return OBJECT_TEEN3;
+ if(value == "Teen4" ) return OBJECT_TEEN4;
+ if(value == "Teen5" ) return OBJECT_TEEN5;
+ if(value == "Teen6" ) return OBJECT_TEEN6;
+ if(value == "Teen7" ) return OBJECT_TEEN7;
+ if(value == "Teen8" ) return OBJECT_TEEN8;
+ if(value == "Teen9" ) return OBJECT_TEEN9;
+ if(value == "Teen10" ) return OBJECT_TEEN10;
+ if(value == "Teen11" ) return OBJECT_TEEN11;
+ if(value == "Teen12" ) return OBJECT_TEEN12;
+ if(value == "Teen13" ) return OBJECT_TEEN13;
+ if(value == "Teen14" ) return OBJECT_TEEN14;
+ if(value == "Teen15" ) return OBJECT_TEEN15;
+ if(value == "Teen16" ) return OBJECT_TEEN16;
+ if(value == "Teen17" ) return OBJECT_TEEN17;
+ if(value == "Teen18" ) return OBJECT_TEEN18;
+ if(value == "Teen19" ) return OBJECT_TEEN19;
+ if(value == "Teen20" ) return OBJECT_TEEN20;
+ if(value == "Teen21" ) return OBJECT_TEEN21;
+ if(value == "Teen22" ) return OBJECT_TEEN22;
+ if(value == "Teen23" ) return OBJECT_TEEN23;
+ if(value == "Teen24" ) return OBJECT_TEEN24;
+ if(value == "Teen25" ) return OBJECT_TEEN25;
+ if(value == "Teen26" ) return OBJECT_TEEN26;
+ if(value == "Teen27" ) return OBJECT_TEEN27;
+ if(value == "Teen28" ) return OBJECT_TEEN28;
+ if(value == "Teen29" ) return OBJECT_TEEN29;
+ if(value == "Teen30" ) return OBJECT_TEEN30;
+ if(value == "Teen31" ) return OBJECT_TEEN31;
+ if(value == "Teen32" ) return OBJECT_TEEN32;
+ if(value == "Teen33" ) return OBJECT_TEEN33;
+ if(value == "Stone" ) return OBJECT_TEEN34;
+ if(value == "Teen35" ) return OBJECT_TEEN35;
+ if(value == "Teen36" ) return OBJECT_TEEN36;
+ if(value == "Teen37" ) return OBJECT_TEEN37;
+ if(value == "Teen38" ) return OBJECT_TEEN38;
+ if(value == "Teen39" ) return OBJECT_TEEN39;
+ if(value == "Teen40" ) return OBJECT_TEEN40;
+ if(value == "Teen41" ) return OBJECT_TEEN41;
+ if(value == "Teen42" ) return OBJECT_TEEN42;
+ if(value == "Teen43" ) return OBJECT_TEEN43;
+ if(value == "Teen44" ) return OBJECT_TEEN44;
+ if(value == "Quartz0" ) return OBJECT_QUARTZ0;
+ if(value == "Quartz1" ) return OBJECT_QUARTZ1;
+ if(value == "Quartz2" ) return OBJECT_QUARTZ2;
+ if(value == "Quartz3" ) return OBJECT_QUARTZ3;
+ if(value == "MegaStalk0" ) return OBJECT_ROOT0;
+ if(value == "MegaStalk1" ) return OBJECT_ROOT1;
+ if(value == "MegaStalk2" ) return OBJECT_ROOT2;
+ if(value == "MegaStalk3" ) return OBJECT_ROOT3;
+ if(value == "MegaStalk4" ) return OBJECT_ROOT4;
+ if(value == "MegaStalk5" ) return OBJECT_ROOT5;
+ if(value == "ApolloLEM" ) return OBJECT_APOLLO1;
+ if(value == "ApolloJeep" ) return OBJECT_APOLLO2;
+ if(value == "ApolloFlag" ) return OBJECT_APOLLO3;
+ if(value == "ApolloModule" ) return OBJECT_APOLLO4;
+ if(value == "ApolloAntenna" ) return OBJECT_APOLLO5;
+ if(value == "Me" ) return OBJECT_HUMAN;
+ if(value == "Tech" ) return OBJECT_TECH;
+ if(value == "MissionController" ) return OBJECT_CONTROLLER;
+ return static_cast<ObjectType>(Cast<int>(value, "object"));
+}
+
+const std::string CLevelParserParam::FromObjectType(ObjectType value)
+{
+ if(value == OBJECT_PORTICO ) return "Portico";
+ if(value == OBJECT_BASE ) return "SpaceShip";
+ if(value == OBJECT_MOBILEwt ) return "PracticeBot";
+ if(value == OBJECT_MOBILEfa ) return "WingedGrabber";
+ if(value == OBJECT_MOBILEta ) return "TrackedGrabber";
+ if(value == OBJECT_MOBILEwa ) return "WheeledGrabber";
+ if(value == OBJECT_MOBILEia ) return "LeggedGrabber";
+ if(value == OBJECT_MOBILEfc ) return "WingedShooter";
+ if(value == OBJECT_MOBILEtc ) return "TrackedShooter";
+ if(value == OBJECT_MOBILEwc ) return "WheeledShooter";
+ if(value == OBJECT_MOBILEic ) return "LeggedShooter";
+ if(value == OBJECT_MOBILEfi ) return "WingedOrgaShooter";
+ if(value == OBJECT_MOBILEti ) return "TrackedOrgaShooter";
+ if(value == OBJECT_MOBILEwi ) return "WheeledOrgaShooter";
+ if(value == OBJECT_MOBILEii ) return "LeggedOrgaShooter";
+ if(value == OBJECT_MOBILEfs ) return "WingedSniffer";
+ if(value == OBJECT_MOBILEts ) return "TrackedSniffer";
+ if(value == OBJECT_MOBILEws ) return "WheeledSniffer";
+ if(value == OBJECT_MOBILEis ) return "LeggedSniffer";
+ if(value == OBJECT_MOBILErt ) return "Thumper";
+ if(value == OBJECT_MOBILErc ) return "PhazerShooter";
+ if(value == OBJECT_MOBILErr ) return "Recycler";
+ if(value == OBJECT_MOBILErs ) return "Shielder";
+ if(value == OBJECT_MOBILEsa ) return "Subber";
+ if(value == OBJECT_MOBILEtg ) return "TargetBot";
+ if(value == OBJECT_MOBILEdr ) return "Scribbler";
+ if(value == OBJECT_MARKPOWER ) return "PowerSpot";
+ if(value == OBJECT_MARKSTONE ) return "TitaniumSpot";
+ if(value == OBJECT_MARKURANIUM ) return "UraniumSpot";
+ if(value == OBJECT_MARKKEYa ) return "KeyASpot";
+ if(value == OBJECT_MARKKEYb ) return "KeyBSpot";
+ if(value == OBJECT_MARKKEYc ) return "KeyCSpot";
+ if(value == OBJECT_MARKKEYd ) return "KeyDSpot";
+ if(value == OBJECT_WAYPOINT ) return "WayPoint";
+ if(value == OBJECT_FLAGb ) return "BlueFlag";
+ if(value == OBJECT_FLAGr ) return "RedFlag";
+ if(value == OBJECT_FLAGg ) return "GreenFlag";
+ if(value == OBJECT_FLAGy ) return "YellowFlag";
+ if(value == OBJECT_FLAGv ) return "VioletFlag";
+ if(value == OBJECT_POWER ) return "PowerCell";
+ if(value == OBJECT_ATOMIC ) return "NuclearCell";
+ if(value == OBJECT_STONE ) return "TitaniumOre";
+ if(value == OBJECT_URANIUM ) return "UraniumOre";
+ if(value == OBJECT_METAL ) return "Titanium";
+ if(value == OBJECT_BULLET ) return "OrgaMatter";
+ if(value == OBJECT_BBOX ) return "BlackBox";
+ if(value == OBJECT_KEYa ) return "KeyA";
+ if(value == OBJECT_KEYb ) return "KeyB";
+ if(value == OBJECT_KEYc ) return "KeyC";
+ if(value == OBJECT_KEYd ) return "KeyD";
+ if(value == OBJECT_TNT ) return "TNT";
+ if(value == OBJECT_SCRAP1 ) return "Scrap1";
+ if(value == OBJECT_SCRAP2 ) return "Scrap2";
+ if(value == OBJECT_SCRAP3 ) return "Scrap3";
+ if(value == OBJECT_SCRAP4 ) return "Scrap4";
+ if(value == OBJECT_SCRAP5 ) return "Scrap5";
+ if(value == OBJECT_BOMB ) return "Mine";
+ if(value == OBJECT_WINFIRE ) return "Firework";
+ if(value == OBJECT_BAG ) return "Bag";
+ if(value == OBJECT_PLANT0 ) return "Greenery0";
+ if(value == OBJECT_PLANT1 ) return "Greenery1";
+ if(value == OBJECT_PLANT2 ) return "Greenery2";
+ if(value == OBJECT_PLANT3 ) return "Greenery3";
+ if(value == OBJECT_PLANT4 ) return "Greenery4";
+ if(value == OBJECT_PLANT5 ) return "Greenery5";
+ if(value == OBJECT_PLANT6 ) return "Greenery6";
+ if(value == OBJECT_PLANT7 ) return "Greenery7";
+ if(value == OBJECT_PLANT8 ) return "Greenery8";
+ if(value == OBJECT_PLANT9 ) return "Greenery9";
+ if(value == OBJECT_PLANT10 ) return "Greenery10";
+ if(value == OBJECT_PLANT11 ) return "Greenery11";
+ if(value == OBJECT_PLANT12 ) return "Greenery12";
+ if(value == OBJECT_PLANT13 ) return "Greenery13";
+ if(value == OBJECT_PLANT14 ) return "Greenery14";
+ if(value == OBJECT_PLANT15 ) return "Greenery15";
+ if(value == OBJECT_PLANT16 ) return "Greenery16";
+ if(value == OBJECT_PLANT17 ) return "Greenery17";
+ if(value == OBJECT_PLANT18 ) return "Greenery18";
+ if(value == OBJECT_PLANT19 ) return "Greenery19";
+ if(value == OBJECT_TREE0 ) return "Tree0";
+ if(value == OBJECT_TREE1 ) return "Tree1";
+ if(value == OBJECT_TREE2 ) return "Tree2";
+ if(value == OBJECT_TREE3 ) return "Tree3";
+ if(value == OBJECT_TREE4 ) return "Tree4";
+ if(value == OBJECT_TREE5 ) return "Tree5";
+ if(value == OBJECT_MUSHROOM1 ) return "Mushroom1";
+ if(value == OBJECT_MUSHROOM2 ) return "Mushroom2";
+ if(value == OBJECT_HOME1 ) return "Home";
+ if(value == OBJECT_DERRICK ) return "Derrick";
+ if(value == OBJECT_FACTORY ) return "BotFactory";
+ if(value == OBJECT_STATION ) return "PowerStation";
+ if(value == OBJECT_CONVERT ) return "Converter";
+ if(value == OBJECT_REPAIR ) return "RepairCenter";
+ if(value == OBJECT_DESTROYER ) return "Destroyer";
+ if(value == OBJECT_TOWER ) return "DefenseTower";
+ if(value == OBJECT_NEST ) return "AlienNest";
+ if(value == OBJECT_RESEARCH ) return "ResearchCenter";
+ if(value == OBJECT_RADAR ) return "RadarStation";
+ if(value == OBJECT_INFO ) return "ExchangePost";
+ if(value == OBJECT_ENERGY ) return "PowerPlant";
+ if(value == OBJECT_LABO ) return "AutoLab";
+ if(value == OBJECT_NUCLEAR ) return "NuclearPlant";
+ if(value == OBJECT_PARA ) return "PowerCaptor";
+ if(value == OBJECT_SAFE ) return "Vault";
+ if(value == OBJECT_HUSTON ) return "Houston";
+ if(value == OBJECT_TARGET1 ) return "Target1";
+ if(value == OBJECT_TARGET2 ) return "Target2";
+ if(value == OBJECT_START ) return "StartArea";
+ if(value == OBJECT_END ) return "GoalArea";
+ if(value == OBJECT_MOTHER ) return "AlienQueen";
+ if(value == OBJECT_EGG ) return "AlienEgg";
+ if(value == OBJECT_ANT ) return "AlienAnt";
+ if(value == OBJECT_SPIDER ) return "AlienSpider";
+ if(value == OBJECT_BEE ) return "AlienWasp";
+ if(value == OBJECT_WORM ) return "AlienWorm";
+ if(value == OBJECT_RUINmobilew1) return "WreckBotw1";
+ if(value == OBJECT_RUINmobilew2) return "WreckBotw2";
+ if(value == OBJECT_RUINmobilet1) return "WreckBott1";
+ if(value == OBJECT_RUINmobilet2) return "WreckBott2";
+ if(value == OBJECT_RUINmobiler1) return "WreckBotr1";
+ if(value == OBJECT_RUINmobiler2) return "WreckBotr2";
+ if(value == OBJECT_RUINfactory ) return "RuinBotFactory";
+ if(value == OBJECT_RUINdoor ) return "RuinDoor";
+ if(value == OBJECT_RUINsupport ) return "RuinSupport";
+ if(value == OBJECT_RUINradar ) return "RuinRadar";
+ if(value == OBJECT_RUINconvert ) return "RuinConvert";
+ if(value == OBJECT_RUINbase ) return "RuinBaseCamp";
+ if(value == OBJECT_RUINhead ) return "RuinHeadCamp";
+ if(value == OBJECT_BARRIER0 ) return "Barrier0";
+ if(value == OBJECT_BARRIER1 ) return "Barrier1";
+ if(value == OBJECT_BARRIER2 ) return "Barrier2";
+ if(value == OBJECT_BARRIER3 ) return "Barrier3";
+ if(value == OBJECT_TEEN0 ) return "Teen0";
+ if(value == OBJECT_TEEN1 ) return "Teen1";
+ if(value == OBJECT_TEEN2 ) return "Teen2";
+ if(value == OBJECT_TEEN3 ) return "Teen3";
+ if(value == OBJECT_TEEN4 ) return "Teen4";
+ if(value == OBJECT_TEEN5 ) return "Teen5";
+ if(value == OBJECT_TEEN6 ) return "Teen6";
+ if(value == OBJECT_TEEN7 ) return "Teen7";
+ if(value == OBJECT_TEEN8 ) return "Teen8";
+ if(value == OBJECT_TEEN9 ) return "Teen9";
+ if(value == OBJECT_TEEN10 ) return "Teen10";
+ if(value == OBJECT_TEEN11 ) return "Teen11";
+ if(value == OBJECT_TEEN12 ) return "Teen12";
+ if(value == OBJECT_TEEN13 ) return "Teen13";
+ if(value == OBJECT_TEEN14 ) return "Teen14";
+ if(value == OBJECT_TEEN15 ) return "Teen15";
+ if(value == OBJECT_TEEN16 ) return "Teen16";
+ if(value == OBJECT_TEEN17 ) return "Teen17";
+ if(value == OBJECT_TEEN18 ) return "Teen18";
+ if(value == OBJECT_TEEN19 ) return "Teen19";
+ if(value == OBJECT_TEEN20 ) return "Teen20";
+ if(value == OBJECT_TEEN21 ) return "Teen21";
+ if(value == OBJECT_TEEN22 ) return "Teen22";
+ if(value == OBJECT_TEEN23 ) return "Teen23";
+ if(value == OBJECT_TEEN24 ) return "Teen24";
+ if(value == OBJECT_TEEN25 ) return "Teen25";
+ if(value == OBJECT_TEEN26 ) return "Teen26";
+ if(value == OBJECT_TEEN27 ) return "Teen27";
+ if(value == OBJECT_TEEN28 ) return "Teen28";
+ if(value == OBJECT_TEEN29 ) return "Teen29";
+ if(value == OBJECT_TEEN30 ) return "Teen30";
+ if(value == OBJECT_TEEN31 ) return "Teen31";
+ if(value == OBJECT_TEEN32 ) return "Teen32";
+ if(value == OBJECT_TEEN33 ) return "Teen33";
+ if(value == OBJECT_TEEN34 ) return "Stone";
+ if(value == OBJECT_TEEN35 ) return "Teen35";
+ if(value == OBJECT_TEEN36 ) return "Teen36";
+ if(value == OBJECT_TEEN37 ) return "Teen37";
+ if(value == OBJECT_TEEN38 ) return "Teen38";
+ if(value == OBJECT_TEEN39 ) return "Teen39";
+ if(value == OBJECT_TEEN40 ) return "Teen40";
+ if(value == OBJECT_TEEN41 ) return "Teen41";
+ if(value == OBJECT_TEEN42 ) return "Teen42";
+ if(value == OBJECT_TEEN43 ) return "Teen43";
+ if(value == OBJECT_TEEN44 ) return "Teen44";
+ if(value == OBJECT_QUARTZ0 ) return "Quartz0";
+ if(value == OBJECT_QUARTZ1 ) return "Quartz1";
+ if(value == OBJECT_QUARTZ2 ) return "Quartz2";
+ if(value == OBJECT_QUARTZ3 ) return "Quartz3";
+ if(value == OBJECT_ROOT0 ) return "MegaStalk0";
+ if(value == OBJECT_ROOT1 ) return "MegaStalk1";
+ if(value == OBJECT_ROOT2 ) return "MegaStalk2";
+ if(value == OBJECT_ROOT3 ) return "MegaStalk3";
+ if(value == OBJECT_ROOT4 ) return "MegaStalk4";
+ if(value == OBJECT_ROOT5 ) return "MegaStalk5";
+ if(value == OBJECT_APOLLO1 ) return "ApolloLEM";
+ if(value == OBJECT_APOLLO2 ) return "ApolloJeep";
+ if(value == OBJECT_APOLLO3 ) return "ApolloFlag";
+ if(value == OBJECT_APOLLO4 ) return "ApolloModule";
+ if(value == OBJECT_APOLLO5 ) return "ApolloAntenna";
+ if(value == OBJECT_HUMAN ) return "Me";
+ if(value == OBJECT_TECH ) return "Tech";
+ if(value == OBJECT_CONTROLLER ) return "MissionController";
+ return std::to_string(static_cast<int>(value));
+}
+
+ObjectType CLevelParserParam::AsObjectType()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+ return ToObjectType(m_value);
+}
+
+ObjectType CLevelParserParam::AsObjectType(ObjectType def)
+{
+ if(m_empty)
+ return def;
+ return AsObjectType();
+}
+
+
+DriveType CLevelParserParam::ToDriveType(std::string value)
+{
+ if(value == "Wheeled") return DRIVE_WHEELED;
+ if(value == "Tracked") return DRIVE_TRACKED;
+ if(value == "Winged" ) return DRIVE_WINGED;
+ if(value == "Legged" ) return DRIVE_LEGGED;
+ if(value == "Other" ) return DRIVE_OTHER;
+ return static_cast<DriveType>(Cast<int>(value, "drive"));
+}
+
+DriveType CLevelParserParam::AsDriveType()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+ return ToDriveType(m_value);
+}
+
+DriveType CLevelParserParam::AsDriveType(DriveType def)
+{
+ if(m_empty)
+ return def;
+ return AsDriveType();
+}
+
+
+ToolType CLevelParserParam::ToToolType(std::string value)
+{
+ if(value == "Grabber" ) return TOOL_GRABBER;
+ if(value == "Shiffer" ) return TOOL_SNIFFER;
+ if(value == "Shooter" ) return TOOL_SHOOTER;
+ if(value == "OrgaShooter") return TOOL_ORGASHOOTER;
+ if(value == "Other" ) return TOOL_OTHER;
+ return static_cast<ToolType>(Cast<int>(value, "tool"));
+}
+
+ToolType CLevelParserParam::AsToolType()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+ return ToToolType(m_value);
+}
+
+ToolType CLevelParserParam::AsToolType(ToolType def)
+{
+ if(m_empty)
+ return def;
+ return AsToolType();
+}
+
+
+Gfx::WaterType CLevelParserParam::ToWaterType(std::string value)
+{
+ if(value == "NULL") return Gfx::WATER_NULL;
+ if(value == "TT" ) return Gfx::WATER_TT;
+ if(value == "TO" ) return Gfx::WATER_TO;
+ if(value == "CT" ) return Gfx::WATER_CT;
+ if(value == "CO" ) return Gfx::WATER_CO;
+ return static_cast<Gfx::WaterType>(Cast<int>(value, "watertype"));
+}
+
+Gfx::WaterType CLevelParserParam::AsWaterType()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+ return ToWaterType(m_value);
+}
+
+Gfx::WaterType CLevelParserParam::AsWaterType(Gfx::WaterType def)
+{
+ if(m_empty)
+ return def;
+ return AsWaterType();
+}
+
+
+Gfx::EngineObjectType CLevelParserParam::ToTerrainType(std::string value)
+{
+ if(value == "Terrain") return Gfx::ENG_OBJTYPE_TERRAIN;
+ if(value == "Object" ) return Gfx::ENG_OBJTYPE_FIX;
+ if(value == "Quartz" ) return Gfx::ENG_OBJTYPE_QUARTZ;
+ if(value == "Metal" ) return Gfx::ENG_OBJTYPE_METAL;
+ return static_cast<Gfx::EngineObjectType>(Cast<int>(value, "terraintype"));
+}
+
+Gfx::EngineObjectType CLevelParserParam::AsTerrainType()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+ return ToTerrainType(m_value);
+}
+
+Gfx::EngineObjectType CLevelParserParam::AsTerrainType(Gfx::EngineObjectType def)
+{
+ if(m_empty)
+ return def;
+ return AsTerrainType();
+}
+
+
+int CLevelParserParam::ToBuildFlag(std::string value)
+{
+ if(value == "BotFactory" ) return BUILD_FACTORY;
+ if(value == "Derrick" ) return BUILD_DERRICK;
+ if(value == "Converter" ) return BUILD_CONVERT;
+ if(value == "RadarStation" ) return BUILD_RADAR;
+ if(value == "PowerPlant" ) return BUILD_ENERGY;
+ if(value == "NuclearPlant" ) return BUILD_NUCLEAR;
+ if(value == "FuelCellPlant" ) return BUILD_NUCLEAR;
+ if(value == "PowerStation" ) return BUILD_STATION;
+ if(value == "RepairCenter" ) return BUILD_REPAIR;
+ if(value == "DefenseTower" ) return BUILD_TOWER;
+ if(value == "ResearchCenter") return BUILD_RESEARCH;
+ if(value == "AutoLab" ) return BUILD_LABO;
+ if(value == "PowerCaptor" ) return BUILD_PARA;
+ if(value == "ExchangePost" ) return BUILD_INFO;
+ if(value == "Destroyer" ) return BUILD_DESTROYER;
+ if(value == "FlatGround" ) return BUILD_GFLAT;
+ if(value == "Flag" ) return BUILD_FLAG;
+ return Cast<int>(value, "buildflag");
+}
+
+int CLevelParserParam::AsBuildFlag()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+ return ToBuildFlag(m_value);
+}
+
+int CLevelParserParam::AsBuildFlag(int def)
+{
+ if(m_empty)
+ return def;
+ return AsBuildFlag();
+}
+
+
+int CLevelParserParam::ToResearchFlag(std::string value)
+{
+ if(value == "TRACKER" ) return RESEARCH_TANK;
+ if(value == "WINGER" ) return RESEARCH_FLY;
+ if(value == "THUMPER" ) return RESEARCH_THUMP;
+ if(value == "SHOOTER" ) return RESEARCH_CANON;
+ if(value == "TOWER" ) return RESEARCH_TOWER;
+ if(value == "PHAZER" ) return RESEARCH_PHAZER;
+ if(value == "SHIELDER") return RESEARCH_SHIELD;
+ if(value == "ATOMIC" ) return RESEARCH_ATOMIC;
+ if(value == "iPAW" ) return RESEARCH_iPAW;
+ if(value == "iGUN" ) return RESEARCH_iGUN;
+ if(value == "RECYCLER") return RESEARCH_RECYCLER;
+ if(value == "SUBBER" ) return RESEARCH_SUBM;
+ if(value == "SNIFFER" ) return RESEARCH_SNIFFER;
+ return Cast<int>(value, "researchflag");
+}
+
+int CLevelParserParam::AsResearchFlag()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+ return ToResearchFlag(m_value);
+}
+
+int CLevelParserParam::AsResearchFlag(int def)
+{
+ if(m_empty)
+ return def;
+ return AsResearchFlag();
+}
+
+
+Gfx::PyroType CLevelParserParam::ToPyroType(std::string value)
+{
+ if(value == "FRAGt" ) return Gfx::PT_FRAGT;
+ if(value == "FRAGo" ) return Gfx::PT_FRAGO;
+ if(value == "FRAGw" ) return Gfx::PT_FRAGW;
+ if(value == "EXPLOt") return Gfx::PT_EXPLOT;
+ if(value == "EXPLOo") return Gfx::PT_EXPLOO;
+ if(value == "EXPLOw") return Gfx::PT_EXPLOW;
+ if(value == "SHOTt" ) return Gfx::PT_SHOTT;
+ if(value == "SHOTh" ) return Gfx::PT_SHOTH;
+ if(value == "SHOTm" ) return Gfx::PT_SHOTM;
+ if(value == "SHOTw" ) return Gfx::PT_SHOTW;
+ if(value == "EGG" ) return Gfx::PT_EGG;
+ if(value == "BURNt" ) return Gfx::PT_BURNT;
+ if(value == "BURNo" ) return Gfx::PT_BURNO;
+ if(value == "SPIDER") return Gfx::PT_SPIDER;
+ if(value == "FALL" ) return Gfx::PT_FALL;
+ if(value == "RESET" ) return Gfx::PT_RESET;
+ if(value == "WIN" ) return Gfx::PT_WIN;
+ if(value == "LOST" ) return Gfx::PT_LOST;
+ return static_cast<Gfx::PyroType>(Cast<int>(value, "pyrotype"));
+}
+
+Gfx::PyroType CLevelParserParam::AsPyroType()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+ return ToPyroType(m_value);
+}
+
+Gfx::PyroType CLevelParserParam::AsPyroType(Gfx::PyroType def)
+{
+ if(m_empty)
+ return def;
+ return AsPyroType();
+}
+
+
+Gfx::CameraType CLevelParserParam::ToCameraType(std::string value)
+{
+ if(value == "BACK" ) return Gfx::CAM_TYPE_BACK;
+ if(value == "PLANE" ) return Gfx::CAM_TYPE_PLANE;
+ if(value == "ONBOARD") return Gfx::CAM_TYPE_ONBOARD;
+ if(value == "FIX" ) return Gfx::CAM_TYPE_FIX;
+ return static_cast<Gfx::CameraType>(Cast<int>(value, "camera"));
+}
+
+const std::string CLevelParserParam::FromCameraType(Gfx::CameraType value)
+{
+ if(value == Gfx::CAM_TYPE_ONBOARD) return "ONBOARD";
+ if(value == Gfx::CAM_TYPE_FIX ) return "FIX";
+ return std::to_string(static_cast<int>(value));
+}
+
+Gfx::CameraType CLevelParserParam::AsCameraType()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+ return ToCameraType(m_value);
+}
+
+Gfx::CameraType CLevelParserParam::AsCameraType(Gfx::CameraType def)
+{
+ if(m_empty)
+ return def;
+ return AsCameraType();
+}
+
+
+void CLevelParserParam::ParseArray()
+{
+ if(m_array.size() != 0)
+ return;
+
+ std::vector<std::string> values;
+ boost::split(values, m_value, boost::is_any_of(";"));
+ int i = 0;
+ for(auto& value : values) {
+ boost::algorithm::trim(value);
+ if(value.empty()) continue;
+ CLevelParserParam* param = new CLevelParserParam(m_name+"["+std::to_string(i)+"]", value);
+ param->SetLine(m_line);
+ m_array.push_back(param);
+ i++;
+ }
+}
+
+const std::vector<CLevelParserParam*>& CLevelParserParam::AsArray()
+{
+ if(m_empty)
+ throw CLevelParserExceptionMissingParam(this);
+
+ ParseArray();
+
+ return m_array;
+} \ No newline at end of file
diff --git a/src/object/level/parserparam.h b/src/object/level/parserparam.h
new file mode 100644
index 0000000..9d5ba99
--- /dev/null
+++ b/src/object/level/parserparam.h
@@ -0,0 +1,133 @@
+// * This file is part of the COLOBOT source code
+// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
+// *
+// * This program is free software: you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License as published by
+// * the Free Software Foundation, either version 3 of the License, or
+// * (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+
+/**
+ * \file object/level/parserparam.h
+ * \brief Value of command argument in level file
+ */
+
+#pragma once
+
+#include <object/object.h>
+#include <graphics/core/color.h>
+#include <graphics/engine/water.h>
+#include <graphics/engine/pyro.h>
+#include <math/point.h>
+
+#include <string>
+
+class CLevelParserLine;
+
+class CLevelParserParam
+{
+public:
+ //! Create param with given value
+ //@{
+ CLevelParserParam(int value);
+ CLevelParserParam(float value);
+ CLevelParserParam(std::string value);
+ CLevelParserParam(bool value);
+ CLevelParserParam(Gfx::Color value);
+ CLevelParserParam(Math::Point value);
+ CLevelParserParam(ObjectType value);
+ CLevelParserParam(Gfx::CameraType value);
+ CLevelParserParam(const std::vector<CLevelParserParam*>& value);
+ //@}
+ //! Create param from string
+ CLevelParserParam(std::string name, std::string value);
+ //! Create empty parser param
+ CLevelParserParam(std::string name, bool empty);
+
+ ~CLevelParserParam();
+
+ //! Get value (throws exception if not found or unable to process)
+ //@{
+ int AsInt();
+ float AsFloat();
+ std::string AsString();
+ bool AsBool();
+ std::string AsPath(const std::string defaultDir);
+ Gfx::Color AsColor();
+ Math::Vector AsPoint();
+ ObjectType AsObjectType();
+ DriveType AsDriveType();
+ ToolType AsToolType();
+ Gfx::WaterType AsWaterType();
+ Gfx::EngineObjectType AsTerrainType();
+ int AsBuildFlag();
+ int AsResearchFlag();
+ Gfx::PyroType AsPyroType();
+ Gfx::CameraType AsCameraType();
+ const std::vector<CLevelParserParam*>& AsArray();
+ //@}
+
+ //! Get value (returns default if not found, throws exception if unable to process)
+ //@{
+ int AsInt(int def);
+ float AsFloat(float def);
+ std::string AsString(std::string def);
+ bool AsBool(bool def);
+ std::string AsPath(const std::string defaultDir, std::string def);
+ Gfx::Color AsColor(Gfx::Color def);
+ Math::Vector AsPoint(Math::Vector def);
+ ObjectType AsObjectType(ObjectType def);
+ DriveType AsDriveType(DriveType def);
+ ToolType AsToolType(ToolType def);
+ Gfx::WaterType AsWaterType(Gfx::WaterType def);
+ Gfx::EngineObjectType AsTerrainType(Gfx::EngineObjectType def);
+ int AsBuildFlag(int def);
+ int AsResearchFlag(int def);
+ Gfx::PyroType AsPyroType(Gfx::PyroType def);
+ Gfx::CameraType AsCameraType(Gfx::CameraType def);
+ //@}
+
+ //! Set line this param is part of
+ void SetLine(CLevelParserLine* line);
+ //! Get line this param is part of
+ CLevelParserLine* GetLine();
+
+ std::string GetName();
+ std::string GetValue();
+ bool IsDefined();
+
+private:
+ void ParseArray();
+
+ template<typename T> T Cast(std::string value, std::string requestedType);
+ template<typename T> T Cast(std::string requestedType);
+
+ std::string InjectLevelDir(std::string path, const std::string defaultDir);
+
+ ObjectType ToObjectType(std::string value);
+ DriveType ToDriveType(std::string value);
+ ToolType ToToolType(std::string value);
+ Gfx::WaterType ToWaterType(std::string value);
+ Gfx::EngineObjectType ToTerrainType(std::string value);
+ int ToBuildFlag(std::string value);
+ int ToResearchFlag(std::string value);
+ Gfx::PyroType ToPyroType(std::string value);
+ Gfx::CameraType ToCameraType(std::string value);
+
+ const std::string FromObjectType(ObjectType value);
+ const std::string FromCameraType(Gfx::CameraType value);
+
+private:
+ CLevelParserLine* m_line;
+ bool m_empty;
+ std::string m_name;
+ std::string m_value;
+ std::vector<CLevelParserParam*> m_array;
+}; \ No newline at end of file
diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp
index 407a1ec..ce7f8d0 100644
--- a/src/object/robotmain.cpp
+++ b/src/object/robotmain.cpp
@@ -58,6 +58,7 @@
#include "object/task/task.h"
#include "object/task/taskbuild.h"
#include "object/task/taskmanip.h"
+#include "object/level/parser.h"
#include "physics/physics.h"
@@ -83,7 +84,7 @@
#include <iomanip>
-#include <boost/regex.hpp>
+#include <boost/lexical_cast.hpp>
template<> CRobotMain* CSingleton<CRobotMain>::m_instance = nullptr;
@@ -1208,18 +1209,27 @@ void CRobotMain::ChangePhase(Phase phase)
bool loading = (m_dialog->GetSceneRead()[0] != 0);
m_map->CreateMap();
- CreateScene(m_dialog->GetSceneSoluce(), false, false); // interactive scene
- if (m_mapImage)
- m_map->SetFixImage(m_mapFilename);
+
+ try {
+ CreateScene(m_dialog->GetSceneSoluce(), false, false); // interactive scene
+ if (m_mapImage)
+ m_map->SetFixImage(m_mapFilename);
- m_app->ResetTimeAfterLoading();
+ m_app->ResetTimeAfterLoading();
- if (m_immediatSatCom && !loading &&
- m_infoFilename[SATCOM_HUSTON][0] != 0)
- StartDisplayInfo(SATCOM_HUSTON, false); // shows the instructions
+ if (m_immediatSatCom && !loading &&
+ m_infoFilename[SATCOM_HUSTON][0] != 0)
+ StartDisplayInfo(SATCOM_HUSTON, false); // shows the instructions
- m_sound->StopMusic(0.0f);
- if (!m_base || loading) StartMusic();
+ m_sound->StopMusic(0.0f);
+ if (!m_base || loading) StartMusic();
+ }
+ catch(const CLevelParserException& e)
+ {
+ CLogger::GetInstancePointer()->Error("An error occured while trying to load a level\n");
+ CLogger::GetInstancePointer()->Error("%s\n", e.what());
+ ChangePhase(PHASE_INIT);
+ }
}
if (m_phase == PHASE_WIN)
@@ -1235,29 +1245,37 @@ void CRobotMain::ChangePhase(Phase phase)
m_dialog->SetSceneName("win");
m_dialog->SetSceneRank(m_endingWinRank);
- CreateScene(false, true, false); // sets scene
+ try {
+ CreateScene(false, true, false); // sets scene
- pos.x = ox+sx*1; pos.y = oy+sy*1;
- Math::Point ddim;
- ddim.x = dim.x*2; ddim.y = dim.y*2;
- m_interface->CreateButton(pos, ddim, 16, EVENT_BUTTON_OK);
+ pos.x = ox+sx*1; pos.y = oy+sy*1;
+ Math::Point ddim;
+ ddim.x = dim.x*2; ddim.y = dim.y*2;
+ m_interface->CreateButton(pos, ddim, 16, EVENT_BUTTON_OK);
- if (m_winTerminate)
- {
- pos.x = ox+sx*3; pos.y = oy+sy*0.2f;
- ddim.x = dim.x*15; ddim.y = dim.y*3.0f;
- pe = m_interface->CreateEdit(pos, ddim, 0, EVENT_EDIT0);
- pe->SetGenericMode(true);
- pe->SetFontType(Gfx::FONT_COLOBOT);
- pe->SetEditCap(false);
- pe->SetHighlightCap(false);
- pe->ReadText(std::string("help/") + m_app->GetLanguageChar() + std::string("/win.txt"));
+ if (m_winTerminate)
+ {
+ pos.x = ox+sx*3; pos.y = oy+sy*0.2f;
+ ddim.x = dim.x*15; ddim.y = dim.y*3.0f;
+ pe = m_interface->CreateEdit(pos, ddim, 0, EVENT_EDIT0);
+ pe->SetGenericMode(true);
+ pe->SetFontType(Gfx::FONT_COLOBOT);
+ pe->SetEditCap(false);
+ pe->SetHighlightCap(false);
+ pe->ReadText(std::string("help/") + m_app->GetLanguageChar() + std::string("/win.txt"));
+ }
+ else
+ {
+ m_displayText->DisplayError(INFO_WIN, Math::Vector(0.0f,0.0f,0.0f), 15.0f, 60.0f, 1000.0f);
+ }
+ StartMusic();
}
- else
+ catch(const CLevelParserException& e)
{
- m_displayText->DisplayError(INFO_WIN, Math::Vector(0.0f,0.0f,0.0f), 15.0f, 60.0f, 1000.0f);
+ CLogger::GetInstancePointer()->Error("An error occured while trying to load win scene\n");
+ CLogger::GetInstancePointer()->Error("%s\n", e.what());
+ ChangePhase(PHASE_TERM);
}
- StartMusic();
}
}
@@ -1273,15 +1291,23 @@ void CRobotMain::ChangePhase(Phase phase)
m_winTerminate = false;
m_dialog->SetSceneName("lost");
m_dialog->SetSceneRank(m_endingLostRank);
- CreateScene(false, true, false); // sets scene
+ try {
+ CreateScene(false, true, false); // sets scene
- pos.x = ox+sx*1; pos.y = oy+sy*1;
- Math::Point ddim;
- ddim.x = dim.x*2; ddim.y = dim.y*2;
- m_interface->CreateButton(pos, ddim, 16, EVENT_BUTTON_OK);
- m_displayText->DisplayError(INFO_LOST, Math::Vector(0.0f,0.0f,0.0f), 15.0f, 60.0f, 1000.0f);
+ pos.x = ox+sx*1; pos.y = oy+sy*1;
+ Math::Point ddim;
+ ddim.x = dim.x*2; ddim.y = dim.y*2;
+ m_interface->CreateButton(pos, ddim, 16, EVENT_BUTTON_OK);
+ m_displayText->DisplayError(INFO_LOST, Math::Vector(0.0f,0.0f,0.0f), 15.0f, 60.0f, 1000.0f);
- StartMusic();
+ StartMusic();
+ }
+ catch(const CLevelParserException& e)
+ {
+ CLogger::GetInstancePointer()->Error("An error occured while trying to load lost scene\n");
+ CLogger::GetInstancePointer()->Error("%s\n", e.what());
+ ChangePhase(PHASE_TERM);
+ }
}
}
@@ -3819,7 +3845,14 @@ void CRobotMain::ScenePerso()
m_dialog->SetSceneName("perso");
m_dialog->SetSceneRank(0);
- CreateScene(false, true, false); // sets scene
+ try {
+ CreateScene(false, true, false); // sets scene
+ }
+ catch(const CLevelParserException& e)
+ {
+ CLogger::GetInstancePointer()->Error("An error occured while trying to load apperance scene\n");
+ CLogger::GetInstancePointer()->Error("%s\n", e.what());
+ }
m_engine->SetDrawWorld(false); // does not draw anything on the interface
m_engine->SetDrawFront(true); // draws on the human interface
@@ -3924,27 +3957,9 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_missionResult = ERR_MISSION_NOTERM;
}
-
- char line[500];
- char name[200];
- char dir[100];
- char op[100];
- char filename[500];
- int lineNum = 0;
-
- memset(line, 0, 500);
- memset(name, 0, 200);
- memset(dir, 0, 100);
- memset(op, 0, 100);
- memset(filename, 0, 500);
- std::string tempLine;
- m_dialog->BuildSceneName(tempLine, base, rank);
- strcpy(filename, tempLine.c_str());
-
- CInputStream stream;
- stream.open(filename);
- if (!stream.is_open()) return;
+ CLevelParser* level = new CLevelParser(base, rank/100, rank%100);
+ level->Load();
int rankObj = 0;
int rankGadget = 0;
@@ -3957,584 +3972,445 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
* may speed up loading
*/
- while (stream.getline(line, 500))
+ for(auto& line : level->GetLines())
{
- lineNum++;
- for (int i = 0; i < 500; i++)
+ if (line->GetCommand() == "MissionFile" && !resetObject)
{
- if (line[i] == '\t' ) line[i] = ' '; // replace tab by space
- if (line[i] == '/' && line[i+1] == '/')
- {
- line[i] = 0;
- break;
- }
- }
-
- if (Cmd(line, "MissionFile") && !resetObject) {
- m_version = OpInt(line, "version", 1);
- continue;
+ m_version = line->GetParam("version")->AsInt(1);
+ continue;
}
-
- // TODO: Fallback to an non-localized entry
- sprintf(op, "Title.%c", m_app->GetLanguageChar());
- if (Cmd(line, op) && !resetObject)
+
+ if(line->GetCommand() == "Title" && !resetObject)
{
- OpString(line, "text", m_title);
+ strcpy(m_title, line->GetParam("text")->AsString().c_str());
continue;
}
-
- sprintf(op, "Resume.%c", m_app->GetLanguageChar());
- if (Cmd(line, op) && !resetObject)
+
+ if(line->GetCommand() == "Resume" && !resetObject)
{
- OpString(line, "text", m_resume);
+ strcpy(m_resume, line->GetParam("text")->AsString().c_str());
continue;
}
-
- sprintf(op, "ScriptName.%c", m_app->GetLanguageChar());
- if (Cmd(line, op) && !resetObject)
+
+ if(line->GetCommand() == "ScriptName" && !resetObject)
{
- OpString(line, "text", m_scriptName);
+ strcpy(m_scriptName, line->GetParam("text")->AsString().c_str());
continue;
}
-
- static const boost::regex titleCmdRe("Title\\.[A-Z]");
- static const boost::regex resumeCmdRe("Resume\\.[A-Z]");
- static const boost::regex scriptNameCmdRe("ScriptName\\.[A-Z]");
-
- if (boost::regex_match(GetCmd(line), titleCmdRe)) continue; // Ignore
- if (boost::regex_match(GetCmd(line), resumeCmdRe)) continue; // Ignore
- if (boost::regex_match(GetCmd(line), scriptNameCmdRe)) continue; // Ignore
-
-
- if (Cmd(line, "ScriptFile") && !resetObject)
+
+ if (line->GetCommand() == "ScriptFile" && !resetObject)
{
- OpString(line, "name", m_scriptFile);
+ strcpy(m_scriptFile, line->GetParam("name")->AsString().c_str());
continue;
}
-
- if (Cmd(line, "Instructions") && !resetObject)
+
+ if (line->GetCommand() == "Instructions" && !resetObject)
{
- OpString(line, "name", name);
- std::string path = name;
- InjectLevelDir(path, "help/%lng%");
- strcpy(m_infoFilename[SATCOM_HUSTON], path.c_str());
-
- m_immediatSatCom = OpInt(line, "immediat", 0);
- if (m_version >= 2) m_beginSatCom = m_lockedSatCom = OpInt(line, "lock", 0);
+ strcpy(m_infoFilename[SATCOM_HUSTON], line->GetParam("name")->AsPath("help/%lng%").c_str());
+
+ m_immediatSatCom = line->GetParam("immediat")->AsBool(false);
+ if (m_version >= 2) m_beginSatCom = m_lockedSatCom = line->GetParam("lock")->AsBool(false);
if (m_app->GetSceneTestMode()) m_immediatSatCom = false;
continue;
}
-
- if (Cmd(line, "Satellite") && !resetObject)
+
+ if (line->GetCommand() == "Satellite" && !resetObject)
{
- OpString(line, "name", name);
- std::string path = name;
- InjectLevelDir(path, "help/%lng%");
- strcpy(m_infoFilename[SATCOM_SAT], path.c_str());
+ strcpy(m_infoFilename[SATCOM_SAT], line->GetParam("name")->AsPath("help/%lng%").c_str());
continue;
}
-
- if (Cmd(line, "Loading") && !resetObject)
+
+ if (line->GetCommand() == "Loading" && !resetObject)
{
- OpString(line, "name", name);
- std::string path = name;
- InjectLevelDir(path, "help/%lng%");
- strcpy(m_infoFilename[SATCOM_LOADING], path.c_str());
+ strcpy(m_infoFilename[SATCOM_LOADING], line->GetParam("name")->AsPath("help/%lng%").c_str());
continue;
}
-
- if (Cmd(line, "HelpFile") && !resetObject)
+
+ if (line->GetCommand() == "HelpFile" && !resetObject)
{
- OpString(line, "name", name);
- std::string path = name;
- InjectLevelDir(path, "help/%lng%");
- strcpy(m_infoFilename[SATCOM_PROG], path.c_str());
+ strcpy(m_infoFilename[SATCOM_PROG], line->GetParam("name")->AsPath("help/%lng%").c_str());
continue;
}
- if (Cmd(line, "SoluceFile") && !resetObject)
+ if (line->GetCommand() == "SoluceFile" && !resetObject)
{
- OpString(line, "name", name);
- std::string path = name;
- InjectLevelDir(path, "help/%lng%");
- strcpy(m_infoFilename[SATCOM_SOLUCE], path.c_str());
+ strcpy(m_infoFilename[SATCOM_SOLUCE], line->GetParam("name")->AsPath("help/%lng%").c_str());
continue;
}
-
- if (Cmd(line, "EndingFile") && !resetObject)
+
+ if (line->GetCommand() == "EndingFile" && !resetObject)
{
- m_endingWinRank = OpInt(line, "win", 0);
- m_endingLostRank = OpInt(line, "lost", 0);
+ // NOTE: The old default was 0, but I think -1 is more correct - 0 means "ending file 000", while -1 means "no ending file"
+ m_endingWinRank = line->GetParam("win")->AsInt(-1);
+ m_endingLostRank = line->GetParam("lost")->AsInt(-1);
continue;
}
-
- if (Cmd(line, "MessageDelay") && !resetObject)
+
+ if (line->GetCommand() == "MessageDelay" && !resetObject)
{
- m_displayText->SetDelay(OpFloat(line, "factor", 1.0f));
+ m_displayText->SetDelay(line->GetParam("factor")->AsFloat());
continue;
}
-
- if (Cmd(line, "CacheAudio") && !resetObject && m_version >= 2)
+
+ if (line->GetCommand() == "CacheAudio" && !resetObject && m_version >= 2)
{
- OpString(line, "filename", name);
- m_sound->CacheMusic(name);
+ m_sound->CacheMusic(line->GetParam("filename")->AsPath("").c_str()); //TODO: don't make this relative to music/
continue;
}
-
- if (Cmd(line, "AudioChange") && !resetObject && m_version >= 2 && m_controller == nullptr)
+
+ if (line->GetCommand() == "AudioChange" && !resetObject && m_version >= 2 && m_controller == nullptr)
{
int i = m_audioChangeTotal;
if (i < 10)
{
- m_audioChange[i].pos = OpPos(line, "pos")*g_unit;
- m_audioChange[i].dist = OpFloat(line, "dist", 1000.0f)*g_unit;
- m_audioChange[i].type = OpTypeObject(line, "type", OBJECT_NULL);
- m_audioChange[i].min = OpInt(line, "min", 1);
- m_audioChange[i].max = OpInt(line, "max", 9999);
- m_audioChange[i].powermin = OpFloat(line, "powermin", -1);
- m_audioChange[i].powermax = OpFloat(line, "powermax", 100);
- m_audioChange[i].tool = OpTool(line, "tool");
- m_audioChange[i].drive = OpDrive(line, "drive");
- OpString(line, "filename", m_audioChange[i].music);
- m_audioChange[i].repeat = OpInt(line, "repeat", 1);
+ m_audioChange[i].pos = line->GetParam("pos")->AsPoint(Math::Vector(0.0f, 0.0f, 0.0f))*g_unit;
+ m_audioChange[i].dist = line->GetParam("dist")->AsFloat(1000.0f)*g_unit;
+ m_audioChange[i].type = line->GetParam("type")->AsObjectType(OBJECT_NULL);
+ m_audioChange[i].min = line->GetParam("min")->AsInt(1);
+ m_audioChange[i].max = line->GetParam("max")->AsInt(9999);
+ m_audioChange[i].powermin = line->GetParam("powermin")->AsFloat(-1);
+ m_audioChange[i].powermax = line->GetParam("powermax")->AsFloat(100);
+ m_audioChange[i].tool = line->GetParam("tool")->AsToolType(TOOL_OTHER);
+ m_audioChange[i].drive = line->GetParam("drive")->AsDriveType(DRIVE_OTHER);
+ strcpy(m_audioChange[i].music, line->GetParam("filename")->AsPath("").c_str()); //TODO: don't make this relative to music/
+ m_audioChange[i].repeat = line->GetParam("repeat")->AsBool(true);
m_audioChange[i].changed = false;
m_sound->CacheMusic(m_audioChange[i].music);
m_audioChangeTotal ++;
}
continue;
}
-
- if (Cmd(line, "Audio") && !resetObject && m_controller == nullptr)
+
+ if (line->GetCommand() == "Audio" && !resetObject && m_controller == nullptr)
{
if (m_version < 2)
{
- int trackid = OpInt(line, "track", 0);
+ int trackid = line->GetParam("track")->AsInt();
if (trackid != 0)
{
std::stringstream filenameStr;
filenameStr << "music" << std::setfill('0') << std::setw(3) << trackid << ".ogg";
m_audioTrack = filenameStr.str();
}
- m_audioRepeat = OpInt(line, "repeat", 1);
+ m_audioRepeat = line->GetParam("repeat")->AsBool(true);
}
else
{
- char trackname[100];
+ m_audioTrack = line->GetParam("main")->AsPath("", ""); //TODO: don't make this relative to music/
+ m_audioRepeat = line->GetParam("mainRepeat")->AsBool(true);
- OpString(line, "main", trackname);
- m_audioTrack = trackname;
- m_audioRepeat = OpInt(line, "mainRepeat", 1);
+ m_satcomTrack = line->GetParam("satcom")->AsPath("", ""); //TODO: don't make this relative to music/
+ m_satcomRepeat = line->GetParam("satcomRepeat")->AsBool(true);
- OpString(line, "satcom", trackname);
- m_satcomTrack = trackname;
- m_satcomRepeat = OpInt(line, "satcomRepeat", 1);
-
- OpString(line, "editor", trackname);
- m_editorTrack = trackname;
- m_editorRepeat = OpInt(line, "editorRepeat", 1);
+ m_editorTrack = line->GetParam("editor")->AsPath("", ""); //TODO: don't make this relative to music/
+ m_editorRepeat = line->GetParam("editorRepeat")->AsBool(true);
}
if (m_audioTrack != "") m_sound->CacheMusic(m_audioTrack);
if (m_satcomTrack != "") m_sound->CacheMusic(m_satcomTrack);
if (m_editorTrack != "") m_sound->CacheMusic(m_editorTrack);
continue;
}
-
- if (Cmd(line, "AmbientColor") && !resetObject)
+
+ if (line->GetCommand() == "AmbientColor" && !resetObject)
{
- m_engine->SetAmbientColor(OpColor(line, "air", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)), 0);
- m_engine->SetAmbientColor(OpColor(line, "water", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)), 1);
+ m_engine->SetAmbientColor(line->GetParam("air")->AsColor(Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)), 0);
+ m_engine->SetAmbientColor(line->GetParam("water")->AsColor(Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)), 1);
continue;
}
-
- if (Cmd(line, "FogColor") && !resetObject)
+
+ if (line->GetCommand() == "FogColor" && !resetObject)
{
- m_engine->SetFogColor(OpColor(line, "air", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)), 0);
- m_engine->SetFogColor(OpColor(line, "water", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)), 1);
+ m_engine->SetFogColor(line->GetParam("air")->AsColor(Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)), 0);
+ m_engine->SetFogColor(line->GetParam("water")->AsColor(Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)), 1);
continue;
}
-
- if (Cmd(line, "VehicleColor") && !resetObject)
+
+ if (line->GetCommand() == "VehicleColor" && !resetObject)
{
- m_colorNewBot = OpColor(line, "color", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f));
+ m_colorNewBot = line->GetParam("color")->AsColor(Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f));
continue;
}
-
- if (Cmd(line, "InsectColor") && !resetObject)
+
+ if (line->GetCommand() == "InsectColor" && !resetObject)
{
- m_colorNewAlien = OpColor(line, "color", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f));
+ m_colorNewAlien = line->GetParam("color")->AsColor(Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f));
continue;
}
-
- if (Cmd(line, "GreeneryColor") && !resetObject)
+
+ if (line->GetCommand() == "GreeneryColor" && !resetObject)
{
- m_colorNewGreen = OpColor(line, "color", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f));
+ m_colorNewGreen = line->GetParam("color")->AsColor(Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f));
continue;
}
-
- if (Cmd(line, "DeepView") && !resetObject)
+
+ if (line->GetCommand() == "DeepView" && !resetObject)
{
- m_engine->SetDeepView(OpFloat(line, "air", 500.0f)*g_unit, 0, true);
- m_engine->SetDeepView(OpFloat(line, "water", 100.0f)*g_unit, 1, true);
+ m_engine->SetDeepView(line->GetParam("air")->AsFloat(500.0f)*g_unit, 0, true);
+ m_engine->SetDeepView(line->GetParam("water")->AsFloat(100.0f)*g_unit, 1, true);
continue;
}
-
- if (Cmd(line, "FogStart") && !resetObject)
+
+ if (line->GetCommand() == "FogStart" && !resetObject)
{
- m_engine->SetFogStart(OpFloat(line, "air", 0.5f), 0);
- m_engine->SetFogStart(OpFloat(line, "water", 0.5f), 1);
+ m_engine->SetFogStart(line->GetParam("air")->AsFloat(0.5f), 0);
+ m_engine->SetFogStart(line->GetParam("water")->AsFloat(0.5f), 1);
continue;
}
-
- if (Cmd(line, "SecondTexture") && !resetObject)
+
+ if (line->GetCommand() == "SecondTexture" && !resetObject)
{
- m_engine->SetSecondTexture(OpInt(line, "rank", 1));
+ m_engine->SetSecondTexture(line->GetParam("rank")->AsInt());
continue;
}
-
- if (Cmd(line, "Background") && !resetObject)
- {
- OpString(line, "image", name);
- m_engine->SetBackground(name,
- OpColor(line, "up", Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)),
- OpColor(line, "down", Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)),
- OpColor(line, "cloudUp", Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)),
- OpColor(line, "cloudDown", Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)),
- OpInt(line, "full", 0));
+
+ if (line->GetCommand() == "Background" && !resetObject)
+ {
+ m_engine->SetBackground(line->GetParam("image")->AsPath("", "").c_str(), //TODO: don't make this relative to textures/
+ line->GetParam("up")->AsColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)),
+ line->GetParam("down")->AsColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)),
+ line->GetParam("cloudUp")->AsColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)),
+ line->GetParam("cloudDown")->AsColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)),
+ line->GetParam("full")->AsBool(false));
continue;
}
-
- if (Cmd(line, "Planet") && !resetObject)
+
+ if (line->GetCommand() == "Planet" && !resetObject)
{
Math::Vector ppos, uv1, uv2;
-
- ppos = OpPos(line, "pos");
- uv1 = OpPos(line, "uv1");
- uv2 = OpPos(line, "uv2");
- OpString(line, "image", name);
- m_planet->Create(OpInt(line, "mode", 0),
+
+ ppos = line->GetParam("pos")->AsPoint();
+ uv1 = line->GetParam("uv1")->AsPoint();
+ uv2 = line->GetParam("uv2")->AsPoint();
+ m_planet->Create(line->GetParam("mode")->AsInt(0),
Math::Point(ppos.x, ppos.z),
- OpFloat(line, "dim", 0.2f),
- OpFloat(line, "speed", 0.0f),
- OpFloat(line, "dir", 0.0f),
- name,
+ line->GetParam("dim")->AsFloat(0.2f),
+ line->GetParam("speed")->AsFloat(0.0f),
+ line->GetParam("dir")->AsFloat(0.0f),
+ line->GetParam("image")->AsPath(""), //TODO: don't make this relative to textures/
Math::Point(uv1.x, uv1.z),
Math::Point(uv2.x, uv2.z),
- strstr(name, "planet") != nullptr // TODO: add transparent op or modify textures
- );
+ line->GetParam("image")->AsPath("").find("planet") != std::string::npos // TODO: add transparent op or modify textures
+ );
continue;
}
-
- if (Cmd(line, "ForegroundName") && !resetObject)
+
+ if (line->GetCommand() == "ForegroundName" && !resetObject)
{
- OpString(line, "image", name);
- m_engine->SetForegroundName(name);
+ m_engine->SetForegroundName(line->GetParam("image")->AsPath("")); //TODO: don't make this relative to textures/
continue;
}
-
- if (((m_version == 1 && Cmd(line, "Global")) || (m_version >= 2 && Cmd(line, "Mission"))) && !resetObject)
+
+ if (((line->GetCommand() == "Global") || (m_version >= 2 && line->GetCommand() == "Mission")) && !resetObject)
{
- g_unit = OpFloat(line, "unitScale", 4.0f);
- m_engine->SetTracePrecision(OpFloat(line, "traceQuality", 1.0f));
- m_shortCut = OpInt(line, "shortcut", 1);
+ g_unit = line->GetParam("unitScale")->AsFloat(4.0f);
+ m_engine->SetTracePrecision(line->GetParam("traceQuality")->AsFloat(1.0f));
+ m_shortCut = line->GetParam("shortcut")->AsBool(true);
if (m_version >= 2)
{
- m_retroStyle = OpInt(line, "retro", 0);
+ m_retroStyle = line->GetParam("retro")->AsBool(false);
if (m_retroStyle) GetLogger()->Info("Retro mode enabled.\n");
}
continue;
}
-
- if (Cmd(line, "TerrainGenerate") && !resetObject)
- {
- if (m_terrainCreate)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainGenerate after TerrainCreate\n", filename, lineNum);
- continue;
- }
-
- if (m_terrainInit)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainGenerate after TerrainInit\n", filename, lineNum);
- continue;
- }
-
- m_terrain->Generate(OpInt(line, "mosaic", 20),
- OpInt(line, "brick", 3),
- OpFloat(line, "size", 20.0f),
- OpFloat(line, "vision", 500.0f)*g_unit,
- OpInt(line, "depth", 2),
- OpFloat(line, "hard", 0.5f));
-
- m_terrainGenerate = true;
+
+ if (line->GetCommand() == "TerrainGenerate" && !resetObject)
+ {
+ m_terrain->Generate(line->GetParam("mosaic")->AsInt(20),
+ line->GetParam("brick")->AsInt(3),
+ line->GetParam("size")->AsFloat(20.0f),
+ line->GetParam("vision")->AsFloat(500.0f)*g_unit,
+ line->GetParam("depth")->AsInt(2),
+ line->GetParam("hard")->AsFloat(0.5f));
continue;
}
-
- if (Cmd(line, "TerrainWind") && !resetObject)
+
+ if (line->GetCommand() == "TerrainWind" && !resetObject)
{
- if (m_terrainCreate)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainWind after TerrainCreate\n", filename, lineNum);
- continue;
- }
-
- if (m_terrainInit)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainWind after TerrainInit\n", filename, lineNum);
- continue;
- }
-
- if (!m_terrainGenerate)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainWind before TerrainGenerate\n", filename, lineNum);
- continue;
- }
-
- m_terrain->SetWind(OpPos(line, "speed"));
+ m_terrain->SetWind(line->GetParam("speed")->AsPoint());
continue;
}
-
- if (Cmd(line, "TerrainRelief") && !resetObject)
+
+ if (line->GetCommand() == "TerrainRelief" && !resetObject)
{
- if (m_terrainCreate)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainRelief after TerrainCreate\n", filename, lineNum);
- continue;
- }
-
- if (m_terrainInit)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainRelief after TerrainInit\n", filename, lineNum);
- continue;
- }
-
- if (!m_terrainGenerate)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainRelief before TerrainGenerate\n", filename, lineNum);
- continue;
- }
-
- OpString(line, "image", name);
- m_terrain->LoadRelief(std::string("textures/")+name, OpFloat(line, "factor", 1.0f), OpInt(line, "border", 1));
+ m_terrain->LoadRelief(
+ line->GetParam("image")->AsPath("textures"),
+ line->GetParam("factor")->AsFloat(1.0f),
+ line->GetParam("border")->AsBool(true));
continue;
}
- if (Cmd(line, "TerrainRandomRelief") && !resetObject)
+ if (line->GetCommand() == "TerrainRandomRelief" && !resetObject)
{
m_terrain->RandomizeRelief();
continue;
}
-
- if (Cmd(line, "TerrainResource") && !resetObject)
+
+ if (line->GetCommand() == "TerrainResource" && !resetObject)
{
- if (m_terrainCreate)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainResource after TerrainCreate\n", filename, lineNum);
- continue;
- }
-
- if (m_terrainInit)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainResource after TerrainInit\n", filename, lineNum);
- continue;
- }
-
- if (!m_terrainGenerate)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainResource before TerrainGenerate\n", filename, lineNum);
- continue;
- }
-
- OpString(line, "image", name);
- m_terrain->LoadResources(std::string("textures/")+name);
+ m_terrain->LoadResources(line->GetParam("image")->AsPath("textures"));
continue;
}
-
- if (Cmd(line, "TerrainWater") && !resetObject)
+
+ if (line->GetCommand() == "TerrainWater" && !resetObject)
{
- OpString(line, "image", name);
Math::Vector pos;
- pos.x = OpFloat(line, "moveX", 0.0f);
- pos.y = OpFloat(line, "moveY", 0.0f);
+ pos.x = line->GetParam("moxeX")->AsFloat(0.0f);
+ pos.y = line->GetParam("moxeY")->AsFloat(0.0f);
pos.z = pos.x;
- m_water->Create(OpTypeWater(line, "air", Gfx::WATER_TT),
- OpTypeWater(line, "water", Gfx::WATER_TT),
- name,
- OpColor(line, "diffuse", Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
- OpColor(line, "ambient", Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
- OpFloat(line, "level", 100.0f)*g_unit,
- OpFloat(line, "glint", 1.0f),
+ m_water->Create(line->GetParam("air")->AsWaterType(Gfx::WATER_TT),
+ line->GetParam("water")->AsWaterType(Gfx::WATER_TT),
+ line->GetParam("image")->AsPath(""), //TODO: don't make this relative to textures/
+ line->GetParam("diffuse")->AsColor(Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
+ line->GetParam("ambient")->AsColor(Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
+ line->GetParam("level")->AsFloat(100.0f)*g_unit,
+ line->GetParam("glint")->AsFloat(1.0f),
pos);
- m_colorNewWater = OpColor(line, "color", m_colorRefWater);
- m_colorShiftWater = OpFloat(line, "brightness", 0.0f);
+ m_colorNewWater = line->GetParam("color")->AsColor(m_colorRefWater);
+ m_colorShiftWater = line->GetParam("brightness")->AsFloat(0.0f);
continue;
}
-
- if (Cmd(line, "TerrainLava") && !resetObject)
+
+ if (line->GetCommand() == "TerrainLava" && !resetObject)
{
- m_water->SetLava(OpInt(line, "mode", 0));
+ m_water->SetLava(line->GetParam("mode")->AsBool());
continue;
}
-
- if (Cmd(line, "TerrainCloud") && !resetObject)
+
+ if (line->GetCommand() == "TerrainCloud" && !resetObject)
{
- OpString(line, "image", name);
- m_cloud->Create(name,
- OpColor(line, "diffuse", Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
- OpColor(line, "ambient", Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
- OpFloat(line, "level", 500.0f) * g_unit);
+ m_cloud->Create(line->GetParam("image")->AsPath("", ""), //TODO: don't make this relative to textures/
+ line->GetParam("diffuse")->AsColor(Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
+ line->GetParam("ambient")->AsColor(Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
+ line->GetParam("level")->AsFloat(500.0f)*g_unit);
continue;
}
-
- if (Cmd(line, "TerrainBlitz") && !resetObject)
+
+ if (line->GetCommand() == "TerrainBlitz" && !resetObject)
{
- m_lightning->Create(OpFloat(line, "sleep", 0.0f),
- OpFloat(line, "delay", 3.0f),
- OpFloat(line, "magnetic", 50.0f) * g_unit);
+ m_lightning->Create(line->GetParam("sleep")->AsFloat(0.0f),
+ line->GetParam("delay")->AsFloat(3.0f),
+ line->GetParam("magnetic")->AsFloat(50.0f)*g_unit);
continue;
}
-
- if (Cmd(line, "TerrainInitTextures") && !resetObject)
+
+ if (line->GetCommand() == "TerrainInitTextures" && !resetObject)
{
- if (m_terrainInit)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainInitTextures and TerrainInit at same time\n", filename, lineNum);
- continue;
+ std::string name = line->GetParam("image")->AsPath(""); //TODO: don't make this relative to textures/
+ if(name.find(".") == std::string::npos)
+ name += ".png";
+ int dx = line->GetParam("dx")->AsInt(1);
+ int dy = line->GetParam("dy")->AsInt(1);
+
+ int tt[100]; //TODO: I have no idea how TerrainInitTextures works, but maybe we shuld remove the limit to 100?
+ if(dx*dy > 100)
+ throw CLevelParserException("In TerrainInitTextures: dx*dy must be <100");
+ if(line->GetParam("table")->IsDefined()) {
+ const std::vector<CLevelParserParam*>& table = line->GetParam("table")->AsArray();
+
+ if(table.size() > dx*dy)
+ throw CLevelParserException("In TerrainInitTextures: table size must be dx*dy");
+
+ for (int i = 0; i < dx*dy; i++)
+ {
+ if(i >= table.size())
+ {
+ tt[i] = 0;
+ } else {
+ tt[i] = table[i]->AsInt();
+ }
+ }
+ } else {
+ for (int i = 0; i < dx*dy; i++)
+ {
+ tt[i] = 0;
+ }
}
-
- OpString(line, "image", name);
- AddExt(name, ".png");
- int dx = OpInt(line, "dx", 1);
- int dy = OpInt(line, "dy", 1);
- char* opTable = SearchOp(line, "table");
- int tt[100];
- for (int i = 0; i < dx*dy; i++)
- tt[i] = GetInt(opTable, i, 0);
-
+
+ /*TODO: ???
if (strstr(name, "%user%") != 0)
CopyFileListToTemp(name, tt, dx*dy);
-
- m_terrain->InitTextures(name, tt, dx, dy);
-
- m_terrainInitTextures = true;
+ */
+
+ m_terrain->InitTextures(name.c_str(), tt, dx, dy);
continue;
}
-
- if (Cmd(line, "TerrainInit") && !resetObject)
+
+ if (line->GetCommand() == "TerrainInit" && !resetObject)
{
- if (m_terrainInitTextures)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainInit and TerrainInitTextures at same time\n", filename, lineNum);
- continue;
- }
-
- m_terrain->InitMaterials(OpInt(line, "id", 1));
+ m_terrain->InitMaterials(line->GetParam("id")->AsInt(1));
m_terrainInit = true;
continue;
}
-
- if (Cmd(line, "TerrainMaterial") && !resetObject)
+
+ if (line->GetCommand() == "TerrainMaterial" && !resetObject)
{
- if (m_terrainCreate)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainMaterial after TerrainCreate\n", filename, lineNum);
- continue;
- }
-
- if (m_terrainInit)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainMaterial after TerrainInit\n", filename, lineNum);
- continue;
- }
-
- if (m_terrainInitTextures)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainMaterial and TerrainInitTextures at same time\n", filename, lineNum);
- continue;
- }
-
- OpString(line, "image", name);
- AddExt(name, ".png");
+ std::string name = line->GetParam("image")->AsPath(""); //TODO: don't make this relative to textures/
+ if(name.find(".") == std::string::npos)
+ name += ".png";
+ /*TODO: ???
if (strstr(name, "%user%") != 0)
{
GetProfile().CopyFileToTemp(std::string(name));
}
-
- m_terrain->AddMaterial(OpInt(line, "id", 0),
- name,
- Math::Point(OpFloat(line, "u", 0.0f),
- OpFloat(line, "v", 0.0f)),
- OpInt(line, "up", 1),
- OpInt(line, "right", 1),
- OpInt(line, "down", 1),
- OpInt(line, "left", 1),
- OpFloat(line, "hard", 0.5f));
+ */
+
+ m_terrain->AddMaterial(line->GetParam("id")->AsInt(0),
+ name.c_str(),
+ Math::Point(line->GetParam("u")->AsFloat(),
+ line->GetParam("v")->AsFloat()),
+ line->GetParam("up")->AsInt(),
+ line->GetParam("right")->AsInt(),
+ line->GetParam("down")->AsInt(),
+ line->GetParam("left")->AsInt(),
+ line->GetParam("hard")->AsFloat(0.5f));
continue;
}
-
- if (Cmd(line, "TerrainLevel") && !resetObject)
+
+ if (line->GetCommand() == "TerrainLevel" && !resetObject)
{
- if (m_terrainCreate)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainLevel after TerrainCreate\n", filename, lineNum);
- continue;
- }
-
- if (!m_terrainInit)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainLevel before TerrainInit\n", filename, lineNum);
- continue;
- }
-
- if (m_terrainInitTextures)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainLevel and TerrainInitTextures at same time\n", filename, lineNum);
- continue;
- }
-
- if (!m_terrainGenerate)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainLevel before TerrainGenerate\n", filename, lineNum);
- continue;
- }
-
- char* opId = SearchOp(line, "id");
- int id[50];
- int i = 0;
- while (i < 50)
- {
- id[i] = GetInt(opId, i, 0);
- if (id[i++] == 0) break;
+ int id[50]; //TODO: I have no idea how TerrainLevel works, but maybe we should remove the limit to 50?
+ if(line->GetParam("id")->IsDefined()) {
+ const std::vector<CLevelParserParam*>& id_array = line->GetParam("id")->AsArray();
+
+ if(id_array.size() > 50)
+ throw CLevelParserException("In TerrainLevel: id array size must be < 50");
+
+ int i = 0;
+ while (i < 50)
+ {
+ id[i] = id_array[i]->AsInt();
+ i++;
+ if(i >= id_array.size()) break;
+ }
}
-
+
m_terrain->GenerateMaterials(id,
- OpFloat(line, "min", 0.0f)*g_unit,
- OpFloat(line, "max", 100.0f)*g_unit,
- OpFloat(line, "slope", 5.0f),
- OpFloat(line, "freq", 100.0f),
- OpPos(line, "center")*g_unit,
- OpFloat(line, "radius", 0.0f)*g_unit);
+ line->GetParam("min")->AsFloat(0.0f)*g_unit,
+ line->GetParam("max")->AsFloat(100.0f)*g_unit,
+ line->GetParam("slope")->AsFloat(5.0f),
+ line->GetParam("freq")->AsFloat(100.0f),
+ line->GetParam("center")->AsPoint(Math::Vector(0.0f, 0.0f, 0.0f))*g_unit,
+ line->GetParam("radius")->AsFloat(0.0f)*g_unit);
continue;
}
-
- if (Cmd(line, "TerrainCreate") && !resetObject)
+
+ if (line->GetCommand() == "TerrainCreate" && !resetObject)
{
m_terrain->CreateObjects();
- m_terrainCreate = true;
continue;
}
-
- if (Cmd(line, "BeginObject"))
+
+ if (line->GetCommand() == "BeginObject")
{
InitEye();
SetMovieLock(false);
-
+
if (read[0] != 0) // loading file ?
sel = IOReadScene(read, stack);
-
- m_beginObject = true;
+
continue;
}
-
- if (Cmd(line, "MissionController") && read[0] == 0 && m_version >= 2)
+
+ if (line->GetCommand() == "MissionController" && read[0] == 0 && m_version >= 2)
{
m_controller = CObjectManager::GetInstancePointer()->CreateObject(Math::Vector(0.0f, 0.0f, 0.0f), 0.0f, OBJECT_CONTROLLER, 100.0f);
m_controller->SetMagnifyDamage(100.0f);
@@ -4542,48 +4418,42 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
CBrain* brain = m_controller->GetBrain();
if (brain != nullptr)
{
- OpString(line, "script", name);
- if (name[0] != 0)
- brain->SetScriptName(0, name);
+ std::string name = line->GetParam("script")->AsPath(""); //TODO: Don't make this relative to ai/
+ if (!name.empty())
+ brain->SetScriptName(0, const_cast<char*>(name.c_str()));
brain->SetScriptRun(0);
}
continue;
}
-
- if (Cmd(line, "CreateObject") && read[0] == 0)
+
+ if (line->GetCommand() == "CreateObject" && read[0] == 0)
{
- if (!m_beginObject)
- {
- GetLogger()->Error("Syntax error in file '%s' (line %d): CreateObject before BeginObject\n", filename, lineNum);
- continue;
- }
-
- ObjectType type = OpTypeObject(line, "type", OBJECT_NULL);
-
- int gadget = OpInt(line, "gadget", -1);
+ ObjectType type = line->GetParam("type")->AsObjectType();
+
+ int gadget = line->GetParam("gadget")->AsInt(-1);
if ( gadget == -1 )
{
gadget = 0;
if ( type == OBJECT_TECH ||
- (type >= OBJECT_PLANT0 &&
- type <= OBJECT_PLANT19 ) ||
- (type >= OBJECT_TREE0 &&
- type <= OBJECT_TREE5 ) ||
- (type >= OBJECT_TEEN0 &&
- type <= OBJECT_TEEN44 ) ||
- (type >= OBJECT_QUARTZ0 &&
- type <= OBJECT_QUARTZ3 ) ||
- (type >= OBJECT_ROOT0 &&
- type <= OBJECT_ROOT4 ) ) // not ROOT5!
+ (type >= OBJECT_PLANT0 &&
+ type <= OBJECT_PLANT19 ) ||
+ (type >= OBJECT_TREE0 &&
+ type <= OBJECT_TREE5 ) ||
+ (type >= OBJECT_TEEN0 &&
+ type <= OBJECT_TEEN44 ) ||
+ (type >= OBJECT_QUARTZ0 &&
+ type <= OBJECT_QUARTZ3 ) ||
+ (type >= OBJECT_ROOT0 &&
+ type <= OBJECT_ROOT4 ) ) // not ROOT5!
{
if ( type != OBJECT_TEEN11 && // lamp?
- type != OBJECT_TEEN12 && // coke?
- type != OBJECT_TEEN20 && // wall?
- type != OBJECT_TEEN21 && // wall?
- type != OBJECT_TEEN22 && // wall?
- type != OBJECT_TEEN26 && // lamp?
- type != OBJECT_TEEN28 && // bottle?
- type != OBJECT_TEEN34 ) // stone?
+ type != OBJECT_TEEN12 && // coke?
+ type != OBJECT_TEEN20 && // wall?
+ type != OBJECT_TEEN21 && // wall?
+ type != OBJECT_TEEN22 && // wall?
+ type != OBJECT_TEEN26 && // lamp?
+ type != OBJECT_TEEN28 && // bottle?
+ type != OBJECT_TEEN34 ) // stone?
{
gadget = 1;
}
@@ -4593,19 +4463,20 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
{
if (!TestGadgetQuantity(rankGadget++)) continue;
}
-
- Math::Vector pos = OpPos(line, "pos")*g_unit;
- float dirAngle = OpFloat(line, "dir", 0.0f)*Math::PI;
+
+ Math::Vector pos = line->GetParam("pos")->AsPoint()*g_unit;
+ float dirAngle = line->GetParam("dir")->AsFloat(0.0f)*Math::PI;
bool trainer;
CObject* obj = CObjectManager::GetInstancePointer()->CreateObject(
- pos, dirAngle,
- type,
- OpFloat(line, "power", 1.0f),
- OpFloat(line, "z", 1.0f),
- OpFloat(line, "h", 0.0f),
- trainer = OpInt(line, "trainer", 0),
- OpInt(line, "toy", 0),
- OpInt(line, "option", 0));
+ pos, dirAngle,
+ type,
+ line->GetParam("power")->AsFloat(1.0f),
+ line->GetParam("z")->AsFloat(1.0f),
+ line->GetParam("h")->AsFloat(0.0f),
+ trainer = line->GetParam("trainer")->AsBool(false),
+ line->GetParam("toy")->AsBool(false),
+ line->GetParam("option")->AsInt(0)
+ );
if (m_fixScene && type == OBJECT_HUMAN)
{
@@ -4613,108 +4484,112 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
if (m_phase == PHASE_WIN ) motion->SetAction(MHS_WIN, 0.4f);
if (m_phase == PHASE_LOST) motion->SetAction(MHS_LOST, 0.5f);
}
-
+
if (obj != nullptr)
{
obj->SetDefRank(rankObj);
-
+
if (type == OBJECT_BASE) m_base = true;
-
- Gfx::CameraType cType = OpCamera(line, "camera");
+
+ Gfx::CameraType cType = line->GetParam("camera")->AsCameraType(Gfx::CAM_TYPE_NULL);
if (cType != Gfx::CAM_TYPE_NULL)
obj->SetCameraType(cType);
-
- obj->SetCameraDist(OpFloat(line, "cameraDist", 50.0f));
- obj->SetCameraLock(OpInt(line, "cameraLock", 0));
-
- Gfx::PyroType pType = OpPyro(line, "pyro");
+
+ obj->SetCameraDist(line->GetParam("cameraDist")->AsFloat(50.0f));
+ obj->SetCameraLock(line->GetParam("cameraLock")->AsBool(false));
+
+ Gfx::PyroType pType = line->GetParam("pyro")->AsPyroType(Gfx::PT_NULL);
if (pType != Gfx::PT_NULL)
{
Gfx::CPyro* pyro = new Gfx::CPyro();
pyro->Create(pType, obj);
}
-
+
// Puts information in terminal (OBJECT_INFO).
for (int i = 0; i < OBJECTMAXINFO; i++)
{
- sprintf(op, "info%d", i+1);
- char text[100];
- OpString(line, op, text);
- if (text[0] == 0) break;
- char* p = strchr(text, '=');
- if (p == 0) break;
- *p = 0;
+ std::string op = "info"+std::to_string(i+1);
+ if(!line->GetParam(op)->IsDefined()) break;
+ std::string text = line->GetParam(op)->AsString();
+ std::size_t p = text.find_first_of("=");
+ if(p == std::string::npos)
+ throw CLevelParserExceptionBadParam(line->GetParam(op), "info");
Info info;
- strcpy(info.name, text);
- sscanf(p+1, "%f", &info.value);
+ strcpy(info.name, text.substr(0, p).c_str());
+ try {
+ info.value = boost::lexical_cast<float>(text.substr(p+1).c_str());
+ }
+ catch(...)
+ {
+ throw CLevelParserExceptionBadParam(line->GetParam(op), "info.value (float)");
+ }
obj->SetInfo(i, info);
}
-
+
// Sets the parameters of the command line.
- char* p = SearchOp(line, "cmdline");
- for (int i = 0; i < OBJECTMAXCMDLINE; i++)
- {
- float value = GetFloat(p, i, NAN);
- if (value == NAN) break;
- obj->SetCmdLine(i, value);
+ if(line->GetParam("cmdline")->IsDefined()) {
+ const std::vector<CLevelParserParam*>& cmdline = line->GetParam("cmdline")->AsArray();
+ for (int i = 0; i < OBJECTMAXCMDLINE && i < cmdline.size(); i++) //TODO: get rid of the limit
+ {
+ obj->SetCmdLine(i, cmdline[i]->AsFloat());
+ }
}
-
- if (OpInt(line, "select", 0) == 1)
+
+ if (line->GetParam("select")->AsBool(false))
{
sel = obj;
}
-
- bool selectable = OpInt(line, "selectable", 1);
+
+ bool selectable = line->GetParam("selectable")->AsBool(true);
obj->SetSelectable(selectable);
- obj->SetIgnoreBuildCheck(OpInt(line, "ignoreBuildCheck", 0));
- obj->SetEnable(OpInt(line, "enable", 1));
- obj->SetProxyActivate(OpInt(line, "proxyActivate", 0));
- obj->SetProxyDistance(OpFloat(line, "proxyDistance", 15.0f)*g_unit);
- obj->SetRange(OpFloat(line, "range", 30.0f));
- obj->SetShield(OpFloat(line, "shield", 1.0f));
- obj->SetMagnifyDamage(OpFloat(line, "magnifyDamage", 1.0f));
- obj->SetClip(OpInt(line, "clip", 1));
- obj->SetCheckToken(m_version >= 2 ? trainer || !selectable : OpInt(line, "checkToken", 1));
+ obj->SetIgnoreBuildCheck(line->GetParam("ignoreBuildCheck")->AsBool(false));
+ obj->SetEnable(line->GetParam("enable")->AsBool(true));
+ obj->SetProxyActivate(line->GetParam("proxyActivate")->AsBool(false));
+ if(line->GetParam("proxyActivate")->AsBool(false))
+ obj->SetProxyDistance(line->GetParam("proxyDistance")->AsFloat()*g_unit);
+ obj->SetRange(line->GetParam("range")->AsFloat(30.0f));
+ obj->SetShield(line->GetParam("shield")->AsFloat(1.0f));
+ obj->SetMagnifyDamage(line->GetParam("magnifyDamage")->AsFloat(1.0f));
+ obj->SetClip(line->GetParam("clip")->AsBool(true));
+ obj->SetCheckToken(m_version >= 2 ? trainer || !selectable : line->GetParam("checkToken")->AsBool(true));
// SetManual will affect bot speed
if (type == OBJECT_MOBILEdr)
{
- obj->SetManual(m_version >= 2 ? !trainer : OpInt(line, "manual", 0));
+ obj->SetManual(m_version >= 2 ? !trainer : line->GetParam("manual")->AsBool(false));
}
-
+
if (m_version >= 2)
{
- Math::Vector zoom = OpDir(line, "zoom");
+ Math::Vector zoom = line->GetParam("zoom")->AsPoint(Math::Vector(0.0f, 0.0f, 0.0f));
if (zoom.x != 0.0f || zoom.y != 0.0f || zoom.z != 0.0f)
obj->SetZoom(0, zoom);
}
-
+
+ //TODO: I don't remember what this is used for
CMotion* motion = obj->GetMotion();
- if (motion != nullptr)
+ if (motion != nullptr && line->GetParam("param")->IsDefined())
{
- p = SearchOp(line, "param");
- for (int i = 0; i < 10; i++)
+ const std::vector<CLevelParserParam*>& p = line->GetParam("param")->AsArray();
+ for (int i = 0; i < 10 && i < p.size(); i++)
{
- float value;
- value = GetFloat(p, i, NAN);
- if (value == NAN) break;
- motion->SetParam(i, value);
+ motion->SetParam(i, p[i]->AsFloat());
}
}
-
+
int run = -1;
CBrain* brain = obj->GetBrain();
if (brain != nullptr)
{
for (int i = 0; i < 10; i++)
{
- sprintf(op, "script%d", i+1); // script1..script10
- OpString(line, op, name);
- if (name[0] != 0)
- brain->SetScriptName(i, name);
-
+ std::string op = "script"+std::to_string(i+1); // script1..script10
+ if(line->GetParam(op)->IsDefined()) {
+ brain->SetScriptName(i, const_cast<char*>(line->GetParam(op)->AsPath("").c_str())); //TODO: don't make this relative to ai/
+ }
+
}
-
- int i = OpInt(line, "run", 0);
+
+ int i = line->GetParam("run")->AsInt(0);
if (i != 0)
{
run = i-1;
@@ -4724,17 +4599,16 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
CAuto* automat = obj->GetAuto();
if (automat != nullptr)
{
- type = OpTypeObject(line, "autoType", OBJECT_NULL);
+ type = line->GetParam("autoType")->AsObjectType(OBJECT_NULL);
automat->SetType(type);
for (int i = 0; i < 5; i++)
{
- sprintf(op, "autoValue%d", i+1); // autoValue1..autoValue5
- automat->SetValue(i, OpFloat(line, op, 0.0f));
+ std::string op = "autoValue"+std::to_string(i+1); // autoValue1..autoValue5
+ automat->SetValue(i, line->GetParam(op)->AsFloat(0.0f));
}
- OpString(line, "autoString", name);
- automat->SetString(name);
-
- int i = OpInt(line, "run", -1);
+ automat->SetString(const_cast<char*>(line->GetParam("autoString")->AsString("").c_str()));
+
+ int i = line->GetParam("run")->AsInt(-1);
if (i != -1)
{
if (i != PARAM_FIXSCENE &&
@@ -4742,30 +4616,29 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
automat->Start(i); // starts the film
}
}
-
- OpString(line, "soluce", name);
- if (soluce && brain != 0 && name[0] != 0)
- brain->SetSoluceName(name);
-
+
+ if (soluce && brain != nullptr && line->GetParam("soluce")->IsDefined())
+ brain->SetSoluceName(const_cast<char*>(line->GetParam("soluce")->AsString().c_str()));
+
obj->SetResetPosition(obj->GetPosition(0));
obj->SetResetAngle(obj->GetAngle(0));
obj->SetResetRun(run);
-
- if (OpInt(line, "reset", 0) == 1)
+
+ if (line->GetParam("reset")->AsBool(false))
obj->SetResetCap(RESET_MOVE);
}
-
+
rankObj ++;
continue;
}
-
- if (Cmd(line, "CreateFog") && !resetObject)
+
+ if (line->GetCommand() == "CreateFog" && !resetObject)
{
- Gfx::ParticleType type = static_cast<Gfx::ParticleType>((Gfx::PARTIFOG0+OpInt(line, "type", 0)));
- Math::Vector pos = OpPos(line, "pos")*g_unit;
- float height = OpFloat(line, "height", 1.0f)*g_unit;
- float ddim = OpFloat(line, "dim", 50.0f)*g_unit;
- float delay = OpFloat(line, "delay", 2.0f);
+ Gfx::ParticleType type = static_cast<Gfx::ParticleType>(Gfx::PARTIFOG0+(line->GetParam("type")->AsInt()));
+ Math::Vector pos = line->GetParam("pos")->AsPoint()*g_unit;
+ float height = line->GetParam("height")->AsFloat(1.0f)*g_unit;
+ float ddim = line->GetParam("dim")->AsFloat(50.0f)*g_unit;
+ float delay = line->GetParam("delay")->AsFloat(2.0f);
m_terrain->AdjustToFloor(pos);
pos.y += height;
Math::Point dim;
@@ -4774,149 +4647,150 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_particle->CreateParticle(pos, Math::Vector(0.0f, 0.0f, 0.0f), dim, type, delay, 0.0f, 0.0f);
continue;
}
-
- if (Cmd(line, "CreateLight") && !resetObject)
+
+ if (line->GetCommand() == "CreateLight" && !resetObject)
{
Gfx::EngineObjectType type;
-
- int lightRank = CreateLight(OpDir(line, "dir"),
- OpColor(line, "color", Gfx::Color(0.5f, 0.5f, 0.5f, 1.0f)));
-
- type = OpTypeTerrain(line, "type", Gfx::ENG_OBJTYPE_NULL);
+
+ int lightRank = CreateLight(line->GetParam("dir")->AsPoint(),
+ line->GetParam("color")->AsColor(Gfx::Color(0.5f, 0.5f, 0.5f, 1.0f)));
+
+ type = line->GetParam("type")->AsTerrainType(Gfx::ENG_OBJTYPE_NULL);
+
if (type == Gfx::ENG_OBJTYPE_TERRAIN)
{
m_lightMan->SetLightPriority(lightRank, Gfx::LIGHT_PRI_HIGHEST);
m_lightMan->SetLightIncludeType(lightRank, Gfx::ENG_OBJTYPE_TERRAIN);
}
-
+
if (type == Gfx::ENG_OBJTYPE_QUARTZ)
m_lightMan->SetLightIncludeType(lightRank, Gfx::ENG_OBJTYPE_QUARTZ);
-
+
if (type == Gfx::ENG_OBJTYPE_METAL)
m_lightMan->SetLightIncludeType(lightRank, Gfx::ENG_OBJTYPE_METAL);
-
+
if (type == Gfx::ENG_OBJTYPE_FIX)
m_lightMan->SetLightExcludeType(lightRank, Gfx::ENG_OBJTYPE_TERRAIN);
-
+
continue;
}
- if (Cmd(line, "CreateSpot") && !resetObject)
+ if (line->GetCommand() == "CreateSpot" && !resetObject)
{
Gfx::EngineObjectType type;
-
- int rankLight = CreateSpot(OpDir(line, "pos")*g_unit,
- OpColor(line, "color", Gfx::Color(0.5f, 0.5f, 0.5f, 1.0f)));
-
- type = OpTypeTerrain(line, "type", Gfx::ENG_OBJTYPE_NULL);
+
+ int rankLight = CreateSpot(line->GetParam("pos")->AsPoint()*g_unit,
+ line->GetParam("color")->AsColor(Gfx::Color(0.5f, 0.5f, 0.5f, 1.0f)));
+
+ type = line->GetParam("type")->AsTerrainType(Gfx::ENG_OBJTYPE_NULL);
if (type == Gfx::ENG_OBJTYPE_TERRAIN)
m_lightMan->SetLightIncludeType(rankLight, Gfx::ENG_OBJTYPE_TERRAIN);
-
+
if (type == Gfx::ENG_OBJTYPE_QUARTZ)
m_lightMan->SetLightIncludeType(rankLight, Gfx::ENG_OBJTYPE_QUARTZ);
-
+
if (type == Gfx::ENG_OBJTYPE_METAL)
m_lightMan->SetLightIncludeType(rankLight, Gfx::ENG_OBJTYPE_METAL);
-
+
if (type == Gfx::ENG_OBJTYPE_FIX)
m_lightMan->SetLightExcludeType(rankLight, Gfx::ENG_OBJTYPE_TERRAIN);
-
+
continue;
}
-
- if (Cmd(line, "GroundSpot") && !resetObject)
+
+ if (line->GetCommand() == "GroundSpot" && !resetObject)
{
rank = m_engine->CreateGroundSpot();
if (rank != -1)
{
- m_engine->SetObjectGroundSpotPos(rank, OpPos(line, "pos")*g_unit);
- m_engine->SetObjectGroundSpotRadius(rank, OpFloat(line, "radius", 10.0f)*g_unit);
- m_engine->SetObjectGroundSpotColor(rank, OpColor(line, "color", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)));
- m_engine->SetObjectGroundSpotSmooth(rank, OpFloat(line, "smooth", 1.0f));
- m_engine->SetObjectGroundSpotMinMax(rank, OpFloat(line, "min", 0.0f)*g_unit,
- OpFloat(line, "max", 0.0f)*g_unit);
+ m_engine->SetObjectGroundSpotPos(rank, line->GetParam("pos")->AsPoint()*g_unit);
+ m_engine->SetObjectGroundSpotRadius(rank, line->GetParam("radius")->AsFloat(10.0f)*g_unit);
+ m_engine->SetObjectGroundSpotColor(rank, line->GetParam("color")->AsColor(Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)));
+ m_engine->SetObjectGroundSpotSmooth(rank, line->GetParam("smooth")->AsFloat(1.0f));
+ m_engine->SetObjectGroundSpotMinMax(rank, line->GetParam("min")->AsFloat(0.0f)*g_unit,
+ line->GetParam("max")->AsFloat(0.0f)*g_unit);
}
continue;
}
-
- if (Cmd(line, "WaterColor") && !resetObject)
+
+ if (line->GetCommand() == "WaterColor" && !resetObject)
{
- m_engine->SetWaterAddColor(OpColor(line, "color", Gfx::Color(0.0f, 0.0f, 0.0f, 1.0f)));
+ m_engine->SetWaterAddColor(line->GetParam("color")->AsColor());
continue;
}
-
- if (Cmd(line, "MapColor") && !resetObject)
+
+ if (line->GetCommand() == "MapColor" && !resetObject)
{
- m_map->FloorColorMap(OpColor(line, "floor", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)),
- OpColor(line, "water", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)));
- m_mapShow = OpInt(line, "show", 1);
+ m_map->FloorColorMap(line->GetParam("floor")->AsColor(Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)),
+ line->GetParam("water")->AsColor(Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)));
+ m_mapShow = line->GetParam("show")->AsBool(true);
m_map->ShowMap(m_mapShow);
- m_map->SetToy(OpInt(line, "toyIcon", 0));
- m_mapImage = OpInt(line, "image", 0);
+ m_map->SetToy(line->GetParam("toyIcon")->AsBool(false));
+ m_mapImage = line->GetParam("image")->AsBool(false);
if (m_mapImage)
{
- Math::Vector offset;
- OpString(line, "filename", m_mapFilename);
- offset = OpPos(line, "offset");
- m_map->SetFixParam(OpFloat(line, "zoom", 1.0f),
+ Math::Vector offset;
+ strcpy(m_mapFilename, line->GetParam("filename")->AsPath("").c_str()); //TODO: don't make this relative to textures/
+ offset = line->GetParam("offset")->AsPoint(Math::Vector(0.0f, 0.0f, 0.0f));
+ m_map->SetFixParam(line->GetParam("zoom")->AsFloat(1.0f),
offset.x, offset.z,
- OpFloat(line, "angle", 0.0f)*Math::PI/180.0f,
- OpInt(line, "mode", 0),
- OpInt(line, "debug", 0));
+ line->GetParam("angle")->AsFloat(0.0f)*Math::PI/180.0f,
+ line->GetParam("mode")->AsInt(0),
+ line->GetParam("debug")->AsBool(false));
}
continue;
}
-
- if (Cmd(line, "MapZoom") && !resetObject)
+
+ if (line->GetCommand() == "MapZoom" && !resetObject)
{
- m_map->ZoomMap(OpFloat(line, "factor", 2.0f));
- m_map->MapEnable(OpInt(line, "enable", 1));
+ m_map->ZoomMap(line->GetParam("factor")->AsFloat(2.0f));
+ m_map->MapEnable(line->GetParam("enable")->AsBool(true));
continue;
}
-
- if (Cmd(line, "MaxFlyingHeight") && !resetObject)
+
+ if (line->GetCommand() == "MaxFlyingHeight" && !resetObject)
{
- m_terrain->SetFlyingMaxHeight(OpFloat(line, "max", 280.0f)*g_unit);
+ m_terrain->SetFlyingMaxHeight(line->GetParam("max")->AsFloat(280.0f)*g_unit);
continue;
}
-
- if (Cmd(line, "AddFlyingHeight") && !resetObject)
+
+ if (line->GetCommand() == "AddFlyingHeight" && !resetObject)
{
- m_terrain->AddFlyingLimit(OpPos(line, "center")*g_unit,
- OpFloat(line, "extRadius", 20.0f)*g_unit,
- OpFloat(line, "intRadius", 10.0f)*g_unit,
- OpFloat(line, "maxHeight", 200.0f));
+ m_terrain->AddFlyingLimit(line->GetParam("center")->AsPoint()*g_unit,
+ line->GetParam("extRadius")->AsFloat(20.0f)*g_unit,
+ line->GetParam("intRadius")->AsFloat(10.0f)*g_unit,
+ line->GetParam("maxHeight")->AsFloat(200.0f));
continue;
}
-
- if (Cmd(line, "Camera"))
+
+ if (line->GetCommand() == "Camera")
{
- m_camera->Init(OpDir(line, "eye")*g_unit,
- OpDir(line, "lookat")*g_unit,
- resetObject?0.0f:OpFloat(line, "delay", 0.0f));
-
- if (OpInt(line, "fadeIn", 0) == 1)
+ m_camera->Init(line->GetParam("eye")->AsPoint(Math::Vector(0.0f, 0.0f, 0.0f))*g_unit,
+ line->GetParam("lookat")->AsPoint(Math::Vector(0.0f, 0.0f, 0.0f))*g_unit,
+ resetObject ? 0.0f : line->GetParam("delay")->AsFloat(0.0f));
+
+ if (line->GetParam("fadeIn")->AsBool(false))
m_camera->StartOver(Gfx::CAM_OVER_EFFECT_FADEIN_WHITE, Math::Vector(0.0f, 0.0f, 0.0f), 1.0f);
-
- m_camera->SetFixDirection(OpFloat(line, "fixDirection", 0.25f)*Math::PI);
+
+ m_camera->SetFixDirection(line->GetParam("fixDirection")->AsFloat(0.25f)*Math::PI);
continue;
}
-
- if (Cmd(line, "EndMissionTake") && !resetObject && m_controller == nullptr)
+
+ if (line->GetCommand() == "EndMissionTake" && !resetObject && m_controller == nullptr)
{
int i = m_endTakeTotal;
if (i < 10)
{
- m_endTake[i].pos = OpPos(line, "pos")*g_unit;
- m_endTake[i].dist = OpFloat(line, "dist", (m_version < 2 ? 8.0f : 100.0f))*g_unit;
- m_endTake[i].type = OpTypeObject(line, "type", OBJECT_NULL);
- m_endTake[i].min = OpInt(line, "min", 1);
- m_endTake[i].max = OpInt(line, "max", 9999);
+ m_endTake[i].pos = line->GetParam("pos")->AsPoint(Math::Vector(0.0f, 0.0f, 0.0f))*g_unit;
+ m_endTake[i].dist = line->GetParam("dist")->AsFloat(m_version < 2 ? 8.0f : 100.0f)*g_unit;
+ m_endTake[i].type = line->GetParam("type")->AsObjectType(OBJECT_NULL);
+ m_endTake[i].min = line->GetParam("min")->AsInt(1);
+ m_endTake[i].max = line->GetParam("max")->AsInt(9999);
if (m_version >= 2)
{
- m_endTake[i].powermin = OpFloat(line, "powermin", -1);
- m_endTake[i].powermax = OpFloat(line, "powermax", 100);
- m_endTake[i].tool = OpTool(line, "tool");
- m_endTake[i].drive = OpDrive(line, "drive");
+ m_endTake[i].powermin = line->GetParam("powermin")->AsFloat(-1);
+ m_endTake[i].powermax = line->GetParam("powermax")->AsFloat(100);
+ m_endTake[i].tool = line->GetParam("tool")->AsToolType(TOOL_OTHER);
+ m_endTake[i].drive = line->GetParam("drive")->AsDriveType(DRIVE_OTHER);
}
else
{
@@ -4925,93 +4799,91 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_endTake[i].tool = TOOL_OTHER;
m_endTake[i].drive = DRIVE_OTHER;
}
- m_endTake[i].lost = OpInt(line, "lost", -1);
- m_endTake[i].immediat = OpInt(line, "immediat", 0);
- OpString(line, "message", m_endTake[i].message);
+ m_endTake[i].lost = line->GetParam("lost")->AsInt(-1);
+ m_endTake[i].immediat = line->GetParam("immediat")->AsBool(false);
+ strcpy(m_endTake[i].message, line->GetParam("message")->AsString("").c_str()); //TODO: Really, ending mission on message()? Is this used anywhere? Do we need that?
m_endTakeTotal ++;
}
continue;
}
- if (Cmd(line, "EndMissionDelay") && !resetObject && m_controller == nullptr)
+ if (line->GetCommand() == "EndMissionDelay" && !resetObject && m_controller == nullptr)
{
- m_endTakeWinDelay = OpFloat(line, "win", 2.0f);
- m_endTakeLostDelay = OpFloat(line, "lost", 2.0f);
+ m_endTakeWinDelay = line->GetParam("win")->AsFloat(2.0f);
+ m_endTakeLostDelay = line->GetParam("lost")->AsFloat(2.0f);
continue;
}
- if (Cmd(line, "EndMissionResearch") && !resetObject && m_controller == nullptr)
+ if (line->GetCommand() == "EndMissionResearch" && !resetObject && m_controller == nullptr) //TODO: Is this used anywhere?
{
- m_endTakeResearch |= OpResearch(line, "type");
+ m_endTakeResearch |= line->GetParam("type")->AsResearchFlag();
continue;
}
- if (Cmd(line, "EndMissionNever") && !resetObject && m_controller == nullptr)
+ if (line->GetCommand() == "EndMissionNever" && !resetObject && m_controller == nullptr)
{
m_endTakeNever = true;
continue;
}
-
- if (Cmd(line, "ObligatoryToken") && !resetObject)
+
+ if (line->GetCommand() == "ObligatoryToken" && !resetObject) //NOTE: This was used only in CeeBot, maybe we should add this to some Colobot exercises?
{
int i = m_obligatoryTotal;
- if (i < 100)
+ if (i < 100) //TODO: remove the limit
{
- OpString(line, "text", m_obligatoryToken[i]);
+ strcpy(m_obligatoryToken[i], line->GetParam("text")->AsString().c_str());
m_obligatoryTotal ++;
}
continue;
}
-
- if (Cmd(line, "ProhibitedToken") && !resetObject)
+
+ if (line->GetCommand() == "ProhibitedToken" && !resetObject) //NOTE: This was used only in CeeBot, maybe we should add this to some Colobot exercises?
{
int i = m_prohibitedTotal;
- if (i < 100)
+ if (i < 100) //TODO: remove the limit
{
- OpString(line, "text", m_prohibitedToken[i]);
+ strcpy(m_prohibitedToken[i], line->GetParam("text")->AsString().c_str());
m_prohibitedTotal ++;
}
continue;
}
-
- if (Cmd(line, "EnableBuild") && !resetObject)
+
+ if (line->GetCommand() == "EnableBuild" && !resetObject)
{
- g_build |= OpBuild(line, "type");
+ g_build |= line->GetParam("type")->AsBuildFlag();
continue;
}
-
- if (Cmd(line, "EnableResearch") && !resetObject)
+
+ if (line->GetCommand() == "EnableResearch" && !resetObject)
{
- g_researchEnable |= OpResearch(line, "type");
+ g_researchEnable |= line->GetParam("type")->AsResearchFlag();
continue;
}
-
- if (Cmd(line, "DoneResearch") && read[0] == 0 && !resetObject) // not loading file?
+
+ if (line->GetCommand() == "DoneResearch" && read[0] == 0 && !resetObject) // not loading file?
{
- g_researchDone |= OpResearch(line, "type");
+ g_researchDone |= line->GetParam("type")->AsResearchFlag();
continue;
}
-
- if (Cmd(line, "NewScript") && !resetObject)
+
+ if (line->GetCommand() == "NewScript" && !resetObject)
{
- OpString(line, "name", name);
- AddNewScriptName(OpTypeObject(line, "type", OBJECT_NULL), name);
+ char name[200];
+ strcpy(name, line->GetParam("name")->AsPath("").c_str()); //TODO: don't make this relative to ai/
+ AddNewScriptName(line->GetParam("type")->AsObjectType(OBJECT_NULL), name);
continue;
}
-
- if (line[0] == '\n') continue; // Ignore empty lines
- if (line[0] == '\0') continue; // Ignore empty lines
- if (read[0] != 0) continue; // Ignore when loading saved game
-
- GetLogger()->Error("Syntax error in file '%s' (line %d): Unknown command: %s", filename, lineNum, line); // Don't add \n at the end of log message - it's included in line variable
+
+ if(read[0] != 0) continue; // ignore errors when loading saevd game (TODO: don't report ones that are just not loaded when loading saved game)
+ if(resetObject) continue; // ignore when reseting just objects (TODO: see above)
+
+ throw CLevelParserException("Unknown command: '"+line->GetCommand()+"' in "+line->GetLevel()->GetFilename()+":"+std::to_string(line->GetLineNumber()));
}
- stream.close();
-
if (read[0] == 0)
CompileScript(soluce); // compiles all scripts
- if (strcmp(base, "scene") == 0 && !resetObject) // mission?
+ if (strcmp(base, "missions") == 0 && !resetObject) // mission?
WriteFreeParam();
- if (strcmp(base, "free") == 0 && !resetObject) // free play?
+ if (strcmp(base, "freemissions") == 0 && !resetObject) // free play?
{
g_researchDone = m_freeResearch;
@@ -6541,20 +6413,28 @@ void CRobotMain::ResetCreate()
m_camera->SetType(Gfx::CAM_TYPE_DIALOG);
- CreateScene(m_dialog->GetSceneSoluce(), false, true);
+ try {
+ CreateScene(m_dialog->GetSceneSoluce(), false, true);
- if (!GetNiceReset()) return;
+ if (!GetNiceReset()) return;
- for (int i = 0; i < 1000000; i++)
- {
- CObject* obj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i));
- if (obj == nullptr) break;
+ for (int i = 0; i < 1000000; i++)
+ {
+ CObject* obj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i));
+ if (obj == nullptr) break;
- ResetCap cap = obj->GetResetCap();
- if (cap == RESET_NONE) continue;
+ ResetCap cap = obj->GetResetCap();
+ if (cap == RESET_NONE) continue;
- Gfx::CPyro* pyro = new Gfx::CPyro();
- pyro->Create(Gfx::PT_RESET, obj);
+ Gfx::CPyro* pyro = new Gfx::CPyro();
+ pyro->Create(Gfx::PT_RESET, obj);
+ }
+ }
+ catch(const CLevelParserException& e)
+ {
+ CLogger::GetInstancePointer()->Error("An error occured while trying to reset scene\n");
+ CLogger::GetInstancePointer()->Error("%s\n", e.what());
+ ChangePhase(PHASE_TERM);
}
}
diff --git a/src/script/cmdtoken.cpp b/src/script/cmdtoken.cpp
index 6393505..3a84bb3 100644
--- a/src/script/cmdtoken.cpp
+++ b/src/script/cmdtoken.cpp
@@ -23,6 +23,8 @@
#include <cstdio>
+// TODO: Remove these functions
+
// Skips spaces.
diff --git a/src/script/script.cpp b/src/script/script.cpp
index 578c07d..605df71 100644
--- a/src/script/script.cpp
+++ b/src/script/script.cpp
@@ -53,7 +53,6 @@
#include "ui/edit.h"
#include "ui/list.h"
#include "ui/displaytext.h"
-#include <test/cbot/CBot_console/CClass.h>
#include <stdio.h>