1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "reynolds_manager.h"
23 #include "nel/georges/u_form_loader.h"
24 #include "nel/georges/load_form.h"
27 using namespace NLMISC
;
28 using namespace NLPACS
;
29 using namespace NLGEORGES
;
37 CContinentContainer
CReynoldsManager::_Continents
;
39 // Track Map, all tracks referenced, held by a simple pointer so when no one references a track, it is deleted
40 CReynoldsManager::TTrackMap
CReynoldsManager::_TrackMap
;
42 // Controlled Track Map, only controlled tracks, held by a smart pointer
43 CReynoldsManager::TControlledTrackMap
CReynoldsManager::_ControlledTrackMap
;
46 CReynoldsManager::ICommandInterface
*CReynoldsManager::_CommandInterface
= NULL
;
49 CReynoldsManager::TUserCallback
CReynoldsManager::_UserInitCallback
= NULL
;
51 // User motion callback
52 CReynoldsManager::TUserMotionCallback
CReynoldsManager::_UserMotionCallback
= NULL
;
54 // User release callback
55 CReynoldsManager::TUserCallback
CReynoldsManager::_UserReleaseCallback
= NULL
;
58 map
<CSheetId
, CTrack::CSheet
> CReynoldsManager::_Sheets
;
60 // Sheets initialised ?
61 bool CReynoldsManager::_Initialised
;
63 // Current internal cycle
64 uint32
CReynoldsManager::_Cycle
;
71 // ------------------------------------
73 CReynoldsManager::CReynoldsManager()
75 nlerror("CReynoldsManager: static library, must not be instanciated !");
80 // ------------------------------------
82 void CReynoldsManager::init(const std::string
&packSheetFile
)
84 _Continents
.init(100, 100, 8.0, 1);
86 initSheets(packSheetFile
);
91 // ------------------------------------
93 void CReynoldsManager::update(double dt
)
95 TControlledTrackMap::iterator it
;
96 for (it
=_ControlledTrackMap
.begin(); it
!=_ControlledTrackMap
.end(); ++it
)
98 CTrack
*track
= (CTrack
*)((*it
).second
);
105 // ------------------------------------
107 void CReynoldsManager::release()
111 _ControlledTrackMap
.clear();
113 if (!_TrackMap
.empty())
115 nlwarning("ReynoldsLib:CReynoldsManager:release(): TrackMap not empty at release !!");
117 TTrackMap::iterator it
;
118 for (it
=_TrackMap
.begin(); it
!=_TrackMap
.end(); ++it
)
127 // ------------------------------------
129 void CReynoldsManager::loadContinent(const std::string
&name
, const std::string
&file
, sint index
)
131 _Continents
.loadContinent(name
, file
, index
);
138 // ------------------------------------
140 CTrack
*CReynoldsManager::createTrack(const CEntityId
&entity
)
142 // look for the target, and create a new track if not found
143 TTrackMap::iterator itt
= _TrackMap
.find(entity
);
144 if (itt
== _TrackMap
.end())
146 CTrack
*track
= new CTrack();
147 pair
<TTrackMap::iterator
, bool> res
= _TrackMap
.insert(TTrackMap::value_type(entity
, track
));
150 requestSheet(entity
);
152 return (*itt
).second
;
155 // ------------------------------------
156 // Remove Track from map
157 void CReynoldsManager::removeTrackFromMap(const CEntityId
&entity
)
159 _TrackMap
.erase(entity
);
169 // ------------------------------------
171 void CReynoldsManager::follow(const NLMISC::CEntityId
&entity
, const NLMISC::CEntityId
&target
)
173 // look for the track, and create a new one if not found -- in both maps
174 CTrack
*etrack
= createTrack(entity
);
176 TControlledTrackMap::iterator ite
= _ControlledTrackMap
.find(entity
);
177 if (ite
== _ControlledTrackMap
.end())
178 _ControlledTrackMap
.insert(TControlledTrackMap::value_type(entity
, etrack
));
180 // look for the target, and create a new track if not found
181 CTrack
*ttrack
= createTrack(target
);
183 nldebug("ReynoldsLib:CReynoldsManager:follow(): %s now follows %s", entity
.toString().c_str(), target
.toString().c_str());
185 // let entity follow the target
186 etrack
->follow(ttrack
);
189 // ------------------------------------
191 void CReynoldsManager::goTo(const NLMISC::CEntityId
&entity
, const NLMISC::CVectorD
&position
)
193 // look for the track, and create a new one if not found -- in both maps
194 CTrack
*etrack
= createTrack(entity
);
196 TControlledTrackMap::iterator ite
= _ControlledTrackMap
.find(entity
);
197 if (ite
== _ControlledTrackMap
.end())
198 _ControlledTrackMap
.insert(TControlledTrackMap::value_type(entity
, etrack
));
200 // create a fake track for point position
202 CEntityId
id(0, i
++, 0, 0);
203 CTrack
*pointTo
= createTrack(id
);
204 pointTo
->setStatic();
205 pointTo
->setId(id
, CSheetId::Unknown
);
206 pointTo
->setPosition(position
, 0.0f
);
208 nldebug("ReynoldsLib:CReynoldsManager:goTo(): %s now goes to (%.1f,%.1f)", entity
.toString().c_str(), position
.x
, position
.y
);
210 // let entity follow the target
211 etrack
->follow(pointTo
);
214 // ------------------------------------
216 void CReynoldsManager::leaveMove(const NLMISC::CEntityId
&entity
)
218 TControlledTrackMap::iterator ite
= _ControlledTrackMap
.find(entity
);
219 if (ite
== _ControlledTrackMap
.end())
221 nlwarning("ReynoldsLib:CReynoldsManager:leaveMove(): undefined entity %s", entity
.toString().c_str());
225 nldebug("ReynoldsLib:CReynoldsManager:leaveMove(): %s control left", entity
.toString().c_str());
227 (*ite
).second
->leave();
228 _ControlledTrackMap
.erase(ite
);
231 // ------------------------------------
233 void CReynoldsManager::destroy(const NLMISC::CEntityId
&entity
)
235 CTrack
*track
= getTrack(entity
);
237 track
->forceRelease();
239 if (track
!= NULL
&& track
->hasControlOwned())
242 _ControlledTrackMap
.erase(entity
);
250 // ------------------------------------
252 void CReynoldsManager::requestSheet(const NLMISC::CEntityId
&entity
)
254 if (!checkInterface())
257 _CommandInterface
->requestSheet(entity
);
260 // ------------------------------------
262 void CReynoldsManager::requestPosition(const NLMISC::CEntityId
&entity
)
264 if (!checkInterface())
267 _CommandInterface
->requestPosition(entity
);
270 // ------------------------------------
271 // Request Position Updates
272 void CReynoldsManager::requestPositionUpdates(const NLMISC::CEntityId
&entity
)
274 if (!checkInterface())
277 _CommandInterface
->requestPositionUpdates(entity
);
280 // ------------------------------------
281 // Unrequest Position Updates
282 void CReynoldsManager::unrequestPositionUpdates(const NLMISC::CEntityId
&entity
)
284 if (!checkInterface())
287 _CommandInterface
->unrequestPositionUpdates(entity
);
290 // ------------------------------------
292 void CReynoldsManager::requestVision(const NLMISC::CEntityId
&entity
)
294 if (!checkInterface())
297 _CommandInterface
->requestVision(entity
);
300 // ------------------------------------
302 void CReynoldsManager::unrequestVision(const NLMISC::CEntityId
&entity
)
304 if (!checkInterface())
307 _CommandInterface
->unrequestVision(entity
);
311 // ------------------------------------
313 void CReynoldsManager::updatedPosition(const CEntityId
&entity
, const CVectorD
&position
, float heading
)
315 if (_CommandInterface
!= NULL
)
316 _CommandInterface
->updatePosition(entity
, position
, heading
);
319 // ------------------------------------
321 void CReynoldsManager::stateChanged(const CEntityId
&entity
, CTrackBase::TTrackState state
)
323 if (_CommandInterface
!= NULL
)
324 _CommandInterface
->stateChanged(entity
, state
);
328 // ------------------------------------
330 void CReynoldsManager::trackStop(CTrack
*track
)
332 if (checkInterface())
333 _CommandInterface
->stopTrack(track
->getId());
335 // remove track from controlled tracks
336 _ControlledTrackMap
.erase(track
->getId());
340 // ------------------------------------
341 // Create Move primitive
342 void CReynoldsManager::createMovePrimitive(const NLMISC::CVectorD
&pos
, NLPACS::UMovePrimitive
*&primitive
, NLPACS::UMoveContainer
*&container
)
347 uint8 continent
= _Continents
.findContinent(pos
);
350 nlwarning("ReynoldsLib:CReynoldsManager:createMovePrimitive(): unable to create move primitive");
354 container
= _Continents
.getMoveContainer(continent
);
355 primitive
= container
->addNonCollisionablePrimitive();
362 // ------------------------------------
364 void CReynoldsManager::setSheet(const NLMISC::CEntityId
&id
, const NLMISC::CSheetId
&sheet
)
366 CTrack
*track
= getTrack(id
);
369 nlwarning("ReynoldsLib:CReynoldsManager:setSheet(): Track %s not found", id
.toString().c_str());
375 nlwarning("ReynoldsLib:CReynoldsManager:setSheet(): Track %s already has an Id", id
.toString().c_str());
379 track
->setId(id
, sheet
);
382 // ------------------------------------
384 void CReynoldsManager::setPosition(const NLMISC::CEntityId
&id
, const NLMISC::CVectorD
&position
, float heading
)
386 CTrack
*track
= getTrack(id
);
389 nlwarning("ReynoldsLib:CReynoldsManager:setPosition(): Track %s not found", id
.toString().c_str());
393 track
->setPosition(position
, heading
);
396 // ------------------------------------
398 void CReynoldsManager::setVision(const NLMISC::CEntityId
&id
, const std::vector
<NLMISC::CEntityId
> &in
, const std::vector
<NLMISC::CEntityId
> &out
)
400 CTrack
*track
= getTrack(id
);
403 nlwarning("ReynoldsLib:CReynoldsManager:setVision(): Track %s not found", id
.toString().c_str());
407 track
->updateVision(in
, out
);
410 // ------------------------------------
412 void CReynoldsManager::setVision(const NLMISC::CEntityId
&id
, const std::vector
<NLMISC::CEntityId
> &vision
)
414 CTrack
*track
= getTrack(id
);
417 nlwarning("ReynoldsLib:CReynoldsManager:setVision(): Track %s not found", id
.toString().c_str());
421 track
->updateVision(vision
);
427 //-------------------------------------------------------------------------
429 void CReynoldsManager::initSheets(const std::string
&packSheetFile
)
434 std::vector
<std::string
> filters
;
435 filters
.push_back("creature");
436 filters
.push_back("player");
438 loadForm(filters
, packSheetFile
, _Sheets
);
444 //-------------------------------------------------------------------------
446 const CTrack::CSheet
*CReynoldsManager::lookup(const CSheetId
&id
)
448 nlassert(_Initialised
);
450 // setup an iterator and lookup the sheet id in the map
451 std::map
<CSheetId
, CTrack::CSheet
>::iterator it
;
454 // if we found a valid entry return a pointer to the creature record otherwise 0
455 if (it
!= _Sheets
.end())
456 return &((*it
).second
);