diff --git a/src/script/cbottoken.cpp b/src/script/cbottoken.cpp index 5d24673e..4dd5c8ec 100644 --- a/src/script/cbottoken.cpp +++ b/src/script/cbottoken.cpp @@ -271,6 +271,7 @@ std::string GetHelpFilename(const char *token) if ( strcmp(token, "factory" ) == 0 ) helpfile = "cbot/factory"; if ( strcmp(token, "destroy" ) == 0 ) helpfile = "cbot/destroy"; if ( strcmp(token, "search" ) == 0 ) helpfile = "cbot/search"; + if ( strcmp(token, "searchall" ) == 0 ) helpfile = "cbot/searchall"; if ( strcmp(token, "radar" ) == 0 ) helpfile = "cbot/radar"; if ( strcmp(token, "radarall" ) == 0 ) helpfile = "cbot/radarall"; if ( strcmp(token, "direction" ) == 0 ) helpfile = "cbot/direct"; @@ -421,6 +422,7 @@ bool IsFunction(const char *token) if ( strcmp(token, "takeoff" ) == 0 ) return true; if ( strcmp(token, "destroy" ) == 0 ) return true; if ( strcmp(token, "search" ) == 0 ) return true; + if ( strcmp(token, "searchall" ) == 0 ) return true; if ( strcmp(token, "radar" ) == 0 ) return true; if ( strcmp(token, "radarall" ) == 0 ) return true; if ( strcmp(token, "detect" ) == 0 ) return true; @@ -522,7 +524,8 @@ const char* GetHelpText(const char *token) if ( strcmp(token, "research" ) == 0 ) return "object.research ( type );"; if ( strcmp(token, "takeoff" ) == 0 ) return "object.takeoff ( );"; if ( strcmp(token, "destroy" ) == 0 ) return "object.destroy ( );"; - if ( strcmp(token, "search" ) == 0 ) return "search ( cat, pos );"; + if ( strcmp(token, "search" ) == 0 ) return "search ( cat, pos, min, max, sens, filter );"; + if ( strcmp(token, "searchall" ) == 0 ) return "searchall ( cat, pos, min, max, sens, filter );"; if ( strcmp(token, "radar" ) == 0 ) return "radar ( cat, angle, focus, min, max, sens, filter );"; if ( strcmp(token, "radarall" ) == 0 ) return "radarall ( cat, angle, focus, min, max, sens, filter );"; if ( strcmp(token, "detect" ) == 0 ) return "detect ( cat );"; diff --git a/src/script/scriptfunc.cpp b/src/script/scriptfunc.cpp index 5fc97564..092ceca1 100644 --- a/src/script/scriptfunc.cpp +++ b/src/script/scriptfunc.cpp @@ -79,9 +79,9 @@ CBotTypResult CScriptFunctions::cClassOneFloat(CBotVar* thisclass, CBotVar* &var return cOneFloat(var, nullptr); } -// Compiling a procedure with a "dot". +// Compile a parameter of type "point". -CBotTypResult CScriptFunctions::cPoint(CBotVar* &var, void* user) +CBotTypResult cPoint(CBotVar* &var, void* user) { if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); @@ -698,63 +698,106 @@ bool CScriptFunctions::rDelete(CBotVar* var, CBotVar* result, int& exception, vo return true; } - - -// Compilation of the instruction "search(type, pos)". - -CBotTypResult CScriptFunctions::cSearch(CBotVar* &var, void* user) +CBotTypResult compileSearch(CBotVar* &var, void* user, CBotTypResult returnValue) { - CBotVar* array; - CBotTypResult ret; - if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); if ( var->GetType() == CBotTypArrayPointer ) { - array = var->GetItemList(); - if ( array == nullptr ) return CBotTypResult(CBotTypPointer); - if ( array->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + CBotTypResult type = var->GetTypResult().GetTypElem(); + if ( type.GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadParam); // type } - else if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + else if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type var = var->GetNext(); - if ( var != nullptr ) - { - ret = cPoint(var, user); - if ( ret.GetType() != 0 ) return ret; - if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); - } - return CBotTypResult(CBotTypPointer, "object"); + if ( var == nullptr ) return returnValue; + + CBotTypResult ret = cPoint(var, user); // pos + if ( ret.GetType() != 0 ) return ret; + + if ( var == nullptr ) return returnValue; + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // min + var = var->GetNext(); + if ( var == nullptr ) return returnValue; + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // max + var = var->GetNext(); + if ( var == nullptr ) return returnValue; + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // sense + var = var->GetNext(); + if ( var == nullptr ) return returnValue; + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // filter + var = var->GetNext(); + if ( var == nullptr ) return returnValue; + return CBotTypResult(CBotErrOverParam); } -// Instruction "search(type, pos)". +// Compilation of "search(type, pos, min, max, sens, filter)". -bool CScriptFunctions::rSearch(CBotVar* var, CBotVar* result, int& exception, void* user) +CBotTypResult CScriptFunctions::cSearch(CBotVar* &var, void* user) { - CObject* pThis = static_cast(user)->m_object; - CObject *pBest; - CBotVar* array; - Math::Vector pos, oPos; - bool bArray; - int type; + return compileSearch(var, user, CBotTypResult(CBotTypPointer, "object")); +} + +CBotTypResult CScriptFunctions::cSearchAll(CBotVar* &var, void* user) +{ + return compileSearch(var, user, CBotTypResult(CBotTypArrayPointer, CBotTypResult(CBotTypPointer, "object"))); +} + +bool runSearch(CBotVar* var, Math::Vector pos, int& exception, std::function, Math::Vector, float, float, bool, RadarFilter)> code) +{ + CBotVar* array; + RadarFilter filter; + float minDist, maxDist, sens; + int type; + bool bArray = false; + + type = OBJECT_NULL; + array = nullptr; + minDist = 0.0f*g_unit; + maxDist = 1000.0f*g_unit; + sens = 1.0f; + filter = FILTER_NONE; - if ( var->GetType() == CBotTypArrayPointer ) - { - array = var->GetItemList(); - bArray = true; - } - else - { - type = var->GetValInt(); - bArray = false; - } - var = var->GetNext(); if ( var != nullptr ) { - if ( !GetPoint(var, exception, pos) ) return true; - } - else - { - pos = pThis->GetPosition(); + if ( var->GetType() == CBotTypArrayPointer ) + { + array = var->GetItemList(); + bArray = true; + } + else + { + type = var->GetValInt(); + bArray = false; + } + + var = var->GetNext(); + if ( var != nullptr ) + { + if ( !GetPoint(var, exception, pos) ) return false; + + if ( var != nullptr ) + { + minDist = var->GetValFloat(); + + var = var->GetNext(); + if ( var != nullptr ) + { + maxDist = var->GetValFloat(); + + var = var->GetNext(); + if ( var != nullptr ) + { + sens = var->GetValFloat(); + + var = var->GetNext(); + if ( var != nullptr ) + { + filter = static_cast(var->GetValInt()); + } + } + } + } + } } std::vector type_v; @@ -774,18 +817,47 @@ bool CScriptFunctions::rSearch(CBotVar* var, CBotVar* result, int& exception, vo } } - pBest = CObjectManager::GetInstancePointer()->Radar(pThis, pos, 0.0f, type_v, 0.0f, Math::PI*2.0f, 0.0f, 1000.0f, false, FILTER_NONE, true); + return code(type_v, pos, minDist, maxDist, sens < 0, filter); +} - if ( pBest == nullptr ) - { - result->SetPointer(nullptr); - } - else - { - result->SetPointer(pBest->GetBotVar()); - } +bool CScriptFunctions::rSearch(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CObject* pThis = static_cast(user)->m_object; - return true; + return runSearch(var, pThis->GetPosition(), exception, [&result, pThis](std::vector types, Math::Vector pos, float minDist, float maxDist, bool furthest, RadarFilter filter) + { + CObject* pBest = CObjectManager::GetInstancePointer()->Radar(pThis, pos, 0.0f, types, 0.0f, Math::PI*2.0f, minDist, maxDist, furthest, filter, true); + + if ( pBest == nullptr ) + { + result->SetPointer(nullptr); + } + else + { + result->SetPointer(pBest->GetBotVar()); + } + + return true; + }); +} + +bool CScriptFunctions::rSearchAll(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CObject* pThis = static_cast(user)->m_object; + + return runSearch(var, pThis->GetPosition(), exception, [&result, pThis](std::vector types, Math::Vector pos, float minDist, float maxDist, bool furthest, RadarFilter filter) + { + std::vector best = CObjectManager::GetInstancePointer()->RadarAll(pThis, pos, 0.0f, types, 0.0f, Math::PI*2.0f, minDist, maxDist, furthest, filter, true); + + int i = 0; + result->SetInit(CBotVar::InitType::DEF); + for (CObject* obj : best) + { + result->GetItem(i++, true)->SetPointer(obj->GetBotVar()); + } + + return true; + }); } @@ -2521,7 +2593,7 @@ CBotTypResult CScriptFunctions::cTopo(CBotVar* &var, void* user) CBotTypResult ret; if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); - ret = CScriptFunctions::cPoint(var, user); + ret = cPoint(var, user); if ( ret.GetType() != 0 ) return ret; if ( var == nullptr ) return CBotTypResult(CBotTypFloat); @@ -3249,6 +3321,7 @@ void CScriptFunctions::Init() CBotProgram::AddFunction("retobjectbyid", rGetObjectById, cGetObject); CBotProgram::AddFunction("delete", rDelete, cDelete); CBotProgram::AddFunction("search", rSearch, cSearch); + CBotProgram::AddFunction("searchall", rSearchAll, cSearchAll); CBotProgram::AddFunction("radar", rRadar, cRadar); CBotProgram::AddFunction("radarall", rRadarAll, cRadarAll); CBotProgram::AddFunction("detect", rDetect, cDetect); diff --git a/src/script/scriptfunc.h b/src/script/scriptfunc.h index c3b3d2d1..5778a9f1 100644 --- a/src/script/scriptfunc.h +++ b/src/script/scriptfunc.h @@ -57,6 +57,7 @@ private: static CBot::CBotTypResult cGetObject(CBot::CBotVar* &var, void* user); static CBot::CBotTypResult cDelete(CBot::CBotVar* &var, void* user); static CBot::CBotTypResult cSearch(CBot::CBotVar* &var, void* user); + static CBot::CBotTypResult cSearchAll(CBot::CBotVar* &var, void* user); static CBot::CBotTypResult cRadar(CBot::CBotVar* &var, void* user); static CBot::CBotTypResult cRadarAll(CBot::CBotVar* &var, void* user); static CBot::CBotTypResult cDetect(CBot::CBotVar* &var, void* user); @@ -81,7 +82,6 @@ private: static CBot::CBotTypResult cPenDown(CBot::CBotVar* &var, void* user); static CBot::CBotTypResult cOnePoint(CBot::CBotVar* &var, void* user); - static CBot::CBotTypResult cPoint(CBot::CBotVar* &var, void* user); static CBot::CBotTypResult cOneObject(CBot::CBotVar* &var, void* user); static bool rEndMission(CBot::CBotVar* var, CBot::CBotVar* result, int& exception, void* user); @@ -97,6 +97,7 @@ private: static bool rGetObject(CBot::CBotVar* var, CBot::CBotVar* result, int& exception, void* user); static bool rDelete(CBot::CBotVar* var, CBot::CBotVar* result, int& exception, void* user); static bool rSearch(CBot::CBotVar* var, CBot::CBotVar* result, int& exception, void* user); + static bool rSearchAll(CBot::CBotVar* var, CBot::CBotVar* result, int& exception, void* user); static bool rRadar(CBot::CBotVar* var, CBot::CBotVar* result, int& exception, void* user); static bool rRadarAll(CBot::CBotVar* var, CBot::CBotVar* result, int& exception, void* user); static bool rDetect(CBot::CBotVar* var, CBot::CBotVar* result, int& exception, void* user);