diff --git a/src/object/object_manager.cpp b/src/object/object_manager.cpp index 3c43c757..1ca47aad 100644 --- a/src/object/object_manager.cpp +++ b/src/object/object_manager.cpp @@ -230,15 +230,15 @@ int CObjectManager::CountObjectsImplementing(ObjectInterfaceType interface) return count; } -CObject* CObjectManager::Radar(CObject* pThis, ObjectType type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes) +std::vector CObjectManager::RadarAll(CObject* pThis, ObjectType type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes) { std::vector types; if (type != OBJECT_NULL) types.push_back(type); - return Radar(pThis, types, angle, focus, minDist, maxDist, furthest, filter, cbotTypes); + return RadarAll(pThis, types, angle, focus, minDist, maxDist, furthest, filter, cbotTypes); } -CObject* CObjectManager::Radar(CObject* pThis, std::vector type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes) +std::vector CObjectManager::RadarAll(CObject* pThis, std::vector type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes) { Math::Vector iPos; float iAngle; @@ -253,22 +253,22 @@ CObject* CObjectManager::Radar(CObject* pThis, std::vector type, flo iPos = Math::Vector(); iAngle = 0.0f; } - return Radar(pThis, iPos, iAngle, type, angle, focus, minDist, maxDist, furthest, filter, cbotTypes); + return RadarAll(pThis, iPos, iAngle, type, angle, focus, minDist, maxDist, furthest, filter, cbotTypes); } -CObject* CObjectManager::Radar(CObject* pThis, Math::Vector thisPosition, float thisAngle, ObjectType type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes) +std::vector CObjectManager::RadarAll(CObject* pThis, Math::Vector thisPosition, float thisAngle, ObjectType type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes) { std::vector types; if (type != OBJECT_NULL) types.push_back(type); - return Radar(pThis, thisPosition, thisAngle, types, angle, focus, minDist, maxDist, furthest, filter, cbotTypes); + return RadarAll(pThis, thisPosition, thisAngle, types, angle, focus, minDist, maxDist, furthest, filter, cbotTypes); } -CObject* CObjectManager::Radar(CObject* pThis, Math::Vector thisPosition, float thisAngle, std::vector type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes) +std::vector CObjectManager::RadarAll(CObject* pThis, Math::Vector thisPosition, float thisAngle, std::vector type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes) { - CObject *pObj, *pBest; + CObject *pObj; Math::Vector iPos, oPos; - float best, iAngle, d, a; + float iAngle, d, a; ObjectType oType; minDist *= g_unit; @@ -282,9 +282,7 @@ CObject* CObjectManager::Radar(CObject* pThis, Math::Vector thisPosition, float RadarFilter filter_flying = static_cast(filter & (FILTER_ONLYLANDING | FILTER_ONLYFLYING)); RadarFilter filter_enemy = static_cast(filter & (FILTER_FRIENDLY | FILTER_ENEMY | FILTER_NEUTRAL)); - if ( !furthest ) best = 100000.0f; - else best = 0.0f; - pBest = nullptr; + std::map best; for ( auto it = m_objects.begin() ; it != m_objects.end() ; ++it ) { pObj = it->second.get(); @@ -359,16 +357,51 @@ CObject* CObjectManager::Radar(CObject* pThis, Math::Vector thisPosition, float a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! if ( Math::TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) || focus >= Math::PI*2.0f ) { - if ( (!furthest && d < best) || - (furthest && d > best) ) - { - best = d; - pBest = pObj; - } + best[d] = pObj; } } - return pBest; + std::vector sortedBest; + if (!furthest) + { + for (auto it = best.begin(); it != best.end(); ++it) + { + sortedBest.push_back(it->second); + } + } + else + { + for (auto it = best.rbegin(); it != best.rend(); ++it) + { + sortedBest.push_back(it->second); + } + } + + return sortedBest; +} + +CObject* CObjectManager::Radar(CObject* pThis, ObjectType type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes) +{ + std::vector best = RadarAll(pThis, type, angle, focus, minDist, maxDist, furthest, filter, cbotTypes); + return best.size() > 0 ? best[0] : nullptr; +} + +CObject* CObjectManager::Radar(CObject* pThis, std::vector type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes) +{ + std::vector best = RadarAll(pThis, type, angle, focus, minDist, maxDist, furthest, filter, cbotTypes); + return best.size() > 0 ? best[0] : nullptr; +} + +CObject* CObjectManager::Radar(CObject* pThis, Math::Vector thisPosition, float thisAngle, ObjectType type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes) +{ + std::vector best = RadarAll(pThis, thisPosition, thisAngle, type, angle, focus, minDist, maxDist, furthest, filter, cbotTypes); + return best.size() > 0 ? best[0] : nullptr; +} + +CObject* CObjectManager::Radar(CObject* pThis, Math::Vector thisPosition, float thisAngle, std::vector type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes) +{ + std::vector best = RadarAll(pThis, thisPosition, thisAngle, type, angle, focus, minDist, maxDist, furthest, filter, cbotTypes); + return best.size() > 0 ? best[0] : nullptr; } CObject* CObjectManager::FindNearest(CObject* pThis, ObjectType type, float maxDist, bool cbotTypes) diff --git a/src/object/object_manager.h b/src/object/object_manager.h index 080a25bc..cd2bde5b 100644 --- a/src/object/object_manager.h +++ b/src/object/object_manager.h @@ -192,6 +192,49 @@ public: return CObjectContainerProxy(m_objects, m_activeObjectIterators); } + //! Finds an object, like radar() in CBot + //@{ + std::vector RadarAll(CObject* pThis, + ObjectType type = OBJECT_NULL, + float angle = 0.0f, + float focus = Math::PI*2.0f, + float minDist = 0.0f, + float maxDist = 1000.0f, + bool furthest = false, + RadarFilter filter = FILTER_NONE, + bool cbotTypes = false); + std::vector RadarAll(CObject* pThis, + std::vector type = std::vector(), + float angle = 0.0f, + float focus = Math::PI*2.0f, + float minDist = 0.0f, + float maxDist = 1000.0f, + bool furthest = false, + RadarFilter filter = FILTER_NONE, + bool cbotTypes = false); + std::vector RadarAll(CObject* pThis, + Math::Vector thisPosition, + float thisAngle, + ObjectType type = OBJECT_NULL, + float angle = 0.0f, + float focus = Math::PI*2.0f, + float minDist = 0.0f, + float maxDist = 1000.0f, + bool furthest = false, + RadarFilter filter = FILTER_NONE, + bool cbotTypes = false); + std::vector RadarAll(CObject* pThis, + Math::Vector thisPosition, + float thisAngle, + std::vector type = std::vector(), + float angle = 0.0f, + float focus = Math::PI*2.0f, + float minDist = 0.0f, + float maxDist = 1000.0f, + bool furthest = false, + RadarFilter filter = FILTER_NONE, + bool cbotTypes = false); + //@} //! Finds an object, like radar() in CBot //@{ CObject* Radar(CObject* pThis, diff --git a/src/script/cbottoken.cpp b/src/script/cbottoken.cpp index dc491c55..535265c1 100644 --- a/src/script/cbottoken.cpp +++ b/src/script/cbottoken.cpp @@ -272,6 +272,7 @@ std::string GetHelpFilename(const char *token) if ( strcmp(token, "destroy" ) == 0 ) helpfile = "cbot/destroy"; if ( strcmp(token, "search" ) == 0 ) helpfile = "cbot/search"; if ( strcmp(token, "radar" ) == 0 ) helpfile = "cbot/radar"; + if ( strcmp(token, "radarall" ) == 0 ) helpfile = "cbot/radarall"; if ( strcmp(token, "direction" ) == 0 ) helpfile = "cbot/direct"; if ( strcmp(token, "distance" ) == 0 ) helpfile = "cbot/dist"; if ( strcmp(token, "distance2d" ) == 0 ) helpfile = "cbot/dist2d"; @@ -421,6 +422,7 @@ bool IsFunction(const char *token) if ( strcmp(token, "destroy" ) == 0 ) return true; if ( strcmp(token, "search" ) == 0 ) return true; if ( strcmp(token, "radar" ) == 0 ) return true; + if ( strcmp(token, "radarall" ) == 0 ) return true; if ( strcmp(token, "detect" ) == 0 ) return true; if ( strcmp(token, "direction" ) == 0 ) return true; if ( strcmp(token, "distance" ) == 0 ) return true; @@ -522,6 +524,7 @@ const char* GetHelpText(const char *token) if ( strcmp(token, "destroy" ) == 0 ) return "object.destroy ( );"; if ( strcmp(token, "search" ) == 0 ) return "search ( cat, pos );"; 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 );"; if ( strcmp(token, "direction" ) == 0 ) return "direction ( position );"; if ( strcmp(token, "distance2d") == 0 ) return "distance2d ( p1, p2 );"; @@ -566,10 +569,10 @@ const char* GetHelpText(const char *token) if ( strcmp(token, "strfind" ) == 0 ) return "strfind ( string, substring );"; if ( strcmp(token, "strlower" ) == 0 ) return "strlower ( string );"; if ( strcmp(token, "strupper" ) == 0 ) return "strupper ( string );"; - if ( strcmp(token, "open" ) == 0 ) return "open ( filename, mode );"; - if ( strcmp(token, "close" ) == 0 ) return "close ( );"; - if ( strcmp(token, "writeln" ) == 0 ) return "writeln ( string );"; - if ( strcmp(token, "readln" ) == 0 ) return "readln ( );"; + if ( strcmp(token, "open" ) == 0 ) return "file.open ( filename, mode );"; + if ( strcmp(token, "close" ) == 0 ) return "file.close ( );"; + if ( strcmp(token, "writeln" ) == 0 ) return "file.writeln ( string );"; + if ( strcmp(token, "readln" ) == 0 ) return "file.readln ( );"; if ( strcmp(token, "eof" ) == 0 ) return "eof ( );"; if ( strcmp(token, "deletefile") == 0 ) return "deletefile ( filename );"; if ( strcmp(token, "openfile" ) == 0 ) return "openfile ( filename, mode );"; diff --git a/src/script/scriptfunc.cpp b/src/script/scriptfunc.cpp index 3b55bb23..a49dc9c1 100644 --- a/src/script/scriptfunc.cpp +++ b/src/script/scriptfunc.cpp @@ -1027,51 +1027,56 @@ bool CScriptFunctions::rSearch(CBotVar* var, CBotVar* result, int& exception, vo } -// Compilation of instruction "radar(type, angle, focus, min, max, sens)". - -CBotTypResult CScriptFunctions::cRadar(CBotVar* &var, void* user) +CBotTypResult compileRadar(CBotVar* &var, void* user, CBotTypResult returnValue) { CBotVar* array; - if ( var == nullptr ) return CBotTypResult(CBotTypPointer, "object"); + if ( var == nullptr ) return returnValue; if ( var->GetType() == CBotTypArrayPointer ) { array = var->GetItemList(); - if ( array == nullptr ) return CBotTypResult(CBotTypPointer, "object"); + if ( array == nullptr ) return returnValue; if ( array->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type } else if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type var = var->GetNext(); - if ( var == nullptr ) return CBotTypResult(CBotTypPointer, "object"); + if ( var == nullptr ) return returnValue; if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // angle var = var->GetNext(); - if ( var == nullptr ) return CBotTypResult(CBotTypPointer, "object"); + if ( var == nullptr ) return returnValue; if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // focus var = var->GetNext(); - if ( var == nullptr ) return CBotTypResult(CBotTypPointer, "object"); + if ( var == nullptr ) return returnValue; if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // min var = var->GetNext(); - if ( var == nullptr ) return CBotTypResult(CBotTypPointer, "object"); + if ( var == nullptr ) return returnValue; if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // max var = var->GetNext(); - if ( var == nullptr ) return CBotTypResult(CBotTypPointer, "object"); + if ( var == nullptr ) return returnValue; if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // sense var = var->GetNext(); - if ( var == nullptr ) return CBotTypResult(CBotTypPointer, "object"); + if ( var == nullptr ) return returnValue; if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // filter var = var->GetNext(); - if ( var == nullptr ) return CBotTypResult(CBotTypPointer, "object"); + if ( var == nullptr ) return returnValue; return CBotTypResult(CBotErrOverParam); } -// Instruction "radar(type, angle, focus, min, max, sens, filter)". - -bool CScriptFunctions::rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) +CBotTypResult CScriptFunctions::cRadarAll(CBotVar* &var, void* user) +{ + return compileRadar(var, user, CBotTypResult(CBotTypArrayPointer, CBotTypResult(CBotTypPointer, "object"))); +} + +// Compilation of instruction "radar(type, angle, focus, min, max, sens)". + +CBotTypResult CScriptFunctions::cRadar(CBotVar* &var, void* user) +{ + return compileRadar(var, user, CBotTypResult(CBotTypPointer, "object")); +} + +bool runRadar(CBotVar* var, std::function, float, float, float, float, bool, RadarFilter)> code) { - CObject* pThis = static_cast(user)->m_object; - CObject *pBest; CBotVar* array; - Math::Vector oPos; RadarFilter filter; float minDist, maxDist, sens, angle, focus; int type; @@ -1153,17 +1158,47 @@ bool CScriptFunctions::rRadar(CBotVar* var, CBotVar* result, int& exception, voi } } - pBest = CObjectManager::GetInstancePointer()->Radar(pThis, type_v, angle, focus, minDist, maxDist, sens < 0, filter, true); //TODO: why is "sens" done like that? + return code(type_v, angle, focus, minDist, maxDist, sens < 0, filter); +} - if ( pBest == nullptr ) +// Instruction "radar(type, angle, focus, min, max, sens, filter)". + +bool CScriptFunctions::rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + return runRadar(var, [&result, user](std::vector types, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter) { - result->SetPointer(nullptr); - } - else + CObject* pThis = static_cast(user)->m_object; + CObject* best = CObjectManager::GetInstancePointer()->Radar(pThis, types, angle, focus, minDist, maxDist, furthest, filter, true); + + if (best == nullptr) + { + result->SetPointer(nullptr); + } + else + { + result->SetPointer(best->GetBotVar()); + } + + return true; + }); +} + +bool CScriptFunctions::rRadarAll(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + return runRadar(var, [&result, user](std::vector types, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter) { - result->SetPointer(pBest->GetBotVar()); - } - return true; + CObject* pThis = static_cast(user)->m_object; + std::vector best = CObjectManager::GetInstancePointer()->RadarAll(pThis, types, angle, focus, 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; + }); } @@ -3779,6 +3814,7 @@ void CScriptFunctions::Init() CBotProgram::AddFunction("delete", rDelete, CScriptFunctions::cDelete); CBotProgram::AddFunction("search", rSearch, CScriptFunctions::cSearch); CBotProgram::AddFunction("radar", rRadar, CScriptFunctions::cRadar); + CBotProgram::AddFunction("radarall", rRadarAll, CScriptFunctions::cRadarAll); CBotProgram::AddFunction("detect", rDetect, CScriptFunctions::cDetect); CBotProgram::AddFunction("direction", rDirection, CScriptFunctions::cDirection); CBotProgram::AddFunction("produce", rProduce, CScriptFunctions::cProduce); diff --git a/src/script/scriptfunc.h b/src/script/scriptfunc.h index e01cf7a4..9428879a 100644 --- a/src/script/scriptfunc.h +++ b/src/script/scriptfunc.h @@ -58,6 +58,7 @@ private: static CBotTypResult cDelete(CBotVar* &var, void* user); static CBotTypResult cSearch(CBotVar* &var, void* user); static CBotTypResult cRadar(CBotVar* &var, void* user); + static CBotTypResult cRadarAll(CBotVar* &var, void* user); static CBotTypResult cDetect(CBotVar* &var, void* user); static CBotTypResult cDirection(CBotVar* &var, void* user); static CBotTypResult cProduce(CBotVar* &var, void* user); @@ -108,6 +109,7 @@ private: static bool rDelete(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rSearch(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rRadar(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rRadarAll(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rDetect(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rDirection(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rCanBuild(CBotVar* var, CBotVar* result, int& exception, void* user);