[colobot] 250/390: CObjectManager::Radar
Didier Raboud
odyx at moszumanska.debian.org
Fri Jun 12 14:21:51 UTC 2015
This is an automated email from the git hooks/post-receive script.
odyx pushed a commit to branch upstream/latest
in repository colobot.
commit e8a0dc8ddb646744aad396a4f26aac18d189c92a
Author: krzys-h <krzys_h at interia.pl>
Date: Sat Dec 20 20:36:09 2014 +0100
CObjectManager::Radar
---
src/object/objman.cpp | 123 ++++++++++++++++-
src/object/objman.h | 9 ++
src/script/scriptfunc.cpp | 339 +++++++---------------------------------------
3 files changed, 181 insertions(+), 290 deletions(-)
diff --git a/src/object/objman.cpp b/src/object/objman.cpp
index 040b4fb..5b930c4 100644
--- a/src/object/objman.cpp
+++ b/src/object/objman.cpp
@@ -17,11 +17,17 @@
* along with this program. If not, see http://gnu.org/licenses
*/
+#include "object/objman.h"
+
+
+#include "math/all.h"
#include "object/object.h"
#include "object/auto/auto.h"
-#include "object/objman.h"
+#include "physics/physics.h"
+
+#include <algorithm>
template<> CObjectManager* CSingleton<CObjectManager>::m_instance = nullptr;
@@ -63,6 +69,11 @@ CObject* CObjectManager::GetObjectById(int id)
return m_table[id];
}
+const std::map<int, CObject*>& CObjectManager::GetAllObjects()
+{
+ return m_table;
+}
+
void CObjectManager::Flush()
{
m_table.clear();
@@ -369,4 +380,114 @@ bool CObjectManager::DestroyObject(int id)
if(obj == nullptr) return false;
delete obj; // Destructor calls CObjectManager::DeleteObject
return true;
+}
+
+CObject* CObjectManager::Radar(CObject* pThis, ObjectType type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes)
+{
+ return Radar(pThis, std::vector<ObjectType>(1, type), angle, focus, minDist, maxDist, furthest, filter, cbotTypes);
+}
+
+CObject* CObjectManager::Radar(CObject* pThis, std::vector<ObjectType> type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes)
+{
+ Math::Vector iPos;
+ float iAngle;
+ iPos = pThis->GetPosition(0);
+ iAngle = pThis->GetAngleY(0);
+ iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI
+ return Radar(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)
+{
+ return Radar(pThis, thisPosition, thisAngle, std::vector<ObjectType>(1, type), angle, focus, minDist, maxDist, furthest, filter, cbotTypes);
+}
+
+CObject* CObjectManager::Radar(CObject* pThis, Math::Vector thisPosition, float thisAngle, std::vector<ObjectType> type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes)
+{
+ CObject *pObj, *pBest;
+ CPhysics* physics;
+ Math::Vector iPos, oPos;
+ float best, iAngle, d, a;
+ ObjectType oType;
+
+ minDist *= g_unit;
+ maxDist *= g_unit;
+
+ iPos = thisPosition;
+ iAngle = thisAngle+angle;
+ iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI
+
+ if ( !furthest ) best = 100000.0f;
+ else best = 0.0f;
+ pBest = nullptr;
+ for ( auto it = m_table.begin() ; it != m_table.end() ; ++it )
+ {
+ pObj = it->second;
+ if ( pObj == 0 ) break;
+ if ( pObj == pThis ) continue;
+
+ if ( pObj->GetTruck() != 0 ) continue; // object transported?
+ if ( !pObj->GetActif() ) continue;
+ if ( pObj->GetProxyActivate() ) continue;
+
+ oType = pObj->GetType();
+ if ( oType == OBJECT_TOTO || oType == OBJECT_CONTROLLER ) continue;
+
+ if(cbotTypes) {
+ // TODO: handle this differently (new class describing types? CObjectType::GetBaseType()?)
+ if ( oType == OBJECT_RUINmobilew2 ||
+ oType == OBJECT_RUINmobilet1 ||
+ oType == OBJECT_RUINmobilet2 ||
+ oType == OBJECT_RUINmobiler1 ||
+ oType == OBJECT_RUINmobiler2 )
+ {
+ oType = OBJECT_RUINmobilew1; // any ruin
+ }
+
+ if ( oType == OBJECT_SCRAP2 ||
+ oType == OBJECT_SCRAP3 ||
+ oType == OBJECT_SCRAP4 ||
+ oType == OBJECT_SCRAP5 ) // wastes?
+ {
+ oType = OBJECT_SCRAP1; // any waste
+ }
+
+ if ( oType == OBJECT_BARRIER2 ||
+ oType == OBJECT_BARRIER3 ) // barriers?
+ {
+ oType = OBJECT_BARRIER1; // any barrier
+ }
+ // END OF TODO
+ }
+
+ if ( filter == FILTER_ONLYLANDING )
+ {
+ physics = pObj->GetPhysics();
+ if ( physics != nullptr && !physics->GetLand() ) continue;
+ }
+ if ( filter == FILTER_ONLYFLYING )
+ {
+ physics = pObj->GetPhysics();
+ if ( physics != nullptr && physics->GetLand() ) continue;
+ }
+
+ if ( std::find(type.begin(), type.end(), oType) == type.end() && type.size() > 0 ) continue;
+
+ oPos = pObj->GetPosition(0);
+ d = Math::DistanceProjected(iPos, oPos);
+ if ( d < minDist || d > maxDist ) continue; // too close or too far?
+
+ 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;
+ }
+ }
+ }
+
+ return pBest;
}
\ No newline at end of file
diff --git a/src/object/objman.h b/src/object/objman.h
index 0197c9b..94c4158 100644
--- a/src/object/objman.h
+++ b/src/object/objman.h
@@ -46,6 +46,8 @@ public:
bool DeleteObject(CObject* instance);
//! Finds object by id
CObject* GetObjectById(int id);
+ //! Returns all objects
+ const std::map<int, CObject*>& GetAllObjects();
//! Removes all objects
void Flush();
@@ -54,6 +56,13 @@ public:
CObject* CreateObject(Math::Vector pos, float angle, ObjectType type, float power = -1.f, float zoom = 1.f, float height = 0.f, bool trainer = false, bool toy = false, int option = 0);
//! Destroys an object
bool DestroyObject(int id);
+ //! Finds an object, like radar() in CBot
+ //@{
+ CObject* Radar(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);
+ CObject* Radar(CObject* pThis, std::vector<ObjectType> type = {}, 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);
+ CObject* Radar(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);
+ CObject* Radar(CObject* pThis, Math::Vector thisPosition, float thisAngle, std::vector<ObjectType> type = {}, 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);
+ //@}
protected:
std::map<int, CObject*> m_table;
diff --git a/src/script/scriptfunc.cpp b/src/script/scriptfunc.cpp
index f5ccf86..15bd411 100644
--- a/src/script/scriptfunc.cpp
+++ b/src/script/scriptfunc.cpp
@@ -1049,13 +1049,12 @@ CBotTypResult CScriptFunctions::cSearch(CBotVar* &var, void* user)
bool CScriptFunctions::rSearch(CBotVar* var, CBotVar* result, int& exception, void* user)
{
- CObject *pObj, *pBest;
+ CObject* pThis = static_cast<CObject *>(user);
+ CObject *pBest;
CBotVar* array;
Math::Vector pos, oPos;
- bool bNearest = false;
bool bArray;
- float min, dist;
- int type, oType, i;
+ int type;
if ( var->GetType() == CBotTypArrayPointer )
{
@@ -1071,73 +1070,27 @@ bool CScriptFunctions::rSearch(CBotVar* var, CBotVar* result, int& exception, vo
if ( var != 0 )
{
if ( !GetPoint(var, exception, pos) ) return true;
- bNearest = true;
+ } else {
+ pos = pThis->GetPosition(0);
}
- CInstanceManager* iMan = CInstanceManager::GetInstancePointer();
-
- min = 100000.0f;
- pBest = 0;
- for ( i=0 ; i<1000000 ; i++ )
+ std::vector<ObjectType> type_v;
+ if(bArray)
{
- pObj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i));
- if ( pObj == 0 ) break;
-
- if ( pObj->GetTruck() != 0 ) continue; // object transported?
- if ( !pObj->GetActif() ) continue;
-
- oType = pObj->GetType();
- if ( oType == OBJECT_TOTO ) continue;
-
- if ( oType == OBJECT_RUINmobilew2 ||
- oType == OBJECT_RUINmobilet1 ||
- oType == OBJECT_RUINmobilet2 ||
- oType == OBJECT_RUINmobiler1 ||
- oType == OBJECT_RUINmobiler2 )
- {
- oType = OBJECT_RUINmobilew1; // any ruin
- }
-
- if ( oType == OBJECT_SCRAP2 ||
- oType == OBJECT_SCRAP3 ||
- oType == OBJECT_SCRAP4 ||
- oType == OBJECT_SCRAP5 ) // wastes?
+ while ( array != 0 )
{
- oType = OBJECT_SCRAP1; // any waste
+ type_v.push_back(static_cast<ObjectType>(array->GetValInt()));
+ array = array->GetNext();
}
-
- if ( oType == OBJECT_BARRIER2 ||
- oType == OBJECT_BARRIER3 ) // barriers?
- {
- oType = OBJECT_BARRIER1; // any barrier
- }
-
- if ( bArray )
- {
- if ( !FindList(array, oType) ) continue;
- }
- else
- {
- if ( type != oType && type != OBJECT_NULL ) continue;
- }
-
- if ( bNearest )
- {
- oPos = pObj->GetPosition(0);
- dist = Math::DistanceProjected(pos, oPos);
- if ( dist < min )
- {
- min = dist;
- pBest = pObj;
- }
- }
- else
+ } else {
+ if(type != OBJECT_NULL)
{
- pBest = pObj;
- break;
+ type_v.push_back(static_cast<ObjectType>(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);
@@ -1192,13 +1145,12 @@ CBotTypResult CScriptFunctions::cRadar(CBotVar* &var, void* user)
bool CScriptFunctions::rRadar(CBotVar* var, CBotVar* result, int& exception, void* user)
{
CObject* pThis = static_cast<CObject *>(user);
- CObject *pObj, *pBest;
- CPhysics* physics;
+ CObject *pBest;
CBotVar* array;
- Math::Vector iPos, oPos;
+ Math::Vector oPos;
RadarFilter filter;
- float best, minDist, maxDist, sens, iAngle, angle, focus, d, a;
- int type, oType, i;
+ float minDist, maxDist, sens, angle, focus;
+ int type;
bool bArray = false;
type = OBJECT_NULL;
@@ -1260,100 +1212,24 @@ bool CScriptFunctions::rRadar(CBotVar* var, CBotVar* result, int& exception, voi
}
}
- iPos = pThis->GetPosition(0);
- iAngle = pThis->GetAngleY(0)+angle;
- iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI
-
- CInstanceManager* iMan = CInstanceManager::GetInstancePointer();
-
- if ( sens >= 0.0f ) best = 100000.0f;
- else best = 0.0f;
- pBest = 0;
- for ( i=0 ; i<1000000 ; i++ )
+ std::vector<ObjectType> type_v;
+ if(bArray)
{
- pObj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i));
- if ( pObj == 0 ) break;
- if ( pObj == pThis ) continue;
-
- if ( pObj->GetTruck() != 0 ) continue; // object transported?
- if ( !pObj->GetActif() ) continue;
- if ( pObj->GetProxyActivate() ) continue;
-
- oType = pObj->GetType();
- if ( oType == OBJECT_TOTO || oType == OBJECT_CONTROLLER ) continue;
-
- if ( oType == OBJECT_RUINmobilew2 ||
- oType == OBJECT_RUINmobilet1 ||
- oType == OBJECT_RUINmobilet2 ||
- oType == OBJECT_RUINmobiler1 ||
- oType == OBJECT_RUINmobiler2 )
- {
- oType = OBJECT_RUINmobilew1; // any ruin
- }
-
- if ( oType == OBJECT_SCRAP2 ||
- oType == OBJECT_SCRAP3 ||
- oType == OBJECT_SCRAP4 ||
- oType == OBJECT_SCRAP5 ) // wastes?
- {
- oType = OBJECT_SCRAP1; // any waste
- }
-
- if ( oType == OBJECT_BARRIER2 ||
- oType == OBJECT_BARRIER3 ) // barriers?
- {
- oType = OBJECT_BARRIER1; // any barrier
- }
-
- if ( filter == FILTER_ONLYLANDING )
+ while ( array != 0 )
{
- physics = pObj->GetPhysics();
- if ( physics != 0 && !physics->GetLand() ) continue;
- }
- if ( filter == FILTER_ONLYFLYING )
- {
- physics = pObj->GetPhysics();
- if ( physics != 0 && physics->GetLand() ) continue;
- }
-
- if ( bArray )
- {
- if ( !FindList(array, oType) ) continue;
- }
- else
- {
- if ( type != oType && type != OBJECT_NULL ) continue;
- }
-
- oPos = pObj->GetPosition(0);
- d = Math::DistanceProjected(iPos, oPos);
- if ( d < minDist || d > maxDist ) continue; // too close or too far?
-
- if ( focus >= Math::PI*2.0f )
- {
- if ( (sens >= 0.0f && d < best) ||
- (sens < 0.0f && d > best) )
- {
- best = d;
- pBest = pObj;
- }
- continue;
+ type_v.push_back(static_cast<ObjectType>(array->GetValInt()));
+ array = array->GetNext();
}
-
- a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW !
- //TODO uninitialized variable
- if ( Math::TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) )
+ } else {
+ if(type != OBJECT_NULL)
{
- if ( (sens >= 0.0f && d < best) ||
- (sens < 0.0f && d > best) )
- {
- best = d;
- pBest = pObj;
- }
+ type_v.push_back(static_cast<ObjectType>(type));
}
}
- if ( pBest == 0 )
+ 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);
}
@@ -1427,13 +1303,9 @@ bool CScriptFunctions::rDetect(CBotVar* var, CBotVar* result, int& exception, vo
{
CScript* script = (static_cast<CObject *>(user))->GetRunScript();
CObject* pThis = static_cast<CObject *>(user);
- CObject *pObj, *pGoal, *pBest;
- CPhysics* physics;
+ CObject *pBest;
CBotVar* array;
- Math::Vector iPos, oPos;
- RadarFilter filter;
- float bGoal, best, minDist, maxDist, sens, iAngle, angle, focus, d, a;
- int type, oType, i;
+ int type;
bool bArray = false;
Error err;
@@ -1443,12 +1315,6 @@ bool CScriptFunctions::rDetect(CBotVar* var, CBotVar* result, int& exception, vo
{
type = OBJECT_NULL;
array = 0;
- angle = 0.0f;
- focus = 45.0f*Math::PI/180.0f;
- minDist = 0.0f*g_unit;
- maxDist = 20.0f*g_unit;
- sens = 1.0f;
- filter = FILTER_NONE;
if ( var != 0 )
{
@@ -1464,109 +1330,24 @@ bool CScriptFunctions::rDetect(CBotVar* var, CBotVar* result, int& exception, vo
}
}
- iPos = pThis->GetPosition(0);
- iAngle = pThis->GetAngleY(0)+angle;
- iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI
-
- CInstanceManager* iMan = CInstanceManager::GetInstancePointer();
-
- bGoal = 100000.0f;
- pGoal = 0;
- if ( sens >= 0.0f ) best = 100000.0f;
- else best = 0.0f;
- pBest = 0;
- for ( i=0 ; i<1000000 ; i++ )
+ std::vector<ObjectType> type_v;
+ if(bArray)
{
- pObj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i));
- if ( pObj == 0 ) break;
- if ( pObj == pThis ) continue;
-
- if ( pObj->GetTruck() != 0 ) continue; // object transported?
- if ( !pObj->GetActif() ) continue;
- if ( pObj->GetProxyActivate() ) continue;
-
- oType = pObj->GetType();
- if ( oType == OBJECT_TOTO ) continue;
-
- if ( oType == OBJECT_RUINmobilew2 ||
- oType == OBJECT_RUINmobilet1 ||
- oType == OBJECT_RUINmobilet2 ||
- oType == OBJECT_RUINmobiler1 ||
- oType == OBJECT_RUINmobiler2 )
- {
- oType = OBJECT_RUINmobilew1; // any ruin
- }
-
- if ( oType == OBJECT_SCRAP2 ||
- oType == OBJECT_SCRAP3 ||
- oType == OBJECT_SCRAP4 ||
- oType == OBJECT_SCRAP5 ) // wastes?
- {
- oType = OBJECT_SCRAP1; // any waste
- }
-
- if ( oType == OBJECT_BARRIER2 ||
- oType == OBJECT_BARRIER3 ) // barriers?
- {
- oType = OBJECT_BARRIER1; // any barrier
- }
-
- if ( filter == FILTER_ONLYLANDING )
- {
- physics = pObj->GetPhysics();
- if ( physics != 0 && !physics->GetLand() ) continue;
- }
- if ( filter == FILTER_ONLYFLYING )
- {
- physics = pObj->GetPhysics();
- if ( physics != 0 && physics->GetLand() ) continue;
- }
-
- if ( bArray )
- {
- if ( !FindList(array, oType) ) continue;
- }
- else
- {
- if ( type != oType && type != OBJECT_NULL ) continue;
- }
-
- oPos = pObj->GetPosition(0);
- d = Math::DistanceProjected(iPos, oPos);
- a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW !
-
- if ( d < bGoal &&
- Math::TestAngle(a, iAngle-(5.0f*Math::PI/180.0f)/2.0f, iAngle+(5.0f*Math::PI/180.0f)/2.0f) )
+ while ( array != 0 )
{
- bGoal = d;
- pGoal = pObj;
+ type_v.push_back(static_cast<ObjectType>(array->GetValInt()));
+ array = array->GetNext();
}
-
- if ( d < minDist || d > maxDist ) continue; // too close or too far?
-
- if ( focus >= Math::PI*2.0f )
+ } else {
+ if(type != OBJECT_NULL)
{
- if ( (sens >= 0.0f && d < best) ||
- (sens < 0.0f && d > best) )
- {
- best = d;
- pBest = pObj;
- }
- continue;
- }
-
- if ( Math::TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) )
- {
- if ( (sens >= 0.0f && d < best) ||
- (sens < 0.0f && d > best) )
- {
- best = d;
- pBest = pObj;
- }
+ type_v.push_back(static_cast<ObjectType>(type));
}
}
- pThis->StartDetectEffect(pGoal, pBest!=0);
+ 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 )
{
@@ -2554,37 +2335,17 @@ bool CScriptFunctions::rSend(CBotVar* var, CBotVar* result, int& exception, void
CObject* CScriptFunctions::SearchInfo(CScript* script, CObject* object, float power)
{
- CObject *pObj, *pBest;
+ CObject *pBest;
Math::Vector iPos, oPos;
- ObjectType type;
- float dist, min;
- int i;
iPos = object->GetPosition(0);
+ pBest = CObjectManager::GetInstancePointer()->Radar(object, OBJECT_INFO);
+ if(pBest == nullptr)
+ return nullptr;
+ oPos = object->GetPosition(0);
- CInstanceManager* iMan = CInstanceManager::GetInstancePointer();
-
- min = 100000.0f;
- pBest = 0;
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i));
- if ( pObj == 0 ) break;
-
- type = pObj->GetType();
- if ( type != OBJECT_INFO ) continue;
-
- if ( !pObj->GetActif() ) continue;
-
- oPos = pObj->GetPosition(0);
- dist = Math::Distance(oPos, iPos);
- if ( dist > power ) continue; // too far?
- if ( dist < min )
- {
- min = dist;
- pBest = pObj;
- }
- }
+ if(Math::DistanceProjected(iPos, oPos) > power)
+ return nullptr;
return pBest;
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git
More information about the Pkg-games-commits
mailing list