CObjectManager::Radar

dev-mp
krzys-h 2014-12-20 20:36:09 +01:00
parent c5b6faea05
commit e8a0dc8ddb
3 changed files with 181 additions and 290 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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 )
while ( array != 0 )
{
oType = OBJECT_RUINmobilew1; // any ruin
type_v.push_back(static_cast<ObjectType>(array->GetValInt()));
array = array->GetNext();
}
if ( oType == OBJECT_SCRAP2 ||
oType == OBJECT_SCRAP3 ||
oType == OBJECT_SCRAP4 ||
oType == OBJECT_SCRAP5 ) // wastes?
} else {
if(type != OBJECT_NULL)
{
oType = OBJECT_SCRAP1; // any waste
}
if ( oType == OBJECT_BARRIER2 ||
oType == OBJECT_BARRIER3 ) // barriers?
{
oType = OBJECT_BARRIER1; // any barrier
}
if ( bArray )
{
if ( !FindList(array, oType) ) continue;
}
else
{
if ( type != oType && type != OBJECT_NULL ) continue;
}
if ( bNearest )
{
oPos = pObj->GetPosition(0);
dist = Math::DistanceProjected(pos, oPos);
if ( dist < min )
{
min = dist;
pBest = pObj;
}
}
else
{
pBest = pObj;
break;
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 )
while ( array != 0 )
{
oType = OBJECT_RUINmobilew1; // any ruin
type_v.push_back(static_cast<ObjectType>(array->GetValInt()));
array = array->GetNext();
}
if ( oType == OBJECT_SCRAP2 ||
oType == OBJECT_SCRAP3 ||
oType == OBJECT_SCRAP4 ||
oType == OBJECT_SCRAP5 ) // wastes?
} else {
if(type != OBJECT_NULL)
{
oType = OBJECT_SCRAP1; // any waste
}
if ( oType == OBJECT_BARRIER2 ||
oType == OBJECT_BARRIER3 ) // barriers?
{
oType = OBJECT_BARRIER1; // any barrier
}
if ( filter == FILTER_ONLYLANDING )
{
physics = pObj->GetPhysics();
if ( physics != 0 && !physics->GetLand() ) continue;
}
if ( filter == FILTER_ONLYFLYING )
{
physics = pObj->GetPhysics();
if ( physics != 0 && physics->GetLand() ) continue;
}
if ( bArray )
{
if ( !FindList(array, oType) ) continue;
}
else
{
if ( type != oType && type != OBJECT_NULL ) continue;
}
oPos = pObj->GetPosition(0);
d = Math::DistanceProjected(iPos, oPos);
if ( d < minDist || d > maxDist ) continue; // too close or too far?
if ( focus >= Math::PI*2.0f )
{
if ( (sens >= 0.0f && d < best) ||
(sens < 0.0f && d > best) )
{
best = d;
pBest = pObj;
}
continue;
}
a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW !
//TODO uninitialized variable
if ( Math::TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) )
{
if ( (sens >= 0.0f && d < best) ||
(sens < 0.0f && d > best) )
{
best = d;
pBest = pObj;
}
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 )
while ( array != 0 )
{
oType = OBJECT_RUINmobilew1; // any ruin
type_v.push_back(static_cast<ObjectType>(array->GetValInt()));
array = array->GetNext();
}
if ( oType == OBJECT_SCRAP2 ||
oType == OBJECT_SCRAP3 ||
oType == OBJECT_SCRAP4 ||
oType == OBJECT_SCRAP5 ) // wastes?
} else {
if(type != OBJECT_NULL)
{
oType = OBJECT_SCRAP1; // any waste
}
if ( oType == OBJECT_BARRIER2 ||
oType == OBJECT_BARRIER3 ) // barriers?
{
oType = OBJECT_BARRIER1; // any barrier
}
if ( filter == FILTER_ONLYLANDING )
{
physics = pObj->GetPhysics();
if ( physics != 0 && !physics->GetLand() ) continue;
}
if ( filter == FILTER_ONLYFLYING )
{
physics = pObj->GetPhysics();
if ( physics != 0 && physics->GetLand() ) continue;
}
if ( bArray )
{
if ( !FindList(array, oType) ) continue;
}
else
{
if ( type != oType && type != OBJECT_NULL ) continue;
}
oPos = pObj->GetPosition(0);
d = Math::DistanceProjected(iPos, oPos);
a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW !
if ( d < bGoal &&
Math::TestAngle(a, iAngle-(5.0f*Math::PI/180.0f)/2.0f, iAngle+(5.0f*Math::PI/180.0f)/2.0f) )
{
bGoal = d;
pGoal = pObj;
}
if ( d < minDist || d > maxDist ) continue; // too close or too far?
if ( focus >= Math::PI*2.0f )
{
if ( (sens >= 0.0f && d < best) ||
(sens < 0.0f && d > best) )
{
best = d;
pBest = pObj;
}
continue;
}
if ( Math::TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) )
{
if ( (sens >= 0.0f && d < best) ||
(sens < 0.0f && d > best) )
{
best = d;
pBest = pObj;
}
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;
}