From 07c651bd0af0b93da6b7d87b5fa3d3efb90a0c0d Mon Sep 17 00:00:00 2001 From: krzys-h Date: Sat, 20 Dec 2014 18:45:46 +0100 Subject: [PATCH] Moved all CBot functions into a separate class --- src/CMakeLists.txt | 1 + src/object/robotmain.cpp | 7 +- src/script/script.cpp | 4136 +----------------------------------- src/script/script.h | 152 +- src/script/scriptfunc.cpp | 4147 +++++++++++++++++++++++++++++++++++++ src/script/scriptfunc.h | 180 ++ 6 files changed, 4348 insertions(+), 4275 deletions(-) create mode 100644 src/script/scriptfunc.cpp create mode 100644 src/script/scriptfunc.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c4938e38..9e234937 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -166,6 +166,7 @@ set(BASE_SOURCES script/cbottoken.cpp script/cmdtoken.cpp script/script.cpp + script/scriptfunc.cpp sound/sound.cpp ui/button.cpp ui/check.cpp diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index 8ae92b9a..23d9f5c2 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -71,6 +71,7 @@ #include "script/cbottoken.h" #include "script/cmdtoken.h" #include "script/script.h" +#include "script/scriptfunc.h" #include "sound/sound.h" @@ -277,8 +278,8 @@ CRobotMain::CRobotMain(CApplication* app, bool loadProfile) m_showLimit[i].link = 0; } - CScript::m_filesDir = CResourceManager::GetSaveLocation()+"/"+m_dialog->GetFilesDir(); //TODO: Refactor to PHYSFS while rewriting CBot engine - CScript::InitFonctions(); + CScriptFunctions::m_filesDir = CResourceManager::GetSaveLocation()+"/"+m_dialog->GetFilesDir(); //TODO: Refactor to PHYSFS while rewriting CBot engine + CScriptFunctions::Init(); } //! Destructor of robot application @@ -4842,7 +4843,7 @@ char* CRobotMain::GetNewScriptName(ObjectType type, int rank) //! Seeks if an object occupies in a spot, to prevent a backup of the game bool CRobotMain::IsBusy() { - if (CScript::m_CompteurFileOpen > 0) return true; + if (CScriptFunctions::m_CompteurFileOpen > 0) return true; CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); diff --git a/src/script/script.cpp b/src/script/script.cpp index b5a314e6..55d85428 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -20,3916 +20,31 @@ #include "script/script.h" -#include "app/app.h" -#include "common/global.h" -#include "common/iman.h" +#include "app/pausemanager.h" + +#include "common/resources/resourcemanager.h" +#include "common/resources/inputstream.h" +#include "common/resources/outputstream.h" #include "common/restext.h" #include "common/stringutils.h" -#include "common/resources/inputstream.h" -#include "common/resources/resourcemanager.h" - -#include "graphics/engine/terrain.h" -#include "graphics/engine/water.h" +#include "graphics/engine/engine.h" #include "graphics/engine/text.h" -#include "math/geometry.h" -#include "math/vector.h" - -#include "object/object.h" -#include "object/robotmain.h" #include "object/task/taskmanager.h" -#include "object/objman.h" - -#include "object/auto/auto.h" -#include "object/auto/autofactory.h" -#include "object/auto/autobase.h" - -#include "physics/physics.h" +#include "object/robotmain.h" #include "script/cbottoken.h" -#include "sound/sound.h" - #include "ui/interface.h" #include "ui/edit.h" #include "ui/list.h" #include "ui/displaytext.h" -#include - - - -const int CBOT_IPF = 100; // CBOT: number of instructions / frame - -const int ERM_CONT = 0; // if error -> continue -const int ERM_STOP = 1; // if error -> stop - - - - -// Compiling a procedure without any parameters. - -CBotTypResult CScript::cNull(CBotVar* &var, void* user) -{ - if ( var != 0 ) return CBotErrOverParam; - return CBotTypResult(CBotTypFloat); -} - -CBotTypResult CScript::cClassNull(CBotVar* thisclass, CBotVar* &var) -{ - return CScript::cNull(var, nullptr); -} - -// Compiling a procedure with a single real number. - -CBotTypResult CScript::cOneFloat(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -CBotTypResult CScript::cClassOneFloat(CBotVar* thisclass, CBotVar* &var) -{ - return CScript::cOneFloat(var, nullptr); -} - -// Compiling a procedure with two real numbers. - -CBotTypResult CScript::cTwoFloat(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Compiling a procedure with a "dot". - -CBotTypResult CScript::cPoint(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - - if ( var->GetType() <= CBotTypDouble ) - { - var = var->GetNext(); - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); -//? if ( var == 0 ) return CBotTypResult(CBotErrLowParam); -//? if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); -//? var = var->GetNext(); - return CBotTypResult(0); - } - - if ( var->GetType() == CBotTypClass ) - { - if ( !var->IsElemOfClass("point") ) return CBotTypResult(CBotErrBadParam); - var = var->GetNext(); - return CBotTypResult(0); - } - - return CBotTypResult(CBotErrBadParam); -} - -// Compiling a procedure with a single "point". - -CBotTypResult CScript::cOnePoint(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - ret = cPoint(var, user); - if ( ret.GetType() != 0 ) return ret; - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Compiling a procedure with a single string. - -CBotTypResult CScript::cString(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() != CBotTypString && - var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Compiling a procedure with a single string, returning string. - -CBotTypResult CScript::cStringString(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() != CBotTypString && - var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypString); -} - - -// Seeking value in an array of integers. - -bool FindList(CBotVar* array, int type) -{ - while ( array != 0 ) - { - if ( type == array->GetValInt() ) return true; - array = array->GetNext(); - } - return false; -} - - -// Gives a parameter of type "point". - -bool GetPoint(CBotVar* &var, int& exception, Math::Vector& pos) -{ - CBotVar *pX, *pY, *pZ; - - if ( var->GetType() <= CBotTypDouble ) - { - pos.x = var->GetValFloat()*g_unit; - var = var->GetNext(); - - pos.z = var->GetValFloat()*g_unit; - var = var->GetNext(); - - pos.y = 0.0f; - } - else - { - pX = var->GetItem("x"); - if ( pX == NULL ) - { - exception = CBotErrUndefItem; return true; - } - pos.x = pX->GetValFloat()*g_unit; - - pY = var->GetItem("y"); - if ( pY == NULL ) - { - exception = CBotErrUndefItem; return true; - } - pos.z = pY->GetValFloat()*g_unit; // attention y -> z ! - - pZ = var->GetItem("z"); - if ( pZ == NULL ) - { - exception = CBotErrUndefItem; return true; - } - pos.y = pZ->GetValFloat()*g_unit; // attention z -> y ! - - var = var->GetNext(); - } - return true; -} - - -// Instruction "sin(degrees)". - -bool CScript::rSin(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(sinf(value*Math::PI/180.0f)); - return true; -} - -// Instruction "cos(degrees)". - -bool CScript::rCos(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(cosf(value*Math::PI/180.0f)); - return true; -} - -// Instruction "tan(degrees)". - -bool CScript::rTan(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(tanf(value*Math::PI/180.0f)); - return true; -} - -// Instruction "asin(degrees)". - -bool raSin(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(asinf(value)*180.0f/Math::PI); - return true; -} - -// Instruction "acos(degrees)". - -bool raCos(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(acosf(value)*180.0f/Math::PI); - return true; -} - -// Instruction "atan(degrees)". - -bool raTan(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(atanf(value)*180.0f/Math::PI); - return true; -} - -// Instruction "sqrt(value)". - -bool CScript::rSqrt(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(sqrtf(value)); - return true; -} - -// Instruction "pow(x, y)". - -bool CScript::rPow(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float x, y; - - x = var->GetValFloat(); - var = var->GetNext(); - y = var->GetValFloat(); - result->SetValFloat(powf(x, y)); - return true; -} - -// Instruction "rand()". - -bool CScript::rRand(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - result->SetValFloat(Math::Rand()); - return true; -} - -// Instruction "abs()". - -bool CScript::rAbs(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(fabs(value)); - return true; -} - -// Compilation of the instruction "endmission(result, delay)" - -CBotTypResult CScript::cEndMission(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Instruction "endmission(result, delay)" - -bool CScript::rEndMission(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - Error ended; - float delay; - - ended = static_cast(var->GetValFloat()); - var = var->GetNext(); - - delay = var->GetValFloat(); - - CRobotMain::GetInstancePointer()->SetEndMission(ended, delay); - return true; -} - -// Compilation of the instruction "playmusic(filename, repeat)" - -CBotTypResult CScript::cPlayMusic(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Instruction "playmusic(filename, repeat)" - -bool CScript::rPlayMusic(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - std::string filename; - CBotString cbs; - bool repeat; - - cbs = var->GetValString(); - filename = std::string(cbs); - var = var->GetNext(); - - repeat = var->GetValInt(); - - CApplication::GetInstancePointer()->GetSound()->StopMusic(); - CApplication::GetInstancePointer()->GetSound()->PlayMusic(filename, repeat); - return true; -} - -// Instruction "stopmusic()" - -bool CScript::rStopMusic(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CApplication::GetInstancePointer()->GetSound()->StopMusic(); - return true; -} - -// Instruction "getbuild()" - -bool CScript::rGetBuild(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - result->SetValInt(g_build); - return true; -} - -// Instruction "getresearchenable()" - -bool CScript::rGetResearchEnable(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - result->SetValInt(g_researchEnable); - return true; -} - -// Instruction "getresearchdone()" - -bool CScript::rGetResearchDone(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - result->SetValInt(g_researchDone); - return true; -} - -// Instruction "setbuild()" - -bool CScript::rSetBuild(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - g_build = var->GetValInt(); - CApplication::GetInstancePointer()->GetEventQueue()->AddEvent(Event(EVENT_UPDINTERFACE)); - return true; -} - -// Instruction "setresearchenable()" - -bool CScript::rSetResearchEnable(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - g_researchEnable = var->GetValInt(); - CApplication::GetInstancePointer()->GetEventQueue()->AddEvent(Event(EVENT_UPDINTERFACE)); - return true; -} - -// Instruction "setresearchdone()" - -bool CScript::rSetResearchDone(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - g_researchDone = var->GetValInt(); - CApplication::GetInstancePointer()->GetEventQueue()->AddEvent(Event(EVENT_UPDINTERFACE)); - return true; -} - -// Compilation of the instruction "retobject(rank)". - -CBotTypResult CScript::cGetObject(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypPointer, "object"); -} - -// Instruction "retobjectbyid(rank)". - -bool CScript::rGetObjectById(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CObject* pObj; - int rank; - - rank = var->GetValInt(); - - pObj = static_cast(CObjectManager::GetInstancePointer()->SearchInstance(rank)); - if ( pObj == 0 ) - { - result->SetPointer(0); - } - else - { - result->SetPointer(pObj->GetBotVar()); - } - return true; -} - -// Instruction "retobject(rank)". - -bool CScript::rGetObject(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CObject* pObj; - int rank; - - rank = var->GetValInt(); - - pObj = static_cast(CInstanceManager::GetInstancePointer()->SearchInstance(CLASS_OBJECT, rank)); - if ( pObj == 0 ) - { - result->SetPointer(0); - } - else - { - result->SetPointer(pObj->GetBotVar()); - } - return true; -} - - -// Instruction "progfunc(funcname)". - -bool CScript::rProgFunc(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CBotString cbs; - const char* funcname; - std::string program; - - cbs = var->GetValString(); - funcname = cbs; - - //TODO: Translation :) - program = "extern void object::Auto()\n{\n\t\n\t//Automatically generated by progfunc(\""; - program += funcname; - program += "\");\n\t"; - program += funcname; - program += "();\n\t\n}\n"; - - result->SetValString(program.c_str()); - - return true; -} - -// Compilation of instruction "object.busy()" -CBotTypResult CScript::cBusy(CBotVar* thisclass, CBotVar* &var) -{ - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypBoolean); -} - -// Instruction "object.busy()" - -bool CScript::rBusy(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception) -{ - exception = 0; - - CBotVar* classVars = thisclass->GetItemList(); // "category" - classVars = classVars->GetNext(); // "position" - classVars = classVars->GetNext(); // "orientation" - classVars = classVars->GetNext(); // "pitch" - classVars = classVars->GetNext(); // "roll" - classVars = classVars->GetNext(); // "energyLevel" - classVars = classVars->GetNext(); // "shieldLevel" - classVars = classVars->GetNext(); // "temperature" - classVars = classVars->GetNext(); // "altitude" - classVars = classVars->GetNext(); // "lifeTime" - classVars = classVars->GetNext(); // "material" - classVars = classVars->GetNext(); // "energyCell" - classVars = classVars->GetNext(); // "load" - classVars = classVars->GetNext(); // "id" - int rank = classVars->GetValInt(); - CObject* obj = CObjectManager::GetInstancePointer()->SearchInstance(rank); - CAuto* automat = obj->GetAuto(); - - if ( automat != nullptr ) - result->SetValInt(automat->GetBusy()); - else - exception = ERR_WRONG_OBJ; - - return true; -} - -bool CScript::rDestroy(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception) -{ - exception = 0; - Error err; - - CBotVar* classVars = thisclass->GetItemList(); // "category" - ObjectType thisType = static_cast(classVars->GetValInt()); - classVars = classVars->GetNext(); // "position" - classVars = classVars->GetNext(); // "orientation" - classVars = classVars->GetNext(); // "pitch" - classVars = classVars->GetNext(); // "roll" - classVars = classVars->GetNext(); // "energyLevel" - classVars = classVars->GetNext(); // "shieldLevel" - classVars = classVars->GetNext(); // "temperature" - classVars = classVars->GetNext(); // "altitude" - classVars = classVars->GetNext(); // "lifeTime" - classVars = classVars->GetNext(); // "material" - classVars = classVars->GetNext(); // "energyCell" - classVars = classVars->GetNext(); // "load" - classVars = classVars->GetNext(); // "id" - int rank = classVars->GetValInt(); - CObject* obj = CObjectManager::GetInstancePointer()->SearchInstance(rank); - CAuto* automat = obj->GetAuto(); - - if ( thisType == OBJECT_DESTROYER ) - { - err = automat->StartAction(0); - } else - err = ERR_WRONG_OBJ; - - if ( err != ERR_OK ) - { - result->SetValInt(err); // return error -//TODO: if ( script->m_errMode == ERM_STOP ) - if( true ) - { - exception = err; - return false; - } - return true; - } - - return true; -} - - -// Compilation of instruction "object.factory(cat, program)" - -CBotTypResult CScript::cFactory(CBotVar* thisclass, CBotVar* &var) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != 0 ) - { - if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - } - return CBotTypResult(CBotTypFloat); -} - -// Instruction "object.factory(cat, program)" - -bool CScript::rFactory(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception) -{ - Error err; - - exception = 0; - - ObjectType type = static_cast(var->GetValInt()); - var = var->GetNext(); - CBotString cbs; - const char* program; - if ( var != 0 ) - { - cbs = var->GetValString(); - program = cbs; - } - else - program = ""; - - CBotVar* classVars = thisclass->GetItemList(); // "category" - ObjectType thisType = static_cast(classVars->GetValInt()); - classVars = classVars->GetNext(); // "position" - classVars = classVars->GetNext(); // "orientation" - classVars = classVars->GetNext(); // "pitch" - classVars = classVars->GetNext(); // "roll" - classVars = classVars->GetNext(); // "energyLevel" - classVars = classVars->GetNext(); // "shieldLevel" - classVars = classVars->GetNext(); // "temperature" - classVars = classVars->GetNext(); // "altitude" - classVars = classVars->GetNext(); // "lifeTime" - classVars = classVars->GetNext(); // "material" - classVars = classVars->GetNext(); // "energyCell" - classVars = classVars->GetNext(); // "load" - classVars = classVars->GetNext(); // "id" - int rank = classVars->GetValInt(); - CObject* factory = CObjectManager::GetInstancePointer()->SearchInstance(rank); - if (factory == nullptr) { - exception = ERR_GENERIC; - result->SetValInt(ERR_GENERIC); - CLogger::GetInstancePointer()->Error("in object.factory() - factory is nullptr"); - return false; - } - - if ( thisType == OBJECT_FACTORY ) - { - CAutoFactory* automat = static_cast(factory->GetAuto()); - if(automat == nullptr) { - exception = ERR_GENERIC; - result->SetValInt(ERR_GENERIC); - CLogger::GetInstancePointer()->Error("in object.factory() - automat is nullptr"); - return false; - } - - bool bEnable = false; - - if ( type == OBJECT_MOBILEwa ) - { - bEnable = true; - } - if ( type == OBJECT_MOBILEta ) - { - bEnable = g_researchDone&RESEARCH_TANK; - } - if ( type == OBJECT_MOBILEfa ) - { - bEnable = g_researchDone&RESEARCH_FLY; - } - if ( type == OBJECT_MOBILEia ) - { - bEnable = g_researchDone&RESEARCH_iPAW; - } - - if ( type == OBJECT_MOBILEws ) - { - bEnable = g_researchDone&RESEARCH_SNIFFER; - } - if ( type == OBJECT_MOBILEts ) - { - bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && - (g_researchDone&RESEARCH_TANK) ); - } - if ( type == OBJECT_MOBILEfs ) - { - bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && - (g_researchDone&RESEARCH_FLY) ); - } - if ( type == OBJECT_MOBILEis ) - { - bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && - (g_researchDone&RESEARCH_iPAW) ); - } - - if ( type == OBJECT_MOBILEwc ) - { - bEnable = g_researchDone&RESEARCH_CANON; - } - if ( type == OBJECT_MOBILEtc ) - { - bEnable = ( (g_researchDone&RESEARCH_CANON) && - (g_researchDone&RESEARCH_TANK) ); - } - if ( type == OBJECT_MOBILEfc ) - { - bEnable = ( (g_researchDone&RESEARCH_CANON) && - (g_researchDone&RESEARCH_FLY) ); - } - if ( type == OBJECT_MOBILEic ) - { - bEnable = ( (g_researchDone&RESEARCH_CANON) && - (g_researchDone&RESEARCH_iPAW) ); - } - - if ( type == OBJECT_MOBILEwi ) - { - bEnable = g_researchDone&RESEARCH_iGUN; - } - if ( type == OBJECT_MOBILEti ) - { - bEnable = ( (g_researchDone&RESEARCH_iGUN) && - (g_researchDone&RESEARCH_TANK) ); - } - if ( type == OBJECT_MOBILEfi ) - { - bEnable = ( (g_researchDone&RESEARCH_iGUN) && - (g_researchDone&RESEARCH_FLY) ); - } - if ( type == OBJECT_MOBILEii ) - { - bEnable = ( (g_researchDone&RESEARCH_iGUN) && - (g_researchDone&RESEARCH_iPAW) ); - } - - if ( type == OBJECT_MOBILErt ) - { - bEnable = ( (g_researchDone&RESEARCH_THUMP) && - (g_researchDone&RESEARCH_TANK) ); - } - if ( type == OBJECT_MOBILErc ) - { - bEnable = ( (g_researchDone&RESEARCH_PHAZER) && - (g_researchDone&RESEARCH_TANK) ); - } - if ( type == OBJECT_MOBILErr ) - { - bEnable = ( (g_researchDone&RESEARCH_RECYCLER) && - (g_researchDone&RESEARCH_TANK) ); - } - if ( type == OBJECT_MOBILErs ) - { - bEnable = ( (g_researchDone&RESEARCH_SHIELD) && - (g_researchDone&RESEARCH_TANK) ); - } - - if ( type == OBJECT_MOBILEsa ) - { - bEnable = g_researchDone&RESEARCH_SUBM; - } - - if ( bEnable ) - { - if ( automat != nullptr ) - { - err = automat->StartAction(type); - if ( err == ERR_OK ) automat->SetProgram(program); - } - else - err = ERR_GENERIC; - } - else - err = ERR_BUILD_DISABLED; - } - else - err = ERR_WRONG_OBJ; - - if ( err != ERR_OK ) - { - result->SetValInt(err); // return error -//TODO: if ( script->m_errMode == ERM_STOP ) - if( true ) - { - exception = err; - return false; - } - return true; - } - - return true; -} - -// Instruction "object.research(type)" - -bool CScript::rResearch(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception) -{ - Error err; - - exception = 0; - - ResearchType type = static_cast(var->GetValInt()); - - CBotVar* classVars = thisclass->GetItemList(); // "category" - ObjectType thisType = static_cast(classVars->GetValInt()); - classVars = classVars->GetNext(); // "position" - classVars = classVars->GetNext(); // "orientation" - classVars = classVars->GetNext(); // "pitch" - classVars = classVars->GetNext(); // "roll" - classVars = classVars->GetNext(); // "energyLevel" - classVars = classVars->GetNext(); // "shieldLevel" - classVars = classVars->GetNext(); // "temperature" - classVars = classVars->GetNext(); // "altitude" - classVars = classVars->GetNext(); // "lifeTime" - classVars = classVars->GetNext(); // "material" - classVars = classVars->GetNext(); // "energyCell" - classVars = classVars->GetNext(); // "load" - classVars = classVars->GetNext(); // "id" - int rank = classVars->GetValInt(); - CObject* center = CObjectManager::GetInstancePointer()->SearchInstance(rank); - CAuto* automat = center->GetAuto(); - - if ( thisType == OBJECT_RESEARCH || - thisType == OBJECT_LABO ) - { - bool ok = false; - if ( type == RESEARCH_iPAW || - type == RESEARCH_iGUN ) - { - if ( thisType != OBJECT_LABO ) - err = ERR_WRONG_OBJ; - else - ok = true; - } - else - { - if ( thisType != OBJECT_RESEARCH ) - err = ERR_WRONG_OBJ; - else - ok = true; - } - if ( ok ) - { - bool bEnable = ( g_researchEnable & type ); - if ( bEnable ) - { - if ( automat != nullptr ) - { - err = automat->StartAction(type); - } - else - err = ERR_GENERIC; - } - else - err = ERR_BUILD_DISABLED; - } - } - else - err = ERR_WRONG_OBJ; - - if ( err != ERR_OK ) - { - result->SetValInt(err); // return error -//TODO: if ( script->m_errMode == ERM_STOP ) - if( true ) - { - exception = err; - return false; - } - return true; - } - - return true; -} - -// Instruction "object.takeoff()" - -bool CScript::rTakeOff(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception) -{ - Error err; - - exception = 0; - - CBotVar* classVars = thisclass->GetItemList(); // "category" - ObjectType thisType = static_cast(classVars->GetValInt()); - classVars = classVars->GetNext(); // "position" - classVars = classVars->GetNext(); // "orientation" - classVars = classVars->GetNext(); // "pitch" - classVars = classVars->GetNext(); // "roll" - classVars = classVars->GetNext(); // "energyLevel" - classVars = classVars->GetNext(); // "shieldLevel" - classVars = classVars->GetNext(); // "temperature" - classVars = classVars->GetNext(); // "altitude" - classVars = classVars->GetNext(); // "lifeTime" - classVars = classVars->GetNext(); // "material" - classVars = classVars->GetNext(); // "energyCell" - classVars = classVars->GetNext(); // "load" - classVars = classVars->GetNext(); // "id" - int rank = classVars->GetValInt(); - CObject* center = CObjectManager::GetInstancePointer()->SearchInstance(rank); - CAuto* automat = center->GetAuto(); - - if ( thisType == OBJECT_BASE ) - { - err = (static_cast(automat))->TakeOff(false); - } else - err = ERR_WRONG_OBJ; - - if ( err != ERR_OK ) - { - result->SetValInt(err); // return error -//TODO: if ( script->m_errMode == ERM_STOP ) - if( true ) - { - exception = err; - return false; - } - return true; - } - - return true; -} - -// Compilation of the instruction "delete(rank[, exploType[, force]])". - -CBotTypResult CScript::cDelete(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != 0 ) - { - if ( var->GetType() != CBotTypInt ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != 0 ) - { - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - } - } - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "delete(rank[, exploType[, force]])". - -bool CScript::rDelete(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CObject* pObj; - int rank; - int exploType = 0; - float force = 1.0f; - - rank = var->GetValInt(); - var->GetNext(); - if ( var != 0 ) - { - exploType = var->GetValInt(); - var->GetNext(); - if ( var != 0 ) - { - force = var->GetValFloat(); - } - } - - pObj = static_cast(CObjectManager::GetInstancePointer()->SearchInstance(rank)); - if ( pObj == 0 ) - { - return true; - } - else - { - if ( exploType ) - { - pObj->ExploObject(static_cast(exploType), force); - } - else - { - pObj->DeleteObject(false); - } - } - return true; -} - - - -// Compilation of the instruction "search(type, pos)". - -CBotTypResult CScript::cSearch(CBotVar* &var, void* user) -{ - CBotVar* array; - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() == CBotTypArrayPointer ) - { - array = var->GetItemList(); - if ( array == 0 ) return CBotTypResult(CBotTypPointer); - if ( array->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - } - else if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != 0 ) - { - ret = cPoint(var, user); - if ( ret.GetType() != 0 ) return ret; - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - } - - return CBotTypResult(CBotTypPointer, "object"); -} - -// Instruction "search(type, pos)". - -bool CScript::rSearch(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CObject *pObj, *pBest; - CBotVar* array; - Math::Vector pos, oPos; - bool bNearest = false; - bool bArray; - float min, dist; - int type, oType, i; - - if ( var->GetType() == CBotTypArrayPointer ) - { - array = var->GetItemList(); - bArray = true; - } - else - { - type = var->GetValInt(); - bArray = false; - } - var = var->GetNext(); - if ( var != 0 ) - { - if ( !GetPoint(var, exception, pos) ) return true; - bNearest = true; - } - - CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); - - min = 100000.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = static_cast(iMan->SearchInstance(CLASS_OBJECT, i)); - if ( pObj == 0 ) break; - - if ( pObj->GetTruck() != 0 ) continue; // object transported? - if ( !pObj->GetActif() ) continue; - - oType = pObj->GetType(); - if ( oType == OBJECT_TOTO ) continue; - - if ( oType == OBJECT_RUINmobilew2 || - oType == OBJECT_RUINmobilet1 || - oType == OBJECT_RUINmobilet2 || - oType == OBJECT_RUINmobiler1 || - oType == OBJECT_RUINmobiler2 ) - { - oType = OBJECT_RUINmobilew1; // any ruin - } - - if ( oType == OBJECT_SCRAP2 || - oType == OBJECT_SCRAP3 || - oType == OBJECT_SCRAP4 || - oType == OBJECT_SCRAP5 ) // wastes? - { - oType = OBJECT_SCRAP1; // any waste - } - - if ( oType == OBJECT_BARRIER2 || - oType == OBJECT_BARRIER3 ) // barriers? - { - oType = OBJECT_BARRIER1; // any barrier - } - - if ( bArray ) - { - if ( !FindList(array, oType) ) continue; - } - else - { - if ( type != oType && type != OBJECT_NULL ) continue; - } - - if ( bNearest ) - { - oPos = pObj->GetPosition(0); - dist = Math::DistanceProjected(pos, oPos); - if ( dist < min ) - { - min = dist; - pBest = pObj; - } - } - else - { - pBest = pObj; - break; - } - } - - if ( pBest == 0 ) - { - result->SetPointer(0); - } - else - { - result->SetPointer(pBest->GetBotVar()); - } - return true; -} - - -// Compilation of instruction "radar(type, angle, focus, min, max, sens)". - -CBotTypResult CScript::cRadar(CBotVar* &var, void* user) -{ - CBotVar* array; - - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GetType() == CBotTypArrayPointer ) - { - array = var->GetItemList(); - if ( array == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( array->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type - } - else if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type - var = var->GetNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // angle - var = var->GetNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // focus - var = var->GetNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // min - var = var->GetNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // max - var = var->GetNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // sense - var = var->GetNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // filter - var = var->GetNext(); - if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - return CBotTypResult(CBotErrOverParam); -} - -// Instruction "radar(type, angle, focus, min, max, sens, filter)". - -bool CScript::rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CObject* pThis = static_cast(user); - CObject *pObj, *pBest; - CPhysics* physics; - CBotVar* array; - Math::Vector iPos, oPos; - RadarFilter filter; - float best, minDist, maxDist, sens, iAngle, angle, focus, d, a; - int type, oType, i; - bool bArray = false; - - type = OBJECT_NULL; - array = 0; - angle = 0.0f; - focus = Math::PI*2.0f; - minDist = 0.0f*g_unit; - maxDist = 1000.0f*g_unit; - sens = 1.0f; - filter = FILTER_NONE; - - if ( var != 0 ) - { - if ( var->GetType() == CBotTypArrayPointer ) - { - array = var->GetItemList(); - bArray = true; - } - else - { - type = var->GetValInt(); - bArray = false; - } - - var = var->GetNext(); - if ( var != 0 ) - { - angle = -var->GetValFloat()*Math::PI/180.0f; - - var = var->GetNext(); - if ( var != 0 ) - { - focus = var->GetValFloat()*Math::PI/180.0f; - - var = var->GetNext(); - if ( var != 0 ) - { - minDist = var->GetValFloat()*g_unit; - - var = var->GetNext(); - if ( var != 0 ) - { - maxDist = var->GetValFloat()*g_unit; - - var = var->GetNext(); - if ( var != 0 ) - { - sens = var->GetValFloat(); - - var = var->GetNext(); - if ( var != 0 ) - { - filter = static_cast(var->GetValInt()); - } - } - } - } - } - } - } - - iPos = pThis->GetPosition(0); - iAngle = pThis->GetAngleY(0)+angle; - iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI - - CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); - - if ( sens >= 0.0f ) best = 100000.0f; - else best = 0.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = static_cast(iMan->SearchInstance(CLASS_OBJECT, i)); - if ( pObj == 0 ) break; - if ( pObj == pThis ) continue; - - if ( pObj->GetTruck() != 0 ) continue; // object transported? - if ( !pObj->GetActif() ) continue; - if ( pObj->GetProxyActivate() ) continue; - - oType = pObj->GetType(); - if ( oType == OBJECT_TOTO || oType == OBJECT_CONTROLLER ) continue; - - if ( oType == OBJECT_RUINmobilew2 || - oType == OBJECT_RUINmobilet1 || - oType == OBJECT_RUINmobilet2 || - oType == OBJECT_RUINmobiler1 || - oType == OBJECT_RUINmobiler2 ) - { - oType = OBJECT_RUINmobilew1; // any ruin - } - - if ( oType == OBJECT_SCRAP2 || - oType == OBJECT_SCRAP3 || - oType == OBJECT_SCRAP4 || - oType == OBJECT_SCRAP5 ) // wastes? - { - oType = OBJECT_SCRAP1; // any waste - } - - if ( oType == OBJECT_BARRIER2 || - oType == OBJECT_BARRIER3 ) // barriers? - { - oType = OBJECT_BARRIER1; // any barrier - } - - if ( filter == FILTER_ONLYLANDING ) - { - physics = pObj->GetPhysics(); - if ( physics != 0 && !physics->GetLand() ) continue; - } - if ( filter == FILTER_ONLYFLYING ) - { - physics = pObj->GetPhysics(); - if ( physics != 0 && physics->GetLand() ) continue; - } - - if ( bArray ) - { - if ( !FindList(array, oType) ) continue; - } - else - { - if ( type != oType && type != OBJECT_NULL ) continue; - } - - oPos = pObj->GetPosition(0); - d = Math::DistanceProjected(iPos, oPos); - if ( d < minDist || d > maxDist ) continue; // too close or too far? - - if ( focus >= Math::PI*2.0f ) - { - if ( (sens >= 0.0f && d < best) || - (sens < 0.0f && d > best) ) - { - best = d; - pBest = pObj; - } - continue; - } - - a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - //TODO uninitialized variable - if ( Math::TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) ) - { - if ( (sens >= 0.0f && d < best) || - (sens < 0.0f && d > best) ) - { - best = d; - pBest = pObj; - } - } - } - - if ( pBest == 0 ) - { - result->SetPointer(0); - } - else - { - result->SetPointer(pBest->GetBotVar()); - } - return true; -} - - -// Monitoring a task. - -bool CScript::Process(CScript* script, CBotVar* result, int &exception) -{ - Error err; - - err = script->m_primaryTask->IsEnded(); - if ( err != ERR_CONTINUE ) // task terminated? - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - - script->m_bContinue = false; - - if ( err == ERR_STOP ) err = ERR_OK; - result->SetValInt(err); // indicates the error or ok - if ( ShouldProcessStop(err, script->m_errMode) ) - { - exception = err; - return false; - } - return true; // it's all over - } - - script->m_primaryTask->EventProcess(script->m_event); - script->m_bContinue = true; - return false; // not done -} - - -// Returns true if error code means real error and exception must be thrown - -bool CScript::ShouldProcessStop(Error err, int errMode) -{ - // aim impossible - not a real error - if ( err == ERR_AIM_IMPOSSIBLE ) - return false; - - if ( err != ERR_OK && errMode == ERM_STOP ) - return true; - - return false; -} - - -// Compilation of the instruction "detect(type)". - -CBotTypResult CScript::cDetect(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypBoolean); -} - -// Instruction "detect(type)". - -bool CScript::rDetect(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - CObject *pObj, *pGoal, *pBest; - CPhysics* physics; - CBotVar* array; - Math::Vector iPos, oPos; - RadarFilter filter; - float bGoal, best, minDist, maxDist, sens, iAngle, angle, focus, d, a; - int type, oType, i; - bool bArray = false; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - type = OBJECT_NULL; - array = 0; - angle = 0.0f; - focus = 45.0f*Math::PI/180.0f; - minDist = 0.0f*g_unit; - maxDist = 20.0f*g_unit; - sens = 1.0f; - filter = FILTER_NONE; - - if ( var != 0 ) - { - if ( var->GetType() == CBotTypArrayPointer ) - { - array = var->GetItemList(); - bArray = true; - } - else - { - type = var->GetValInt(); - bArray = false; - } - } - - iPos = pThis->GetPosition(0); - iAngle = pThis->GetAngleY(0)+angle; - iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI - - CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); - - bGoal = 100000.0f; - pGoal = 0; - if ( sens >= 0.0f ) best = 100000.0f; - else best = 0.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = static_cast(iMan->SearchInstance(CLASS_OBJECT, i)); - if ( pObj == 0 ) break; - if ( pObj == pThis ) continue; - - if ( pObj->GetTruck() != 0 ) continue; // object transported? - if ( !pObj->GetActif() ) continue; - if ( pObj->GetProxyActivate() ) continue; - - oType = pObj->GetType(); - if ( oType == OBJECT_TOTO ) continue; - - if ( oType == OBJECT_RUINmobilew2 || - oType == OBJECT_RUINmobilet1 || - oType == OBJECT_RUINmobilet2 || - oType == OBJECT_RUINmobiler1 || - oType == OBJECT_RUINmobiler2 ) - { - oType = OBJECT_RUINmobilew1; // any ruin - } - - if ( oType == OBJECT_SCRAP2 || - oType == OBJECT_SCRAP3 || - oType == OBJECT_SCRAP4 || - oType == OBJECT_SCRAP5 ) // wastes? - { - oType = OBJECT_SCRAP1; // any waste - } - - if ( oType == OBJECT_BARRIER2 || - oType == OBJECT_BARRIER3 ) // barriers? - { - oType = OBJECT_BARRIER1; // any barrier - } - - if ( filter == FILTER_ONLYLANDING ) - { - physics = pObj->GetPhysics(); - if ( physics != 0 && !physics->GetLand() ) continue; - } - if ( filter == FILTER_ONLYFLYING ) - { - physics = pObj->GetPhysics(); - if ( physics != 0 && physics->GetLand() ) continue; - } - - if ( bArray ) - { - if ( !FindList(array, oType) ) continue; - } - else - { - if ( type != oType && type != OBJECT_NULL ) continue; - } - - oPos = pObj->GetPosition(0); - d = Math::DistanceProjected(iPos, oPos); - a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - - if ( d < bGoal && - Math::TestAngle(a, iAngle-(5.0f*Math::PI/180.0f)/2.0f, iAngle+(5.0f*Math::PI/180.0f)/2.0f) ) - { - bGoal = d; - pGoal = pObj; - } - - if ( d < minDist || d > maxDist ) continue; // too close or too far? - - if ( focus >= Math::PI*2.0f ) - { - if ( (sens >= 0.0f && d < best) || - (sens < 0.0f && d > best) ) - { - best = d; - pBest = pObj; - } - continue; - } - - if ( Math::TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) ) - { - if ( (sens >= 0.0f && d < best) || - (sens < 0.0f && d > best) ) - { - best = d; - pBest = pObj; - } - } - } - - pThis->StartDetectEffect(pGoal, pBest!=0); - - if ( pBest == 0 ) - { - script->m_returnValue = 0.0f; - } - else - { - script->m_returnValue = 1.0f; - } - - script->m_primaryTask = new CTaskManager(script->m_object); - err = script->m_primaryTask->StartTaskWait(0.3f); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - if ( !Process(script, result, exception) ) return false; // not finished - result->SetValFloat(script->m_returnValue); - return true; -} - - -// Compilation of the instruction "direction(pos)". - -CBotTypResult CScript::cDirection(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = cPoint(var, user); - if ( ret.GetType() != 0 ) return ret; - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "direction(pos)". - -bool CScript::rDirection(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CObject* pThis = static_cast(user); - Math::Vector iPos, oPos; - float a, g; - - if ( !GetPoint(var, exception, oPos) ) return true; - - iPos = pThis->GetPosition(0); - - a = pThis->GetAngleY(0); - g = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - - result->SetValFloat(-Math::Direction(a, g)*180.0f/Math::PI); - return true; -} - -// compilation of instruction "canbuild ( category );" - -CBotTypResult CScript::cCanBuild(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypBoolean); -} - -// Instruction "canbuild ( category );" -// returns true if this building can be built - -bool CScript::rCanBuild(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - ObjectType category = static_cast(var->GetValInt()); //get category parameter - exception = 0; - - bool can = false; - - if ( (category == OBJECT_DERRICK && (g_build & BUILD_DERRICK)) || - (category == OBJECT_FACTORY && (g_build & BUILD_FACTORY)) || - (category == OBJECT_STATION && (g_build & BUILD_STATION)) || - (category == OBJECT_CONVERT && (g_build & BUILD_CONVERT)) || - (category == OBJECT_REPAIR && (g_build & BUILD_REPAIR)) || - (category == OBJECT_TOWER && (g_build & BUILD_TOWER)) || - (category == OBJECT_RESEARCH && (g_build & BUILD_RESEARCH)) || - (category == OBJECT_RADAR && (g_build & BUILD_RADAR)) || - (category == OBJECT_ENERGY && (g_build & BUILD_ENERGY)) || - (category == OBJECT_LABO && (g_build & BUILD_LABO)) || - (category == OBJECT_NUCLEAR && (g_build & BUILD_NUCLEAR)) || - (category == OBJECT_INFO && (g_build & BUILD_INFO)) || - (category == OBJECT_PARA && (g_build & BUILD_PARA)) || - (category == OBJECT_DESTROYER && (g_build & BUILD_DESTROYER))) - { - - // if we want to build not researched one - if ( (category == OBJECT_TOWER && !(g_researchDone & RESEARCH_TOWER)) || - (category == OBJECT_NUCLEAR && !(g_researchDone & RESEARCH_ATOMIC)) - ) - { - can = false; - } - else - { - can = true; - } - - } - - result->SetValInt(can); - - - return true; -} - -// Instruction "build(type)" -// draws error if can not build (wher errormode stop), otherwise 0 <- error - -bool CScript::rBuild(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - ObjectType oType; - ObjectType category; - Error err = ERR_BUILD_DISABLED; - - exception = 0; - - oType = pThis->GetType(); - - if ( oType != OBJECT_MOBILEfa && // allowed only for grabber bots - oType != OBJECT_MOBILEta && - oType != OBJECT_MOBILEwa && - oType != OBJECT_MOBILEia) - { - err = ERR_MANIP_VEH; //Wrong vehicle; - } - else - { - category = static_cast(var->GetValInt()); // get category parameter - if ( (category == OBJECT_DERRICK && (g_build & BUILD_DERRICK)) || - (category == OBJECT_FACTORY && (g_build & BUILD_FACTORY)) || - (category == OBJECT_STATION && (g_build & BUILD_STATION)) || - (category == OBJECT_CONVERT && (g_build & BUILD_CONVERT)) || - (category == OBJECT_REPAIR && (g_build & BUILD_REPAIR)) || - (category == OBJECT_TOWER && (g_build & BUILD_TOWER)) || - (category == OBJECT_RESEARCH && (g_build & BUILD_RESEARCH)) || - (category == OBJECT_RADAR && (g_build & BUILD_RADAR)) || - (category == OBJECT_ENERGY && (g_build & BUILD_ENERGY)) || - (category == OBJECT_LABO && (g_build & BUILD_LABO)) || - (category == OBJECT_NUCLEAR && (g_build & BUILD_NUCLEAR)) || - (category == OBJECT_INFO && (g_build & BUILD_INFO)) || - (category == OBJECT_PARA && (g_build & BUILD_PARA)) || - (category == OBJECT_DESTROYER && (g_build & BUILD_DESTROYER))) - { - - // if we want to build not researched one - if ( (category == OBJECT_TOWER && !(g_researchDone & RESEARCH_TOWER)) || - (category == OBJECT_NUCLEAR && !(g_researchDone & RESEARCH_ATOMIC)) - ) - { - err = ERR_BUILD_RESEARCH; - } - else - { - err = ERR_OK; - } - - } - - if (pThis->GetIgnoreBuildCheck()) - err = ERR_OK; - - if (err == ERR_OK && script->m_primaryTask == 0) // if we can build and no task is present - { - script->m_primaryTask = new CTaskManager(script->m_object); - err = script->m_primaryTask->StartTaskBuild(category); - - if (err != ERR_OK) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - } - } - // When script is waiting for finishing this task, it sets ERR_OK, and continues executing Process - // without creating new task. I think, there was a problem with previous version in release configuration - // It did not init error variable in this situation, and code tried to use variable with trash inside - } - - if ( err != ERR_OK ) - { - result->SetValInt(err); // return error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - - return Process(script, result, exception); - -} - -// Compilation of the instruction "produce(pos, angle, type[, scriptName[, power]])" -// or "produce(type[, power])". - -CBotTypResult CScript::cProduce(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - - if ( var->GetType() <= CBotTypDouble ) - { - var = var->GetNext(); - if( var != 0 ) - { - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - } - } - else - { - ret = cPoint(var, user); - if ( ret.GetType() != 0 ) return ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != 0 ) - { - if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GetNext(); - - if ( var != 0 ) - { - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - } - } - } - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "produce(pos, angle, type[, scriptName[, power]])" -// or "produce(type[, power])". - -bool CScript::rProduce(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* object; - CObject* me = (static_cast(user)); - CBotString cbs; - const char* name; - Math::Vector pos; - float angle; - ObjectType type; - float power; - - if ( var->GetType() <= CBotTypDouble ) - { - type = static_cast(var->GetValInt()); - var = var->GetNext(); - - pos = me->GetPosition(0); - - Math::Vector rotation = me->GetAngle(0) + me->GetInclinaison(); - angle = rotation.y; - - if( var != 0 ) - power = var->GetValFloat(); - else - power = -1.0f; - - name = ""; - } - else - { - if ( !GetPoint(var, exception, pos) ) return true; - - angle = var->GetValFloat()*Math::PI/180.0f; - var = var->GetNext(); - - type = static_cast(var->GetValInt()); - var = var->GetNext(); - - if ( var != 0 ) - { - cbs = var->GetValString(); - name = cbs; - var = var->GetNext(); - if ( var != 0 ) - { - power = var->GetValFloat(); - } - else - { - power = -1.0f; - } - } - else - { - name = ""; - power = -1.0f; - } - } - - if ( type == OBJECT_ANT || - type == OBJECT_SPIDER || - type == OBJECT_BEE || - type == OBJECT_WORM ) - { - CObject* egg; - - object = new CObject(); - if ( !object->CreateInsect(pos, angle, type) ) - { - delete object; - result->SetValInt(1); // error - return true; - } - - egg = new CObject(); - if ( !egg->CreateResource(pos, angle, OBJECT_EGG, 0.0f) ) - { - delete egg; - } - object->SetActivity(false); - } else { - if ((type == OBJECT_POWER || type == OBJECT_ATOMIC) && power == -1.0f) power = 1.0f; - object = CObjectManager::GetInstancePointer()->CreateObject(pos, angle, type, power); - if ( object == nullptr ) - { - result->SetValInt(1); // error - return true; - } - script->m_main->CreateShortcuts(); - } - - if (name[0] != 0) - { - object->ReadProgram(0, static_cast(name)); - object->RunProgram(0); - } - - result->SetValInt(0); // no error - return true; -} - - -// Compilation of the instruction "distance(p1, p2)". - -CBotTypResult CScript::cDistance(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = cPoint(var, user); - if ( ret.GetType() != 0 ) return ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = cPoint(var, user); - if ( ret.GetType() != 0 ) return ret; - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "distance(p1, p2)". - -bool CScript::rDistance(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - Math::Vector p1, p2; - float value; - - if ( !GetPoint(var, exception, p1) ) return true; - if ( !GetPoint(var, exception, p2) ) return true; - - value = Math::Distance(p1, p2); - result->SetValFloat(value/g_unit); - return true; -} - -// Instruction "distance2d(p1, p2)". - -bool CScript::rDistance2d(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - Math::Vector p1, p2; - float value; - - if ( !GetPoint(var, exception, p1) ) return true; - if ( !GetPoint(var, exception, p2) ) return true; - - value = Math::DistanceProjected(p1, p2); - result->SetValFloat(value/g_unit); - return true; -} - - -// Compilation of the instruction "space(center, rMin, rMax, dist)". - -CBotTypResult CScript::cSpace(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); - ret = cPoint(var, user); - if ( ret.GetType() != 0 ) return ret; - - if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypIntrinsic, "point"); -} - -// Instruction "space(center, rMin, rMax, dist)". - -bool CScript::rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - CBotVar* pSub; - Math::Vector center; - float rMin, rMax, dist; - - rMin = 10.0f*g_unit; - rMax = 50.0f*g_unit; - dist = 4.0f*g_unit; - - if ( var == 0 ) - { - center = pThis->GetPosition(0); - } - else - { - if ( !GetPoint(var, exception, center) ) return true; - - if ( var != 0 ) - { - rMin = var->GetValFloat()*g_unit; - var = var->GetNext(); - - if ( var != 0 ) - { - rMax = var->GetValFloat()*g_unit; - var = var->GetNext(); - - if ( var != 0 ) - { - dist = var->GetValFloat()*g_unit; - var = var->GetNext(); - } - } - } - } - script->m_main->FreeSpace(center, rMin, rMax, dist, pThis); - - if ( result != 0 ) - { - pSub = result->GetItemList(); - if ( pSub != 0 ) - { - pSub->SetValFloat(center.x/g_unit); - pSub = pSub->GetNext(); // "y" - pSub->SetValFloat(center.z/g_unit); - pSub = pSub->GetNext(); // "z" - pSub->SetValFloat(center.y/g_unit); - } - } - return true; -} - - -// Compilation of the instruction "flatground(center, rMax)". - -CBotTypResult CScript::cFlatGround(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = cPoint(var, user); - if ( ret.GetType() != 0 ) return ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "flatground(center, rMax)". - -bool CScript::rFlatGround(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - Math::Vector center; - float rMax, dist; - - if ( !GetPoint(var, exception, center) ) return true; - rMax = var->GetValFloat()*g_unit; - var = var->GetNext(); - - dist = script->m_main->GetFlatZoneRadius(center, rMax, pThis); - result->SetValFloat(dist/g_unit); - - return true; -} - - -// Instruction "wait(t)". - -bool CScript::rWait(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - float value; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_object); - value = var->GetValFloat(); - err = script->m_primaryTask->StartTaskWait(value); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); -} - -// Instruction "move(dist)". - -bool CScript::rMove(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - float value; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_object); - value = var->GetValFloat(); - err = script->m_primaryTask->StartTaskAdvance(value*g_unit); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); -} - -// Instruction "turn(angle)". - -bool CScript::rTurn(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - float value; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_object); - value = var->GetValFloat(); - err = script->m_primaryTask->StartTaskTurn(-value*Math::PI/180.0f); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); -} - -// Compilation of the instruction "goto(pos, altitude, crash, goal)". - -CBotTypResult CScript::cGoto(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = cPoint(var, user); - if ( ret.GetType() != 0 ) return ret; - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - return CBotTypResult(CBotErrOverParam); -} - -// Instruction "goto(pos, altitude, mode)". - -bool CScript::rGoto(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - Math::Vector pos; - TaskGotoGoal goal; - TaskGotoCrash crash; - float altitude; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_object); - if ( !GetPoint(var, exception, pos) ) return true; - - goal = TGG_DEFAULT; - crash = TGC_DEFAULT; - altitude = 0.0f*g_unit; - - if ( var != 0 ) - { - altitude = var->GetValFloat()*g_unit; - - var = var->GetNext(); - if ( var != 0 ) - { - goal = static_cast(var->GetValInt()); - - var = var->GetNext(); - if ( var != 0 ) - { - crash = static_cast(var->GetValInt()); - } - } - } - - err = script->m_primaryTask->StartTaskGoto(pos, altitude, goal, crash); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); -} - -// Compilation "grab/drop(oper)". - -CBotTypResult CScript::cGrabDrop(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Instruction "grab(oper)". - -bool CScript::rGrab(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - ObjectType oType; - TaskManipArm type; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_object); - if ( var == 0 ) - { - type = TMA_FFRONT; - } - else - { - type = static_cast(var->GetValInt()); - } - - oType = pThis->GetType(); - if ( oType == OBJECT_HUMAN || - oType == OBJECT_TECH ) - { - err = script->m_primaryTask->StartTaskTake(); - } - else - { - err = script->m_primaryTask->StartTaskManip(TMO_GRAB, type); - } - - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); -} - -// Instruction "drop(oper)". - -bool CScript::rDrop(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - ObjectType oType; - TaskManipArm type; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_object); - if ( var == 0 ) type = TMA_FFRONT; - else type = static_cast(var->GetValInt()); - - oType = pThis->GetType(); - if ( oType == OBJECT_HUMAN || - oType == OBJECT_TECH ) - { - err = script->m_primaryTask->StartTaskTake(); - } - else - { - err = script->m_primaryTask->StartTaskManip(TMO_DROP, type); - } - - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); -} - -// Instruction "sniff()". - -bool CScript::rSniff(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_object); - err = script->m_primaryTask->StartTaskSearch(); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); -} - -// Compilation of the instruction "receive(nom, power)". - -CBotTypResult CScript::cReceive(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Instruction "receive(nom, power)". - -bool CScript::rReceive(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - CBotString cbs; - Error err; - const char* p; - float value, power; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_object); - - cbs = var->GetValString(); - p = cbs; - var = var->GetNext(); - - power = 10.0f*g_unit; - if ( var != 0 ) - { - power = var->GetValFloat()*g_unit; - var = var->GetNext(); - } - - err = script->m_primaryTask->StartTaskInfo(static_cast(p), 0.0f, power, false); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetInit(IS_NAN); - return true; - } - } - if ( !Process(script, result, exception) ) return false; // not finished - - value = pThis->GetInfoReturn(); - if ( value == NAN ) - { - result->SetInit(IS_NAN); - } - else - { - result->SetValFloat(value); - } - return true; -} - -// Compilation of the instruction "send(nom, value, power)". - -CBotTypResult CScript::cSend(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Instruction "send(nom, value, power)". - -bool CScript::rSend(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CBotString cbs; - Error err; - const char* p; - float value, power; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_object); - - cbs = var->GetValString(); - p = cbs; - var = var->GetNext(); - - value = var->GetValFloat(); - var = var->GetNext(); - - power = 10.0f*g_unit; - if ( var != 0 ) - { - power = var->GetValFloat()*g_unit; - var = var->GetNext(); - } - - err = script->m_primaryTask->StartTaskInfo(static_cast(p), value, power, true); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); -} - -// Seeks the nearest information terminal. - -CObject* CScript::SearchInfo(CScript* script, CObject* object, float power) -{ - CObject *pObj, *pBest; - Math::Vector iPos, oPos; - ObjectType type; - float dist, min; - int i; - - iPos = object->GetPosition(0); - - CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); - - min = 100000.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = static_cast(iMan->SearchInstance(CLASS_OBJECT, i)); - if ( pObj == 0 ) break; - - type = pObj->GetType(); - if ( type != OBJECT_INFO ) continue; - - if ( !pObj->GetActif() ) continue; - - oPos = pObj->GetPosition(0); - dist = Math::Distance(oPos, iPos); - if ( dist > power ) continue; // too far? - if ( dist < min ) - { - min = dist; - pBest = pObj; - } - } - - return pBest; -} - -// Compilation of the instruction "deleteinfo(nom, power)". - -CBotTypResult CScript::cDeleteInfo(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Instruction "deleteinfo(nom, power)". - -bool CScript::rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - CObject* pInfo; - CBotString cbs; - Info info; - const char* p; - float power; - int i, total; - - exception = 0; - - cbs = var->GetValString(); - p = cbs; - var = var->GetNext(); - - power = 10.0f*g_unit; - if ( var != 0 ) - { - power = var->GetValFloat()*g_unit; - var = var->GetNext(); - } - - pInfo = SearchInfo(script, pThis, power); - if ( pInfo == 0 ) - { - result->SetValFloat(0.0f); // false - return true; - } - - total = pInfo->GetInfoTotal(); - for ( i=0 ; iGetInfo(i); - if ( strcmp(info.name, p) == 0 ) - { - pInfo->DeleteInfo(i); - result->SetValFloat(1.0f); // true - return true; - } - } - result->SetValFloat(0.0f); // false - return true; -} - -// Compilation of the instruction "testinfo(nom, power)". - -CBotTypResult CScript::cTestInfo(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypBoolean); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypBoolean); -} - -// Instruction "testinfo(nom, power)". - -bool CScript::rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - CObject* pInfo; - CBotString cbs; - Info info; - const char* p; - float power; - int i, total; - - exception = 0; - - cbs = var->GetValString(); - p = cbs; - var = var->GetNext(); - - power = 10.0f*g_unit; - if ( var != 0 ) - { - power = var->GetValFloat()*g_unit; - var = var->GetNext(); - } - - pInfo = SearchInfo(script, pThis, power); - if ( pInfo == 0 ) - { - result->SetValInt(false); - return true; - } - - total = pInfo->GetInfoTotal(); - for ( i=0 ; iGetInfo(i); - if ( strcmp(info.name, p) == 0 ) - { - result->SetValInt(true); - return true; - } - } - result->SetValInt(false); - return true; -} - -// Instruction "thump()". - -bool CScript::rThump(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_object); - err = script->m_primaryTask->StartTaskTerraform(); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); -} - -// Instruction "recycle()". - -bool CScript::rRecycle(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_object); - err = script->m_primaryTask->StartTaskRecover(); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); -} - -// Compilation "shield(oper, radius)". - -CBotTypResult CScript::cShield(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "shield(oper, radius)". - -bool CScript::rShield(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - float oper, radius; - Error err; - - oper = var->GetValFloat(); // 0=down, 1=up - var = var->GetNext(); - - radius = var->GetValFloat(); - if ( radius < 10.0f ) radius = 10.0f; - if ( radius > 25.0f ) radius = 25.0f; - radius = (radius-10.0f)/15.0f; - - if ( *script->m_secondaryTask == 0 ) // shield folds? - { - if ( oper == 0.0f ) // down? - { - result->SetValInt(1); // shows the error - } - else // up ? - { - pThis->SetParam(radius); - - *script->m_secondaryTask = new CTaskManager(script->m_object); - err = (*script->m_secondaryTask)->StartTaskShield(TSM_UP, 1000.0f); - if ( err != ERR_OK ) - { - delete *script->m_secondaryTask; - *script->m_secondaryTask = 0; - result->SetValInt(err); // shows the error - } - } - } - else // shield deployed? - { - if ( oper == 0.0f ) // down? - { - (*script->m_secondaryTask)->StartTaskShield(TSM_DOWN, 0.0f); - } - else // up? - { -//? result->SetValInt(1); // shows the error - pThis->SetParam(radius); - (*script->m_secondaryTask)->StartTaskShield(TSM_UPDATE, 0.0f); - } - } - - return true; -} - -// Compilation "fire(delay)". - -CBotTypResult CScript::cFire(CBotVar* &var, void* user) -{ - CObject* pThis = static_cast(user); - ObjectType type; - - type = pThis->GetType(); - - if ( type == OBJECT_ANT ) - { - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - CBotTypResult ret = cPoint(var, user); - if ( ret.GetType() != 0 ) return ret; - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - } - else if ( type == OBJECT_SPIDER ) - { - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - } - else - { - if ( var != 0 ) - { - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - } - } - return CBotTypResult(CBotTypFloat); -} - -// Instruction "fire(delay)". - -bool CScript::rFire(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - float delay; - Math::Vector impact; - Error err; - ObjectType type; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_object); - - type = pThis->GetType(); - - if ( type == OBJECT_ANT ) - { - if ( !GetPoint(var, exception, impact) ) return true; - impact.y += pThis->GetWaterLevel(); - err = script->m_primaryTask->StartTaskFireAnt(impact); - } - else if ( type == OBJECT_SPIDER ) - { - err = script->m_primaryTask->StartTaskSpiderExplo(); - } - else - { - if ( var == 0 ) delay = 0.0f; - else delay = var->GetValFloat(); - if ( delay < 0.0f ) delay = -delay; - err = script->m_primaryTask->StartTaskFire(delay); - } - - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - return true; - } - } - return Process(script, result, exception); -} - -// Compilation of the instruction "aim(x, y)". - -CBotTypResult CScript::cAim(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "aim(dir)". - -bool CScript::rAim(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - float x, y; - Error err; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - script->m_primaryTask = new CTaskManager(script->m_object); - x = var->GetValFloat(); - var = var->GetNext(); - var == 0 ? y=0.0f : y=var->GetValFloat(); - err = script->m_primaryTask->StartTaskGunGoal(x*Math::PI/180.0f, y*Math::PI/180.0f); - if ( err == ERR_AIM_IMPOSSIBLE ) - { - result->SetValInt(err); // shows the error - } - else if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - return true; - } - } - return Process(script, result, exception); -} - -// Compilation of the instruction "motor(left, right)". - -CBotTypResult CScript::cMotor(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(CBotTypFloat); -} - -// Instruction "motor(left, right)". - -bool CScript::rMotor(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CObject* pThis = static_cast(user); - CPhysics* physics = (static_cast(user))->GetPhysics(); - float left, right, speed, turn; - - left = var->GetValFloat(); - var = var->GetNext(); - right = var->GetValFloat(); - - speed = (left+right)/2.0f; - if ( speed < -1.0f ) speed = -1.0f; - if ( speed > 1.0f ) speed = 1.0f; - - turn = left-right; - if ( turn < -1.0f ) turn = -1.0f; - if ( turn > 1.0f ) turn = 1.0f; - - if ( pThis->GetFixed() ) // ant on the back? - { - speed = 0.0f; - turn = 0.0f; - } - - physics->SetMotorSpeedX(speed); // forward/backward - physics->SetMotorSpeedZ(turn); // turns - - return true; -} - -// Instruction "jet(power)". - -bool CScript::rJet(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CPhysics* physics = (static_cast(user))->GetPhysics(); - float value; - - value = var->GetValFloat(); - if( value > 1.0f ) value = 1.0f; - - physics->SetMotorSpeedY(value); - - return true; -} - -// Compilation of the instruction "topo(pos)". - -CBotTypResult CScript::cTopo(CBotVar* &var, void* user) -{ - CBotTypResult ret; - - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = CScript::cPoint(var, user); - if ( ret.GetType() != 0 ) return ret; - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - return CBotTypResult(CBotErrOverParam); -} - -// Instruction "topo(pos)". - -bool CScript::rTopo(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - Math::Vector pos; - float level; - - exception = 0; - - if ( !GetPoint(var, exception, pos) ) return true; - - level = script->m_terrain->GetFloorLevel(pos); - level -= script->m_water->GetLevel(); - result->SetValFloat(level/g_unit); - return true; -} - -// Compilation of the instruction "message(string, type)". - -CBotTypResult CScript::cMessage(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() != CBotTypString && - var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - return CBotTypResult(CBotErrOverParam); -} - -// Instruction "message(string, type)". - -bool CScript::rMessage(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CBotString cbs; - const char* p; - Ui::TextType type; - - cbs = var->GetValString(); - p = cbs; - - type = Ui::TT_MESSAGE; - var = var->GetNext(); - if ( var != 0 ) - { - type = static_cast(var->GetValInt()); - } - - script->m_main->GetDisplayText()->DisplayText(p, script->m_object, 10.0f, type); - script->m_main->CheckEndMessage(p); - - return true; -} - -// Instruction "cmdline(rank)". - -bool CScript::rCmdline(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CObject* pThis = static_cast(user); - float value; - int rank; - - rank = var->GetValInt(); - value = pThis->GetCmdLine(rank); - result->SetValFloat(value); - - return true; -} - -// Instruction "ismovie()". - -bool CScript::rIsMovie(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - float value; - - value = script->m_main->GetMovieLock()?1.0f:0.0f; - result->SetValFloat(value); - - return true; -} - -// Instruction "errmode(mode)". - -bool CScript::rErrMode(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - int value; - - value = var->GetValInt(); - if ( value < 0 ) value = 0; - if ( value > 1 ) value = 1; - script->m_errMode = value; - - return true; -} - -// Instruction "ipf(num)". - -bool CScript::rIPF(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - int value; - - value = var->GetValInt(); - if ( value < 1 ) value = 1; - if ( value > 10000 ) value = 10000; - script->m_ipf = value; - - return true; -} - -// Instruction "abstime()". - -bool CScript::rAbsTime(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - float value; - - value = script->m_main->GetGameTime(); - result->SetValFloat(value); - return true; -} - - -// Prepares a file name. - -void PrepareFilename(CBotString &filename, const char *dir) -{ - int pos; - - pos = filename.ReverseFind('\\'); - if ( pos > 0 ) - { - filename = filename.Mid(pos+1); // removes folders - } - - pos = filename.ReverseFind('/'); - if ( pos > 0 ) - { - filename = filename.Mid(pos+1); // also those with / - } - - pos = filename.ReverseFind(':'); - if ( pos > 0 ) - { - filename = filename.Mid(pos+1); // also removes the drive letter C: - } - - filename = CBotString(dir) + CBotString("\\") + filename; -} - -// Instruction "deletefile(filename)". - -bool CScript::rDeleteFile(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CBotString cbs; - const char* filename; - const char* dir; - - cbs = var->GetValString(); - dir = script->m_main->GetFilesDir(); - PrepareFilename(cbs, dir); - filename = cbs; - //std function that removes file. - return (!remove(filename)); -} - -// Compilation of the instruction "pendown(color, width)". - -CBotTypResult CScript::cPenDown(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - return CBotTypResult(CBotErrOverParam); -} - -// Instruction "pendown(color, width)". - -bool CScript::rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - int color; - float width; - Error err; - - if ( pThis->GetType() == OBJECT_MOBILEdr ) - { - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - if ( var != 0 ) - { - color = var->GetValInt(); - if ( color < 0 ) color = 0; - if ( color > 17 ) color = 17; - pThis->SetTraceColor(color); - - var = var->GetNext(); - if ( var != 0 ) - { - width = var->GetValFloat(); - if ( width < 0.1f ) width = 0.1f; - if ( width > 1.0f ) width = 1.0f; - pThis->SetTraceWidth(width); - } - } - pThis->SetTraceDown(true); - - script->m_primaryTask = new CTaskManager(script->m_object); - err = script->m_primaryTask->StartTaskPen(pThis->GetTraceDown(), pThis->GetTraceColor()); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); - } - else - { - if ( var != 0 ) - { - color = var->GetValInt(); - if ( color < 0 ) color = 0; - if ( color > 17 ) color = 17; - pThis->SetTraceColor(color); - - var = var->GetNext(); - if ( var != 0 ) - { - width = var->GetValFloat(); - if ( width < 0.1f ) width = 0.1f; - if ( width > 1.0f ) width = 1.0f; - pThis->SetTraceWidth(width); - } - } - pThis->SetTraceDown(true); - - return true; - } -} - -// Instruction "penup()". - -bool CScript::rPenUp(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - Error err; - - if ( pThis->GetType() == OBJECT_MOBILEdr ) - { - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - pThis->SetTraceDown(false); - - script->m_primaryTask = new CTaskManager(script->m_object); - err = script->m_primaryTask->StartTaskPen(pThis->GetTraceDown(), pThis->GetTraceColor()); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); - } - else - { - pThis->SetTraceDown(false); - return true; - } -} - -// Instruction "pencolor()". - -bool CScript::rPenColor(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - int color; - Error err; - - if ( pThis->GetType() == OBJECT_MOBILEdr ) - { - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - color = var->GetValInt(); - if ( color < 0 ) color = 0; - if ( color > 17 ) color = 17; - pThis->SetTraceColor(color); - - script->m_primaryTask = new CTaskManager(script->m_object); - err = script->m_primaryTask->StartTaskPen(pThis->GetTraceDown(), pThis->GetTraceColor()); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); - } - else - { - color = var->GetValInt(); - if ( color < 0 ) color = 0; - if ( color > 17 ) color = 17; - pThis->SetTraceColor(color); - - return true; - } -} - -// Instruction "penwidth()". - -bool CScript::rPenWidth(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CObject* pThis = static_cast(user); - float width; - - width = var->GetValFloat(); - if ( width < 0.1f ) width = 0.1f; - if ( width > 1.0f ) width = 1.0f; - pThis->SetTraceWidth(width); - return true; -} - -// Compilation of the instruction with one object parameter - -CBotTypResult CScript::cOneObject(CBotVar* &var, void* user) -{ - if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - var = var->GetNext(); - if ( var == 0 ) return CBotTypResult(CBotTypFloat); - - return CBotTypResult(CBotErrOverParam); -} - -// Instruction "camerafocus(object)". - -bool CScript::rCameraFocus(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast(user))->GetRunScript(); - - CBotVar* classVars = var->GetItemList(); // "category" - classVars = classVars->GetNext(); // "position" - classVars = classVars->GetNext(); // "orientation" - classVars = classVars->GetNext(); // "pitch" - classVars = classVars->GetNext(); // "roll" - classVars = classVars->GetNext(); // "energyLevel" - classVars = classVars->GetNext(); // "shieldLevel" - classVars = classVars->GetNext(); // "temperature" - classVars = classVars->GetNext(); // "altitude" - classVars = classVars->GetNext(); // "lifeTime" - classVars = classVars->GetNext(); // "material" - classVars = classVars->GetNext(); // "energyCell" - classVars = classVars->GetNext(); // "load" - classVars = classVars->GetNext(); // "id" - int rank = classVars->GetValInt(); - CObject* object = CObjectManager::GetInstancePointer()->SearchInstance(rank); - - script->m_main->SelectObject(object, false); - - result->SetValInt(ERR_OK); - exception = ERR_OK; - return true; -} - -// Static variables - -int CScript::m_CompteurFileOpen = 0; -std::string CScript::m_filesDir; - - - -// Prepares a file name. - -void PrepareFilename(CBotString &filename) -{ - int pos = filename.ReverseFind('/'); - if ( pos > 0 ) - { - filename = filename.Mid(pos+1); // Remove files with / - } - - pos = filename.ReverseFind(':'); - if ( pos > 0 ) - { - filename = filename.Mid(pos+1); // also removes the drive letter C: - } - - filename = CBotString(CScript::m_filesDir.c_str()) + CBotString("/") + filename; - CLogger::GetInstancePointer()->Debug("CBot accessing file '%s'\n", static_cast(filename)); -} - - -// constructor of the class -// get the filename as a parameter - -// execution -bool CScript::rfconstruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - CBotString mode; - - // accepts no parameters - if ( pVar == NULL ) return true; - - // must be a character string - if ( pVar->GetType() != CBotTypString ) { Exception = CBotErrBadString; return false; } - - CBotString filename = pVar->GetValString(); - PrepareFilename(filename); - - // there may be a second parameter - pVar = pVar->GetNext(); - if ( pVar != NULL ) - { - // recover mode - mode = pVar->GetValString(); - if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return false; } - - // no third parameter - if ( pVar->GetNext() != NULL ) { Exception = CBotErrOverParam; return false; } - } - - // saves the file name - pVar = pThis->GetItem("filename"); - pVar->SetValString(filename); - - if ( ! mode.IsEmpty() ) - { - // opens the requested file - FILE* pFile = fopen( filename, mode ); - if ( pFile == NULL ) { Exception = CBotErrFileOpen; return false; } - - m_CompteurFileOpen ++; - - // save the file handle - pVar = pThis->GetItem("handle"); - pVar->SetValInt(reinterpret_cast(pFile)); - } - - return true; -} - -// compilation -CBotTypResult CScript::cfconstruct (CBotVar* pThis, CBotVar* &pVar) -{ - // accepts no parameters - if ( pVar == NULL ) return CBotTypResult( 0 ); - - // must be a character string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( CBotErrBadString ); - - // there may be a second parameter - pVar = pVar->GetNext(); - if ( pVar != NULL ) - { - // which must be a string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( CBotErrBadString ); - // no third parameter - if ( pVar->GetNext() != NULL ) return CBotTypResult( CBotErrOverParam ); - } - - // the result is void (constructor) - return CBotTypResult( 0 ); -} - - -// destructor of the class - -// execution -bool CScript::rfdestruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - // retrieve the item "handle" - pVar = pThis->GetItem("handle"); - - // don't open? no problem :) - if ( pVar->GetInit() != IS_DEF) return true; - - FILE* pFile= reinterpret_cast(pVar->GetValInt()); - fclose(pFile); - m_CompteurFileOpen --; - - pVar->SetInit(IS_NAN); - - return true; -} - - -// process FILE :: open -// get the r/w mode as a parameter - -// execution -bool CScript::rfopen (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - // there must be a parameter - if ( pVar == NULL ) { Exception = CBotErrLowParam; return false; } - - // which must be a character string - if ( pVar->GetType() != CBotTypString ) { Exception = CBotErrBadString; return false; } - - // There may be a second parameter - if ( pVar->GetNext() != NULL ) - { - // if the first parameter is the file name - CBotString filename = pVar->GetValString(); - PrepareFilename(filename); - - // saves the file name - CBotVar* pVar2 = pThis->GetItem("filename"); - pVar2->SetValString(filename); - - // next parameter is the mode - pVar = pVar -> GetNext(); - } - - CBotString mode = pVar->GetValString(); - if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return false; } - - // no third parameter - if ( pVar->GetNext() != NULL ) { Exception = CBotErrOverParam; return false; } - - // retrieve the item "handle" - pVar = pThis->GetItem("handle"); - - // which must not be initialized - if ( pVar->GetInit() == IS_DEF) { Exception = CBotErrFileOpen; return false; } - - // file contains the name - pVar = pThis->GetItem("filename"); - CBotString filename = pVar->GetValString(); - - PrepareFilename(filename); // if the name was h.filename attribute = "..."; - - // opens the requested file - FILE* pFile = fopen( filename, mode ); - if ( pFile == NULL ) - { - pResult->SetValInt(false); - return true; - } - - m_CompteurFileOpen ++; - - // save file handle - pVar = pThis->GetItem("handle"); - pVar->SetValInt(reinterpret_cast(pFile)); - - pResult->SetValInt(true); - return true; -} - -// compilation -CBotTypResult CScript::cfopen (CBotVar* pThis, CBotVar* &pVar) -{ - // there must be a parameter - if ( pVar == NULL ) return CBotTypResult( CBotErrLowParam ); - - // which must be a string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( CBotErrBadString ); - - // there may be a second parameter - pVar = pVar->GetNext(); - if ( pVar != NULL ) - { - // which must be a string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( CBotErrBadString ); - - // no third parameter - if ( pVar->GetNext() != NULL ) return CBotTypResult( CBotErrOverParam ); - } - - // the result is bool - return CBotTypResult(CBotTypBoolean); -} - - -// process FILE :: close - -// execeution -bool CScript::rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - // it shouldn't be any parameters - if ( pVar != NULL ) return CBotErrOverParam; - - // retrieve the item "handle" - pVar = pThis->GetItem("handle"); - - if ( pVar->GetInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; } - - FILE* pFile= reinterpret_cast(pVar->GetValInt()); - fclose(pFile); - m_CompteurFileOpen --; - - pVar->SetInit(IS_NAN); - - return true; -} - -// compilation -CBotTypResult CScript::cfclose (CBotVar* pThis, CBotVar* &pVar) -{ - // it shouldn't be any parameters - if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam ); - - // function returns a result "void" - return CBotTypResult( 0 ); -} - -// process FILE :: writeln - -// execution -bool CScript::rfwrite (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - // there must be a parameter - if ( pVar == NULL ) { Exception = CBotErrLowParam; return false; } - - // which must be a character string - if ( pVar->GetType() != CBotTypString ) { Exception = CBotErrBadString; return false; } - - CBotString param = pVar->GetValString(); - - // retrieve the item "handle" - pVar = pThis->GetItem("handle"); - - if ( pVar->GetInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; } - - FILE* pFile= reinterpret_cast(pVar->GetValInt()); - - int res = fputs(param+CBotString("\n"), pFile); - - // if an error occurs generate an exception - if ( res < 0 ) { Exception = CBotErrWrite; return false; } - - return true; -} - -// compilation -CBotTypResult CScript::cfwrite (CBotVar* pThis, CBotVar* &pVar) -{ - // there must be a parameter - if ( pVar == NULL ) return CBotTypResult( CBotErrLowParam ); - - // which must be a character string - if ( pVar->GetType() != CBotTypString ) return CBotTypResult( CBotErrBadString ); - - // no other parameter - if ( pVar->GetNext() != NULL ) return CBotTypResult( CBotErrOverParam ); - - // the function returns a void result - return CBotTypResult( 0 ); -} - -// process FILE :: readln - -// execution -bool CScript::rfread (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - // it shouldn't be any parameters - if ( pVar != NULL ) { Exception = CBotErrOverParam; return false; } - - // retrieve the item "handle" - pVar = pThis->GetItem("handle"); - - if ( pVar->GetInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; } - - FILE* pFile= reinterpret_cast(pVar->GetValInt()); - - char chaine[2000]; - int i; - for ( i = 0 ; i < 2000 ; i++ ) chaine[i] = 0; - - fgets(chaine, 1999, pFile); - - for ( i = 0 ; i < 2000 ; i++ ) if (chaine[i] == '\n') chaine[i] = 0; - - // if an error occurs generate an exception - if ( ferror(pFile) ) { Exception = CBotErrRead; return false; } - - pResult->SetValString( chaine ); - - return true; -} - -// compilation -CBotTypResult CScript::cfread (CBotVar* pThis, CBotVar* &pVar) -{ - // it should not be any parameter - if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam ); - - // function returns a result "string" - return CBotTypResult( CBotTypString ); -} -// process FILE :: readln - - -// execution -bool CScript::rfeof (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - // it should not be any parameter - if ( pVar != NULL ) { Exception = CBotErrOverParam; return false; } - - // retrieve the item "handle" - pVar = pThis->GetItem("handle"); - - if ( pVar->GetInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; } - - FILE* pFile= reinterpret_cast(pVar->GetValInt()); - - pResult->SetValInt( feof( pFile ) ); - - return true; -} - -// compilation -CBotTypResult CScript::cfeof (CBotVar* pThis, CBotVar* &pVar) -{ - // it shouldn't be any parameter - if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam ); - - // the function returns a boolean result - return CBotTypResult( CBotTypBoolean ); -} - -// Compilation of class "point". - -CBotTypResult CScript::cPointConstructor(CBotVar* pThis, CBotVar* &var) -{ - if ( !pThis->IsElemOfClass("point") ) return CBotTypResult(CBotErrBadNum); - - if ( var == NULL ) return CBotTypResult(0); // ok if no parameter - - // First parameter (x): - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - // Second parameter (y): - if ( var == NULL ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - // Third parameter (z): - if ( var == NULL ) // only 2 parameters? - { - return CBotTypResult(0); // this function returns void - } - - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != NULL ) return CBotTypResult(CBotErrOverParam); - - return CBotTypResult(0); // this function returns void -} - -//Execution of the class "point". - -bool CScript::rPointConstructor(CBotVar* pThis, CBotVar* var, CBotVar* pResult, int& Exception) -{ - CBotVar *pX, *pY, *pZ; - - if ( var == NULL ) return true; // constructor with no parameters is ok - - if ( var->GetType() > CBotTypDouble ) - { - Exception = CBotErrBadNum; return false; - } - - pX = pThis->GetItem("x"); - if ( pX == NULL ) - { - Exception = CBotErrUndefItem; return false; - } - pX->SetValFloat( var->GetValFloat() ); - var = var->GetNext(); - - if ( var == NULL ) - { - Exception = CBotErrLowParam; return false; - } - - if ( var->GetType() > CBotTypDouble ) - { - Exception = CBotErrBadNum; return false; - } - - pY = pThis->GetItem("y"); - if ( pY == NULL ) - { - Exception = CBotErrUndefItem; return false; - } - pY->SetValFloat( var->GetValFloat() ); - var = var->GetNext(); - - if ( var == NULL ) - { - return true; // ok with only two parameters - } - - pZ = pThis->GetItem("z"); - if ( pZ == NULL ) - { - Exception = CBotErrUndefItem; return false; - } - pZ->SetValFloat( var->GetValFloat() ); - var = var->GetNext(); - - if ( var != NULL ) - { - Exception = CBotErrOverParam; return false; - } - - return true; // no interruption -} +const int CBOT_IPF = 100; // CBOT: default number of instructions / frame // Object's constructor. @@ -3944,10 +59,10 @@ CScript::CScript(CObject* object, CTaskManager** secondaryTask) m_object = object; m_primaryTask = nullptr; m_secondaryTask = secondaryTask; - + m_interface = m_main->GetInterface(); m_pause = CPauseManager::GetInstancePointer(); - + m_ipf = CBOT_IPF; m_errMode = ERM_STOP; m_len = 0; @@ -3962,237 +77,6 @@ CScript::CScript(CObject* object, CTaskManager** secondaryTask) m_filename[0] = 0; } -// Initializes all functions for module CBOT. - -void CScript::InitFonctions() -{ - CBotProgram::SetTimer(100); - CBotProgram::Init(); - - for (int i = 0; i < OBJECT_MAX; i++) - { - ObjectType type = static_cast(i); - const char* token = GetObjectName(type); - if (token[0] != 0) - CBotProgram::DefineNum(token, type); - - token = GetObjectAlias(type); - if (token[0] != 0) - CBotProgram::DefineNum(token, type); - } - - CBotProgram::DefineNum("White", 0); - CBotProgram::DefineNum("Black", 1); - CBotProgram::DefineNum("Gray", 2); - CBotProgram::DefineNum("LightGray", 3); - CBotProgram::DefineNum("Red", 4); - CBotProgram::DefineNum("Pink", 5); - CBotProgram::DefineNum("Purple", 6); - CBotProgram::DefineNum("Orange", 7); - CBotProgram::DefineNum("Yellow", 8); - CBotProgram::DefineNum("Beige", 9); - CBotProgram::DefineNum("Brown", 10); - CBotProgram::DefineNum("Skin", 11); - CBotProgram::DefineNum("Green", 12); - CBotProgram::DefineNum("LightGreen", 13); - CBotProgram::DefineNum("Blue", 14); - CBotProgram::DefineNum("LightBlue", 15); - CBotProgram::DefineNum("BlackArrow", 16); - CBotProgram::DefineNum("RedArrow", 17); - - CBotProgram::DefineNum("Metal", OM_METAL); - CBotProgram::DefineNum("Plastic", OM_PLASTIC); - - CBotProgram::DefineNum("InFront", TMA_FFRONT); - CBotProgram::DefineNum("Behind", TMA_FBACK); - CBotProgram::DefineNum("EnergyCell", TMA_POWER); - - CBotProgram::DefineNum("DisplayError", Ui::TT_ERROR); - CBotProgram::DefineNum("DisplayWarning", Ui::TT_WARNING); - CBotProgram::DefineNum("DisplayInfo", Ui::TT_INFO); - CBotProgram::DefineNum("DisplayMessage", Ui::TT_MESSAGE); - - CBotProgram::DefineNum("FilterNone", FILTER_NONE); - CBotProgram::DefineNum("FilterOnlyLanding", FILTER_ONLYLANDING); - CBotProgram::DefineNum("FilterOnlyFliying", FILTER_ONLYFLYING); - - CBotProgram::DefineNum("ExploNone", 0); - CBotProgram::DefineNum("ExploBoum", EXPLO_BOUM); - CBotProgram::DefineNum("ExploBurn", EXPLO_BURN); - CBotProgram::DefineNum("ExploWater", EXPLO_WATER); - - CBotProgram::DefineNum("ResultNotEnded", ERR_MISSION_NOTERM); - CBotProgram::DefineNum("ResultLost", INFO_LOST); - CBotProgram::DefineNum("ResultLostQuick", INFO_LOSTq); - CBotProgram::DefineNum("ResultWin", ERR_OK); - - CBotProgram::DefineNum("BuildBotFactory", BUILD_FACTORY); - CBotProgram::DefineNum("BuildDerrick", BUILD_DERRICK); - CBotProgram::DefineNum("BuildConverter", BUILD_CONVERT); - CBotProgram::DefineNum("BuildRadarStation", BUILD_RADAR); - CBotProgram::DefineNum("BuildPowerPlant", BUILD_ENERGY); - CBotProgram::DefineNum("BuildNuclearPlant", BUILD_NUCLEAR); - CBotProgram::DefineNum("BuildPowerStation", BUILD_STATION); - CBotProgram::DefineNum("BuildRepairCenter", BUILD_REPAIR); - CBotProgram::DefineNum("BuildDefenseTower", BUILD_TOWER); - CBotProgram::DefineNum("BuildResearchCenter", BUILD_RESEARCH); - CBotProgram::DefineNum("BuildAutoLab", BUILD_LABO); - CBotProgram::DefineNum("BuildPowerCaptor", BUILD_PARA); - CBotProgram::DefineNum("BuildExchangePost", BUILD_INFO); - CBotProgram::DefineNum("BuildDestroyer", BUILD_DESTROYER); - CBotProgram::DefineNum("FlatGround", BUILD_GFLAT); - CBotProgram::DefineNum("UseFlags", BUILD_FLAG); - - CBotProgram::DefineNum("ResearchTracked", RESEARCH_TANK); - CBotProgram::DefineNum("ResearchWinged", RESEARCH_FLY); - CBotProgram::DefineNum("ResearchShooter", RESEARCH_CANON); - CBotProgram::DefineNum("ResearchDefenseTower", RESEARCH_TOWER); - CBotProgram::DefineNum("ResearchNuclearPlant", RESEARCH_ATOMIC); - CBotProgram::DefineNum("ResearchThumper", RESEARCH_THUMP); - CBotProgram::DefineNum("ResearchShielder", RESEARCH_SHIELD); - CBotProgram::DefineNum("ResearchPhazerShooter", RESEARCH_PHAZER); - CBotProgram::DefineNum("ResearchLegged", RESEARCH_iPAW); - CBotProgram::DefineNum("ResearchOrgaShooter", RESEARCH_iGUN); - CBotProgram::DefineNum("ResearchRecycler", RESEARCH_RECYCLER); - CBotProgram::DefineNum("ResearchSubber", RESEARCH_SUBM); - CBotProgram::DefineNum("ResearchSniffer", RESEARCH_SNIFFER); - - CBotProgram::DefineNum("PolskiPortalColobota", 1337); - - CBotClass* bc; - - // Add the class Point. - bc = new CBotClass("point", NULL, true); // intrinsic class - bc->AddItem("x", CBotTypFloat); - bc->AddItem("y", CBotTypFloat); - bc->AddItem("z", CBotTypFloat); - bc->AddFunction("point", CScript::rPointConstructor, CScript::cPointConstructor); - - // Adds the class Object. - bc = new CBotClass("object", NULL); - bc->AddItem("category", CBotTypResult(CBotTypInt), PR_READ); - bc->AddItem("position", CBotTypResult(CBotTypClass, "point"), PR_READ); - bc->AddItem("orientation", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("pitch", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("roll", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("energyLevel", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("shieldLevel", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("temperature", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("altitude", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("lifeTime", CBotTypResult(CBotTypFloat), PR_READ); - bc->AddItem("material", CBotTypResult(CBotTypInt), PR_READ); - bc->AddItem("energyCell", CBotTypResult(CBotTypPointer, "object"), PR_READ); - bc->AddItem("load", CBotTypResult(CBotTypPointer, "object"), PR_READ); - bc->AddItem("id", CBotTypResult(CBotTypInt), PR_READ); - bc->AddFunction("busy", CScript::rBusy, CScript::cBusy); - bc->AddFunction("factory", CScript::rFactory, CScript::cFactory); - bc->AddFunction("research", CScript::rResearch, CScript::cClassOneFloat); - bc->AddFunction("takeoff", CScript::rTakeOff, CScript::cClassNull); - bc->AddFunction("destroy", CScript::rDestroy, CScript::cClassNull); - - // InitClassFILE: - // create a class for file management - // the use is as follows: - // file canal( "NomFichier.txt" ) - // canal.open( "r" ); // open for read - // s = canal.readln( ); // reads a line - // canal.close(); // close the file - - // create the class FILE - bc = new CBotClass("file", NULL); - // adds the component ".filename" - bc->AddItem("filename", CBotTypString); - // adds the component ".handle" - bc->AddItem("handle", CBotTypInt, PR_PRIVATE); - - // define a constructor and a destructor - bc->AddFunction("file", CScript::rfconstruct, CScript::cfconstruct ); - bc->AddFunction("~file", CScript::rfdestruct, NULL ); - - // end of the methods associated - bc->AddFunction("open", CScript::rfopen, CScript::cfopen ); - bc->AddFunction("close", CScript::rfclose, CScript::cfclose ); - bc->AddFunction("writeln", CScript::rfwrite, CScript::cfwrite ); - bc->AddFunction("readln", CScript::rfread, CScript::cfread ); - bc->AddFunction("eof", CScript::rfeof, CScript::cfeof ); - - //m_pFuncFile = new CBotProgram( ); - //CBotStringArray ListFonctions; - //m_pFuncFile->Compile( "public file openfile(string name, string mode) {return new file(name, mode);}", ListFonctions); - //m_pFuncFile->SetIdent(-2); // restoreState in special identifier for this function - - CBotProgram::AddFunction("sin", rSin, CScript::cOneFloat); - CBotProgram::AddFunction("cos", rCos, CScript::cOneFloat); - CBotProgram::AddFunction("tan", rTan, CScript::cOneFloat); - CBotProgram::AddFunction("asin", raSin, CScript::cOneFloat); - CBotProgram::AddFunction("acos", raCos, CScript::cOneFloat); - CBotProgram::AddFunction("atan", raTan, CScript::cOneFloat); - CBotProgram::AddFunction("sqrt", rSqrt, CScript::cOneFloat); - CBotProgram::AddFunction("pow", rPow, CScript::cTwoFloat); - CBotProgram::AddFunction("rand", rRand, CScript::cNull); - CBotProgram::AddFunction("abs", rAbs, CScript::cOneFloat); - - CBotProgram::AddFunction("endmission",rEndMission,CScript::cEndMission); - CBotProgram::AddFunction("playmusic", rPlayMusic ,CScript::cPlayMusic); - CBotProgram::AddFunction("stopmusic", rStopMusic ,CScript::cNull); - - CBotProgram::AddFunction("getbuild", rGetBuild, CScript::cNull); - CBotProgram::AddFunction("getresearchenable", rGetResearchEnable, CScript::cNull); - CBotProgram::AddFunction("getresearchdone", rGetResearchDone, CScript::cNull); - CBotProgram::AddFunction("setbuild", rSetBuild, CScript::cOneFloat); - CBotProgram::AddFunction("setresearchenable", rSetResearchEnable, CScript::cOneFloat); - CBotProgram::AddFunction("setresearchdone", rSetResearchDone, CScript::cOneFloat); - - CBotProgram::AddFunction("progfunc", rProgFunc, CScript::cStringString); - CBotProgram::AddFunction("retobject", rGetObject, CScript::cGetObject); - CBotProgram::AddFunction("retobjectbyid", rGetObjectById, CScript::cGetObject); - CBotProgram::AddFunction("delete", rDelete, CScript::cDelete); - CBotProgram::AddFunction("search", rSearch, CScript::cSearch); - CBotProgram::AddFunction("radar", rRadar, CScript::cRadar); - CBotProgram::AddFunction("detect", rDetect, CScript::cDetect); - CBotProgram::AddFunction("direction", rDirection, CScript::cDirection); - CBotProgram::AddFunction("produce", rProduce, CScript::cProduce); - CBotProgram::AddFunction("distance", rDistance, CScript::cDistance); - CBotProgram::AddFunction("distance2d",rDistance2d,CScript::cDistance); - CBotProgram::AddFunction("space", rSpace, CScript::cSpace); - CBotProgram::AddFunction("flatground",rFlatGround,CScript::cFlatGround); - CBotProgram::AddFunction("wait", rWait, CScript::cOneFloat); - CBotProgram::AddFunction("move", rMove, CScript::cOneFloat); - CBotProgram::AddFunction("turn", rTurn, CScript::cOneFloat); - CBotProgram::AddFunction("goto", rGoto, CScript::cGoto); - CBotProgram::AddFunction("grab", rGrab, CScript::cGrabDrop); - CBotProgram::AddFunction("drop", rDrop, CScript::cGrabDrop); - CBotProgram::AddFunction("sniff", rSniff, CScript::cNull); - CBotProgram::AddFunction("receive", rReceive, CScript::cReceive); - CBotProgram::AddFunction("send", rSend, CScript::cSend); - CBotProgram::AddFunction("deleteinfo",rDeleteInfo,CScript::cDeleteInfo); - CBotProgram::AddFunction("testinfo", rTestInfo, CScript::cTestInfo); - CBotProgram::AddFunction("thump", rThump, CScript::cNull); - CBotProgram::AddFunction("recycle", rRecycle, CScript::cNull); - CBotProgram::AddFunction("shield", rShield, CScript::cShield); - CBotProgram::AddFunction("fire", rFire, CScript::cFire); - CBotProgram::AddFunction("aim", rAim, CScript::cAim); - CBotProgram::AddFunction("motor", rMotor, CScript::cMotor); - CBotProgram::AddFunction("jet", rJet, CScript::cOneFloat); - CBotProgram::AddFunction("topo", rTopo, CScript::cTopo); - CBotProgram::AddFunction("message", rMessage, CScript::cMessage); - CBotProgram::AddFunction("cmdline", rCmdline, CScript::cOneFloat); - CBotProgram::AddFunction("ismovie", rIsMovie, CScript::cNull); - CBotProgram::AddFunction("errmode", rErrMode, CScript::cOneFloat); - CBotProgram::AddFunction("ipf", rIPF, CScript::cOneFloat); - CBotProgram::AddFunction("abstime", rAbsTime, CScript::cNull); - CBotProgram::AddFunction("deletefile",rDeleteFile,CScript::cString); - CBotProgram::AddFunction("pendown", rPenDown, CScript::cPenDown); - CBotProgram::AddFunction("penup", rPenUp, CScript::cNull); - CBotProgram::AddFunction("pencolor", rPenColor, CScript::cOneFloat); - CBotProgram::AddFunction("penwidth", rPenWidth, CScript::cOneFloat); - - CBotProgram::AddFunction("camerafocus", rCameraFocus, CScript::cOneObject); - - CBotProgram::AddFunction("canbuild", rCanBuild, CScript::cCanBuild); - CBotProgram::AddFunction("build", rBuild, CScript::cOneFloat); -} - // Object's destructor. CScript::~CScript() diff --git a/src/script/script.h b/src/script/script.h index 740164b4..8512082f 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -29,16 +29,14 @@ #include "common/global.h" -#include "app/pausemanager.h" - #include "CBot/CBotDll.h" -#include - class CObject; class CTaskManager; class CRobotMain; +class CPauseManager; +class CScriptFunctions; namespace Ui{ class CEdit; @@ -53,15 +51,17 @@ class CWater; } /* Gfx */ +const int ERM_CONT = 0; // if error -> continue +const int ERM_STOP = 1; // if error -> stop + class CScript { +friend class CScriptFunctions; public: CScript(CObject* object, CTaskManager** secondaryTask); ~CScript(); - static void InitFonctions(); - void PutScript(Ui::CEdit* edit, const char* name); bool GetScript(Ui::CEdit* edit); bool GetCompile(); @@ -99,146 +99,6 @@ protected: bool CheckToken(); bool Compile(); -private: - static CBotTypResult cNull(CBotVar* &var, void* user); - static CBotTypResult cOneFloat(CBotVar* &var, void* user); - static CBotTypResult cTwoFloat(CBotVar* &var, void* user); - static CBotTypResult cString(CBotVar* &var, void* user); - static CBotTypResult cStringString(CBotVar* &var, void* user); - static CBotTypResult cEndMission(CBotVar* &var, void* user); - static CBotTypResult cPlayMusic(CBotVar* &var, void* user); - static CBotTypResult cGetObject(CBotVar* &var, void* user); - static CBotTypResult cDelete(CBotVar* &var, void* user); - static CBotTypResult cSearch(CBotVar* &var, void* user); - static CBotTypResult cRadar(CBotVar* &var, void* user); - static CBotTypResult cDetect(CBotVar* &var, void* user); - static CBotTypResult cDirection(CBotVar* &var, void* user); - static CBotTypResult cCanBuild(CBotVar* &var, void* user); - static CBotTypResult cProduce(CBotVar* &var, void* user); - static CBotTypResult cDistance(CBotVar* &var, void* user); - static CBotTypResult cSpace(CBotVar* &var, void* user); - static CBotTypResult cFlatGround(CBotVar* &var, void* user); - static CBotTypResult cGoto(CBotVar* &var, void* user); - static CBotTypResult cGrabDrop(CBotVar* &var, void* user); - static CBotTypResult cReceive(CBotVar* &var, void* user); - static CBotTypResult cSend(CBotVar* &var, void* user); - static CBotTypResult cDeleteInfo(CBotVar* &var, void* user); - static CBotTypResult cTestInfo(CBotVar* &var, void* user); - static CBotTypResult cShield(CBotVar* &var, void* user); - static CBotTypResult cFire(CBotVar* &var, void* user); - static CBotTypResult cAim(CBotVar* &var, void* user); - static CBotTypResult cMotor(CBotVar* &var, void* user); - static CBotTypResult cTopo(CBotVar* &var, void* user); - static CBotTypResult cMessage(CBotVar* &var, void* user); - static CBotTypResult cPenDown(CBotVar* &var, void* user); - static CBotTypResult cOnePoint(CBotVar* &var, void* user); - static CBotTypResult cPoint(CBotVar* &var, void* user); - static CBotTypResult cOneObject(CBotVar* &var, void* user); - - - static bool rSin(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rCos(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rTan(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rSqrt(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rPow(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rRand(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rAbs(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rEndMission(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rPlayMusic(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rStopMusic(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rGetBuild(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rGetResearchEnable(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rGetResearchDone(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rSetBuild(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rSetResearchEnable(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rSetResearchDone(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rGetObjectById(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rGetObject(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rProgFunc(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rDelete(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rSearch(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rRadar(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rDetect(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rDirection(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rCanBuild(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rBuild(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rProduce(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rDistance(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rDistance2d(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rSpace(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rFlatGround(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rWait(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rMove(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rTurn(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rGoto(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rFind(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rGrab(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rDrop(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rSniff(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rReceive(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rSend(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rThump(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rRecycle(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rShield(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rFire(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rAim(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rMotor(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rJet(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rTopo(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rMessage(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rCmdline(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rIsMovie(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rErrMode(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rIPF(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rAbsTime(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rDeleteFile(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rPenUp(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rPenColor(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rPenWidth(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rCameraFocus(CBotVar* var, CBotVar* result, int& exception, void* user); - - - static CBotTypResult cBusy(CBotVar* thisclass, CBotVar* &var); - static CBotTypResult cFactory(CBotVar* thisclass, CBotVar* &var); - static CBotTypResult cClassNull(CBotVar* thisclass, CBotVar* &var); - static CBotTypResult cClassOneFloat(CBotVar* thisclass, CBotVar* &var); - - static bool rBusy(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); - static bool rFactory(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); - static bool rResearch(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); - static bool rTakeOff(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); - static bool rDestroy(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); - - - static CBotTypResult cfconstruct (CBotVar* pThis, CBotVar* &pVar); - static CBotTypResult cfopen (CBotVar* pThis, CBotVar* &pVar); - static CBotTypResult cfclose (CBotVar* pThis, CBotVar* &pVar); - static CBotTypResult cfwrite (CBotVar* pThis, CBotVar* &pVar); - static CBotTypResult cfread (CBotVar* pThis, CBotVar* &pVar); - static CBotTypResult cfeof (CBotVar* pThis, CBotVar* &pVar); - static bool rfconstruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); - static bool rfdestruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); - static bool rfopen (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); - static bool rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); - static bool rfwrite (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); - static bool rfread (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); - static bool rfeof (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); - - static CBotTypResult cPointConstructor(CBotVar* pThis, CBotVar* &var); - static bool rPointConstructor(CBotVar* pThis, CBotVar* var, CBotVar* pResult, int& Exception); - -public: - static int m_CompteurFileOpen; - static std::string m_filesDir; - -private: - static bool Process(CScript* script, CBotVar* result, int &exception); - static bool ShouldProcessStop(Error err, int errMode); - static CObject* SearchInfo(CScript* script, CObject* object, float power); - protected: Gfx::CEngine* m_engine; Ui::CInterface* m_interface; diff --git a/src/script/scriptfunc.cpp b/src/script/scriptfunc.cpp new file mode 100644 index 00000000..b4477960 --- /dev/null +++ b/src/script/scriptfunc.cpp @@ -0,0 +1,4147 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + +#include "script/scriptfunc.h" + + +#include "app/app.h" + +#include "common/iman.h" + +#include "common/resources/inputstream.h" +#include "common/resources/resourcemanager.h" + +#include "graphics/engine/terrain.h" +#include "graphics/engine/water.h" + +#include "math/all.h" + +#include "object/object.h" +#include "object/robotmain.h" +#include "object/task/taskmanager.h" +#include "object/objman.h" + +#include "object/auto/auto.h" +#include "object/auto/autofactory.h" +#include "object/auto/autobase.h" + +#include "physics/physics.h" + +#include "script/cbottoken.h" +#include "script/script.h" + +#include "sound/sound.h" + +#include "ui/displaytext.h" + + + +// Compiling a procedure without any parameters. + +CBotTypResult CScriptFunctions::cNull(CBotVar* &var, void* user) +{ + if ( var != 0 ) return CBotErrOverParam; + return CBotTypResult(CBotTypFloat); +} + +CBotTypResult CScriptFunctions::cClassNull(CBotVar* thisclass, CBotVar* &var) +{ + return CScriptFunctions::cNull(var, nullptr); +} + +// Compiling a procedure with a single real number. + +CBotTypResult CScriptFunctions::cOneFloat(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +CBotTypResult CScriptFunctions::cClassOneFloat(CBotVar* thisclass, CBotVar* &var) +{ + return CScriptFunctions::cOneFloat(var, nullptr); +} + +// Compiling a procedure with two real numbers. + +CBotTypResult CScriptFunctions::cTwoFloat(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Compiling a procedure with a "dot". + +CBotTypResult CScriptFunctions::cPoint(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + + if ( var->GetType() <= CBotTypDouble ) + { + var = var->GetNext(); + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + //? if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + //? if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + //? var = var->GetNext(); + return CBotTypResult(0); + } + + if ( var->GetType() == CBotTypClass ) + { + if ( !var->IsElemOfClass("point") ) return CBotTypResult(CBotErrBadParam); + var = var->GetNext(); + return CBotTypResult(0); + } + + return CBotTypResult(CBotErrBadParam); +} + +// Compiling a procedure with a single "point". + +CBotTypResult CScriptFunctions::cOnePoint(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + ret = cPoint(var, user); + if ( ret.GetType() != 0 ) return ret; + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Compiling a procedure with a single string. + +CBotTypResult CScriptFunctions::cString(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() != CBotTypString && + var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Compiling a procedure with a single string, returning string. + +CBotTypResult CScriptFunctions::cStringString(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() != CBotTypString && + var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypString); +} + + +// Seeking value in an array of integers. + +bool FindList(CBotVar* array, int type) +{ + while ( array != 0 ) + { + if ( type == array->GetValInt() ) return true; + array = array->GetNext(); + } + return false; +} + + +// Gives a parameter of type "point". + +bool GetPoint(CBotVar* &var, int& exception, Math::Vector& pos) +{ + CBotVar *pX, *pY, *pZ; + + if ( var->GetType() <= CBotTypDouble ) + { + pos.x = var->GetValFloat()*g_unit; + var = var->GetNext(); + + pos.z = var->GetValFloat()*g_unit; + var = var->GetNext(); + + pos.y = 0.0f; + } + else + { + pX = var->GetItem("x"); + if ( pX == NULL ) + { + exception = CBotErrUndefItem; return true; + } + pos.x = pX->GetValFloat()*g_unit; + + pY = var->GetItem("y"); + if ( pY == NULL ) + { + exception = CBotErrUndefItem; return true; + } + pos.z = pY->GetValFloat()*g_unit; // attention y -> z ! + + pZ = var->GetItem("z"); + if ( pZ == NULL ) + { + exception = CBotErrUndefItem; return true; + } + pos.y = pZ->GetValFloat()*g_unit; // attention z -> y ! + + var = var->GetNext(); + } + return true; +} + + +// Instruction "sin(degrees)". + +bool CScriptFunctions::rSin(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(sinf(value*Math::PI/180.0f)); + return true; +} + +// Instruction "cos(degrees)". + +bool CScriptFunctions::rCos(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(cosf(value*Math::PI/180.0f)); + return true; +} + +// Instruction "tan(degrees)". + +bool CScriptFunctions::rTan(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(tanf(value*Math::PI/180.0f)); + return true; +} + +// Instruction "asin(degrees)". + +bool raSin(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(asinf(value)*180.0f/Math::PI); + return true; +} + +// Instruction "acos(degrees)". + +bool raCos(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(acosf(value)*180.0f/Math::PI); + return true; +} + +// Instruction "atan(degrees)". + +bool raTan(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(atanf(value)*180.0f/Math::PI); + return true; +} + +// Instruction "sqrt(value)". + +bool CScriptFunctions::rSqrt(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(sqrtf(value)); + return true; +} + +// Instruction "pow(x, y)". + +bool CScriptFunctions::rPow(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float x, y; + + x = var->GetValFloat(); + var = var->GetNext(); + y = var->GetValFloat(); + result->SetValFloat(powf(x, y)); + return true; +} + +// Instruction "rand()". + +bool CScriptFunctions::rRand(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + result->SetValFloat(Math::Rand()); + return true; +} + +// Instruction "abs()". + +bool CScriptFunctions::rAbs(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(fabs(value)); + return true; +} + +// Compilation of the instruction "endmission(result, delay)" + +CBotTypResult CScriptFunctions::cEndMission(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Instruction "endmission(result, delay)" + +bool CScriptFunctions::rEndMission(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + Error ended; + float delay; + + ended = static_cast(var->GetValFloat()); + var = var->GetNext(); + + delay = var->GetValFloat(); + + CRobotMain::GetInstancePointer()->SetEndMission(ended, delay); + return true; +} + +// Compilation of the instruction "playmusic(filename, repeat)" + +CBotTypResult CScriptFunctions::cPlayMusic(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Instruction "playmusic(filename, repeat)" + +bool CScriptFunctions::rPlayMusic(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + std::string filename; + CBotString cbs; + bool repeat; + + cbs = var->GetValString(); + filename = std::string(cbs); + var = var->GetNext(); + + repeat = var->GetValInt(); + + CApplication::GetInstancePointer()->GetSound()->StopMusic(); + CApplication::GetInstancePointer()->GetSound()->PlayMusic(filename, repeat); + return true; +} + +// Instruction "stopmusic()" + +bool CScriptFunctions::rStopMusic(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CApplication::GetInstancePointer()->GetSound()->StopMusic(); + return true; +} + +// Instruction "getbuild()" + +bool CScriptFunctions::rGetBuild(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + result->SetValInt(g_build); + return true; +} + +// Instruction "getresearchenable()" + +bool CScriptFunctions::rGetResearchEnable(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + result->SetValInt(g_researchEnable); + return true; +} + +// Instruction "getresearchdone()" + +bool CScriptFunctions::rGetResearchDone(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + result->SetValInt(g_researchDone); + return true; +} + +// Instruction "setbuild()" + +bool CScriptFunctions::rSetBuild(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + g_build = var->GetValInt(); + CApplication::GetInstancePointer()->GetEventQueue()->AddEvent(Event(EVENT_UPDINTERFACE)); + return true; +} + +// Instruction "setresearchenable()" + +bool CScriptFunctions::rSetResearchEnable(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + g_researchEnable = var->GetValInt(); + CApplication::GetInstancePointer()->GetEventQueue()->AddEvent(Event(EVENT_UPDINTERFACE)); + return true; +} + +// Instruction "setresearchdone()" + +bool CScriptFunctions::rSetResearchDone(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + g_researchDone = var->GetValInt(); + CApplication::GetInstancePointer()->GetEventQueue()->AddEvent(Event(EVENT_UPDINTERFACE)); + return true; +} + +// Compilation of the instruction "retobject(rank)". + +CBotTypResult CScriptFunctions::cGetObject(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypPointer, "object"); +} + +// Instruction "retobjectbyid(rank)". + +bool CScriptFunctions::rGetObjectById(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CObject* pObj; + int rank; + + rank = var->GetValInt(); + + pObj = static_cast(CObjectManager::GetInstancePointer()->SearchInstance(rank)); + if ( pObj == 0 ) + { + result->SetPointer(0); + } + else + { + result->SetPointer(pObj->GetBotVar()); + } + return true; +} + +// Instruction "retobject(rank)". + +bool CScriptFunctions::rGetObject(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CObject* pObj; + int rank; + + rank = var->GetValInt(); + + pObj = static_cast(CInstanceManager::GetInstancePointer()->SearchInstance(CLASS_OBJECT, rank)); + if ( pObj == 0 ) + { + result->SetPointer(0); + } + else + { + result->SetPointer(pObj->GetBotVar()); + } + return true; +} + + +// Instruction "progfunc(funcname)". + +bool CScriptFunctions::rProgFunc(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CBotString cbs; + const char* funcname; + std::string program; + + cbs = var->GetValString(); + funcname = cbs; + + //TODO: Translation :) + program = "extern void object::Auto()\n{\n\t\n\t//Automatically generated by progfunc(\""; + program += funcname; + program += "\");\n\t"; + program += funcname; + program += "();\n\t\n}\n"; + + result->SetValString(program.c_str()); + + return true; +} + +// Compilation of instruction "object.busy()" +CBotTypResult CScriptFunctions::cBusy(CBotVar* thisclass, CBotVar* &var) +{ + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypBoolean); +} + +// Instruction "object.busy()" + +bool CScriptFunctions::rBusy(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception) +{ + exception = 0; + + CBotVar* classVars = thisclass->GetItemList(); // "category" + classVars = classVars->GetNext(); // "position" + classVars = classVars->GetNext(); // "orientation" + classVars = classVars->GetNext(); // "pitch" + classVars = classVars->GetNext(); // "roll" + classVars = classVars->GetNext(); // "energyLevel" + classVars = classVars->GetNext(); // "shieldLevel" + classVars = classVars->GetNext(); // "temperature" + classVars = classVars->GetNext(); // "altitude" + classVars = classVars->GetNext(); // "lifeTime" + classVars = classVars->GetNext(); // "material" + classVars = classVars->GetNext(); // "energyCell" + classVars = classVars->GetNext(); // "load" + classVars = classVars->GetNext(); // "id" + int rank = classVars->GetValInt(); + CObject* obj = CObjectManager::GetInstancePointer()->SearchInstance(rank); + CAuto* automat = obj->GetAuto(); + + if ( automat != nullptr ) + result->SetValInt(automat->GetBusy()); + else + exception = ERR_WRONG_OBJ; + + return true; +} + +bool CScriptFunctions::rDestroy(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception) +{ + exception = 0; + Error err; + + CBotVar* classVars = thisclass->GetItemList(); // "category" + ObjectType thisType = static_cast(classVars->GetValInt()); + classVars = classVars->GetNext(); // "position" + classVars = classVars->GetNext(); // "orientation" + classVars = classVars->GetNext(); // "pitch" + classVars = classVars->GetNext(); // "roll" + classVars = classVars->GetNext(); // "energyLevel" + classVars = classVars->GetNext(); // "shieldLevel" + classVars = classVars->GetNext(); // "temperature" + classVars = classVars->GetNext(); // "altitude" + classVars = classVars->GetNext(); // "lifeTime" + classVars = classVars->GetNext(); // "material" + classVars = classVars->GetNext(); // "energyCell" + classVars = classVars->GetNext(); // "load" + classVars = classVars->GetNext(); // "id" + int rank = classVars->GetValInt(); + CObject* obj = CObjectManager::GetInstancePointer()->SearchInstance(rank); + CAuto* automat = obj->GetAuto(); + + if ( thisType == OBJECT_DESTROYER ) + { + err = automat->StartAction(0); + } else + err = ERR_WRONG_OBJ; + + if ( err != ERR_OK ) + { + result->SetValInt(err); // return error + //TODO: if ( script->m_errMode == ERM_STOP ) + if( true ) + { + exception = err; + return false; + } + return true; + } + + return true; +} + + +// Compilation of instruction "object.factory(cat, program)" + +CBotTypResult CScriptFunctions::cFactory(CBotVar* thisclass, CBotVar* &var) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != 0 ) + { + if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + } + return CBotTypResult(CBotTypFloat); +} + +// Instruction "object.factory(cat, program)" + +bool CScriptFunctions::rFactory(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception) +{ + Error err; + + exception = 0; + + ObjectType type = static_cast(var->GetValInt()); + var = var->GetNext(); + CBotString cbs; + const char* program; + if ( var != 0 ) + { + cbs = var->GetValString(); + program = cbs; + } + else + program = ""; + + CBotVar* classVars = thisclass->GetItemList(); // "category" + ObjectType thisType = static_cast(classVars->GetValInt()); + classVars = classVars->GetNext(); // "position" + classVars = classVars->GetNext(); // "orientation" + classVars = classVars->GetNext(); // "pitch" + classVars = classVars->GetNext(); // "roll" + classVars = classVars->GetNext(); // "energyLevel" + classVars = classVars->GetNext(); // "shieldLevel" + classVars = classVars->GetNext(); // "temperature" + classVars = classVars->GetNext(); // "altitude" + classVars = classVars->GetNext(); // "lifeTime" + classVars = classVars->GetNext(); // "material" + classVars = classVars->GetNext(); // "energyCell" + classVars = classVars->GetNext(); // "load" + classVars = classVars->GetNext(); // "id" + int rank = classVars->GetValInt(); + CObject* factory = CObjectManager::GetInstancePointer()->SearchInstance(rank); + if (factory == nullptr) { + exception = ERR_GENERIC; + result->SetValInt(ERR_GENERIC); + CLogger::GetInstancePointer()->Error("in object.factory() - factory is nullptr"); + return false; + } + + if ( thisType == OBJECT_FACTORY ) + { + CAutoFactory* automat = static_cast(factory->GetAuto()); + if(automat == nullptr) { + exception = ERR_GENERIC; + result->SetValInt(ERR_GENERIC); + CLogger::GetInstancePointer()->Error("in object.factory() - automat is nullptr"); + return false; + } + + bool bEnable = false; + + if ( type == OBJECT_MOBILEwa ) + { + bEnable = true; + } + if ( type == OBJECT_MOBILEta ) + { + bEnable = g_researchDone&RESEARCH_TANK; + } + if ( type == OBJECT_MOBILEfa ) + { + bEnable = g_researchDone&RESEARCH_FLY; + } + if ( type == OBJECT_MOBILEia ) + { + bEnable = g_researchDone&RESEARCH_iPAW; + } + + if ( type == OBJECT_MOBILEws ) + { + bEnable = g_researchDone&RESEARCH_SNIFFER; + } + if ( type == OBJECT_MOBILEts ) + { + bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( type == OBJECT_MOBILEfs ) + { + bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && + (g_researchDone&RESEARCH_FLY) ); + } + if ( type == OBJECT_MOBILEis ) + { + bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && + (g_researchDone&RESEARCH_iPAW) ); + } + + if ( type == OBJECT_MOBILEwc ) + { + bEnable = g_researchDone&RESEARCH_CANON; + } + if ( type == OBJECT_MOBILEtc ) + { + bEnable = ( (g_researchDone&RESEARCH_CANON) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( type == OBJECT_MOBILEfc ) + { + bEnable = ( (g_researchDone&RESEARCH_CANON) && + (g_researchDone&RESEARCH_FLY) ); + } + if ( type == OBJECT_MOBILEic ) + { + bEnable = ( (g_researchDone&RESEARCH_CANON) && + (g_researchDone&RESEARCH_iPAW) ); + } + + if ( type == OBJECT_MOBILEwi ) + { + bEnable = g_researchDone&RESEARCH_iGUN; + } + if ( type == OBJECT_MOBILEti ) + { + bEnable = ( (g_researchDone&RESEARCH_iGUN) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( type == OBJECT_MOBILEfi ) + { + bEnable = ( (g_researchDone&RESEARCH_iGUN) && + (g_researchDone&RESEARCH_FLY) ); + } + if ( type == OBJECT_MOBILEii ) + { + bEnable = ( (g_researchDone&RESEARCH_iGUN) && + (g_researchDone&RESEARCH_iPAW) ); + } + + if ( type == OBJECT_MOBILErt ) + { + bEnable = ( (g_researchDone&RESEARCH_THUMP) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( type == OBJECT_MOBILErc ) + { + bEnable = ( (g_researchDone&RESEARCH_PHAZER) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( type == OBJECT_MOBILErr ) + { + bEnable = ( (g_researchDone&RESEARCH_RECYCLER) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( type == OBJECT_MOBILErs ) + { + bEnable = ( (g_researchDone&RESEARCH_SHIELD) && + (g_researchDone&RESEARCH_TANK) ); + } + + if ( type == OBJECT_MOBILEsa ) + { + bEnable = g_researchDone&RESEARCH_SUBM; + } + + if ( bEnable ) + { + if ( automat != nullptr ) + { + err = automat->StartAction(type); + if ( err == ERR_OK ) automat->SetProgram(program); + } + else + err = ERR_GENERIC; + } + else + err = ERR_BUILD_DISABLED; + } + else + err = ERR_WRONG_OBJ; + + if ( err != ERR_OK ) + { + result->SetValInt(err); // return error + //TODO: if ( script->m_errMode == ERM_STOP ) + if( true ) + { + exception = err; + return false; + } + return true; + } + + return true; +} + +// Instruction "object.research(type)" + +bool CScriptFunctions::rResearch(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception) +{ + Error err; + + exception = 0; + + ResearchType type = static_cast(var->GetValInt()); + + CBotVar* classVars = thisclass->GetItemList(); // "category" + ObjectType thisType = static_cast(classVars->GetValInt()); + classVars = classVars->GetNext(); // "position" + classVars = classVars->GetNext(); // "orientation" + classVars = classVars->GetNext(); // "pitch" + classVars = classVars->GetNext(); // "roll" + classVars = classVars->GetNext(); // "energyLevel" + classVars = classVars->GetNext(); // "shieldLevel" + classVars = classVars->GetNext(); // "temperature" + classVars = classVars->GetNext(); // "altitude" + classVars = classVars->GetNext(); // "lifeTime" + classVars = classVars->GetNext(); // "material" + classVars = classVars->GetNext(); // "energyCell" + classVars = classVars->GetNext(); // "load" + classVars = classVars->GetNext(); // "id" + int rank = classVars->GetValInt(); + CObject* center = CObjectManager::GetInstancePointer()->SearchInstance(rank); + CAuto* automat = center->GetAuto(); + + if ( thisType == OBJECT_RESEARCH || + thisType == OBJECT_LABO ) + { + bool ok = false; + if ( type == RESEARCH_iPAW || + type == RESEARCH_iGUN ) + { + if ( thisType != OBJECT_LABO ) + err = ERR_WRONG_OBJ; + else + ok = true; + } + else + { + if ( thisType != OBJECT_RESEARCH ) + err = ERR_WRONG_OBJ; + else + ok = true; + } + if ( ok ) + { + bool bEnable = ( g_researchEnable & type ); + if ( bEnable ) + { + if ( automat != nullptr ) + { + err = automat->StartAction(type); + } + else + err = ERR_GENERIC; + } + else + err = ERR_BUILD_DISABLED; + } + } + else + err = ERR_WRONG_OBJ; + + if ( err != ERR_OK ) + { + result->SetValInt(err); // return error + //TODO: if ( script->m_errMode == ERM_STOP ) + if( true ) + { + exception = err; + return false; + } + return true; + } + + return true; +} + +// Instruction "object.takeoff()" + +bool CScriptFunctions::rTakeOff(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception) +{ + Error err; + + exception = 0; + + CBotVar* classVars = thisclass->GetItemList(); // "category" + ObjectType thisType = static_cast(classVars->GetValInt()); + classVars = classVars->GetNext(); // "position" + classVars = classVars->GetNext(); // "orientation" + classVars = classVars->GetNext(); // "pitch" + classVars = classVars->GetNext(); // "roll" + classVars = classVars->GetNext(); // "energyLevel" + classVars = classVars->GetNext(); // "shieldLevel" + classVars = classVars->GetNext(); // "temperature" + classVars = classVars->GetNext(); // "altitude" + classVars = classVars->GetNext(); // "lifeTime" + classVars = classVars->GetNext(); // "material" + classVars = classVars->GetNext(); // "energyCell" + classVars = classVars->GetNext(); // "load" + classVars = classVars->GetNext(); // "id" + int rank = classVars->GetValInt(); + CObject* center = CObjectManager::GetInstancePointer()->SearchInstance(rank); + CAuto* automat = center->GetAuto(); + + if ( thisType == OBJECT_BASE ) + { + err = (static_cast(automat))->TakeOff(false); + } else + err = ERR_WRONG_OBJ; + + if ( err != ERR_OK ) + { + result->SetValInt(err); // return error + //TODO: if ( script->m_errMode == ERM_STOP ) + if( true ) + { + exception = err; + return false; + } + return true; + } + + return true; +} + +// Compilation of the instruction "delete(rank[, exploType[, force]])". + +CBotTypResult CScriptFunctions::cDelete(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != 0 ) + { + if ( var->GetType() != CBotTypInt ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != 0 ) + { + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + } + } + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "delete(rank[, exploType[, force]])". + +bool CScriptFunctions::rDelete(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CObject* pObj; + int rank; + int exploType = 0; + float force = 1.0f; + + rank = var->GetValInt(); + var->GetNext(); + if ( var != 0 ) + { + exploType = var->GetValInt(); + var->GetNext(); + if ( var != 0 ) + { + force = var->GetValFloat(); + } + } + + pObj = static_cast(CObjectManager::GetInstancePointer()->SearchInstance(rank)); + if ( pObj == 0 ) + { + return true; + } + else + { + if ( exploType ) + { + pObj->ExploObject(static_cast(exploType), force); + } + else + { + pObj->DeleteObject(false); + } + } + return true; +} + + + +// Compilation of the instruction "search(type, pos)". + +CBotTypResult CScriptFunctions::cSearch(CBotVar* &var, void* user) +{ + CBotVar* array; + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() == CBotTypArrayPointer ) + { + array = var->GetItemList(); + if ( array == 0 ) return CBotTypResult(CBotTypPointer); + if ( array->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + } + else if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != 0 ) + { + ret = cPoint(var, user); + if ( ret.GetType() != 0 ) return ret; + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + } + + return CBotTypResult(CBotTypPointer, "object"); +} + +// Instruction "search(type, pos)". + +bool CScriptFunctions::rSearch(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CObject *pObj, *pBest; + CBotVar* array; + Math::Vector pos, oPos; + bool bNearest = false; + bool bArray; + float min, dist; + int type, oType, i; + + if ( var->GetType() == CBotTypArrayPointer ) + { + array = var->GetItemList(); + bArray = true; + } + else + { + type = var->GetValInt(); + bArray = false; + } + var = var->GetNext(); + if ( var != 0 ) + { + if ( !GetPoint(var, exception, pos) ) return true; + bNearest = true; + } + + CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); + + min = 100000.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = static_cast(iMan->SearchInstance(CLASS_OBJECT, i)); + if ( pObj == 0 ) break; + + if ( pObj->GetTruck() != 0 ) continue; // object transported? + if ( !pObj->GetActif() ) continue; + + oType = pObj->GetType(); + if ( oType == OBJECT_TOTO ) continue; + + if ( oType == OBJECT_RUINmobilew2 || + oType == OBJECT_RUINmobilet1 || + oType == OBJECT_RUINmobilet2 || + oType == OBJECT_RUINmobiler1 || + oType == OBJECT_RUINmobiler2 ) + { + oType = OBJECT_RUINmobilew1; // any ruin + } + + if ( oType == OBJECT_SCRAP2 || + oType == OBJECT_SCRAP3 || + oType == OBJECT_SCRAP4 || + oType == OBJECT_SCRAP5 ) // wastes? + { + oType = OBJECT_SCRAP1; // any waste + } + + if ( oType == OBJECT_BARRIER2 || + oType == OBJECT_BARRIER3 ) // barriers? + { + oType = OBJECT_BARRIER1; // any barrier + } + + if ( bArray ) + { + if ( !FindList(array, oType) ) continue; + } + else + { + if ( type != oType && type != OBJECT_NULL ) continue; + } + + if ( bNearest ) + { + oPos = pObj->GetPosition(0); + dist = Math::DistanceProjected(pos, oPos); + if ( dist < min ) + { + min = dist; + pBest = pObj; + } + } + else + { + pBest = pObj; + break; + } + } + + if ( pBest == 0 ) + { + result->SetPointer(0); + } + else + { + result->SetPointer(pBest->GetBotVar()); + } + return true; +} + + +// Compilation of instruction "radar(type, angle, focus, min, max, sens)". + +CBotTypResult CScriptFunctions::cRadar(CBotVar* &var, void* user) +{ + CBotVar* array; + + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GetType() == CBotTypArrayPointer ) + { + array = var->GetItemList(); + if ( array == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( array->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type + } + else if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type + var = var->GetNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // angle + var = var->GetNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // focus + var = var->GetNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // min + var = var->GetNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // max + var = var->GetNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // sense + var = var->GetNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // filter + var = var->GetNext(); + if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); + return CBotTypResult(CBotErrOverParam); +} + +// Instruction "radar(type, angle, focus, min, max, sens, filter)". + +bool CScriptFunctions::rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CObject* pThis = static_cast(user); + CObject *pObj, *pBest; + CPhysics* physics; + CBotVar* array; + Math::Vector iPos, oPos; + RadarFilter filter; + float best, minDist, maxDist, sens, iAngle, angle, focus, d, a; + int type, oType, i; + bool bArray = false; + + type = OBJECT_NULL; + array = 0; + angle = 0.0f; + focus = Math::PI*2.0f; + minDist = 0.0f*g_unit; + maxDist = 1000.0f*g_unit; + sens = 1.0f; + filter = FILTER_NONE; + + if ( var != 0 ) + { + if ( var->GetType() == CBotTypArrayPointer ) + { + array = var->GetItemList(); + bArray = true; + } + else + { + type = var->GetValInt(); + bArray = false; + } + + var = var->GetNext(); + if ( var != 0 ) + { + angle = -var->GetValFloat()*Math::PI/180.0f; + + var = var->GetNext(); + if ( var != 0 ) + { + focus = var->GetValFloat()*Math::PI/180.0f; + + var = var->GetNext(); + if ( var != 0 ) + { + minDist = var->GetValFloat()*g_unit; + + var = var->GetNext(); + if ( var != 0 ) + { + maxDist = var->GetValFloat()*g_unit; + + var = var->GetNext(); + if ( var != 0 ) + { + sens = var->GetValFloat(); + + var = var->GetNext(); + if ( var != 0 ) + { + filter = static_cast(var->GetValInt()); + } + } + } + } + } + } + } + + iPos = pThis->GetPosition(0); + iAngle = pThis->GetAngleY(0)+angle; + iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI + + CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); + + if ( sens >= 0.0f ) best = 100000.0f; + else best = 0.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = static_cast(iMan->SearchInstance(CLASS_OBJECT, i)); + if ( pObj == 0 ) break; + if ( pObj == pThis ) continue; + + if ( pObj->GetTruck() != 0 ) continue; // object transported? + if ( !pObj->GetActif() ) continue; + if ( pObj->GetProxyActivate() ) continue; + + oType = pObj->GetType(); + if ( oType == OBJECT_TOTO || oType == OBJECT_CONTROLLER ) continue; + + if ( oType == OBJECT_RUINmobilew2 || + oType == OBJECT_RUINmobilet1 || + oType == OBJECT_RUINmobilet2 || + oType == OBJECT_RUINmobiler1 || + oType == OBJECT_RUINmobiler2 ) + { + oType = OBJECT_RUINmobilew1; // any ruin + } + + if ( oType == OBJECT_SCRAP2 || + oType == OBJECT_SCRAP3 || + oType == OBJECT_SCRAP4 || + oType == OBJECT_SCRAP5 ) // wastes? + { + oType = OBJECT_SCRAP1; // any waste + } + + if ( oType == OBJECT_BARRIER2 || + oType == OBJECT_BARRIER3 ) // barriers? + { + oType = OBJECT_BARRIER1; // any barrier + } + + if ( filter == FILTER_ONLYLANDING ) + { + physics = pObj->GetPhysics(); + if ( physics != 0 && !physics->GetLand() ) continue; + } + if ( filter == FILTER_ONLYFLYING ) + { + physics = pObj->GetPhysics(); + if ( physics != 0 && physics->GetLand() ) continue; + } + + if ( bArray ) + { + if ( !FindList(array, oType) ) continue; + } + else + { + if ( type != oType && type != OBJECT_NULL ) continue; + } + + oPos = pObj->GetPosition(0); + d = Math::DistanceProjected(iPos, oPos); + if ( d < minDist || d > maxDist ) continue; // too close or too far? + + if ( focus >= Math::PI*2.0f ) + { + if ( (sens >= 0.0f && d < best) || + (sens < 0.0f && d > best) ) + { + best = d; + pBest = pObj; + } + continue; + } + + a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + //TODO uninitialized variable + if ( Math::TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) ) + { + if ( (sens >= 0.0f && d < best) || + (sens < 0.0f && d > best) ) + { + best = d; + pBest = pObj; + } + } + } + + if ( pBest == 0 ) + { + result->SetPointer(0); + } + else + { + result->SetPointer(pBest->GetBotVar()); + } + return true; +} + + +// Monitoring a task. + +bool CScriptFunctions::Process(CScript* script, CBotVar* result, int &exception) +{ + Error err; + + err = script->m_primaryTask->IsEnded(); + if ( err != ERR_CONTINUE ) // task terminated? + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + + script->m_bContinue = false; + + if ( err == ERR_STOP ) err = ERR_OK; + result->SetValInt(err); // indicates the error or ok + if ( ShouldProcessStop(err, script->m_errMode) ) + { + exception = err; + return false; + } + return true; // it's all over + } + + script->m_primaryTask->EventProcess(script->m_event); + script->m_bContinue = true; + return false; // not done +} + + +// Returns true if error code means real error and exception must be thrown + +bool CScriptFunctions::ShouldProcessStop(Error err, int errMode) +{ + // aim impossible - not a real error + if ( err == ERR_AIM_IMPOSSIBLE ) + return false; + + if ( err != ERR_OK && errMode == ERM_STOP ) + return true; + + return false; +} + + +// Compilation of the instruction "detect(type)". + +CBotTypResult CScriptFunctions::cDetect(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypBoolean); +} + +// Instruction "detect(type)". + +bool CScriptFunctions::rDetect(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + CObject *pObj, *pGoal, *pBest; + CPhysics* physics; + CBotVar* array; + Math::Vector iPos, oPos; + RadarFilter filter; + float bGoal, best, minDist, maxDist, sens, iAngle, angle, focus, d, a; + int type, oType, i; + bool bArray = false; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + type = OBJECT_NULL; + array = 0; + angle = 0.0f; + focus = 45.0f*Math::PI/180.0f; + minDist = 0.0f*g_unit; + maxDist = 20.0f*g_unit; + sens = 1.0f; + filter = FILTER_NONE; + + if ( var != 0 ) + { + if ( var->GetType() == CBotTypArrayPointer ) + { + array = var->GetItemList(); + bArray = true; + } + else + { + type = var->GetValInt(); + bArray = false; + } + } + + iPos = pThis->GetPosition(0); + iAngle = pThis->GetAngleY(0)+angle; + iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI + + CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); + + bGoal = 100000.0f; + pGoal = 0; + if ( sens >= 0.0f ) best = 100000.0f; + else best = 0.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = static_cast(iMan->SearchInstance(CLASS_OBJECT, i)); + if ( pObj == 0 ) break; + if ( pObj == pThis ) continue; + + if ( pObj->GetTruck() != 0 ) continue; // object transported? + if ( !pObj->GetActif() ) continue; + if ( pObj->GetProxyActivate() ) continue; + + oType = pObj->GetType(); + if ( oType == OBJECT_TOTO ) continue; + + if ( oType == OBJECT_RUINmobilew2 || + oType == OBJECT_RUINmobilet1 || + oType == OBJECT_RUINmobilet2 || + oType == OBJECT_RUINmobiler1 || + oType == OBJECT_RUINmobiler2 ) + { + oType = OBJECT_RUINmobilew1; // any ruin + } + + if ( oType == OBJECT_SCRAP2 || + oType == OBJECT_SCRAP3 || + oType == OBJECT_SCRAP4 || + oType == OBJECT_SCRAP5 ) // wastes? + { + oType = OBJECT_SCRAP1; // any waste + } + + if ( oType == OBJECT_BARRIER2 || + oType == OBJECT_BARRIER3 ) // barriers? + { + oType = OBJECT_BARRIER1; // any barrier + } + + if ( filter == FILTER_ONLYLANDING ) + { + physics = pObj->GetPhysics(); + if ( physics != 0 && !physics->GetLand() ) continue; + } + if ( filter == FILTER_ONLYFLYING ) + { + physics = pObj->GetPhysics(); + if ( physics != 0 && physics->GetLand() ) continue; + } + + if ( bArray ) + { + if ( !FindList(array, oType) ) continue; + } + else + { + if ( type != oType && type != OBJECT_NULL ) continue; + } + + oPos = pObj->GetPosition(0); + d = Math::DistanceProjected(iPos, oPos); + a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + + if ( d < bGoal && + Math::TestAngle(a, iAngle-(5.0f*Math::PI/180.0f)/2.0f, iAngle+(5.0f*Math::PI/180.0f)/2.0f) ) + { + bGoal = d; + pGoal = pObj; + } + + if ( d < minDist || d > maxDist ) continue; // too close or too far? + + if ( focus >= Math::PI*2.0f ) + { + if ( (sens >= 0.0f && d < best) || + (sens < 0.0f && d > best) ) + { + best = d; + pBest = pObj; + } + continue; + } + + if ( Math::TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) ) + { + if ( (sens >= 0.0f && d < best) || + (sens < 0.0f && d > best) ) + { + best = d; + pBest = pObj; + } + } + } + + pThis->StartDetectEffect(pGoal, pBest!=0); + + if ( pBest == 0 ) + { + script->m_returnValue = 0.0f; + } + else + { + script->m_returnValue = 1.0f; + } + + script->m_primaryTask = new CTaskManager(script->m_object); + err = script->m_primaryTask->StartTaskWait(0.3f); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + if ( !Process(script, result, exception) ) return false; // not finished + result->SetValFloat(script->m_returnValue); + return true; +} + + +// Compilation of the instruction "direction(pos)". + +CBotTypResult CScriptFunctions::cDirection(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + ret = cPoint(var, user); + if ( ret.GetType() != 0 ) return ret; + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "direction(pos)". + +bool CScriptFunctions::rDirection(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CObject* pThis = static_cast(user); + Math::Vector iPos, oPos; + float a, g; + + if ( !GetPoint(var, exception, oPos) ) return true; + + iPos = pThis->GetPosition(0); + + a = pThis->GetAngleY(0); + g = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + + result->SetValFloat(-Math::Direction(a, g)*180.0f/Math::PI); + return true; +} + +// compilation of instruction "canbuild ( category );" + +CBotTypResult CScriptFunctions::cCanBuild(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypBoolean); +} + +// Instruction "canbuild ( category );" +// returns true if this building can be built + +bool CScriptFunctions::rCanBuild(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + ObjectType category = static_cast(var->GetValInt()); //get category parameter + exception = 0; + + bool can = false; + + if ( (category == OBJECT_DERRICK && (g_build & BUILD_DERRICK)) || + (category == OBJECT_FACTORY && (g_build & BUILD_FACTORY)) || + (category == OBJECT_STATION && (g_build & BUILD_STATION)) || + (category == OBJECT_CONVERT && (g_build & BUILD_CONVERT)) || + (category == OBJECT_REPAIR && (g_build & BUILD_REPAIR)) || + (category == OBJECT_TOWER && (g_build & BUILD_TOWER)) || + (category == OBJECT_RESEARCH && (g_build & BUILD_RESEARCH)) || + (category == OBJECT_RADAR && (g_build & BUILD_RADAR)) || + (category == OBJECT_ENERGY && (g_build & BUILD_ENERGY)) || + (category == OBJECT_LABO && (g_build & BUILD_LABO)) || + (category == OBJECT_NUCLEAR && (g_build & BUILD_NUCLEAR)) || + (category == OBJECT_INFO && (g_build & BUILD_INFO)) || + (category == OBJECT_PARA && (g_build & BUILD_PARA)) || + (category == OBJECT_DESTROYER && (g_build & BUILD_DESTROYER))) + { + + // if we want to build not researched one + if ( (category == OBJECT_TOWER && !(g_researchDone & RESEARCH_TOWER)) || + (category == OBJECT_NUCLEAR && !(g_researchDone & RESEARCH_ATOMIC)) + ) + { + can = false; + } + else + { + can = true; + } + + } + + result->SetValInt(can); + + + return true; +} + +// Instruction "build(type)" +// draws error if can not build (wher errormode stop), otherwise 0 <- error + +bool CScriptFunctions::rBuild(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + ObjectType oType; + ObjectType category; + Error err = ERR_BUILD_DISABLED; + + exception = 0; + + oType = pThis->GetType(); + + if ( oType != OBJECT_MOBILEfa && // allowed only for grabber bots + oType != OBJECT_MOBILEta && + oType != OBJECT_MOBILEwa && + oType != OBJECT_MOBILEia) + { + err = ERR_MANIP_VEH; //Wrong vehicle; + } + else + { + category = static_cast(var->GetValInt()); // get category parameter + if ( (category == OBJECT_DERRICK && (g_build & BUILD_DERRICK)) || + (category == OBJECT_FACTORY && (g_build & BUILD_FACTORY)) || + (category == OBJECT_STATION && (g_build & BUILD_STATION)) || + (category == OBJECT_CONVERT && (g_build & BUILD_CONVERT)) || + (category == OBJECT_REPAIR && (g_build & BUILD_REPAIR)) || + (category == OBJECT_TOWER && (g_build & BUILD_TOWER)) || + (category == OBJECT_RESEARCH && (g_build & BUILD_RESEARCH)) || + (category == OBJECT_RADAR && (g_build & BUILD_RADAR)) || + (category == OBJECT_ENERGY && (g_build & BUILD_ENERGY)) || + (category == OBJECT_LABO && (g_build & BUILD_LABO)) || + (category == OBJECT_NUCLEAR && (g_build & BUILD_NUCLEAR)) || + (category == OBJECT_INFO && (g_build & BUILD_INFO)) || + (category == OBJECT_PARA && (g_build & BUILD_PARA)) || + (category == OBJECT_DESTROYER && (g_build & BUILD_DESTROYER))) + { + + // if we want to build not researched one + if ( (category == OBJECT_TOWER && !(g_researchDone & RESEARCH_TOWER)) || + (category == OBJECT_NUCLEAR && !(g_researchDone & RESEARCH_ATOMIC)) + ) + { + err = ERR_BUILD_RESEARCH; + } + else + { + err = ERR_OK; + } + + } + + if (pThis->GetIgnoreBuildCheck()) + err = ERR_OK; + + if (err == ERR_OK && script->m_primaryTask == 0) // if we can build and no task is present + { + script->m_primaryTask = new CTaskManager(script->m_object); + err = script->m_primaryTask->StartTaskBuild(category); + + if (err != ERR_OK) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + } + } + // When script is waiting for finishing this task, it sets ERR_OK, and continues executing Process + // without creating new task. I think, there was a problem with previous version in release configuration + // It did not init error variable in this situation, and code tried to use variable with trash inside + } + + if ( err != ERR_OK ) + { + result->SetValInt(err); // return error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + + return Process(script, result, exception); + +} + +// Compilation of the instruction "produce(pos, angle, type[, scriptName[, power]])" +// or "produce(type[, power])". + +CBotTypResult CScriptFunctions::cProduce(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + + if ( var->GetType() <= CBotTypDouble ) + { + var = var->GetNext(); + if( var != 0 ) + { + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + } + } + else + { + ret = cPoint(var, user); + if ( ret.GetType() != 0 ) return ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != 0 ) + { + if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GetNext(); + + if ( var != 0 ) + { + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + } + } + } + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "produce(pos, angle, type[, scriptName[, power]])" +// or "produce(type[, power])". + +bool CScriptFunctions::rProduce(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* object; + CObject* me = (static_cast(user)); + CBotString cbs; + const char* name; + Math::Vector pos; + float angle; + ObjectType type; + float power; + + if ( var->GetType() <= CBotTypDouble ) + { + type = static_cast(var->GetValInt()); + var = var->GetNext(); + + pos = me->GetPosition(0); + + Math::Vector rotation = me->GetAngle(0) + me->GetInclinaison(); + angle = rotation.y; + + if( var != 0 ) + power = var->GetValFloat(); + else + power = -1.0f; + + name = ""; + } + else + { + if ( !GetPoint(var, exception, pos) ) return true; + + angle = var->GetValFloat()*Math::PI/180.0f; + var = var->GetNext(); + + type = static_cast(var->GetValInt()); + var = var->GetNext(); + + if ( var != 0 ) + { + cbs = var->GetValString(); + name = cbs; + var = var->GetNext(); + if ( var != 0 ) + { + power = var->GetValFloat(); + } + else + { + power = -1.0f; + } + } + else + { + name = ""; + power = -1.0f; + } + } + + if ( type == OBJECT_ANT || + type == OBJECT_SPIDER || + type == OBJECT_BEE || + type == OBJECT_WORM ) + { + CObject* egg; + + object = new CObject(); + if ( !object->CreateInsect(pos, angle, type) ) + { + delete object; + result->SetValInt(1); // error + return true; + } + + egg = new CObject(); + if ( !egg->CreateResource(pos, angle, OBJECT_EGG, 0.0f) ) + { + delete egg; + } + object->SetActivity(false); + } else { + if ((type == OBJECT_POWER || type == OBJECT_ATOMIC) && power == -1.0f) power = 1.0f; + object = CObjectManager::GetInstancePointer()->CreateObject(pos, angle, type, power); + if ( object == nullptr ) + { + result->SetValInt(1); // error + return true; + } + script->m_main->CreateShortcuts(); + } + + if (name[0] != 0) + { + object->ReadProgram(0, static_cast(name)); + object->RunProgram(0); + } + + result->SetValInt(0); // no error + return true; +} + + +// Compilation of the instruction "distance(p1, p2)". + +CBotTypResult CScriptFunctions::cDistance(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + ret = cPoint(var, user); + if ( ret.GetType() != 0 ) return ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + ret = cPoint(var, user); + if ( ret.GetType() != 0 ) return ret; + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "distance(p1, p2)". + +bool CScriptFunctions::rDistance(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + Math::Vector p1, p2; + float value; + + if ( !GetPoint(var, exception, p1) ) return true; + if ( !GetPoint(var, exception, p2) ) return true; + + value = Math::Distance(p1, p2); + result->SetValFloat(value/g_unit); + return true; +} + +// Instruction "distance2d(p1, p2)". + +bool CScriptFunctions::rDistance2d(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + Math::Vector p1, p2; + float value; + + if ( !GetPoint(var, exception, p1) ) return true; + if ( !GetPoint(var, exception, p2) ) return true; + + value = Math::DistanceProjected(p1, p2); + result->SetValFloat(value/g_unit); + return true; +} + + +// Compilation of the instruction "space(center, rMin, rMax, dist)". + +CBotTypResult CScriptFunctions::cSpace(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); + ret = cPoint(var, user); + if ( ret.GetType() != 0 ) return ret; + + if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypIntrinsic, "point"); +} + +// Instruction "space(center, rMin, rMax, dist)". + +bool CScriptFunctions::rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + CBotVar* pSub; + Math::Vector center; + float rMin, rMax, dist; + + rMin = 10.0f*g_unit; + rMax = 50.0f*g_unit; + dist = 4.0f*g_unit; + + if ( var == 0 ) + { + center = pThis->GetPosition(0); + } + else + { + if ( !GetPoint(var, exception, center) ) return true; + + if ( var != 0 ) + { + rMin = var->GetValFloat()*g_unit; + var = var->GetNext(); + + if ( var != 0 ) + { + rMax = var->GetValFloat()*g_unit; + var = var->GetNext(); + + if ( var != 0 ) + { + dist = var->GetValFloat()*g_unit; + var = var->GetNext(); + } + } + } + } + script->m_main->FreeSpace(center, rMin, rMax, dist, pThis); + + if ( result != 0 ) + { + pSub = result->GetItemList(); + if ( pSub != 0 ) + { + pSub->SetValFloat(center.x/g_unit); + pSub = pSub->GetNext(); // "y" + pSub->SetValFloat(center.z/g_unit); + pSub = pSub->GetNext(); // "z" + pSub->SetValFloat(center.y/g_unit); + } + } + return true; +} + + +// Compilation of the instruction "flatground(center, rMax)". + +CBotTypResult CScriptFunctions::cFlatGround(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + ret = cPoint(var, user); + if ( ret.GetType() != 0 ) return ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "flatground(center, rMax)". + +bool CScriptFunctions::rFlatGround(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + Math::Vector center; + float rMax, dist; + + if ( !GetPoint(var, exception, center) ) return true; + rMax = var->GetValFloat()*g_unit; + var = var->GetNext(); + + dist = script->m_main->GetFlatZoneRadius(center, rMax, pThis); + result->SetValFloat(dist/g_unit); + + return true; +} + + +// Instruction "wait(t)". + +bool CScriptFunctions::rWait(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + float value; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_object); + value = var->GetValFloat(); + err = script->m_primaryTask->StartTaskWait(value); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + return Process(script, result, exception); +} + +// Instruction "move(dist)". + +bool CScriptFunctions::rMove(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + float value; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_object); + value = var->GetValFloat(); + err = script->m_primaryTask->StartTaskAdvance(value*g_unit); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + return Process(script, result, exception); +} + +// Instruction "turn(angle)". + +bool CScriptFunctions::rTurn(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + float value; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_object); + value = var->GetValFloat(); + err = script->m_primaryTask->StartTaskTurn(-value*Math::PI/180.0f); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + return Process(script, result, exception); +} + +// Compilation of the instruction "goto(pos, altitude, crash, goal)". + +CBotTypResult CScriptFunctions::cGoto(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + ret = cPoint(var, user); + if ( ret.GetType() != 0 ) return ret; + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + return CBotTypResult(CBotErrOverParam); +} + +// Instruction "goto(pos, altitude, mode)". + +bool CScriptFunctions::rGoto(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + Math::Vector pos; + TaskGotoGoal goal; + TaskGotoCrash crash; + float altitude; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_object); + if ( !GetPoint(var, exception, pos) ) return true; + + goal = TGG_DEFAULT; + crash = TGC_DEFAULT; + altitude = 0.0f*g_unit; + + if ( var != 0 ) + { + altitude = var->GetValFloat()*g_unit; + + var = var->GetNext(); + if ( var != 0 ) + { + goal = static_cast(var->GetValInt()); + + var = var->GetNext(); + if ( var != 0 ) + { + crash = static_cast(var->GetValInt()); + } + } + } + + err = script->m_primaryTask->StartTaskGoto(pos, altitude, goal, crash); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + return Process(script, result, exception); +} + +// Compilation "grab/drop(oper)". + +CBotTypResult CScriptFunctions::cGrabDrop(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Instruction "grab(oper)". + +bool CScriptFunctions::rGrab(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + ObjectType oType; + TaskManipArm type; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_object); + if ( var == 0 ) + { + type = TMA_FFRONT; + } + else + { + type = static_cast(var->GetValInt()); + } + + oType = pThis->GetType(); + if ( oType == OBJECT_HUMAN || + oType == OBJECT_TECH ) + { + err = script->m_primaryTask->StartTaskTake(); + } + else + { + err = script->m_primaryTask->StartTaskManip(TMO_GRAB, type); + } + + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + return Process(script, result, exception); +} + +// Instruction "drop(oper)". + +bool CScriptFunctions::rDrop(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + ObjectType oType; + TaskManipArm type; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_object); + if ( var == 0 ) type = TMA_FFRONT; + else type = static_cast(var->GetValInt()); + + oType = pThis->GetType(); + if ( oType == OBJECT_HUMAN || + oType == OBJECT_TECH ) + { + err = script->m_primaryTask->StartTaskTake(); + } + else + { + err = script->m_primaryTask->StartTaskManip(TMO_DROP, type); + } + + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + return Process(script, result, exception); +} + +// Instruction "sniff()". + +bool CScriptFunctions::rSniff(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_object); + err = script->m_primaryTask->StartTaskSearch(); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + return Process(script, result, exception); +} + +// Compilation of the instruction "receive(nom, power)". + +CBotTypResult CScriptFunctions::cReceive(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Instruction "receive(nom, power)". + +bool CScriptFunctions::rReceive(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + CBotString cbs; + Error err; + const char* p; + float value, power; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_object); + + cbs = var->GetValString(); + p = cbs; + var = var->GetNext(); + + power = 10.0f*g_unit; + if ( var != 0 ) + { + power = var->GetValFloat()*g_unit; + var = var->GetNext(); + } + + err = script->m_primaryTask->StartTaskInfo(static_cast(p), 0.0f, power, false); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetInit(IS_NAN); + return true; + } + } + if ( !Process(script, result, exception) ) return false; // not finished + + value = pThis->GetInfoReturn(); + if ( value == NAN ) + { + result->SetInit(IS_NAN); + } + else + { + result->SetValFloat(value); + } + return true; +} + +// Compilation of the instruction "send(nom, value, power)". + +CBotTypResult CScriptFunctions::cSend(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Instruction "send(nom, value, power)". + +bool CScriptFunctions::rSend(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CBotString cbs; + Error err; + const char* p; + float value, power; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_object); + + cbs = var->GetValString(); + p = cbs; + var = var->GetNext(); + + value = var->GetValFloat(); + var = var->GetNext(); + + power = 10.0f*g_unit; + if ( var != 0 ) + { + power = var->GetValFloat()*g_unit; + var = var->GetNext(); + } + + err = script->m_primaryTask->StartTaskInfo(static_cast(p), value, power, true); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + return Process(script, result, exception); +} + +// Seeks the nearest information terminal. + +CObject* CScriptFunctions::SearchInfo(CScript* script, CObject* object, float power) +{ + CObject *pObj, *pBest; + Math::Vector iPos, oPos; + ObjectType type; + float dist, min; + int i; + + iPos = object->GetPosition(0); + + CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); + + min = 100000.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = static_cast(iMan->SearchInstance(CLASS_OBJECT, i)); + if ( pObj == 0 ) break; + + type = pObj->GetType(); + if ( type != OBJECT_INFO ) continue; + + if ( !pObj->GetActif() ) continue; + + oPos = pObj->GetPosition(0); + dist = Math::Distance(oPos, iPos); + if ( dist > power ) continue; // too far? + if ( dist < min ) + { + min = dist; + pBest = pObj; + } + } + + return pBest; +} + +// Compilation of the instruction "deleteinfo(nom, power)". + +CBotTypResult CScriptFunctions::cDeleteInfo(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Instruction "deleteinfo(nom, power)". + +bool CScriptFunctions::rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + CObject* pInfo; + CBotString cbs; + Info info; + const char* p; + float power; + int i, total; + + exception = 0; + + cbs = var->GetValString(); + p = cbs; + var = var->GetNext(); + + power = 10.0f*g_unit; + if ( var != 0 ) + { + power = var->GetValFloat()*g_unit; + var = var->GetNext(); + } + + pInfo = SearchInfo(script, pThis, power); + if ( pInfo == 0 ) + { + result->SetValFloat(0.0f); // false + return true; + } + + total = pInfo->GetInfoTotal(); + for ( i=0 ; iGetInfo(i); + if ( strcmp(info.name, p) == 0 ) + { + pInfo->DeleteInfo(i); + result->SetValFloat(1.0f); // true + return true; + } + } + result->SetValFloat(0.0f); // false + return true; +} + +// Compilation of the instruction "testinfo(nom, power)". + +CBotTypResult CScriptFunctions::cTestInfo(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypBoolean); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypBoolean); +} + +// Instruction "testinfo(nom, power)". + +bool CScriptFunctions::rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + CObject* pInfo; + CBotString cbs; + Info info; + const char* p; + float power; + int i, total; + + exception = 0; + + cbs = var->GetValString(); + p = cbs; + var = var->GetNext(); + + power = 10.0f*g_unit; + if ( var != 0 ) + { + power = var->GetValFloat()*g_unit; + var = var->GetNext(); + } + + pInfo = SearchInfo(script, pThis, power); + if ( pInfo == 0 ) + { + result->SetValInt(false); + return true; + } + + total = pInfo->GetInfoTotal(); + for ( i=0 ; iGetInfo(i); + if ( strcmp(info.name, p) == 0 ) + { + result->SetValInt(true); + return true; + } + } + result->SetValInt(false); + return true; +} + +// Instruction "thump()". + +bool CScriptFunctions::rThump(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_object); + err = script->m_primaryTask->StartTaskTerraform(); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + return Process(script, result, exception); +} + +// Instruction "recycle()". + +bool CScriptFunctions::rRecycle(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_object); + err = script->m_primaryTask->StartTaskRecover(); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + return Process(script, result, exception); +} + +// Compilation "shield(oper, radius)". + +CBotTypResult CScriptFunctions::cShield(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "shield(oper, radius)". + +bool CScriptFunctions::rShield(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + float oper, radius; + Error err; + + oper = var->GetValFloat(); // 0=down, 1=up + var = var->GetNext(); + + radius = var->GetValFloat(); + if ( radius < 10.0f ) radius = 10.0f; + if ( radius > 25.0f ) radius = 25.0f; + radius = (radius-10.0f)/15.0f; + + if ( *script->m_secondaryTask == 0 ) // shield folds? + { + if ( oper == 0.0f ) // down? + { + result->SetValInt(1); // shows the error + } + else // up ? + { + pThis->SetParam(radius); + + *script->m_secondaryTask = new CTaskManager(script->m_object); + err = (*script->m_secondaryTask)->StartTaskShield(TSM_UP, 1000.0f); + if ( err != ERR_OK ) + { + delete *script->m_secondaryTask; + *script->m_secondaryTask = 0; + result->SetValInt(err); // shows the error + } + } + } + else // shield deployed? + { + if ( oper == 0.0f ) // down? + { + (*script->m_secondaryTask)->StartTaskShield(TSM_DOWN, 0.0f); + } + else // up? + { + //? result->SetValInt(1); // shows the error + pThis->SetParam(radius); + (*script->m_secondaryTask)->StartTaskShield(TSM_UPDATE, 0.0f); + } + } + + return true; +} + +// Compilation "fire(delay)". + +CBotTypResult CScriptFunctions::cFire(CBotVar* &var, void* user) +{ + CObject* pThis = static_cast(user); + ObjectType type; + + type = pThis->GetType(); + + if ( type == OBJECT_ANT ) + { + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + CBotTypResult ret = cPoint(var, user); + if ( ret.GetType() != 0 ) return ret; + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + } + else if ( type == OBJECT_SPIDER ) + { + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + } + else + { + if ( var != 0 ) + { + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + } + } + return CBotTypResult(CBotTypFloat); +} + +// Instruction "fire(delay)". + +bool CScriptFunctions::rFire(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + float delay; + Math::Vector impact; + Error err; + ObjectType type; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_object); + + type = pThis->GetType(); + + if ( type == OBJECT_ANT ) + { + if ( !GetPoint(var, exception, impact) ) return true; + impact.y += pThis->GetWaterLevel(); + err = script->m_primaryTask->StartTaskFireAnt(impact); + } + else if ( type == OBJECT_SPIDER ) + { + err = script->m_primaryTask->StartTaskSpiderExplo(); + } + else + { + if ( var == 0 ) delay = 0.0f; + else delay = var->GetValFloat(); + if ( delay < 0.0f ) delay = -delay; + err = script->m_primaryTask->StartTaskFire(delay); + } + + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + return true; + } + } + return Process(script, result, exception); +} + +// Compilation of the instruction "aim(x, y)". + +CBotTypResult CScriptFunctions::cAim(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "aim(dir)". + +bool CScriptFunctions::rAim(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + float x, y; + Error err; + + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + script->m_primaryTask = new CTaskManager(script->m_object); + x = var->GetValFloat(); + var = var->GetNext(); + var == 0 ? y=0.0f : y=var->GetValFloat(); + err = script->m_primaryTask->StartTaskGunGoal(x*Math::PI/180.0f, y*Math::PI/180.0f); + if ( err == ERR_AIM_IMPOSSIBLE ) + { + result->SetValInt(err); // shows the error + } + else if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + return true; + } + } + return Process(script, result, exception); +} + +// Compilation of the instruction "motor(left, right)". + +CBotTypResult CScriptFunctions::cMotor(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != 0 ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(CBotTypFloat); +} + +// Instruction "motor(left, right)". + +bool CScriptFunctions::rMotor(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CObject* pThis = static_cast(user); + CPhysics* physics = (static_cast(user))->GetPhysics(); + float left, right, speed, turn; + + left = var->GetValFloat(); + var = var->GetNext(); + right = var->GetValFloat(); + + speed = (left+right)/2.0f; + if ( speed < -1.0f ) speed = -1.0f; + if ( speed > 1.0f ) speed = 1.0f; + + turn = left-right; + if ( turn < -1.0f ) turn = -1.0f; + if ( turn > 1.0f ) turn = 1.0f; + + if ( pThis->GetFixed() ) // ant on the back? + { + speed = 0.0f; + turn = 0.0f; + } + + physics->SetMotorSpeedX(speed); // forward/backward + physics->SetMotorSpeedZ(turn); // turns + + return true; +} + +// Instruction "jet(power)". + +bool CScriptFunctions::rJet(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CPhysics* physics = (static_cast(user))->GetPhysics(); + float value; + + value = var->GetValFloat(); + if( value > 1.0f ) value = 1.0f; + + physics->SetMotorSpeedY(value); + + return true; +} + +// Compilation of the instruction "topo(pos)". + +CBotTypResult CScriptFunctions::cTopo(CBotVar* &var, void* user) +{ + CBotTypResult ret; + + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + ret = CScriptFunctions::cPoint(var, user); + if ( ret.GetType() != 0 ) return ret; + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + return CBotTypResult(CBotErrOverParam); +} + +// Instruction "topo(pos)". + +bool CScriptFunctions::rTopo(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + Math::Vector pos; + float level; + + exception = 0; + + if ( !GetPoint(var, exception, pos) ) return true; + + level = script->m_terrain->GetFloorLevel(pos); + level -= script->m_water->GetLevel(); + result->SetValFloat(level/g_unit); + return true; +} + +// Compilation of the instruction "message(string, type)". + +CBotTypResult CScriptFunctions::cMessage(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() != CBotTypString && + var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + return CBotTypResult(CBotErrOverParam); +} + +// Instruction "message(string, type)". + +bool CScriptFunctions::rMessage(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CBotString cbs; + const char* p; + Ui::TextType type; + + cbs = var->GetValString(); + p = cbs; + + type = Ui::TT_MESSAGE; + var = var->GetNext(); + if ( var != 0 ) + { + type = static_cast(var->GetValInt()); + } + + script->m_main->GetDisplayText()->DisplayText(p, script->m_object, 10.0f, type); + script->m_main->CheckEndMessage(p); + + return true; +} + +// Instruction "cmdline(rank)". + +bool CScriptFunctions::rCmdline(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CObject* pThis = static_cast(user); + float value; + int rank; + + rank = var->GetValInt(); + value = pThis->GetCmdLine(rank); + result->SetValFloat(value); + + return true; +} + +// Instruction "ismovie()". + +bool CScriptFunctions::rIsMovie(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + float value; + + value = script->m_main->GetMovieLock()?1.0f:0.0f; + result->SetValFloat(value); + + return true; +} + +// Instruction "errmode(mode)". + +bool CScriptFunctions::rErrMode(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + int value; + + value = var->GetValInt(); + if ( value < 0 ) value = 0; + if ( value > 1 ) value = 1; + script->m_errMode = value; + + return true; +} + +// Instruction "ipf(num)". + +bool CScriptFunctions::rIPF(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + int value; + + value = var->GetValInt(); + if ( value < 1 ) value = 1; + if ( value > 10000 ) value = 10000; + script->m_ipf = value; + + return true; +} + +// Instruction "abstime()". + +bool CScriptFunctions::rAbsTime(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + float value; + + value = script->m_main->GetGameTime(); + result->SetValFloat(value); + return true; +} + + +// Prepares a file name. + +void PrepareFilename(CBotString &filename, const char *dir) +{ + int pos; + + pos = filename.ReverseFind('\\'); + if ( pos > 0 ) + { + filename = filename.Mid(pos+1); // removes folders + } + + pos = filename.ReverseFind('/'); + if ( pos > 0 ) + { + filename = filename.Mid(pos+1); // also those with / + } + + pos = filename.ReverseFind(':'); + if ( pos > 0 ) + { + filename = filename.Mid(pos+1); // also removes the drive letter C: + } + + filename = CBotString(dir) + CBotString("\\") + filename; +} + +// Instruction "deletefile(filename)". + +bool CScriptFunctions::rDeleteFile(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CBotString cbs; + const char* filename; + const char* dir; + + cbs = var->GetValString(); + dir = script->m_main->GetFilesDir(); + PrepareFilename(cbs, dir); + filename = cbs; + //std function that removes file. + return (!remove(filename)); +} + +// Compilation of the instruction "pendown(color, width)". + +CBotTypResult CScriptFunctions::cPenDown(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + return CBotTypResult(CBotErrOverParam); +} + +// Instruction "pendown(color, width)". + +bool CScriptFunctions::rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + int color; + float width; + Error err; + + if ( pThis->GetType() == OBJECT_MOBILEdr ) + { + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + if ( var != 0 ) + { + color = var->GetValInt(); + if ( color < 0 ) color = 0; + if ( color > 17 ) color = 17; + pThis->SetTraceColor(color); + + var = var->GetNext(); + if ( var != 0 ) + { + width = var->GetValFloat(); + if ( width < 0.1f ) width = 0.1f; + if ( width > 1.0f ) width = 1.0f; + pThis->SetTraceWidth(width); + } + } + pThis->SetTraceDown(true); + + script->m_primaryTask = new CTaskManager(script->m_object); + err = script->m_primaryTask->StartTaskPen(pThis->GetTraceDown(), pThis->GetTraceColor()); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + return Process(script, result, exception); + } + else + { + if ( var != 0 ) + { + color = var->GetValInt(); + if ( color < 0 ) color = 0; + if ( color > 17 ) color = 17; + pThis->SetTraceColor(color); + + var = var->GetNext(); + if ( var != 0 ) + { + width = var->GetValFloat(); + if ( width < 0.1f ) width = 0.1f; + if ( width > 1.0f ) width = 1.0f; + pThis->SetTraceWidth(width); + } + } + pThis->SetTraceDown(true); + + return true; + } +} + +// Instruction "penup()". + +bool CScriptFunctions::rPenUp(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + Error err; + + if ( pThis->GetType() == OBJECT_MOBILEdr ) + { + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + pThis->SetTraceDown(false); + + script->m_primaryTask = new CTaskManager(script->m_object); + err = script->m_primaryTask->StartTaskPen(pThis->GetTraceDown(), pThis->GetTraceColor()); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + return Process(script, result, exception); + } + else + { + pThis->SetTraceDown(false); + return true; + } +} + +// Instruction "pencolor()". + +bool CScriptFunctions::rPenColor(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + CObject* pThis = static_cast(user); + int color; + Error err; + + if ( pThis->GetType() == OBJECT_MOBILEdr ) + { + exception = 0; + + if ( script->m_primaryTask == 0 ) // no task in progress? + { + color = var->GetValInt(); + if ( color < 0 ) color = 0; + if ( color > 17 ) color = 17; + pThis->SetTraceColor(color); + + script->m_primaryTask = new CTaskManager(script->m_object); + err = script->m_primaryTask->StartTaskPen(pThis->GetTraceDown(), pThis->GetTraceColor()); + if ( err != ERR_OK ) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + result->SetValInt(err); // shows the error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + } + return Process(script, result, exception); + } + else + { + color = var->GetValInt(); + if ( color < 0 ) color = 0; + if ( color > 17 ) color = 17; + pThis->SetTraceColor(color); + + return true; + } +} + +// Instruction "penwidth()". + +bool CScriptFunctions::rPenWidth(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CObject* pThis = static_cast(user); + float width; + + width = var->GetValFloat(); + if ( width < 0.1f ) width = 0.1f; + if ( width > 1.0f ) width = 1.0f; + pThis->SetTraceWidth(width); + return true; +} + +// Compilation of the instruction with one object parameter + +CBotTypResult CScriptFunctions::cOneObject(CBotVar* &var, void* user) +{ + if ( var == 0 ) return CBotTypResult(CBotErrLowParam); + var = var->GetNext(); + if ( var == 0 ) return CBotTypResult(CBotTypFloat); + + return CBotTypResult(CBotErrOverParam); +} + +// Instruction "camerafocus(object)". + +bool CScriptFunctions::rCameraFocus(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast(user))->GetRunScript(); + + CBotVar* classVars = var->GetItemList(); // "category" + classVars = classVars->GetNext(); // "position" + classVars = classVars->GetNext(); // "orientation" + classVars = classVars->GetNext(); // "pitch" + classVars = classVars->GetNext(); // "roll" + classVars = classVars->GetNext(); // "energyLevel" + classVars = classVars->GetNext(); // "shieldLevel" + classVars = classVars->GetNext(); // "temperature" + classVars = classVars->GetNext(); // "altitude" + classVars = classVars->GetNext(); // "lifeTime" + classVars = classVars->GetNext(); // "material" + classVars = classVars->GetNext(); // "energyCell" + classVars = classVars->GetNext(); // "load" + classVars = classVars->GetNext(); // "id" + int rank = classVars->GetValInt(); + CObject* object = CObjectManager::GetInstancePointer()->SearchInstance(rank); + + script->m_main->SelectObject(object, false); + + result->SetValInt(ERR_OK); + exception = ERR_OK; + return true; +} + +// Static variables + +int CScriptFunctions::m_CompteurFileOpen = 0; +std::string CScriptFunctions::m_filesDir; + + + +// Prepares a file name. + +void PrepareFilename(CBotString &filename) +{ + int pos = filename.ReverseFind('/'); + if ( pos > 0 ) + { + filename = filename.Mid(pos+1); // Remove files with / + } + + pos = filename.ReverseFind(':'); + if ( pos > 0 ) + { + filename = filename.Mid(pos+1); // also removes the drive letter C: + } + + filename = CBotString(CScriptFunctions::m_filesDir.c_str()) + CBotString("/") + filename; + CLogger::GetInstancePointer()->Debug("CBot accessing file '%s'\n", static_cast(filename)); +} + + +// constructor of the class +// get the filename as a parameter + +// execution +bool CScriptFunctions::rfconstruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + CBotString mode; + + // accepts no parameters + if ( pVar == NULL ) return true; + + // must be a character string + if ( pVar->GetType() != CBotTypString ) { Exception = CBotErrBadString; return false; } + + CBotString filename = pVar->GetValString(); + PrepareFilename(filename); + + // there may be a second parameter + pVar = pVar->GetNext(); + if ( pVar != NULL ) + { + // recover mode + mode = pVar->GetValString(); + if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return false; } + + // no third parameter + if ( pVar->GetNext() != NULL ) { Exception = CBotErrOverParam; return false; } + } + + // saves the file name + pVar = pThis->GetItem("filename"); + pVar->SetValString(filename); + + if ( ! mode.IsEmpty() ) + { + // opens the requested file + FILE* pFile = fopen( filename, mode ); + if ( pFile == NULL ) { Exception = CBotErrFileOpen; return false; } + + m_CompteurFileOpen ++; + + // save the file handle + pVar = pThis->GetItem("handle"); + pVar->SetValInt(reinterpret_cast(pFile)); + } + + return true; +} + +// compilation +CBotTypResult CScriptFunctions::cfconstruct (CBotVar* pThis, CBotVar* &pVar) +{ + // accepts no parameters + if ( pVar == NULL ) return CBotTypResult( 0 ); + + // must be a character string + if ( pVar->GetType() != CBotTypString ) + return CBotTypResult( CBotErrBadString ); + + // there may be a second parameter + pVar = pVar->GetNext(); + if ( pVar != NULL ) + { + // which must be a string + if ( pVar->GetType() != CBotTypString ) + return CBotTypResult( CBotErrBadString ); + // no third parameter + if ( pVar->GetNext() != NULL ) return CBotTypResult( CBotErrOverParam ); + } + + // the result is void (constructor) + return CBotTypResult( 0 ); +} + + +// destructor of the class + +// execution +bool CScriptFunctions::rfdestruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + // retrieve the item "handle" + pVar = pThis->GetItem("handle"); + + // don't open? no problem :) + if ( pVar->GetInit() != IS_DEF) return true; + + FILE* pFile= reinterpret_cast(pVar->GetValInt()); + fclose(pFile); + m_CompteurFileOpen --; + + pVar->SetInit(IS_NAN); + + return true; +} + + +// process FILE :: open +// get the r/w mode as a parameter + +// execution +bool CScriptFunctions::rfopen (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + // there must be a parameter + if ( pVar == NULL ) { Exception = CBotErrLowParam; return false; } + + // which must be a character string + if ( pVar->GetType() != CBotTypString ) { Exception = CBotErrBadString; return false; } + + // There may be a second parameter + if ( pVar->GetNext() != NULL ) + { + // if the first parameter is the file name + CBotString filename = pVar->GetValString(); + PrepareFilename(filename); + + // saves the file name + CBotVar* pVar2 = pThis->GetItem("filename"); + pVar2->SetValString(filename); + + // next parameter is the mode + pVar = pVar -> GetNext(); + } + + CBotString mode = pVar->GetValString(); + if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return false; } + + // no third parameter + if ( pVar->GetNext() != NULL ) { Exception = CBotErrOverParam; return false; } + + // retrieve the item "handle" + pVar = pThis->GetItem("handle"); + + // which must not be initialized + if ( pVar->GetInit() == IS_DEF) { Exception = CBotErrFileOpen; return false; } + + // file contains the name + pVar = pThis->GetItem("filename"); + CBotString filename = pVar->GetValString(); + + PrepareFilename(filename); // if the name was h.filename attribute = "..."; + + // opens the requested file + FILE* pFile = fopen( filename, mode ); + if ( pFile == NULL ) + { + pResult->SetValInt(false); + return true; + } + + m_CompteurFileOpen ++; + + // save file handle + pVar = pThis->GetItem("handle"); + pVar->SetValInt(reinterpret_cast(pFile)); + + pResult->SetValInt(true); + return true; +} + +// compilation +CBotTypResult CScriptFunctions::cfopen (CBotVar* pThis, CBotVar* &pVar) +{ + // there must be a parameter + if ( pVar == NULL ) return CBotTypResult( CBotErrLowParam ); + + // which must be a string + if ( pVar->GetType() != CBotTypString ) + return CBotTypResult( CBotErrBadString ); + + // there may be a second parameter + pVar = pVar->GetNext(); + if ( pVar != NULL ) + { + // which must be a string + if ( pVar->GetType() != CBotTypString ) + return CBotTypResult( CBotErrBadString ); + + // no third parameter + if ( pVar->GetNext() != NULL ) return CBotTypResult( CBotErrOverParam ); + } + + // the result is bool + return CBotTypResult(CBotTypBoolean); +} + + +// process FILE :: close + +// execeution +bool CScriptFunctions::rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + // it shouldn't be any parameters + if ( pVar != NULL ) return CBotErrOverParam; + + // retrieve the item "handle" + pVar = pThis->GetItem("handle"); + + if ( pVar->GetInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; } + + FILE* pFile= reinterpret_cast(pVar->GetValInt()); + fclose(pFile); + m_CompteurFileOpen --; + + pVar->SetInit(IS_NAN); + + return true; +} + +// compilation +CBotTypResult CScriptFunctions::cfclose (CBotVar* pThis, CBotVar* &pVar) +{ + // it shouldn't be any parameters + if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam ); + + // function returns a result "void" + return CBotTypResult( 0 ); +} + +// process FILE :: writeln + +// execution +bool CScriptFunctions::rfwrite (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + // there must be a parameter + if ( pVar == NULL ) { Exception = CBotErrLowParam; return false; } + + // which must be a character string + if ( pVar->GetType() != CBotTypString ) { Exception = CBotErrBadString; return false; } + + CBotString param = pVar->GetValString(); + + // retrieve the item "handle" + pVar = pThis->GetItem("handle"); + + if ( pVar->GetInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; } + + FILE* pFile= reinterpret_cast(pVar->GetValInt()); + + int res = fputs(param+CBotString("\n"), pFile); + + // if an error occurs generate an exception + if ( res < 0 ) { Exception = CBotErrWrite; return false; } + + return true; +} + +// compilation +CBotTypResult CScriptFunctions::cfwrite (CBotVar* pThis, CBotVar* &pVar) +{ + // there must be a parameter + if ( pVar == NULL ) return CBotTypResult( CBotErrLowParam ); + + // which must be a character string + if ( pVar->GetType() != CBotTypString ) return CBotTypResult( CBotErrBadString ); + + // no other parameter + if ( pVar->GetNext() != NULL ) return CBotTypResult( CBotErrOverParam ); + + // the function returns a void result + return CBotTypResult( 0 ); +} + +// process FILE :: readln + +// execution +bool CScriptFunctions::rfread (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + // it shouldn't be any parameters + if ( pVar != NULL ) { Exception = CBotErrOverParam; return false; } + + // retrieve the item "handle" + pVar = pThis->GetItem("handle"); + + if ( pVar->GetInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; } + + FILE* pFile= reinterpret_cast(pVar->GetValInt()); + + char chaine[2000]; + int i; + for ( i = 0 ; i < 2000 ; i++ ) chaine[i] = 0; + + fgets(chaine, 1999, pFile); + + for ( i = 0 ; i < 2000 ; i++ ) if (chaine[i] == '\n') chaine[i] = 0; + + // if an error occurs generate an exception + if ( ferror(pFile) ) { Exception = CBotErrRead; return false; } + + pResult->SetValString( chaine ); + + return true; +} + +// compilation +CBotTypResult CScriptFunctions::cfread (CBotVar* pThis, CBotVar* &pVar) +{ + // it should not be any parameter + if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam ); + + // function returns a result "string" + return CBotTypResult( CBotTypString ); +} +// process FILE :: readln + + +// execution +bool CScriptFunctions::rfeof (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + // it should not be any parameter + if ( pVar != NULL ) { Exception = CBotErrOverParam; return false; } + + // retrieve the item "handle" + pVar = pThis->GetItem("handle"); + + if ( pVar->GetInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; } + + FILE* pFile= reinterpret_cast(pVar->GetValInt()); + + pResult->SetValInt( feof( pFile ) ); + + return true; +} + +// compilation +CBotTypResult CScriptFunctions::cfeof (CBotVar* pThis, CBotVar* &pVar) +{ + // it shouldn't be any parameter + if ( pVar != NULL ) return CBotTypResult( CBotErrOverParam ); + + // the function returns a boolean result + return CBotTypResult( CBotTypBoolean ); +} + +// Compilation of class "point". + +CBotTypResult CScriptFunctions::cPointConstructor(CBotVar* pThis, CBotVar* &var) +{ + if ( !pThis->IsElemOfClass("point") ) return CBotTypResult(CBotErrBadNum); + + if ( var == NULL ) return CBotTypResult(0); // ok if no parameter + + // First parameter (x): + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + // Second parameter (y): + if ( var == NULL ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + // Third parameter (z): + if ( var == NULL ) // only 2 parameters? + { + return CBotTypResult(0); // this function returns void + } + + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != NULL ) return CBotTypResult(CBotErrOverParam); + + return CBotTypResult(0); // this function returns void +} + +//Execution of the class "point". + +bool CScriptFunctions::rPointConstructor(CBotVar* pThis, CBotVar* var, CBotVar* pResult, int& Exception) +{ + CBotVar *pX, *pY, *pZ; + + if ( var == NULL ) return true; // constructor with no parameters is ok + + if ( var->GetType() > CBotTypDouble ) + { + Exception = CBotErrBadNum; return false; + } + + pX = pThis->GetItem("x"); + if ( pX == NULL ) + { + Exception = CBotErrUndefItem; return false; + } + pX->SetValFloat( var->GetValFloat() ); + var = var->GetNext(); + + if ( var == NULL ) + { + Exception = CBotErrLowParam; return false; + } + + if ( var->GetType() > CBotTypDouble ) + { + Exception = CBotErrBadNum; return false; + } + + pY = pThis->GetItem("y"); + if ( pY == NULL ) + { + Exception = CBotErrUndefItem; return false; + } + pY->SetValFloat( var->GetValFloat() ); + var = var->GetNext(); + + if ( var == NULL ) + { + return true; // ok with only two parameters + } + + pZ = pThis->GetItem("z"); + if ( pZ == NULL ) + { + Exception = CBotErrUndefItem; return false; + } + pZ->SetValFloat( var->GetValFloat() ); + var = var->GetNext(); + + if ( var != NULL ) + { + Exception = CBotErrOverParam; return false; + } + + return true; // no interruption +} + + + + +// Initializes all functions for module CBOT. + +void CScriptFunctions::Init() +{ + CBotProgram::SetTimer(100); + CBotProgram::Init(); + + for (int i = 0; i < OBJECT_MAX; i++) + { + ObjectType type = static_cast(i); + const char* token = GetObjectName(type); + if (token[0] != 0) + CBotProgram::DefineNum(token, type); + + token = GetObjectAlias(type); + if (token[0] != 0) + CBotProgram::DefineNum(token, type); + } + + CBotProgram::DefineNum("White", 0); + CBotProgram::DefineNum("Black", 1); + CBotProgram::DefineNum("Gray", 2); + CBotProgram::DefineNum("LightGray", 3); + CBotProgram::DefineNum("Red", 4); + CBotProgram::DefineNum("Pink", 5); + CBotProgram::DefineNum("Purple", 6); + CBotProgram::DefineNum("Orange", 7); + CBotProgram::DefineNum("Yellow", 8); + CBotProgram::DefineNum("Beige", 9); + CBotProgram::DefineNum("Brown", 10); + CBotProgram::DefineNum("Skin", 11); + CBotProgram::DefineNum("Green", 12); + CBotProgram::DefineNum("LightGreen", 13); + CBotProgram::DefineNum("Blue", 14); + CBotProgram::DefineNum("LightBlue", 15); + CBotProgram::DefineNum("BlackArrow", 16); + CBotProgram::DefineNum("RedArrow", 17); + + CBotProgram::DefineNum("Metal", OM_METAL); + CBotProgram::DefineNum("Plastic", OM_PLASTIC); + + CBotProgram::DefineNum("InFront", TMA_FFRONT); + CBotProgram::DefineNum("Behind", TMA_FBACK); + CBotProgram::DefineNum("EnergyCell", TMA_POWER); + + CBotProgram::DefineNum("DisplayError", Ui::TT_ERROR); + CBotProgram::DefineNum("DisplayWarning", Ui::TT_WARNING); + CBotProgram::DefineNum("DisplayInfo", Ui::TT_INFO); + CBotProgram::DefineNum("DisplayMessage", Ui::TT_MESSAGE); + + CBotProgram::DefineNum("FilterNone", FILTER_NONE); + CBotProgram::DefineNum("FilterOnlyLanding", FILTER_ONLYLANDING); + CBotProgram::DefineNum("FilterOnlyFliying", FILTER_ONLYFLYING); + + CBotProgram::DefineNum("ExploNone", 0); + CBotProgram::DefineNum("ExploBoum", EXPLO_BOUM); + CBotProgram::DefineNum("ExploBurn", EXPLO_BURN); + CBotProgram::DefineNum("ExploWater", EXPLO_WATER); + + CBotProgram::DefineNum("ResultNotEnded", ERR_MISSION_NOTERM); + CBotProgram::DefineNum("ResultLost", INFO_LOST); + CBotProgram::DefineNum("ResultLostQuick", INFO_LOSTq); + CBotProgram::DefineNum("ResultWin", ERR_OK); + + CBotProgram::DefineNum("BuildBotFactory", BUILD_FACTORY); + CBotProgram::DefineNum("BuildDerrick", BUILD_DERRICK); + CBotProgram::DefineNum("BuildConverter", BUILD_CONVERT); + CBotProgram::DefineNum("BuildRadarStation", BUILD_RADAR); + CBotProgram::DefineNum("BuildPowerPlant", BUILD_ENERGY); + CBotProgram::DefineNum("BuildNuclearPlant", BUILD_NUCLEAR); + CBotProgram::DefineNum("BuildPowerStation", BUILD_STATION); + CBotProgram::DefineNum("BuildRepairCenter", BUILD_REPAIR); + CBotProgram::DefineNum("BuildDefenseTower", BUILD_TOWER); + CBotProgram::DefineNum("BuildResearchCenter", BUILD_RESEARCH); + CBotProgram::DefineNum("BuildAutoLab", BUILD_LABO); + CBotProgram::DefineNum("BuildPowerCaptor", BUILD_PARA); + CBotProgram::DefineNum("BuildExchangePost", BUILD_INFO); + CBotProgram::DefineNum("BuildDestroyer", BUILD_DESTROYER); + CBotProgram::DefineNum("FlatGround", BUILD_GFLAT); + CBotProgram::DefineNum("UseFlags", BUILD_FLAG); + + CBotProgram::DefineNum("ResearchTracked", RESEARCH_TANK); + CBotProgram::DefineNum("ResearchWinged", RESEARCH_FLY); + CBotProgram::DefineNum("ResearchShooter", RESEARCH_CANON); + CBotProgram::DefineNum("ResearchDefenseTower", RESEARCH_TOWER); + CBotProgram::DefineNum("ResearchNuclearPlant", RESEARCH_ATOMIC); + CBotProgram::DefineNum("ResearchThumper", RESEARCH_THUMP); + CBotProgram::DefineNum("ResearchShielder", RESEARCH_SHIELD); + CBotProgram::DefineNum("ResearchPhazerShooter", RESEARCH_PHAZER); + CBotProgram::DefineNum("ResearchLegged", RESEARCH_iPAW); + CBotProgram::DefineNum("ResearchOrgaShooter", RESEARCH_iGUN); + CBotProgram::DefineNum("ResearchRecycler", RESEARCH_RECYCLER); + CBotProgram::DefineNum("ResearchSubber", RESEARCH_SUBM); + CBotProgram::DefineNum("ResearchSniffer", RESEARCH_SNIFFER); + + CBotProgram::DefineNum("PolskiPortalColobota", 1337); + + CBotClass* bc; + + // Add the class Point. + bc = new CBotClass("point", NULL, true); // intrinsic class + bc->AddItem("x", CBotTypFloat); + bc->AddItem("y", CBotTypFloat); + bc->AddItem("z", CBotTypFloat); + bc->AddFunction("point", CScriptFunctions::rPointConstructor, CScriptFunctions::cPointConstructor); + + // Adds the class Object. + bc = new CBotClass("object", NULL); + bc->AddItem("category", CBotTypResult(CBotTypInt), PR_READ); + bc->AddItem("position", CBotTypResult(CBotTypClass, "point"), PR_READ); + bc->AddItem("orientation", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("pitch", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("roll", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("energyLevel", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("shieldLevel", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("temperature", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("altitude", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("lifeTime", CBotTypResult(CBotTypFloat), PR_READ); + bc->AddItem("material", CBotTypResult(CBotTypInt), PR_READ); + bc->AddItem("energyCell", CBotTypResult(CBotTypPointer, "object"), PR_READ); + bc->AddItem("load", CBotTypResult(CBotTypPointer, "object"), PR_READ); + bc->AddItem("id", CBotTypResult(CBotTypInt), PR_READ); + bc->AddFunction("busy", CScriptFunctions::rBusy, CScriptFunctions::cBusy); + bc->AddFunction("factory", CScriptFunctions::rFactory, CScriptFunctions::cFactory); + bc->AddFunction("research", CScriptFunctions::rResearch, CScriptFunctions::cClassOneFloat); + bc->AddFunction("takeoff", CScriptFunctions::rTakeOff, CScriptFunctions::cClassNull); + bc->AddFunction("destroy", CScriptFunctions::rDestroy, CScriptFunctions::cClassNull); + + // InitClassFILE: + // create a class for file management + // the use is as follows: + // file canal( "NomFichier.txt" ) + // canal.open( "r" ); // open for read + // s = canal.readln( ); // reads a line + // canal.close(); // close the file + + // create the class FILE + bc = new CBotClass("file", NULL); + // adds the component ".filename" + bc->AddItem("filename", CBotTypString); + // adds the component ".handle" + bc->AddItem("handle", CBotTypInt, PR_PRIVATE); + + // define a constructor and a destructor + bc->AddFunction("file", CScriptFunctions::rfconstruct, CScriptFunctions::cfconstruct ); + bc->AddFunction("~file", CScriptFunctions::rfdestruct, NULL ); + + // end of the methods associated + bc->AddFunction("open", CScriptFunctions::rfopen, CScriptFunctions::cfopen ); + bc->AddFunction("close", CScriptFunctions::rfclose, CScriptFunctions::cfclose ); + bc->AddFunction("writeln", CScriptFunctions::rfwrite, CScriptFunctions::cfwrite ); + bc->AddFunction("readln", CScriptFunctions::rfread, CScriptFunctions::cfread ); + bc->AddFunction("eof", CScriptFunctions::rfeof, CScriptFunctions::cfeof ); + + //m_pFuncFile = new CBotProgram( ); + //CBotStringArray ListFonctions; + //m_pFuncFile->Compile( "public file openfile(string name, string mode) {return new file(name, mode);}", ListFonctions); + //m_pFuncFile->SetIdent(-2); // restoreState in special identifier for this function + + CBotProgram::AddFunction("sin", rSin, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("cos", rCos, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("tan", rTan, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("asin", raSin, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("acos", raCos, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("atan", raTan, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("sqrt", rSqrt, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("pow", rPow, CScriptFunctions::cTwoFloat); + CBotProgram::AddFunction("rand", rRand, CScriptFunctions::cNull); + CBotProgram::AddFunction("abs", rAbs, CScriptFunctions::cOneFloat); + + CBotProgram::AddFunction("endmission",rEndMission,CScriptFunctions::cEndMission); + CBotProgram::AddFunction("playmusic", rPlayMusic ,CScriptFunctions::cPlayMusic); + CBotProgram::AddFunction("stopmusic", rStopMusic ,CScriptFunctions::cNull); + + CBotProgram::AddFunction("getbuild", rGetBuild, CScriptFunctions::cNull); + CBotProgram::AddFunction("getresearchenable", rGetResearchEnable, CScriptFunctions::cNull); + CBotProgram::AddFunction("getresearchdone", rGetResearchDone, CScriptFunctions::cNull); + CBotProgram::AddFunction("setbuild", rSetBuild, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("setresearchenable", rSetResearchEnable, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("setresearchdone", rSetResearchDone, CScriptFunctions::cOneFloat); + + CBotProgram::AddFunction("progfunc", rProgFunc, CScriptFunctions::cStringString); + CBotProgram::AddFunction("retobject", rGetObject, CScriptFunctions::cGetObject); + CBotProgram::AddFunction("retobjectbyid", rGetObjectById, CScriptFunctions::cGetObject); + CBotProgram::AddFunction("delete", rDelete, CScriptFunctions::cDelete); + CBotProgram::AddFunction("search", rSearch, CScriptFunctions::cSearch); + CBotProgram::AddFunction("radar", rRadar, CScriptFunctions::cRadar); + CBotProgram::AddFunction("detect", rDetect, CScriptFunctions::cDetect); + CBotProgram::AddFunction("direction", rDirection, CScriptFunctions::cDirection); + CBotProgram::AddFunction("produce", rProduce, CScriptFunctions::cProduce); + CBotProgram::AddFunction("distance", rDistance, CScriptFunctions::cDistance); + CBotProgram::AddFunction("distance2d",rDistance2d,CScriptFunctions::cDistance); + CBotProgram::AddFunction("space", rSpace, CScriptFunctions::cSpace); + CBotProgram::AddFunction("flatground",rFlatGround,CScriptFunctions::cFlatGround); + CBotProgram::AddFunction("wait", rWait, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("move", rMove, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("turn", rTurn, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("goto", rGoto, CScriptFunctions::cGoto); + CBotProgram::AddFunction("grab", rGrab, CScriptFunctions::cGrabDrop); + CBotProgram::AddFunction("drop", rDrop, CScriptFunctions::cGrabDrop); + CBotProgram::AddFunction("sniff", rSniff, CScriptFunctions::cNull); + CBotProgram::AddFunction("receive", rReceive, CScriptFunctions::cReceive); + CBotProgram::AddFunction("send", rSend, CScriptFunctions::cSend); + CBotProgram::AddFunction("deleteinfo",rDeleteInfo,CScriptFunctions::cDeleteInfo); + CBotProgram::AddFunction("testinfo", rTestInfo, CScriptFunctions::cTestInfo); + CBotProgram::AddFunction("thump", rThump, CScriptFunctions::cNull); + CBotProgram::AddFunction("recycle", rRecycle, CScriptFunctions::cNull); + CBotProgram::AddFunction("shield", rShield, CScriptFunctions::cShield); + CBotProgram::AddFunction("fire", rFire, CScriptFunctions::cFire); + CBotProgram::AddFunction("aim", rAim, CScriptFunctions::cAim); + CBotProgram::AddFunction("motor", rMotor, CScriptFunctions::cMotor); + CBotProgram::AddFunction("jet", rJet, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("topo", rTopo, CScriptFunctions::cTopo); + CBotProgram::AddFunction("message", rMessage, CScriptFunctions::cMessage); + CBotProgram::AddFunction("cmdline", rCmdline, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("ismovie", rIsMovie, CScriptFunctions::cNull); + CBotProgram::AddFunction("errmode", rErrMode, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("ipf", rIPF, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("abstime", rAbsTime, CScriptFunctions::cNull); + CBotProgram::AddFunction("deletefile",rDeleteFile,CScriptFunctions::cString); + CBotProgram::AddFunction("pendown", rPenDown, CScriptFunctions::cPenDown); + CBotProgram::AddFunction("penup", rPenUp, CScriptFunctions::cNull); + CBotProgram::AddFunction("pencolor", rPenColor, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("penwidth", rPenWidth, CScriptFunctions::cOneFloat); + + CBotProgram::AddFunction("camerafocus", rCameraFocus, CScriptFunctions::cOneObject); + + CBotProgram::AddFunction("canbuild", rCanBuild, CScriptFunctions::cCanBuild); + CBotProgram::AddFunction("build", rBuild, CScriptFunctions::cOneFloat); +} \ No newline at end of file diff --git a/src/script/scriptfunc.h b/src/script/scriptfunc.h new file mode 100644 index 00000000..56d66ebf --- /dev/null +++ b/src/script/scriptfunc.h @@ -0,0 +1,180 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * 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://gnu.org/licenses + */ + +/** + * \file script/scriptfunc.h + * \brief CBot script functions + */ + +#pragma once + +#include "common/global.h" + +#include "CBot/CBotDll.h" + + +class CObject; +class CScript; + + +class CScriptFunctions +{ +public: + static void Init(); + +private: + static CBotTypResult cNull(CBotVar* &var, void* user); + static CBotTypResult cOneFloat(CBotVar* &var, void* user); + static CBotTypResult cTwoFloat(CBotVar* &var, void* user); + static CBotTypResult cString(CBotVar* &var, void* user); + static CBotTypResult cStringString(CBotVar* &var, void* user); + static CBotTypResult cEndMission(CBotVar* &var, void* user); + static CBotTypResult cPlayMusic(CBotVar* &var, void* user); + static CBotTypResult cGetObject(CBotVar* &var, void* user); + static CBotTypResult cDelete(CBotVar* &var, void* user); + static CBotTypResult cSearch(CBotVar* &var, void* user); + static CBotTypResult cRadar(CBotVar* &var, void* user); + static CBotTypResult cDetect(CBotVar* &var, void* user); + static CBotTypResult cDirection(CBotVar* &var, void* user); + static CBotTypResult cCanBuild(CBotVar* &var, void* user); + static CBotTypResult cProduce(CBotVar* &var, void* user); + static CBotTypResult cDistance(CBotVar* &var, void* user); + static CBotTypResult cSpace(CBotVar* &var, void* user); + static CBotTypResult cFlatGround(CBotVar* &var, void* user); + static CBotTypResult cGoto(CBotVar* &var, void* user); + static CBotTypResult cGrabDrop(CBotVar* &var, void* user); + static CBotTypResult cReceive(CBotVar* &var, void* user); + static CBotTypResult cSend(CBotVar* &var, void* user); + static CBotTypResult cDeleteInfo(CBotVar* &var, void* user); + static CBotTypResult cTestInfo(CBotVar* &var, void* user); + static CBotTypResult cShield(CBotVar* &var, void* user); + static CBotTypResult cFire(CBotVar* &var, void* user); + static CBotTypResult cAim(CBotVar* &var, void* user); + static CBotTypResult cMotor(CBotVar* &var, void* user); + static CBotTypResult cTopo(CBotVar* &var, void* user); + static CBotTypResult cMessage(CBotVar* &var, void* user); + static CBotTypResult cPenDown(CBotVar* &var, void* user); + static CBotTypResult cOnePoint(CBotVar* &var, void* user); + static CBotTypResult cPoint(CBotVar* &var, void* user); + static CBotTypResult cOneObject(CBotVar* &var, void* user); + + + static bool rSin(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rCos(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rTan(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rSqrt(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rPow(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rRand(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rAbs(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rEndMission(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rPlayMusic(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rStopMusic(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rGetBuild(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rGetResearchEnable(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rGetResearchDone(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rSetBuild(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rSetResearchEnable(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rSetResearchDone(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rGetObjectById(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rGetObject(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rProgFunc(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDelete(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rSearch(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rRadar(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDetect(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDirection(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rCanBuild(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rBuild(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rProduce(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDistance(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDistance2d(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rSpace(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rFlatGround(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rWait(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rMove(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rTurn(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rGoto(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rFind(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rGrab(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDrop(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rSniff(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rReceive(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rSend(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rThump(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rRecycle(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rShield(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rFire(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rAim(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rMotor(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rJet(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rTopo(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rMessage(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rCmdline(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rIsMovie(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rErrMode(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rIPF(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rAbsTime(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDeleteFile(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rPenUp(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rPenColor(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rPenWidth(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rCameraFocus(CBotVar* var, CBotVar* result, int& exception, void* user); + + + static CBotTypResult cBusy(CBotVar* thisclass, CBotVar* &var); + static CBotTypResult cFactory(CBotVar* thisclass, CBotVar* &var); + static CBotTypResult cClassNull(CBotVar* thisclass, CBotVar* &var); + static CBotTypResult cClassOneFloat(CBotVar* thisclass, CBotVar* &var); + + static bool rBusy(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); + static bool rFactory(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); + static bool rResearch(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); + static bool rTakeOff(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); + static bool rDestroy(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); + + + static CBotTypResult cfconstruct (CBotVar* pThis, CBotVar* &pVar); + static CBotTypResult cfopen (CBotVar* pThis, CBotVar* &pVar); + static CBotTypResult cfclose (CBotVar* pThis, CBotVar* &pVar); + static CBotTypResult cfwrite (CBotVar* pThis, CBotVar* &pVar); + static CBotTypResult cfread (CBotVar* pThis, CBotVar* &pVar); + static CBotTypResult cfeof (CBotVar* pThis, CBotVar* &pVar); + static bool rfconstruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); + static bool rfdestruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); + static bool rfopen (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); + static bool rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); + static bool rfwrite (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); + static bool rfread (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); + static bool rfeof (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); + + static CBotTypResult cPointConstructor(CBotVar* pThis, CBotVar* &var); + static bool rPointConstructor(CBotVar* pThis, CBotVar* var, CBotVar* pResult, int& Exception); + +public: + static int m_CompteurFileOpen; + static std::string m_filesDir; + +private: + static bool Process(CScript* script, CBotVar* result, int &exception); + static bool ShouldProcessStop(Error err, int errMode); + static CObject* SearchInfo(CScript* script, CObject* object, float power); +}; \ No newline at end of file