Matei
0ed2815c8b
LOS issues still outstanding: - LOS looks ugly because of quad tesselation into 2 triangles - Quad tesselation is unspecified by OpenGL (in fact using GL_QUADS on LOS quads seemed to give different tesselations than it did for the underlying terrain quads, but terrain rendering also used GL_QUADS). This should be fixed once we decide on the quad tesselation issue. - Units with traits.vision.permanent set are visible through FOW even if you havent seen them before; this should only be true when you have seen them before. But it gets even more complicated - if a permanent unit seen through FOW dies or gets upgraded or something, perhaps you should remember the old version. I'm not completely sure how to do this (probably involves cloning its actor somehow). This was SVN commit r2876.
130 lines
3.4 KiB
C++
Executable File
130 lines
3.4 KiB
C++
Executable File
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Name: UnitManager.cpp
|
|
// Author: Rich Cross
|
|
// Contact: rich@wildfiregames.com
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "precompiled.h"
|
|
|
|
#include "lib/res/res.h"
|
|
#include "Model.h"
|
|
#include "UnitManager.h"
|
|
#include "Unit.h"
|
|
#include "CConsole.h"
|
|
#include "ObjectManager.h"
|
|
#include "ObjectEntry.h"
|
|
#include "LOSManager.h"
|
|
|
|
extern CConsole* g_Console;
|
|
|
|
#include <algorithm>
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CUnitManager constructor
|
|
CUnitManager::CUnitManager()
|
|
{
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// 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) const
|
|
{
|
|
CLOSManager* losMgr = g_Game->GetWorld()->GetLOSManager();
|
|
|
|
// closest object found so far
|
|
CUnit* hit = 0;
|
|
// distance to closest object found so far
|
|
float dist = 1.0e30f;
|
|
// closest approach offset (easier to pick small stuff in forests than standard ScEd style selection)
|
|
float minrel = 1.0e30f;
|
|
|
|
for (uint i=0;i<m_Units.size();i++) {
|
|
CUnit* unit=m_Units[i];
|
|
float tmin,tmax;
|
|
|
|
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 (!hit || rel < minrel ) {
|
|
hit=unit;
|
|
dist=tmin;
|
|
minrel = rel;
|
|
}
|
|
}
|
|
}
|
|
return hit;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CreateUnit: create a new unit and add it to the world
|
|
CUnit* CUnitManager::CreateUnit(CStr& actorName, CEntity* entity)
|
|
{
|
|
CObjectEntry* obj = g_ObjMan.FindObject(actorName);
|
|
|
|
if (! obj)
|
|
return NULL;
|
|
|
|
CUnit* unit = new CUnit(obj, obj->m_Model->Clone(), entity);
|
|
AddUnit(unit);
|
|
return unit;
|
|
}
|