// Ryzom - MMORPG Framework
// 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 .
#ifndef NL_BAR_MANAGER_H
#define NL_BAR_MANAGER_H
#include "nel/misc/types_nl.h"
#include "game_share/entity_types.h"
#include "game_share/inventories.h"
#include "game_share/scores.h"
// ***************************************************************************
/**
* Class that Manage display of Bars (HP, Sta, Sap, Focus)
* Such a manager is necessary because the property are sent in 2 ways:
* - From Visual Property, often more frequently updated, but only if Entity is in Vision AND within
* a certain distance (aka VP threshold which is for instance 30m for Bars)
* - From DB (Target, Team, Animal), which are always sent, but less frequently updated
* The purpose of this manager is to take either the Visual Property or the Database Value, deciding which is the most
* accurate one.
* Then the same values are used for the Target, Team and Animal interface, as the 3D InScene interface
* \author Lionel Berenguier
* \author Nevrax France
* \date 2004
*/
class CBarManager
{
public:
// singleton
static CBarManager *getInstance()
{
if(!_Instance)
{
_Instance= new CBarManager;
}
return _Instance;
}
// release singleton
static void releaseInstance();
// types of entries
enum TEntryType
{
EntityType= 0,
TeamMemberType,
AnimalType,
TargetType,
MaxEntryType
};
// Max Array size for each entry
enum
{
MaxEntity= 256,
MaxTeamMember= 8,
MaxAnimal= MAX_INVENTORY_ANIMAL,
MaxTarget= 1
};
// Flags
enum TScoreFlag
{
HpFlag= (1< Out Target Database is flushed with current data
void setLocalTarget(uint dataSetId);
// get the bar values. WARNING assert that entityId < MaxEntity
CBarInfo getBarsByEntityId(CLFECOMMON::TCLEntityId entityId) const;
/*
* For Interface Team, Target, and Animal, values are updated in the database:
* UI:VARIABLES:BARS:TEAM:i:HP
* UI:VARIABLES:BARS:ANIMAL:i:HP
* UI:VARIABLES:BARS:TARGET:HP
* They are updated on a updateBars(), addxxx() or delxxxx()
*/
/// Special Message to set the current HP/SAP/STA/FOCUS for the user.
void setupUserBarInfo(uint8 msgNumber, sint32 hp, sint32 sap, sint32 sta, sint32 focus);
/// From last setuped user HP/SAP/STA/FOCUS, and current database MAX, setup the Bars for the user (slot 0) entry
void updateUserBars();
sint32 getUserScore(SCORES::TScores score);
// ************
private:
CBarManager();
~CBarManager() {}
static CBarManager *_Instance;
// *** Tell us the Bar values, and to which input/output they are connected
class CBarDataUID
{
public:
/* What connexion are valid. empty() in each case if not, else the index in the array of entries
* NB: this is a set because some time, a bar data may be connected to multiple entries of same type
* This typically happens when you dismiss the team member 0 'Paul' while you have a team member 1 'Pierre':
* because of the server array shift, there will be a short time where TeamMember0= TeamMember1= Pierre
* Hence the set: Pierre is bound to 2 teammember entries: 0 and 1.
*/
std::set EntryId[MaxEntryType];
// The current values of the bars
CBarInfo BarInfo;
// For each score, server tick of last setup
NLMISC::TGameCycle ScoreDate[SCORES::NUM_SCORES];
CBarDataUID()
{
for(uint i=0;i TUIDToDatas;
TUIDToDatas _UIDBars;
// *** Data sorted by connexion Id (duplication for faster access...)
class CBarDataEntry
{
public:
// To which DataSetId this apply (INVALID_CLIENT_DATASET_INDEX if not valid)
uint DataSetId;
// The current values of the bars
CBarInfo BarInfo;
// Connection input (used only for TargetType, TeamMemberType and AnimalType)
class CCDBNodeLeaf *UIDIn;
class CCDBNodeLeaf *PresentIn; // if not NULL, this is an additional test: if(PresentIn->getValue()==0) => not present
class CCDBNodeLeaf *ScoreIn[SCORES::NUM_SCORES];
// Connection output
class CCDBNodeLeaf *ScoreOut[SCORES::NUM_SCORES];
public:
CBarDataEntry();
// reset the DataSetId, and BarInfo (not DB)
void clear();
// connect
void connectDB(const std::string &baseDBin, const std::string &baseDBout, const std::string &presentDB,
const std::string &hpDB, const std::string &sapDB, const std::string &staDB, const std::string &focusDB);
void resetDB();
// flush the value to the DB (only values linked)
void flushDBOut();
// modify from the DB in (only values linked)
void modifyFromDBIn(CBarInfo &barInfo) const;
};
// "template" method to add or remove an entry
void addEntry(TEntryType type, uint entryId, uint dataSetId);
void delEntry(TEntryType type, uint entryId);
// "template" method to update an entry from DB
void updateEntryFromDB(TEntryType type, uint entryId);
void updateEntryFromDBNoAddDel(TEntryType type, CBarDataEntry &bde);
// One array for each type
std::vector _EntryBars[MaxEntryType];
// For each type, tells what entry are connected
uint _EntryScoreFlags[MaxEntryType];
/// Special For UserBars (transferred from impulse)
// @{
uint8 _LastUserBarMsgNumber;
struct CUserScore
{
// last score get from impulse USER:BARS
sint32 Score;
// input DB value, to get the current MAX
class CCDBNodeLeaf *DBInMax;
// output DB to store the real value, but clamped to 0
class CCDBNodeLeaf *DBOutVal;
// output DB to store the ratio -1024,1024 value
class CCDBNodeLeaf *DBOutRatio;
CUserScore()
{
Score= 0;
DBInMax= DBOutVal= DBOutRatio= NULL;
}
};
CUserScore _UserScores[SCORES::NUM_SCORES];
CBarInfo _UserBarInfo;
enum {UserBarMaxRatio= 1024};
// @}
};
#endif // NL_BAR_MANAGER_H
/* End of bar_manager.h */