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/>.
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"
36 const uint16 MaxNbActiveSources
= std::numeric_limits
<uint16
>::max();
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
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) {}
53 bool addActiveSource() { if ( _NbActiveSources
== MaxNbActiveSources
) return false; ++_NbActiveSources
; return true; }
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();
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;
97 /// Test if site has sources
98 bool hasActiveSources() const { return _NbActiveSources
!=0; }
102 /// Pointer to deposit (deposits don't move in memory). Never NULL.
105 /// Center of site area
106 NLMISC::CVector _Pos
;
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
130 bool build( const NLLIGO::CPrimZone
* zone
);
133 TEcotype
ecotype() const { return _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
);
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)
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
);
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
;
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
);
195 class CWordsDictionary
;
199 * \author Nicolas Brigand, Alain Saffray, Olivier Cado
200 * \author Nevrax France
203 class CDeposit
: public NLLIGO::CPrimZone
, public NLMISC::CRefCount
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) {}
213 /// Add an ecotype information
214 static void addEcotype( CEcotypeZone
*ecotypeZone
) { _EcotypeZones
.push_back( ecotypeZone
); }
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(); }
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();
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
);
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)
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)
394 /// Recent forage site list (per deposit, which means forage won't affect another overlapped deposit)
395 CRecentForageSites _RecentForageSites
;
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...
406 /// Min quality or -1 if there is no inferior limit
409 /// Max quality or -1 if it has to be taken from the raw material information
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
421 /// Is this deposit enabled or disabled (for deposits that are not permanent)
424 /// Is this deposit allows depletion risk. True by default
425 bool _AllowDepletionRisk
;
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 )
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 */