1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #ifndef NL_BAR_MANAGER_H
21 #define NL_BAR_MANAGER_H
24 #include "nel/misc/types_nl.h"
25 #include "game_share/entity_types.h"
26 #include "game_share/inventories.h"
27 #include "game_share/scores.h"
34 // ***************************************************************************
36 * Class that Manage display of Bars (HP, Sta, Sap, Focus)
37 * Such a manager is necessary because the property are sent in 2 ways:
38 * - From Visual Property, often more frequently updated, but only if Entity is in Vision AND within
39 * a certain distance (aka VP threshold which is for instance 30m for Bars)
40 * - From DB (Target, Team, Animal), which are always sent, but less frequently updated
41 * The purpose of this manager is to take either the Visual Property or the Database Value, deciding which is the most
43 * Then the same values are used for the Target, Team and Animal interface, as the 3D InScene interface
44 * \author Lionel Berenguier
45 * \author Nevrax France
52 static CBarManager
*getInstance()
56 _Instance
= new CBarManager
;
62 static void releaseInstance();
75 // Max Array size for each entry
80 MaxAnimal
= MAX_INVENTORY_ANIMAL
,
87 HpFlag
= (1<<SCORES::hit_points
),
88 SapFlag
= (1<<SCORES::sap
),
89 StaFlag
= (1<<SCORES::stamina
),
90 FocusFlag
= (1<<SCORES::focus
)
96 sint8 Score
[SCORES::NUM_SCORES
];
103 nlctassert(SCORES::NUM_SCORES
==4);
104 Score
[0]= Score
[1]= Score
[2]= Score
[3]= 0;
111 // init. Call after Server/Client Database initialisation (CInterfaceManager)
113 void releaseInGame();
114 void resetShardSpecificData();
116 /** \name Bar registration. Each Entity is uniquely identified by its dataSetId.
117 * The entity can be "connected" through diffent ways (entity in vision, entry in team list etc...).
118 * If it was not connected before, its Bars value are reseted
119 * WARNING: each of this method assert that the entryId (entityId etc...) is less than the corresponding Max Size (MaxEntity etc...)
122 // register an entity in Vision. reset bar values to 0, and assign dataSetId to entity
123 void addEntity(CLFECOMMON::TCLEntityId entityId
, uint dataSetId
);
124 void delEntity(CLFECOMMON::TCLEntityId entityId
);
125 // register a TeamMember. NB: no-op if already registered. YOU SHOULD USE updateTeamMemberFromDB()
126 void addTeamMember(uint teamMemberId
, uint dataSetId
);
127 void delTeamMember(uint teamMemberId
);
128 // register a Pet Animal. NB: no-op if already registered. YOU SHOULD USE updateAnimalFromDB()
129 void addAnimal(uint paId
, uint dataSetId
);
130 void delAnimal(uint paId
);
131 // register the target. NB: no-op if already registered. YOU SHOULD USE updateTargetFromDB()
132 void addTarget(uint dataSetId
);
136 /** called either by VP or DB receive. NB: no-op if the dataSetId was not added through any of preceding fct
137 * \param serverTick the server date validity of this info (if too old, skiped)
138 * \param scoreFlags an ORed of TScoreFlag. if not set, the value is not relevant (eg: Team DB don't precise Focus)
140 void updateBars(uint dataSetId
, CBarInfo barInfo
, NLMISC::TGameCycle serverTick
, uint scoreFlags
);
142 // do the appropriate addEntry(), delEntry() or/and updateBars(), according to SERVER db change
143 void updateTeamMemberFromDB(uint teamMemberId
);
144 void updateAnimalFromDB(uint paId
);
145 void updateTargetFromDB();
147 // special for the Target. Called when the client select an entity => Out Target Database is flushed with current data
148 void setLocalTarget(uint dataSetId
);
150 // get the bar values. WARNING assert that entityId < MaxEntity
151 CBarInfo
getBarsByEntityId(CLFECOMMON::TCLEntityId entityId
) const;
154 * For Interface Team, Target, and Animal, values are updated in the database:
155 * UI:VARIABLES:BARS:TEAM:i:HP
156 * UI:VARIABLES:BARS:ANIMAL:i:HP
157 * UI:VARIABLES:BARS:TARGET:HP
158 * They are updated on a updateBars(), addxxx() or delxxxx()
161 /// Special Message to set the current HP/SAP/STA/FOCUS for the user.
162 void setupUserBarInfo(uint8 msgNumber
, sint32 hp
, sint32 sap
, sint32 sta
, sint32 focus
);
163 /// From last setuped user HP/SAP/STA/FOCUS, and current database MAX, setup the Bars for the user (slot 0) entry
164 void updateUserBars();
166 sint32
getUserScore(SCORES::TScores score
);
172 static CBarManager
*_Instance
;
175 // *** Tell us the Bar values, and to which input/output they are connected
179 /* What connection are valid. empty() in each case if not, else the index in the array of entries
180 * NB: this is a set because some time, a bar data may be connected to multiple entries of same type
181 * This typically happens when you dismiss the team member 0 'Paul' while you have a team member 1 'Pierre':
182 * because of the server array shift, there will be a short time where TeamMember0= TeamMember1= Pierre
183 * Hence the set: Pierre is bound to 2 teammember entries: 0 and 1.
185 std::set
<uint
> EntryId
[MaxEntryType
];
187 // The current values of the bars
190 // For each score, server tick of last setup
191 NLMISC::TGameCycle ScoreDate
[SCORES::NUM_SCORES
];
195 for(uint i
=0;i
<SCORES::NUM_SCORES
;i
++)
198 bool noMoreEntry() const
200 for(uint i
=0;i
<MaxEntryType
;i
++)
202 if(!EntryId
[i
].empty())
208 // Data sorted by dataSetId
209 typedef std::map
<uint
, CBarDataUID
> TUIDToDatas
;
210 TUIDToDatas _UIDBars
;
213 // *** Data sorted by connection Id (duplication for faster access...)
217 // To which DataSetId this apply (INVALID_CLIENT_DATASET_INDEX if not valid)
220 // The current values of the bars
223 // Connection input (used only for TargetType, TeamMemberType and AnimalType)
224 NLMISC::CCDBNodeLeaf
*UIDIn
;
225 NLMISC::CCDBNodeLeaf
*PresentIn
; // if not NULL, this is an additional test: if(PresentIn->getValue()==0) => not present
226 NLMISC::CCDBNodeLeaf
*ScoreIn
[SCORES::NUM_SCORES
];
229 NLMISC::CCDBNodeLeaf
*ScoreOut
[SCORES::NUM_SCORES
];
233 // reset the DataSetId, and BarInfo (not DB)
236 void connectDB(const std::string
&baseDBin
, const std::string
&baseDBout
, const std::string
&presentDB
,
237 const std::string
&hpDB
, const std::string
&sapDB
, const std::string
&staDB
, const std::string
&focusDB
);
239 // flush the value to the DB (only values linked)
241 // modify from the DB in (only values linked)
242 void modifyFromDBIn(CBarInfo
&barInfo
) const;
245 // "template" method to add or remove an entry
246 void addEntry(TEntryType type
, uint entryId
, uint dataSetId
);
247 void delEntry(TEntryType type
, uint entryId
);
249 // "template" method to update an entry from DB
250 void updateEntryFromDB(TEntryType type
, uint entryId
);
251 void updateEntryFromDBNoAddDel(TEntryType type
, CBarDataEntry
&bde
);
253 // One array for each type
254 std::vector
<CBarDataEntry
> _EntryBars
[MaxEntryType
];
256 // For each type, tells what entry are connected
257 uint _EntryScoreFlags
[MaxEntryType
];
260 /// Special For UserBars (transferred from impulse)
262 uint8 _LastUserBarMsgNumber
;
265 // last score get from impulse USER:BARS
267 // input DB value, to get the current MAX
268 NLMISC::CCDBNodeLeaf
*DBInMax
;
269 // output DB to store the real value, but clamped to 0
270 NLMISC::CCDBNodeLeaf
*DBOutVal
;
271 // output DB to store the ratio -1024,1024 value
272 NLMISC::CCDBNodeLeaf
*DBOutRatio
;
276 DBInMax
= DBOutVal
= DBOutRatio
= NULL
;
279 CUserScore _UserScores
[SCORES::NUM_SCORES
];
280 CBarInfo _UserBarInfo
;
281 enum {UserBarMaxRatio
= 1024};
287 #endif // NL_BAR_MANAGER_H
289 /* End of bar_manager.h */