28#include <OgreFileSystem.h>
29#include <OgreArchive.h>
30#include <OgreArchiveManager.h>
31#include <OgreException.h>
192 int hour, minute, second;
282 else if (returncode ==
sBreak)
287 else if (returncode ==
sRecalc)
291 else if (returncode ==
sExit)
333 int location = insert_line;
339 if (location > (
int)
BuildingData.size() - 1 || location < 0)
341 ScriptError(
"Cannot insert file beyond end of script");
359 Ogre::Archive *filesystem = 0;
360 Ogre::ArchiveManager::ArchiveMapIterator it = Ogre::ArchiveManager::getSingleton().getArchiveIterator();
361 Ogre::DataStreamPtr filedata;
362 while(it.hasMoreElements())
365 const std::string& key = it.peekNextKey();
366 filesystem = it.getNext();
372 std::string shortname;
375 if (group ==
"General")
378 if (filesystem->exists(Filename) ==
true)
382 filedata = filesystem->open(Filename,
true);
384 catch (Ogre::Exception &e)
386 std::string msg =
"Error loading building file\nDetails: " + e.getDescription();
400 std::string msg =
"Error loading building file";
408 Ogre::DataStreamPtr file(
new Ogre::MemoryDataStream(Filename, filedata,
true,
true));
410 std::vector<std::string> insert_data;
411 insert_data.reserve(512);
413 while (file->eof() ==
false)
416 std::string
line = file->getLine(
true);
426 insert_data.emplace_back(
line);
434 location += (int)insert_data.size();
436 int end = location - 1;
437 int lines = end - insert_line;
441 for (
int i = 0; i < (int)
includes.size(); i++)
451 for (
size_t i = 0; i <
functions.size(); i++)
482 if (text.size() == 0)
485 std::vector<std::string> textarray;
490 for (
size_t i = 0; i < textarray.size(); i++)
505 int LineNumber, FunctionLine;
506 bool IsInclude, IsIncludeFunction;
507 std::string FunctionName, IncludeFile, IncludeFunctionFile;
509 GetLineInformation(
true, LineNumber, FunctionName, FunctionLine, IsInclude, IncludeFile, IsIncludeFunction, IncludeFunctionFile);
511 if (warning ==
false)
512 error =
"Script error ";
514 error =
"Script warning ";
516 if (IsInclude ==
true)
517 error +=
"in included file " + IncludeFile +
" ";
525 error +=
"\nLine Text: " +
LineData;
528 error +=
"\nFunction: " + FunctionName;
530 if (IsIncludeFunction ==
true)
531 error +=
"\nFunction included in file: " + IncludeFunctionFile;
533 error +=
"\nFunction call line: " +
ToString(FunctionLine) +
"\nLine Text: " +
LineData;
542 if (warning ==
false)
545 wxMessageDialog dialog (0, error,
"Skyscraper", wxOK | wxICON_ERROR);
552void ScriptProcessor::GetLineInformation(
bool CheckFunctionCall,
int &LineNumber, std::string &FunctionName,
int &FunctionLine,
bool &IsInclude, std::string &IncludeFile,
bool &IsIncludeFunction, std::string &IncludeFunctionFile)
562 int newlinenum =
line;
563 int linenum_start = 0;
564 int function_line = 0;
565 int newfunction_line = 0;
566 int function_line_start = 0;
567 int included_lines = 0;
568 int included_lines_f = 0;
573 IsIncludeFunction =
false;
576 IncludeFunctionFile =
"";
582 newfunction_line = function_line;
586 for (
int i = 0; i < (int)
includes.size(); i++)
588 if (linenum <
includes[i].start_line)
596 newlinenum = linenum -
includes[i].start_line;
598 linenum_start =
includes[i].start_line;
602 if (CheckFunctionCall ==
true)
604 if (function_line >=
includes[i].start_line && function_line <=
includes[i].end_line)
606 IsIncludeFunction =
true;
607 IncludeFunctionFile =
includes[i].filename;
608 newfunction_line = function_line -
includes[i].start_line;
610 function_line_start =
includes[i].start_line;
615 linenum = newlinenum;
616 function_line = newfunction_line;
619 for (
int i = 0; i < (int)
includes.size(); i++)
623 if (linenum + linenum_start >
includes[i].end_line)
627 if (CheckFunctionCall ==
true)
631 if (function_line + function_line_start >
includes[i].end_line)
642 LineNumber = linenum - included_lines;
645 FunctionLine = function_line - included_lines_f;
653 int loc = message.find_last_of(
":");
655 std::string result = message.substr(loc + 1);
673 std::string tmpcalc = expression;
685 start = tmpcalc.find(
"(", 0);
691 for (
int i = start + 1; i < (int)tmpcalc.length(); i++)
693 char &tmpchar = tmpcalc.at(i);
708 newdata =
Calc(tmpcalc.substr(start + 1, end - start - 1));
714 one = tmpcalc.substr(0, start);
715 if (end < (
int)tmpcalc.length() - 1)
716 two = tmpcalc.substr(end + 1);
719 tmpcalc = one + newdata + two;
723 ScriptError(
"Syntax error in math operation: '" + tmpcalc +
"' (might be nested)");
738 for (
int i = 1; i < (int)tmpcalc.length(); i++)
740 char &tmpchar = tmpcalc.at(i);
741 char &tmpcharprev = tmpcalc.at(i - 1);
742 if (tmpchar ==
'+' || tmpchar ==
'/' || tmpchar ==
'*' || tmpchar ==
'^')
745 if (i < (
int)tmpcalc.length() - 1)
747 char &tmpcharnext = tmpcalc.at(i + 1);
748 if (
IsNumeric(tmpcharprev) ==
true && (
IsNumeric(tmpcharnext) ==
true || tmpcharnext ==
'-' || tmpcharnext ==
'.'))
757 if (tmpchar ==
'-' && tmpcharprev !=
'-' && tmpcharprev !=
'+' && tmpcharprev !=
'/' && tmpcharprev !=
'*' && tmpcharprev !=
'^')
760 if (i < (
int)tmpcalc.length() - 1)
762 char &tmpcharnext = tmpcalc.at(i + 1);
763 if (
IsNumeric(tmpcharprev) ==
true && (
IsNumeric(tmpcharnext) ==
true || tmpcharnext ==
'-' || tmpcharnext ==
'.'))
773 if (end >= (
int)tmpcalc.length() - 1 && operators > 0)
775 ScriptError(
"Syntax error in math operation: '" + tmpcalc +
"' (might be nested)");
782 newdata =
Calc(tmpcalc.substr(0, end));
788 two = tmpcalc.substr(end);
789 tmpcalc = newdata + two;
803 temp1 = tmpcalc.find(
"+", 1);
806 one = tmpcalc.substr(0, temp1);
807 two = tmpcalc.substr(temp1 + 1);
812 Real tmpnum = first + second;
823 temp1 = tmpcalc.find(
"/", 1);
826 one = tmpcalc.substr(0, temp1);
827 two = tmpcalc.substr(temp1 + 1);
834 ScriptError(
"Division by zero in math operation: '" + tmpcalc +
"' (might be nested)");
838 Real tmpnum = first / second;
849 temp1 = tmpcalc.find(
"*", 1);
852 one = tmpcalc.substr(0, temp1);
853 two = tmpcalc.substr(temp1 + 1);
858 Real tmpnum = first * second;
869 temp1 = tmpcalc.find(
"^", 1);
872 one = tmpcalc.substr(0, temp1);
873 two = tmpcalc.substr(temp1 + 1);
878 Real tmpnum = powf(first, second);
889 temp1 = tmpcalc.find(
"-", 1);
892 one = tmpcalc.substr(0, temp1);
893 two = tmpcalc.substr(temp1 + 1);
898 Real tmpnum = first - second;
919 int LineNumber, FunctionLine;
920 bool IsInclude, IsIncludeFunction;
921 std::string FunctionName, IncludeFile, IncludeFunctionFile;
923 GetLineInformation(
false, LineNumber, FunctionName, FunctionLine, IsInclude, IncludeFile, IsIncludeFunction, IncludeFunctionFile);
924 object->linenum = LineNumber;
925 object->includefile = IncludeFile;
929 object->command_processed =
LineData;
934 object->context =
"Floor " + current;
936 object->context =
"Elevator " + current;
940 object->context =
"Vehicle " + current;
942 object->context =
"Controller " + current;
944 object->context =
"Call Station " + current;
950 for (
size_t i = 0; i <
functions.size(); i++)
968 int location2 = location + (int)data.
Name.length() + 1;
969 int end_loc =
LineData.find_last_of(
")");
970 std::string newdata =
LineData.substr(location2, end_loc - location2);
971 std::vector<std::string> tempdata;
975 data.
Params.reserve(tempdata.size());
977 for (
int j = 0; j < (int)tempdata.size(); j++)
979 buffer =
Calc(tempdata[j]);
981 data.
Params.emplace_back(buffer);
1006 for (
int i = 0; i <
functions.size(); i++)
1015 data.
Name =
"runloop";
1029 std::string file = filename;
1034 int loc = file.find_last_of(
"/");
1037 if (file.length() == loc + 1)
1040 loc = file.find_last_of(
"\\");
1043 if (file.length() == loc + 1)
1050 loc = file.find_last_of(
"*");
1056 bool exists =
false;
1065 if (exists ==
false)
1079 for (
size_t i = 0; i <
functions.size(); i++)
1091 int LineNumber, FunctionLine;
1092 bool IsInclude, IsIncludeFunction;
1093 std::string FunctionName, IncludeFile, IncludeFunctionFile;
1095 GetLineInformation(
true, LineNumber, FunctionName, FunctionLine, IsInclude, IncludeFile, IsIncludeFunction, IncludeFunctionFile);
1097 std::string output =
"Line number: " +
ToString(LineNumber) +
"\n";
1098 if (IsInclude ==
true)
1099 output.append(
"In included file: " + IncludeFile +
"\n");
1108 output.append(
"Function: " + FunctionName +
"\n");
1109 if (IsIncludeFunction ==
true)
1110 output.append(
"Function include file: " + IncludeFunctionFile +
"\n");
1111 output.append(
"Function call line: " +
ToString(FunctionLine) +
"\n");
1113 output.append(
"Line text: " +
LineData +
"\n");
1145 loc2 =
LineData.find(
"%", loc1 + 6);
1146 if (loc2 >= (
int)
LineData.length() || loc2 < 0)
1161 if (loc1 + loc2 > 0)
1163 std::string str =
LineData.substr(loc1 + 6, loc2 - (loc1 + 6));
1167 int index =
ToInt(str);
1170 std::string replacement;
1189 std::string percent_s =
ToString(percent);
1190 int marker = percent / 10;
1215 loc2 =
LineData.find(
"%", loc1 + 1);
1216 if (loc2 >= (
int)
LineData.length() || loc2 < 0)
1231 if (loc1 + loc2 > 0)
1233 str =
LineData.substr(loc1 + 1, loc2 - loc1 - 1);
1237 for (
size_t i = 0; i <
variables.size(); i++)
1302 std::string includefile =
LineData.substr(9, endloc - 9);
1311 if (result ==
false)
1327 ScriptError(
"Cannot define a function within a section");
1339 std::string function =
LineData.substr(10, endloc - 10);
1345 if (defined ==
true)
1346 engine->
Report(
"Function '" + function +
"' already defined");
1351 info.
name = function;
1366 if (defined ==
false)
1392 if (data.
Name ==
"runloop")
1410 int loc = linecheck.find(
"to", 0);
1418 std::string str1 =
LineData.substr(8, loc - 9);
1419 std::string str2 =
LineData.substr(loc + 2,
LineData.length() - (loc + 2) - 1);
1463 int loc = linecheck.find(
"to", 10);
1469 std::string str1 =
LineData.substr(11, loc - 12);
1470 std::string str2 =
LineData.substr(loc + 2,
LineData.length() - (loc + 2) - 1);
1530 int loc = linecheck.find(
"to", 5);
1544 std::string str1 =
LineData.substr(6, loc - 7);
1545 std::string str2 =
LineData.substr(loc + 2,
LineData.length() - (loc + 2) - 1);
1608 int loc = linecheck.find(
"to", 9);
1614 std::string str1 =
LineData.substr(10, loc - 11);
1615 std::string str2 =
LineData.substr(loc + 2,
LineData.length() - (loc + 2) - 1);
1664 int loc = linecheck.find(
"to", 12);
1670 std::string str1 =
LineData.substr(13, loc - 14);
1671 std::string str2 =
LineData.substr(loc + 2,
LineData.length() - (loc + 2) - 1);
1715 int loc = linecheck.find(
"to", 13);
1729 std::string str1 =
LineData.substr(14, loc - 15);
1730 std::string str2 =
LineData.substr(loc + 2,
LineData.length() - (loc + 2) - 1);
1798 int loc1 =
LineData.find(
"(", exists);
1799 int loc2 =
LineData.find(
")", exists);
1813 std::string tempdata =
Calc(
LineData.substr(loc1 + 1, loc2 - loc1 - 1));
1829 std::string buffer =
ToString(floor);
1831 std::string name =
"floor(" + buffer +
").fullheight";
1834 loc1 = buffer.find(name, 0);
1845 name =
"floor(" + buffer +
").height";
1848 loc1 = buffer.find(name, 0);
1859 name =
"floor(" + buffer +
").altitude";
1862 loc1 = buffer.find(name, 0);
1873 name =
"floor(" + buffer +
").interfloorheight";
1876 loc1 = buffer.find(name, 0);
1888 name =
"floor(" + buffer +
").base";
1891 loc1 = buffer.find(name, 0);
1931 int loc = linecheck.find(
"to", 0);
1939 int loc2 = linecheck.find(
" ", 5);
1945 std::string it =
LineData.substr(5, loc2 - 5);
1949 for (
int i = 0; i <
variables.size(); i++)
1959 std::string str1 =
LineData.substr(loc2, loc - (loc2 + 1));
1960 std::string str2 =
LineData.substr(loc + 2,
LineData.length() - (loc + 2) - 1);
1981 info.
start = RangeL;
1996 if (info.
i > info.
end)
2002 if (info.
i < info.
end)
2006 for (
int i = 0; i <
variables.size(); i++)
2042 for (
int i = 0; i <
functions.size(); i++)
Real GetBase(bool relative=false)
virtual void Report(const std::string &message)
Elevator * GetElevator(int number)
std::string GetMountPath(std::string filename, std::string &newfilename)
bool FileExists(const std::string &filename)
bool IsValidFloor(int floor)
Floor * GetFloor(int number)
TextureManager * GetTextureManager()
std::string BuildingDesigner
Floor * NewFloor(int number)
unsigned long GetRunTime()
std::string VerifyFile(const std::string &filename)
bool ReportError(const std::string &message)
bool UpdateProgress(int percent)
std::string GetFilename()
bool ReportFatalError(const std::string &message)
void Report(const std::string &message)
int Run(std::string &LineData)
int Run(std::string &LineData)
int Run(std::string &LineData)
int Run(std::string &LineData)
int Run(std::string &LineData)
int Run(std::string &LineData)
int Run(std::string &LineData)
int Run(std::string &LineData)
int Run(std::string &LineData)
int Run(std::string &LineData)
VehicleSection * vehicle_section
static const int sNextLine
std::vector< FunctionInfo > functions
std::vector< std::string > nonexistent_files
static const int sContinue
std::vector< IncludeInfo > includes
void ProcessUserVariables()
std::vector< ForInfo > ForLoops
std::vector< VariableMap > variables
ControllerSection * controller_section
std::vector< FunctionData > FunctionStack
int ScriptWarning(std::string message)
bool LoadFromText(const std::string &text)
bool ProcessFunctionParameters()
static const int sCheckFloors
std::vector< std::string > BuildingDataOrig
GlobalsSection * globals_section
int ProcessFloorObjects()
static const int sLoopFor
void GetLineInformation(bool CheckFunctionCall, int &LineNumber, std::string &FunctionName, int &FunctionLine, bool &IsInclude, std::string &IncludeFile, bool &IsIncludeFunction, std::string &IncludeFunctionFile)
BuildingsSection * buildings_section
ElevatorCarSection * GetElevatorCarSection()
std::vector< std::string > * GetBuildingData()
CallStationSection * callstation_section
bool IsFunctionDefined(const std::string &name)
FloorSection * floor_section
void StoreCommand(::SBS::Object *object)
ScriptProcessor(EngineContext *instance)
CommandsSection * commands_section
ElevatorSection * elevator_section
std::string ReplaceLineData
bool LoadDataFile(const std::string &filename, bool insert=false, int insert_line=0)
EngineContext * GetEngine()
std::string Calc(const std::string &expression)
TexturesSection * textures_section
ConfigHandler * GetConfigHandler()
ElevatorCarSection * elevatorcar_section
std::vector< std::string > BuildingData
void CheckFile(const std::string &filename)
static const int sSkipReset
void GetTime(int &hour, int &minute, int &second)
int GetEngineCount(bool loading_only=false)
SkySystem * GetSkySystem()
bool StartsWithNoCase(const std::string &string, const std::string &check_string)
void SplitString(std::vector< std::string > &dest_array, const std::string &original_string, char separator)
void ReplaceAll(std::string &string, const std::string &original, const std::string &replacement)
int ToInt(const std::string &string)
void SetCase(std::string &string, bool uppercase)
std::string ToString(int number)
std::string SetCaseCopy(std::string string, bool uppercase)
Real ToFloat(const std::string &string)
void TrimString(std::string &string)
bool IsNumeric(const wxString &string)
wxString TruncateNumber(float value, int decimals)
std::vector< std::string > Params