khanat-opennel-code/code/ryzom/server/src/server_share/continent_container.h
2014-12-26 13:12:56 +01:00

295 lines
8.1 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/>.
#ifndef NL_CONTINENT_CONTAINER_H
#define NL_CONTINENT_CONTAINER_H
// Nel Misc
#include "nel/misc/types_nl.h"
#include "nel/misc/smart_ptr.h"
#include "nel/misc/vectord.h"
#include "nel/misc/sheet_id.h"
#include "nel/misc/log.h"
#include "nel/misc/entity_id.h"
// Nel Georges
#include "nel/georges/u_form.h"
#include "nel/georges/u_form_elm.h"
// Nel Pacs
#include "nel/pacs/u_move_container.h"
#include "nel/pacs/u_move_primitive.h"
#include "nel/pacs/u_retriever_bank.h"
#include "nel/pacs/u_global_retriever.h"
#include "nel/pacs/u_global_position.h"
#include "nel/pacs/u_primitive_block.h"
/**
* <Class description>
* \author Benjamin Legros
* \author Nevrax France
* \date 2001
*/
class CContinentContainer
{
protected:
/// Container of continent
class CContinentMoveContainer
{
public:
CContinentMoveContainer() : GlobalRetriever(NULL), RetrieverBank(NULL), MoveContainer(NULL), AllowAutoSpawn(false) {}
/// Then name of the continent
std::string Name;
/// The PACS global retriever for this continent
NLPACS::UGlobalRetriever *GlobalRetriever; // Global retriever retrieved surfaces of all territory
/// The PACS retriever bank for this continent
NLPACS::URetrieverBank *RetrieverBank; // Bank of global retriever
/// The PACS move container for this continent
NLPACS::UMoveContainer *MoveContainer; // Move container
/// True if entities are allowed to try spawning in this continent if no continent index is provided
bool AllowAutoSpawn;
};
///
class CSheet
{
public:
CSheet() {}
std::string Name;
std::string PacsRBank;
std::string PacsGR;
std::string LandscapeIG;
std::vector<std::string> ListIG;
void readGeorges (const NLMISC::CSmartPtr<NLGEORGES::UForm> &form, const NLMISC::CSheetId &sheetId)
{
Name = sheetId.toString();
// the form was found so read the true values from George
form->getRootNode ().getValueByName (PacsRBank, "PacsRBank");
form->getRootNode ().getValueByName (PacsGR, "PacsGR");
form->getRootNode ().getValueByName (LandscapeIG, "LandscapeIG");
NLGEORGES::UFormElm *node;
uint numVillages, numIgs;
if (form->getRootNode().getNodeByName(&node, "Villages") && node &&
node->getArraySize(numVillages))
{
for (uint village=0; village<numVillages; ++village)
{
if (form->getRootNode ().getNodeByName(&node, NLMISC::toString("Villages[%d].IgList", village).c_str()) && node &&
node->getArraySize(numIgs))
{
for (uint ig=0; ig<numIgs; ++ig)
{
std::string igName;
if (form->getRootNode ().getValueByName(igName, NLMISC::toString("Villages[%d].IgList[%d].IgName", village, ig).c_str()))
ListIG.push_back(igName);
}
}
}
}
}
void serial (NLMISC::IStream &s)
{
s.serial(Name);
s.serial(PacsRBank, PacsGR, LandscapeIG);
s.serialCont(ListIG);
}
static uint getVersion () { return 1; }
void removed() {}
};
/// The global continent container
typedef std::vector<CContinentMoveContainer> TContinentContainer;
///
typedef std::map<std::string, NLPACS::UPrimitiveBlock*> TPacsPrimMap;
///
typedef std::map<uint, NLMISC::CVectorD> TTriggerMap;
/// the continents
TContinentContainer _Continents;
/// pacs primitives
TPacsPrimMap _PacsPrimMap;
/// Sheet map type
typedef std::map<NLMISC::CSheetId, CSheet> TSheetMap;
///
TSheetMap _SheetMap;
///
TTriggerMap _TriggerMap;
///
uint _GridWidth;
uint _GridHeight;
double _CellSize;
double _PrimitiveMaxSize;
uint _NbWorldImages;
/// Should load dynamic collision (e.g. trees)
bool _LoadPacsPrims;
public:
/// Constructor
CContinentContainer();
/// Init whole continent container
void init(uint gridWidth, uint gridHeight, double primitiveMaxSize, uint nbWorldImages, const std::string &packedSheetsDirectory, double cellSize=0.0, bool loadPacsPrims = true);
/// Build sheets
void buildSheets(const std::string &packedSheetsDirectory);
/// Init pacs prims
void initPacsPrim(const std::string &path = std::string("landscape_col_prim_pacs_list.txt"));
/// Load continent
void loadContinent(std::string name, std::string file, sint index, bool allowAutoSpawn = true);
/// Remove continent
void removeContinent(sint index);
/// Get move container for continent
NLPACS::UMoveContainer *getMoveContainer(sint index)
{
if (index < 0 || index >= (sint)_Continents.size())
{
nlwarning("getMoveContainer(): invalid index %d", index);
return NULL;
}
return _Continents[index].MoveContainer;
}
/// Get move container for continent
NLPACS::UGlobalRetriever *getRetriever(sint index)
{
if (index < 0 || index >= (sint)_Continents.size())
{
nlwarning("getRetriever(): invalid index %d", index);
return NULL;
}
return _Continents[index].GlobalRetriever;
}
/// Get move container for continent
NLPACS::URetrieverBank *getRetrieverBank(sint index)
{
if (index < 0 || index >= (sint)_Continents.size())
{
nlwarning("getRetriverBank(): invalid index %d", index);
return NULL;
}
return _Continents[index].RetrieverBank;
}
/// Find continent to spawn in
sint findContinent(const NLMISC::CVectorD &worldPosition, const NLMISC::CEntityId& id = NLMISC::CEntityId::Unknown)
{
sint continent = -1;
// finds the continent that fits given position
uint i;
for (i=0; i<_Continents.size(); ++i)
{
if (_Continents[i].GlobalRetriever == NULL ||
!_Continents[i].AllowAutoSpawn)
continue;
NLPACS::UGlobalPosition globalPosition = _Continents[i].GlobalRetriever->retrievePosition(worldPosition);
if (globalPosition.InstanceId != -1 && globalPosition.LocalPosition.Surface != -1)
{
if (continent != -1)
{
nlwarning("findContinent%s: continent not provided, and sole position (%.3f, %.3f, %.3f) refers to several continents (%d, %d) -- use first found",
id.toString().c_str(),
worldPosition.x, worldPosition.y, worldPosition.z,
i, continent);
continue;
}
continent = i;
}
}
if (continent == -1)
{
if (worldPosition.x != 0.0 || worldPosition.y != 0.0 || worldPosition.z != 0.0)
nlwarning("findContinent%s: can't find best fitting continent for position (%.3f, %.3f, %.3f) -- use first available continent", id.toString().c_str(), worldPosition.x, worldPosition.y, worldPosition.z);
for (uint i=0; i<_Continents.size(); ++i)
{
if (_Continents[i].MoveContainer != NULL)
{
continent = i;
break;
}
}
}
return continent;
}
/// Get container size
sint size() const { return (sint)_Continents.size(); }
/// clear the container -- WARNING
void clear()
{
uint i;
for (i=0; i<_Continents.size(); ++i)
removeContinent(i);
_Continents.clear();
}
/// get trigger position
NLMISC::CVectorD getTriggerPosition(uint i) const
{
TTriggerMap::const_iterator it = _TriggerMap.find(i);
return (it == _TriggerMap.end()) ? NLMISC::CVectorD::Null : (*it).second;
}
/// Display triggers
void displayTriggers(NLMISC::CLog *log = NLMISC::InfoLog) const
{
TTriggerMap::const_iterator it;
for (it=_TriggerMap.begin(); it!=_TriggerMap.end(); ++it)
log->displayNL("Trigger %d: (%.3f, %.3f, %.3f)", (*it).first, (*it).second.x, (*it).second.y, (*it).second.z);
}
protected:
void loadPacsPrims(const CSheet &sheet, NLPACS::UMoveContainer *moveContainer);
};
#endif // NL_CONTINENT_CONTAINER_H
/* End of continent_container.h */