1
0
forked from 0ad/0ad
0ad/source/graphics/UnitManager.cpp
Ykkrosh 3f017c418c Removed some header files from header files.
Changed SoundGroupTable to use the right string type for the comparison.
Also changed from CStr8 to CStr because I prefer that spelling (and it's
more consistent with most other code).

This was SVN commit r4771.
2007-01-13 22:44:42 +00:00

152 lines
3.9 KiB
C++

///////////////////////////////////////////////////////////////////////////////
//
// Name: UnitManager.cpp
// Author: Rich Cross
// Contact: rich@wildfiregames.com
//
///////////////////////////////////////////////////////////////////////////////
#include "precompiled.h"
#include <float.h>
#include "lib/res/res.h"
#include "Model.h"
#include "UnitManager.h"
#include "Unit.h"
#include "ObjectManager.h"
#include "ObjectEntry.h"
#include "ps/Game.h"
#include "ps/World.h"
#include "simulation/Entity.h"
#include "simulation/LOSManager.h"
#include <algorithm>
///////////////////////////////////////////////////////////////////////////////
// CUnitManager constructor
CUnitManager::CUnitManager()
: m_NextID(0)
{
}
///////////////////////////////////////////////////////////////////////////////
// CUnitManager destructor
CUnitManager::~CUnitManager()
{
DeleteAll();
}
///////////////////////////////////////////////////////////////////////////////
// AddUnit: add given unit to world
void CUnitManager::AddUnit(CUnit* unit)
{
m_Units.push_back(unit);
}
///////////////////////////////////////////////////////////////////////////////
// RemoveUnit: remove given unit from world, but don't delete it
void CUnitManager::RemoveUnit(CUnit* unit)
{
// find entry in list
typedef std::vector<CUnit*>::iterator Iter;
Iter i=std::find(m_Units.begin(),m_Units.end(),unit);
if (i!=m_Units.end()) {
m_Units.erase(i);
}
}
///////////////////////////////////////////////////////////////////////////////
// DeleteUnit: remove given unit from world and delete it
void CUnitManager::DeleteUnit(CUnit* unit)
{
RemoveUnit(unit);
delete unit;
}
///////////////////////////////////////////////////////////////////////////////
// DeleteAll: remove and delete all units
void CUnitManager::DeleteAll()
{
uint i;
for (i=0;i<m_Units.size();i++) {
delete m_Units[i];
}
m_Units.clear();
}
///////////////////////////////////////////////////////////////////////////////
// PickUnit: iterate through units testing given ray against bounds of each
// unit; return the closest unit, or null if everything missed
CUnit* CUnitManager::PickUnit(const CVector3D& origin, const CVector3D& dir, bool entitiesOnly) const
{
CLOSManager* losMgr = g_Game->GetWorld()->GetLOSManager();
// closest object found so far
CUnit* hit = 0;
// distance to closest object found so far
float dist = FLT_MAX;
// closest approach offset (easier to pick small stuff in forests than standard ScEd style selection)
float minrel = FLT_MAX;
for (uint i=0; i<m_Units.size(); i++) {
CUnit* unit = m_Units[i];
float tmin, tmax;
CEntity* ent = unit->GetEntity();
if( entitiesOnly && !ent )
continue;
if( ent && !ent->m_visible )
continue;
if (unit->GetModel()->GetBounds().RayIntersect(origin, dir, tmin, tmax)
&& losMgr->GetUnitStatus(unit, g_Game->GetLocalPlayer()) != UNIT_HIDDEN)
{
// Point of closest approach
CVector3D obj;
unit->GetModel()->GetBounds().GetCentre(obj);
CVector3D delta = obj - origin;
float distance = delta.Dot(dir);
CVector3D closest = origin + dir * distance;
CVector3D offset = obj - closest;
float rel = offset.GetLength();
if (rel < minrel) {
hit = unit;
dist = tmin;
minrel = rel;
}
}
}
return hit;
}
///////////////////////////////////////////////////////////////////////////////
// CreateUnit: create a new unit and add it to the world
CUnit* CUnitManager::CreateUnit(const CStr& actorName, CEntity* entity, const std::set<CStr8>& selections)
{
if (! m_ObjectManager)
return NULL;
CUnit* unit = CUnit::Create(actorName, entity, selections, *m_ObjectManager);
if (unit)
AddUnit(unit);
return unit;
}
///////////////////////////////////////////////////////////////////////////////
// FindByID
CUnit* CUnitManager::FindByID(int id) const
{
if (id < 0)
return NULL;
for (size_t i = 0; i < m_Units.size(); ++i)
if (m_Units[i]->GetID() == id)
return m_Units[i];
return NULL;
}