Add infos into target window
[ryzomcore.git] / ryzom / server / src / entities_game_service / deposit.h
blobfee33662ad08241b40263e639a93c4d47dde4c3a
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
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.
8 //
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/>.
19 #ifndef RY_DEPOSIT_H
20 #define RY_DEPOSIT_H
22 #include "nel/ligo/primitive.h"
23 #include "egs_sheets/egs_static_deposit.h"
24 #include "game_share/time_weather_season/time_and_season.h"
25 #include "game_share/ecosystem.h"
26 #include "game_share/rm_family.h"
27 #include "harvest_info.h"
28 #include "mission_manager/ai_alias_translator.h"
29 #include "egs_variables.h"
30 #include "nel/misc/random.h"
31 #include "nel/misc/variable.h"
34 class CDeposit;
36 const uint16 MaxNbActiveSources = std::numeric_limits<uint16>::max();
38 /**
39 * A recent forage site prevents from extracting too much material from the same place in a short time.
40 * When an extraction is succesful, a timer is launched. If no more extraction is done then, the site
41 * is destroyed after the time is elapsed. If an extraction fails (no more stock available), the site
42 * will be blocked for extraction (isDepleted() will be true) during the specified time, then freed.
43 * Note: the timer resolution is abstract. The actual time in ticks will depend on the rate of update.
45 class CRecentForageSite
47 public:
49 /// Create forage site. Precondition: dep not NULL.
50 CRecentForageSite( CDeposit *dep, const NLMISC::CVector& pos ) : _Deposit(dep), _Pos(pos), _TimeToLive(ForageSiteNbUpdatesToLive.get()), _LowScopeStock(ForageSiteStock.get()), _NbActiveSources(0) {}
52 /// Add a source
53 bool addActiveSource() { if ( _NbActiveSources == MaxNbActiveSources ) return false; ++_NbActiveSources; return true; }
55 /// Remove a source
56 void removeActiveSource() { nlassert(_NbActiveSources!=0); --_NbActiveSources; } // TEMP: assert
58 /// Return the quantity available in the deposit (or FLT_MAX if there is no quantity constraint)
59 float getQuantityInDeposit();
61 /**
62 * Consume 1 unit of forage site stock by a source in the (independant on the quantity extracted).
63 * Reset life time of forage site if successful.
64 * Additionally, consume n units of deposit stock (dependant on the quantity extracted).
65 * Return the actual quantity that is extracted (can be less that requested if the deposit is (nearly or fully) empty.
67 float consume( float n );
69 /// Consume all stock at once
70 void depleteAll() { _LowScopeStock = 0; _TimeToLive = ForageSiteNbUpdatesToLive.get(); }
72 /** Update forage site. Return false if the forage site lifetime is ended and the object must be destroyed (which won't occur while there are active sources)
73 * This method does not need to be called every tick, but at the rate of CDeposit::lowFreqUpdate().
75 bool lowFreqUpdate() { if ( _TimeToLive != 0 ) { --_TimeToLive; return true; } else return hasActiveSources(); }
77 /// Return deposit (never NULL).
78 const CDeposit *deposit() const { return _Deposit; }
80 /// Return center position
81 const NLMISC::CVector& pos() const { return _Pos; }
83 /// Test if site is depleted
84 bool isDepleted() const { return _LowScopeStock == 0; }
86 /// Test if site contains a position
87 bool contains( const NLMISC::CVector& pos ) const;
89 /// Display debug or stat info
90 void display( NLMISC::CLog& log ) const;
92 /// True if the owned deposit allo depletion risk
93 bool allowDepletionRisk() const;
95 protected:
97 /// Test if site has sources
98 bool hasActiveSources() const { return _NbActiveSources!=0; }
100 private:
102 /// Pointer to deposit (deposits don't move in memory). Never NULL.
103 CDeposit *_Deposit;
105 /// Center of site area
106 NLMISC::CVector _Pos;
109 uint16 _TimeToLive;
112 uint16 _LowScopeStock;
115 uint16 _NbActiveSources;
118 typedef std::list<CRecentForageSite> CRecentForageSites;
122 * Type of ecosystem or terrain.
123 * CEcotype ojects are loaded from primitives, are used to build CDeposit objects, then erased.
125 class CEcotypeZone : public NLLIGO::CPrimZone
127 public:
129 /// Init
130 bool build( const NLLIGO::CPrimZone* zone );
132 /// Return ecotype
133 TEcotype ecotype() const { return _Ecotype; }
135 private:
138 TEcotype _Ecotype;
141 typedef std::vector< CEcotypeZone* > CEcotypeZones;
145 * Properties of auto-spawn sources of a deposit
147 struct CAutoSpawnProperties
149 NL_INSTANCE_COUNTER_DECL(CAutoSpawnProperties);
150 public:
151 /// In game cycles, but depends of the update frequency of the deposits
152 uint32 SpawnPeriodGc;
154 /// Time before disappearance when no extraction has started (game cycles)
155 uint32 LifeTimeGc;
157 /// Time remaining since the beginning of the first extraction
158 uint32 ExtractionTimeGc;
160 /// Minimium Number of Auto-Spawned Sources that must always exist
161 uint32 MinimumSpawnedSources;
166 * Quantity constraints
168 struct CQuantityConstraints
170 NL_INSTANCE_COUNTER_DECL(CQuantityConstraints);
171 public:
172 /// Current quantity (shared by all materials in the deposit)
173 float CurrentQuantity;
175 /// Day of the next respawn (valid if CurrentQuantity is 0)
176 uint32 NextRespawnDay;
178 /// Initial quantity
179 uint16 InitialQuantity;
181 /// Time before the initial quantity becomes available backs, in Ryzom Days (note: 30 days for a whole season)
182 uint16 RespawnTimeRyzomDays;
184 /// Return the current quantity. If 0 and the respawn time is elapsed, unlock.
185 float getCurrentQuantity();
187 /// Consume. If the current quantity falls to 0, lock. Return the actual consumed quantity.
188 float consumeQuantity( float consumed );
192 namespace NLMISC
194 class IVariable;
195 class CWordsDictionary;
199 * \author Nicolas Brigand, Alain Saffray, Olivier Cado
200 * \author Nevrax France
201 * \date 2003
203 class CDeposit : public NLLIGO::CPrimZone, public NLMISC::CRefCount
205 public:
207 /// Constructor
208 CDeposit() : _AutoSpawnSourcePt(NULL), _QuantityConstraintsPt(NULL), _Ecotype(ECOSYSTEM::common_ecosystem), _FilterPhase(0), _KamiAnger(0.0f), _MinQuality(-1), _MaxQuality(-1), _SourceFXIndex(0), _CanProspect(false), _Enabled(false), _CurrentNbAutoSpawnedSources(0), _AllowDepletionRisk(true) {}
210 /// Destructor
211 ~CDeposit();
213 /// Add an ecotype information
214 static void addEcotype( CEcotypeZone *ecotypeZone ) { _EcotypeZones.push_back( ecotypeZone ); }
216 /// Init deposit
217 bool build( const NLLIGO::CPrimZone* zone );
219 /// Clear all ecotype information, after having built the deposits
220 static void clearEcotypes();
222 // Update deposit (especially recent forage sites).
223 void lowFreqUpdate();
225 // Update deposit that need to auto spawn because number of harvest sources is too low
226 void autoSpawnUpdate();
228 // fill CHarvestInfos with deposit founded
229 ///void harvestInfo( const NLMISC::CEntityId& charId, HARVEST_INFOS::CHarvestInfos& infos );
231 // character take MP, kami eat this fool character ?
232 //void characterTakeRM( const NLMISC::CEntityId& charId, uint32 depositIndexContent, uint16 quantity );
234 // Display deposit content
235 void displayContent( NLMISC::CLog * log = NLMISC::InfoLog, bool extendedInfo=false, NLMISC::CWordsDictionary *itemDictionary=NULL );
237 const std::string& name() const { return _Name; }
239 /// Return the number of MPS in the deposit
240 uint getContentSize() const { return (uint)_RawMaterials.size(); }
242 /// Return the MPS
243 const std::vector<CStaticDepositRawMaterial>& getContents() const { return _RawMaterials; }
245 /// Return the terrain type
246 TEcotype ecotype() const { return _Ecotype; }
248 /// Return the MinQuality
249 sint16 minQuality() const { return _MinQuality; }
251 /// Return the MaxQuality or -1 if it has to be taken from the raw material information
252 sint16 maxQuality() const { return _MaxQuality; }
254 /// Return the index of the visual shape/FX of the sources from this deposit
255 uint16 sourceFXIndex() const { return _SourceFXIndex; }
257 /// Return true if the deposit is currently enabled
258 bool enabled() const { return _Enabled; }
260 /// Enable(true)/Disable(false) the deposit
261 void enable(bool bEnable) { _Enabled = bEnable; }
263 /// Return true if the deposit can be prospected
264 bool canProspect() const { return _CanProspect; }
266 /// Return true if the submitted terrain matches the deposit
267 bool matchEcotype( TEcotype t ) const
268 { return t==_Ecotype; }
270 /// Return true if the submitted season matches the deposit
271 bool matchSeason( CRyzomTime::ESeason s ) const
272 { return _SeasonFilter.empty() || (std::find( _SeasonFilter.begin(), _SeasonFilter.end(), s ) != _SeasonFilter.end()); }
274 /// Return true if the submitted weather matches the deposit
275 bool matchWeather( CRyzomTime::EWeather w ) const
276 { return _WeatherFilter.empty() || (std::find( _WeatherFilter.begin(), _WeatherFilter.end(), w ) != _WeatherFilter.end()); }
278 /// Return true if the submitted time of day matches the deposit
279 bool matchTimeOfDay( CRyzomTime::ETimeOfDay t ) const
280 { return _TimeOfDayFilter.empty() || (std::find( _TimeOfDayFilter.begin(), _TimeOfDayFilter.end(), t ) != _TimeOfDayFilter.end()); }
282 /// Return true if the deposit contains at least one RM of the specified family
283 bool hasFamily( RM_FAMILY::TRMFamily family ) const;
285 /// Return true if the deposit contains at least one RM of the specified group
286 bool hasGroup( RM_GROUP::TRMGroup group ) const;
288 /// Return true if the deposit contains at least one RM than can craft the specified item part
289 bool hasRMForItemPart( uint itemPartIndex ) const;
291 /// Return true if the deposit contains at least one RM with energy lower_eq than the specified value
292 bool hasLowerStatEnergy( uint8 maxStatEnergy ) const;
294 /// Return true if the deposit contains at least one RM with energy equalling the specifing value
295 bool hasExactStatEnergy( uint8 statEnergy ) const;
297 /// Return the kami anger level (or -1 if disabled)
298 float kamiAnger() const { return _KamiAnger; }
300 /// Set the kami anger level
301 void setKamiAnger( float newKamiAnger ) { _KamiAnger = newKamiAnger; }
303 /// Increment the kami anger level. React if a threshold is reached. Return the kami anger level (see kamiAnger())
304 float incKamiAnger( float delta, const std::vector<TDataSetRow>& foragers );
306 /// Decrement the kami anger level (result clamped to 0)
307 float decKamiAnger( float delta ) { if ( _KamiAnger != -1.0f ) { _KamiAnger -= delta; if ( _KamiAnger < 0 ) _KamiAnger = 0; } return _KamiAnger; }
309 /// True if the deposit allow depletion risk for recent forage site
310 bool allowDepletionRisk() const {return _AllowDepletionRisk;}
312 /// Return the auto spawn properties (if auto-spawn is on, otherwise return NULL)
313 const CAutoSpawnProperties *getAutoSpawnProperties() const { return _AutoSpawnSourcePt; }
315 /// Return the quantuty constraints (if any, otherwise return NULL)
316 const CQuantityConstraints *getQuantityConstraints() const { return _QuantityConstraintsPt; }
318 /// Return the quantity available in the deposit (or FLT_MAX if there is no quantity constraint)
319 float getMaxQuantity() { return _QuantityConstraintsPt ? _QuantityConstraintsPt->getCurrentQuantity() : FLT_MAX; }
321 /// Consume. Return the actual consumed quantity (may be lower if there is no more to get)
322 float consumeQuantity( float requested ) { if ( _QuantityConstraintsPt ) return _QuantityConstraintsPt->consumeQuantity( requested ); else return requested; }
325 * Get a random RM from the neighbourhood of the specified position.
326 * OptFastFloorBegin()/OptFastFloorEnd() must enclose one or more calls to this method.
328 const CStaticDepositRawMaterial *getRandomRMAtPos( const NLMISC::CVector& pos, bool testIfSiteDepleted, bool& isDepleted );
331 * Get the RM at the specified position (no random for map generation).
332 * OptFastFloorBegin()/OptFastFloorEnd() must enclose one or more calls to this method.
333 * \param testIfSiteDepleted Set it to false for map generation.
335 const CStaticDepositRawMaterial *getRMAtPos( const NLMISC::CVector& pos, bool testIfSiteDepleted, bool& isDepleted );
337 /// Return always a forage site
338 CRecentForageSite *findOrCreateForageSite( const NLMISC::CVector& pos );
340 /// Display forage sites info
341 void displayRecentForageSites( NLMISC::CLog& log ) const;
343 /// Empty all forage sites
344 void depleteAllRecentForageSites();
346 // For auto-spawn source minimum number. Internaly used by CHarvestSource only
347 void decreaseAutoSpawnedSources();
348 void increaseAutoSpawnedSources();
350 protected:
352 /// Select the raw materials, using the specified filters and _Ecotype
353 void selectRMsByFilters( std::vector<std::string>& exactRMCodesS, const std::vector<std::string>& rmFamilyFilterS, const std::vector<std::string>& itemPartsFilterS, const std::vector<std::string>& craftCivS, uint minEnergy, uint maxEnergy );
355 std::string getSeasonStr() const;
356 std::string getTimeOfDayStr() const;
357 std::string getWeatherStr() const;
360 * Get the ecotype zone under the position.
361 * This information is valid only at init time. After the deposits are built, this information
362 * can be found only in deposits.
363 * If not found, a NULL pointer is returned.
365 static CEcotypeZone *getEcotypeZone( const NLMISC::CVector& pos );
367 /// auto spawn a source in the deposit, in the given bbox
368 void autoSpawnSource(const NLMISC::CVector &cornerMin, const NLMISC::CVector &cornerMax);
370 private:
372 /// The ecotype zones (only valid at init, cleared after deposit built)
373 static CEcotypeZones _EcotypeZones;
376 /// List of raw materials (const)
377 std::vector< CStaticDepositRawMaterial > _RawMaterials;
379 /// Type of terrain (const)
380 TEcotype _Ecotype;
382 /// Season filter (const)
383 std::vector<CRyzomTime::ESeason> _SeasonFilter;
385 /// Weather filter (const)
386 std::vector<CRyzomTime::EWeather> _WeatherFilter;
388 /// Time of day filter (const)
389 std::vector<CRyzomTime::ETimeOfDay> _TimeOfDayFilter;
391 /// Phase for noise value generator (deduced from season, weather, time... filters)
392 uint _FilterPhase;
394 /// Recent forage site list (per deposit, which means forage won't affect another overlapped deposit)
395 CRecentForageSites _RecentForageSites;
397 /// Deposit name
398 std::string _Name;
400 /// Not null if the deposit can spawn sources without foraging action
401 CAutoSpawnProperties *_AutoSpawnSourcePt;
403 /// From 0 to KAMI_ANGER_THRESHOLD 1 & 2, or -1 for N/A; will be persistant some day...
404 float _KamiAnger;
406 /// Min quality or -1 if there is no inferior limit
407 sint16 _MinQuality;
409 /// Max quality or -1 if it has to be taken from the raw material information
410 sint16 _MaxQuality;
412 /// Not null if the deposit has main quantity constraints
413 CQuantityConstraints *_QuantityConstraintsPt;
415 /// Index of the visual shape/FX of the sources from this deposit
416 uint16 _SourceFXIndex;
418 /// Can a player prospect on this deposit
419 bool _CanProspect;
421 /// Is this deposit enabled or disabled (for deposits that are not permanent)
422 bool _Enabled;
424 /// Is this deposit allows depletion risk. True by default
425 bool _AllowDepletionRisk;
427 // deposit id
428 //uint _Id;
430 /// Current Number of AutoSpawned Sources in this deposit
431 uint32 _CurrentNbAutoSpawnedSources;
436 * Predicate to compare two pointed deposits using their kami anger level.
437 * If a value is -1, it is not considered as lower.
439 struct CHasLowerKamiAngerPred : std::binary_function< CDeposit*, CDeposit*, bool >
441 bool operator() ( CDeposit *d1, CDeposit *d2 )
443 return (d1->kamiAnger() >= 0) && (d1->kamiAnger() < d2->kamiAnger());
449 * Return the quantity available in the deposit (or FLT_MAX if there is no quantity constraint)
451 inline float CRecentForageSite::getQuantityInDeposit()
453 return _Deposit->getMaxQuantity();
458 * Consume 1 unit of forage site stock by a source in the (independant on the quantity extracted).
459 * Reset life time of forage site if successful.
460 * Additionally, consume n units of deposit stock (dependant on the quantity extracted).
461 * Return the actual quantity that is extracted (can be less that requested if the deposit is (nearly or fully) empty.
463 inline float CRecentForageSite::consume( float n )
465 if ( _LowScopeStock != 0 )
467 --_LowScopeStock;
468 _TimeToLive = ForageSiteNbUpdatesToLive.get();
470 return _Deposit->consumeQuantity( n );
475 * Return true if the deposit allows depletion risk
477 inline bool CRecentForageSite::allowDepletionRisk() const
479 return _Deposit && _Deposit->allowDepletionRisk();
484 #endif // RY_DEPOSIT_H
486 /* End of deposit.h */