khanat-opennel-code/code/ryzom/tools/reynolds/reynolds_manager.cpp
2011-05-31 19:50:16 +03:00

461 lines
12 KiB
C++

// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdpch.h"
#include "reynolds_manager.h"
#include "nel/georges/u_form_loader.h"
#include "nel/georges/load_form.h"
using namespace std;
using namespace NLMISC;
using namespace NLPACS;
using namespace NLGEORGES;
/*
* Manager variables
*/
// Continents
CContinentContainer CReynoldsManager::_Continents;
// Track Map, all tracks referenced, held by a simple pointer so when no one references a track, it is deleted
CReynoldsManager::TTrackMap CReynoldsManager::_TrackMap;
// Controlled Track Map, only controlled tracks, held by a smart pointer
CReynoldsManager::TControlledTrackMap CReynoldsManager::_ControlledTrackMap;
// Command interface
CReynoldsManager::ICommandInterface *CReynoldsManager::_CommandInterface = NULL;
// User init callback
CReynoldsManager::TUserCallback CReynoldsManager::_UserInitCallback = NULL;
// User motion callback
CReynoldsManager::TUserMotionCallback CReynoldsManager::_UserMotionCallback = NULL;
// User release callback
CReynoldsManager::TUserCallback CReynoldsManager::_UserReleaseCallback = NULL;
// Georges sheets
map<CSheetId, CTrack::CSheet> CReynoldsManager::_Sheets;
// Sheets initialised ?
bool CReynoldsManager::_Initialised;
// Current internal cycle
uint32 CReynoldsManager::_Cycle;
/*
* Manager methods
*/
// ------------------------------------
// Constructor
CReynoldsManager::CReynoldsManager()
{
nlerror("CReynoldsManager: static library, must not be instanciated !");
}
// ------------------------------------
// Init
void CReynoldsManager::init(const std::string &packSheetFile)
{
_Continents.init(100, 100, 8.0, 1);
initSheets(packSheetFile);
_Cycle = 0;
}
// ------------------------------------
// Update
void CReynoldsManager::update(double dt)
{
TControlledTrackMap::iterator it;
for (it=_ControlledTrackMap.begin(); it!=_ControlledTrackMap.end(); ++it)
{
CTrack *track = (CTrack*)((*it).second);
track->update(dt);
}
++_Cycle;
}
// ------------------------------------
// Release
void CReynoldsManager::release()
{
_Continents.clear();
_ControlledTrackMap.clear();
if (!_TrackMap.empty())
{
nlwarning("ReynoldsLib:CReynoldsManager:release(): TrackMap not empty at release !!");
TTrackMap::iterator it;
for (it=_TrackMap.begin(); it!=_TrackMap.end(); ++it)
delete (*it).second;
_TrackMap.clear();
}
}
// ------------------------------------
// Load continent
void CReynoldsManager::loadContinent(const std::string &name, const std::string &file, sint index)
{
_Continents.loadContinent(name, file, index);
}
// ------------------------------------
// Create Track
CTrack *CReynoldsManager::createTrack(const CEntityId &entity)
{
// look for the target, and create a new track if not found
TTrackMap::iterator itt = _TrackMap.find(entity);
if (itt == _TrackMap.end())
{
CTrack *track = new CTrack();
pair<TTrackMap::iterator, bool> res = _TrackMap.insert(TTrackMap::value_type(entity, track));
itt = res.first;
requestSheet(entity);
}
return (*itt).second;
}
// ------------------------------------
// Remove Track from map
void CReynoldsManager::removeTrackFromMap(const CEntityId &entity)
{
_TrackMap.erase(entity);
}
// ------------------------------------
// Follow
void CReynoldsManager::follow(const NLMISC::CEntityId &entity, const NLMISC::CEntityId &target)
{
// look for the track, and create a new one if not found -- in both maps
CTrack *etrack = createTrack(entity);
TControlledTrackMap::iterator ite = _ControlledTrackMap.find(entity);
if (ite == _ControlledTrackMap.end())
_ControlledTrackMap.insert(TControlledTrackMap::value_type(entity, etrack));
// look for the target, and create a new track if not found
CTrack *ttrack = createTrack(target);
nldebug("ReynoldsLib:CReynoldsManager:follow(): %s now follows %s", entity.toString().c_str(), target.toString().c_str());
// let entity follow the target
etrack->follow(ttrack);
}
// ------------------------------------
// Go to
void CReynoldsManager::goTo(const NLMISC::CEntityId &entity, const NLMISC::CVectorD &position)
{
// look for the track, and create a new one if not found -- in both maps
CTrack *etrack = createTrack(entity);
TControlledTrackMap::iterator ite = _ControlledTrackMap.find(entity);
if (ite == _ControlledTrackMap.end())
_ControlledTrackMap.insert(TControlledTrackMap::value_type(entity, etrack));
// create a fake track for point position
static uint i = 0;
CEntityId id(0, i++, 0, 0);
CTrack *pointTo = createTrack(id);
pointTo->setStatic();
pointTo->setId(id, CSheetId::Unknown);
pointTo->setPosition(position, 0.0f);
nldebug("ReynoldsLib:CReynoldsManager:goTo(): %s now goes to (%.1f,%.1f)", entity.toString().c_str(), position.x, position.y);
// let entity follow the target
etrack->follow(pointTo);
}
// ------------------------------------
// Stop
void CReynoldsManager::leaveMove(const NLMISC::CEntityId &entity)
{
TControlledTrackMap::iterator ite = _ControlledTrackMap.find(entity);
if (ite == _ControlledTrackMap.end())
{
nlwarning("ReynoldsLib:CReynoldsManager:leaveMove(): undefined entity %s", entity.toString().c_str());
return;
}
nldebug("ReynoldsLib:CReynoldsManager:leaveMove(): %s control left", entity.toString().c_str());
(*ite).second->leave();
_ControlledTrackMap.erase(ite);
}
// ------------------------------------
// Destroy
void CReynoldsManager::destroy(const NLMISC::CEntityId &entity)
{
CTrack *track = getTrack(entity);
if (track != NULL)
track->forceRelease();
if (track != NULL && track->hasControlOwned())
track->leave();
_ControlledTrackMap.erase(entity);
}
// ------------------------------------
// Request Sheet
void CReynoldsManager::requestSheet(const NLMISC::CEntityId &entity)
{
if (!checkInterface())
return;
_CommandInterface->requestSheet(entity);
}
// ------------------------------------
// Request Position
void CReynoldsManager::requestPosition(const NLMISC::CEntityId &entity)
{
if (!checkInterface())
return;
_CommandInterface->requestPosition(entity);
}
// ------------------------------------
// Request Position Updates
void CReynoldsManager::requestPositionUpdates(const NLMISC::CEntityId &entity)
{
if (!checkInterface())
return;
_CommandInterface->requestPositionUpdates(entity);
}
// ------------------------------------
// Unrequest Position Updates
void CReynoldsManager::unrequestPositionUpdates(const NLMISC::CEntityId &entity)
{
if (!checkInterface())
return;
_CommandInterface->unrequestPositionUpdates(entity);
}
// ------------------------------------
// Request Vision
void CReynoldsManager::requestVision(const NLMISC::CEntityId &entity)
{
if (!checkInterface())
return;
_CommandInterface->requestVision(entity);
}
// ------------------------------------
// Unrequest Vision
void CReynoldsManager::unrequestVision(const NLMISC::CEntityId &entity)
{
if (!checkInterface())
return;
_CommandInterface->unrequestVision(entity);
}
// ------------------------------------
// Updated position
void CReynoldsManager::updatedPosition(const CEntityId &entity, const CVectorD &position, float heading)
{
if (_CommandInterface != NULL)
_CommandInterface->updatePosition(entity, position, heading);
}
// ------------------------------------
// Updated state
void CReynoldsManager::stateChanged(const CEntityId &entity, CTrackBase::TTrackState state)
{
if (_CommandInterface != NULL)
_CommandInterface->stateChanged(entity, state);
}
// ------------------------------------
// TrackStop
void CReynoldsManager::trackStop(CTrack *track)
{
if (checkInterface())
_CommandInterface->stopTrack(track->getId());
// remove track from controlled tracks
_ControlledTrackMap.erase(track->getId());
}
// ------------------------------------
// Create Move primitive
void CReynoldsManager::createMovePrimitive(const NLMISC::CVectorD &pos, NLPACS::UMovePrimitive *&primitive, NLPACS::UMoveContainer *&container)
{
primitive = NULL;
container = NULL;
uint8 continent = _Continents.findContinent(pos);
if (continent == -1)
{
nlwarning("ReynoldsLib:CReynoldsManager:createMovePrimitive(): unable to create move primitive");
return;
}
container = _Continents.getMoveContainer(continent);
primitive = container->addNonCollisionablePrimitive();
}
// ------------------------------------
// Set Sheet
void CReynoldsManager::setSheet(const NLMISC::CEntityId &id, const NLMISC::CSheetId &sheet)
{
CTrack *track = getTrack(id);
if (track == NULL)
{
nlwarning("ReynoldsLib:CReynoldsManager:setSheet(): Track %s not found", id.toString().c_str());
return;
}
if (track->hasId())
{
nlwarning("ReynoldsLib:CReynoldsManager:setSheet(): Track %s already has an Id", id.toString().c_str());
return;
}
track->setId(id, sheet);
}
// ------------------------------------
// Set Position
void CReynoldsManager::setPosition(const NLMISC::CEntityId &id, const NLMISC::CVectorD &position, float heading)
{
CTrack *track = getTrack(id);
if (track == NULL)
{
nlwarning("ReynoldsLib:CReynoldsManager:setPosition(): Track %s not found", id.toString().c_str());
return;
}
track->setPosition(position, heading);
}
// ------------------------------------
// Set Vision
void CReynoldsManager::setVision(const NLMISC::CEntityId &id, const std::vector<NLMISC::CEntityId> &in, const std::vector<NLMISC::CEntityId> &out)
{
CTrack *track = getTrack(id);
if (track == NULL)
{
nlwarning("ReynoldsLib:CReynoldsManager:setVision(): Track %s not found", id.toString().c_str());
return;
}
track->updateVision(in, out);
}
// ------------------------------------
// Set Vision
void CReynoldsManager::setVision(const NLMISC::CEntityId &id, const std::vector<NLMISC::CEntityId> &vision)
{
CTrack *track = getTrack(id);
if (track == NULL)
{
nlwarning("ReynoldsLib:CReynoldsManager:setVision(): Track %s not found", id.toString().c_str());
return;
}
track->updateVision(vision);
}
//-------------------------------------------------------------------------
// Init Sheets
void CReynoldsManager::initSheets(const std::string &packSheetFile)
{
if (_Initialised)
return;
std::vector<std::string> filters;
filters.push_back("creature");
filters.push_back("player");
loadForm(filters, packSheetFile, _Sheets);
_Initialised=true;
}
//-------------------------------------------------------------------------
// Lookup Sheet
const CTrack::CSheet *CReynoldsManager::lookup(const CSheetId &id)
{
nlassert(_Initialised);
// setup an iterator and lookup the sheet id in the map
std::map<CSheetId, CTrack::CSheet>::iterator it;
it=_Sheets.find(id);
// if we found a valid entry return a pointer to the creature record otherwise 0
if (it != _Sheets.end())
return &((*it).second);
else
return NULL;
}