/* * 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/config.h" #include "common/pathman.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/brain.h" #include "object/object.h" #include "object/object_manager.h" #include "object/robotmain.h" #include "object/task/taskmanager.h" #include "object/subclass/exchange_post.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" #if PLATFORM_WINDOWS #include "app/system_windows.h" #endif // 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 "atan2(y,x)". bool raTan2(CBotVar* var, CBotVar* result, int& exception, void* user) { float y = var->GetValFloat(); var = var->GetNext(); float x = var->GetValFloat(); result->SetValFloat(atan2(y, x) * 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; } // Instruction "floor()" bool CScriptFunctions::rFloor(CBotVar* var, CBotVar* result, int& exception, void* user) { float value; value = var->GetValFloat(); result->SetValFloat(floor(value)); return true; } // Instruction "ceil()" bool CScriptFunctions::rCeil(CBotVar* var, CBotVar* result, int& exception, void* user) { float value; value = var->GetValFloat(); result->SetValFloat(ceil(value)); return true; } // Instruction "round()" bool CScriptFunctions::rRound(CBotVar* var, CBotVar* result, int& exception, void* user) { float value; value = var->GetValFloat(); result->SetValFloat(round(value)); return true; } // Instruction "trunc()" bool CScriptFunctions::rTrunc(CBotVar* var, CBotVar* result, int& exception, void* user) { float value; value = var->GetValFloat(); result->SetValFloat(trunc(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(static_cast(var->GetValFloat())); // TODO: is this correct?! 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()->GetObjectById(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 = CObjectManager::GetInstancePointer()->GetObjectByRank(rank); if ( pObj == nullptr ) { 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(); // "energyCell" classVars = classVars->GetNext(); // "load" classVars = classVars->GetNext(); // "id" int rank = classVars->GetValInt(); CObject* obj = CObjectManager::GetInstancePointer()->GetObjectById(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(); // "energyCell" classVars = classVars->GetNext(); // "load" classVars = classVars->GetNext(); // "id" int rank = classVars->GetValInt(); CObject* obj = CObjectManager::GetInstancePointer()->GetObjectById(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(); // "energyCell" classVars = classVars->GetNext(); // "load" classVars = classVars->GetNext(); // "id" int rank = classVars->GetValInt(); CObject* factory = CObjectManager::GetInstancePointer()->GetObjectById(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(); // "energyCell" classVars = classVars->GetNext(); // "load" classVars = classVars->GetNext(); // "id" int rank = classVars->GetValInt(); CObject* center = CObjectManager::GetInstancePointer()->GetObjectById(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(); // "energyCell" classVars = classVars->GetNext(); // "load" classVars = classVars->GetNext(); // "id" int rank = classVars->GetValInt(); CObject* center = CObjectManager::GetInstancePointer()->GetObjectById(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) { int exploType = 0; float force = std::numeric_limits::infinity(); int rank = var->GetValInt(); var->GetNext(); if ( var != 0 ) { exploType = var->GetValInt(); var->GetNext(); if ( var != 0 ) { force = var->GetValFloat(); } } CObject* obj = CObjectManager::GetInstancePointer()->GetObjectById(rank); if ( obj == nullptr ) { return true; } else { if ( exploType ) { obj->ExplodeObject(static_cast(exploType), force); } else { CObjectManager::GetInstancePointer()->DeleteObject(obj); } } 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* pThis = static_cast(user); CObject *pBest; CBotVar* array; Math::Vector pos, oPos; bool bArray; int type; 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; } else { pos = pThis->GetPosition(0); } std::vector type_v; if (bArray) { while ( array != 0 ) { type_v.push_back(static_cast(array->GetValInt())); array = array->GetNext(); } } else { if (type != OBJECT_NULL) { type_v.push_back(static_cast(type)); } } pBest = CObjectManager::GetInstancePointer()->Radar(pThis, pos, 0.0f, type_v, 0.0f, Math::PI*2.0f, 0.0f, 1000.0f, false, FILTER_NONE, true); 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 *pBest; CBotVar* array; Math::Vector oPos; RadarFilter filter; float minDist, maxDist, sens, angle, focus; int type; 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(); var = var->GetNext(); if ( var != 0 ) { maxDist = var->GetValFloat(); var = var->GetNext(); if ( var != 0 ) { sens = var->GetValFloat(); var = var->GetNext(); if ( var != 0 ) { filter = static_cast(var->GetValInt()); } } } } } } } std::vector type_v; if (bArray) { while ( array != 0 ) { type_v.push_back(static_cast(array->GetValInt())); array = array->GetNext(); } } else { if (type != OBJECT_NULL) { type_v.push_back(static_cast(type)); } } pBest = CObjectManager::GetInstancePointer()->Radar(pThis, type_v, angle, focus, minDist, maxDist, sens < 0, filter, true); //TODO: why is "sens" done like that? if ( pBest == nullptr ) { 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 *pBest; CBotVar* array; int type; bool bArray = false; Error err; exception = 0; if ( script->m_primaryTask == 0 ) // no task in progress? { type = OBJECT_NULL; array = 0; if ( var != 0 ) { if ( var->GetType() == CBotTypArrayPointer ) { array = var->GetItemList(); bArray = true; } else { type = var->GetValInt(); bArray = false; } } std::vector type_v; if (bArray) { while ( array != 0 ) { type_v.push_back(static_cast(array->GetValInt())); array = array->GetNext(); } } else { if (type != OBJECT_NULL) { type_v.push_back(static_cast(type)); } } pBest = CObjectManager::GetInstancePointer()->Radar(pThis, type_v, 0.0f, 45.0f*Math::PI/180.0f, 0.0f, 20.0f, false, FILTER_NONE, true); pThis->StartDetectEffect(pBest, pBest != nullptr); 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 && humans oType != OBJECT_MOBILEta && oType != OBJECT_MOBILEwa && oType != OBJECT_MOBILEia && oType != OBJECT_HUMAN && oType != OBJECT_TECH) { err = ERR_MANIP_VEH; // Wrong object } 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* me = (static_cast(user)); const char* name = ""; Math::Vector pos; float angle = 0.0f; ObjectType type = OBJECT_NULL; float power = 0.0f; if ( var->GetType() <= CBotTypDouble ) { type = static_cast(var->GetValInt()); var = var->GetNext(); pos = me->GetPosition(0); Math::Vector rotation = me->GetAngle(0) + me->GetTilt(); angle = rotation.y; if ( var != nullptr ) 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 != nullptr ) { CBotString cbs = var->GetValString(); name = cbs; var = var->GetNext(); if ( var != nullptr ) { power = var->GetValFloat(); } else { power = -1.0f; } } else { name = ""; power = -1.0f; } } CObject* object = nullptr; if ( type == OBJECT_ANT || type == OBJECT_SPIDER || type == OBJECT_BEE || type == OBJECT_WORM ) { CObject* object = CObjectManager::GetInstancePointer()->CreateObject(pos, angle, type); CObjectManager::GetInstancePointer()->CreateObject(pos, angle, OBJECT_EGG, 0.0f); 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) { std::string name2 = CPathManager::InjectLevelDir(name, "ai"); CBrain* brain = object->GetBrain(); if (brain != nullptr) { Program* program = brain->AddProgram(); brain->ReadProgram(program, name2.c_str()); brain->RunProgram(program); } } 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. CExchangePost* CScriptFunctions::FindExchangePost(CObject* object, float power) { CObject* exchangePost = CObjectManager::GetInstancePointer()->FindNearest(object, OBJECT_INFO, power/g_unit); return dynamic_cast(exchangePost); } // Compilation of the instruction "deleteinfo(name, 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(CBotTypBoolean); if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypBoolean); } // Instruction "deleteinfo(name, power)". bool CScriptFunctions::rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user) { CObject* pThis = static_cast(user); exception = 0; CBotString infoNameCbs = var->GetValString(); std::string infoName = std::string(static_cast(infoNameCbs)); var = var->GetNext(); float power = 10.0f*g_unit; if (var != nullptr) { power = var->GetValFloat()*g_unit; var = var->GetNext(); } CExchangePost* exchangePost = FindExchangePost(pThis, power); if (exchangePost == nullptr) { result->SetValInt(false); return true; } bool infoDeleted = exchangePost->DeleteInfo(infoName); result->SetValInt(infoDeleted); 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(name, power)". bool CScriptFunctions::rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user) { CObject* pThis = static_cast(user); exception = 0; CBotString infoNameCbs = var->GetValString(); std::string infoName = std::string(static_cast(infoNameCbs)); var = var->GetNext(); float power = 10.0f*g_unit; if (var != nullptr) { power = var->GetValFloat()*g_unit; var = var->GetNext(); } CExchangePost* exchangePost = FindExchangePost(pThis, power); if (exchangePost == nullptr) { result->SetValInt(false); return true; } bool foundInfo = exchangePost->HasInfo(infoName); result->SetValInt(foundInfo); 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; // only shielder can use shield() if (pThis->GetType() != OBJECT_MOBILErs) { result->SetValInt(ERR_MANIP_VEH); // return error if (script->m_errMode == ERM_STOP) { exception = ERR_MANIP_VEH; return false; } return true; } 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(); // "energyCell" classVars = classVars->GetNext(); // "load" classVars = classVars->GetNext(); // "id" int rank = classVars->GetValInt(); CObject* object = CObjectManager::GetInstancePointer()->GetObjectById(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; std::unordered_map CScriptFunctions::m_files; int CScriptFunctions::m_nextFile = 1; // 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: } #if PLATFORM_WINDOWS boost::filesystem::create_directories(CSystemUtilsWindows::UTF8_Decode(CScriptFunctions::m_filesDir)); #else boost::filesystem::create_directories(CScriptFunctions::m_filesDir); #endif 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 ++; int fileHandle = m_nextFile++; m_files[fileHandle] = pFile; // save the file handle pVar = pThis->GetItem("handle"); pVar->SetValInt(fileHandle); } 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; int fileHandle = pVar->GetValInt(); FILE* pFile = m_files[fileHandle]; fclose(pFile); m_CompteurFileOpen--; pVar->SetInit(IS_NAN); m_files.erase(fileHandle); 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 int fileHandle = m_nextFile++; m_files[fileHandle] = pFile; pVar = pThis->GetItem("handle"); pVar->SetValInt(fileHandle); 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) { Exception = CBotErrOverParam; return false; } // retrieve the item "handle" pVar = pThis->GetItem("handle"); if ( pVar->GetInit() != IS_DEF) { Exception = CBotErrNotOpen; return false; } int fileHandle = pVar->GetValInt(); FILE* pFile = m_files[fileHandle]; fclose(pFile); m_CompteurFileOpen--; pVar->SetInit(IS_NAN); m_files.erase(fileHandle); 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; } int fileHandle = pVar->GetValInt(); FILE* pFile = m_files[fileHandle]; 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; } int fileHandle = pVar->GetValInt(); FILE* pFile = m_files[fileHandle]; char chaine[2000]; int i; for (i = 0; i < 2000; i++) chaine[i] = 0; if (fgets(chaine, 1999, pFile) != nullptr) { 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; } int fileHandle = pVar->GetValInt(); FILE* pFile = m_files[fileHandle]; 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("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", static_cast(ExplosionType::Bang)); CBotProgram::DefineNum("ExploBurn", static_cast(ExplosionType::Burn)); CBotProgram::DefineNum("ExploWater", static_cast(ExplosionType::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("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("atan2", raTan2, CScriptFunctions::cTwoFloat); 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("floor", rFloor, CScriptFunctions::cOneFloat); CBotProgram::AddFunction("ceil", rCeil, CScriptFunctions::cOneFloat); CBotProgram::AddFunction("round", rRound, CScriptFunctions::cOneFloat); CBotProgram::AddFunction("trunc", rTrunc, 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); }