// 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_HARVEST_SOURCE_H
#define NL_HARVEST_SOURCE_H
#include "nel/misc/vector_2f.h"
#include "game_share/base_types.h"
#include "egs_mirror.h"
#include "phrase_manager/simple_entity_manager.h"
#include "phrase_manager/toxic_cloud.h"
class CStaticDepositRawMaterial;
class CRecentForageSite;
class CEntityBase;
class CDeposit;
namespace VISIBILITY_RIGHTS
{
/// Visibility rights
enum TVisGroup
{
All,
Private,
Team,
Guild
};
/// Convert a numeric value to TVisGroup
inline TVisGroup fromInt( uint8 i )
{
return (TVisGroup)i;
}
}
#define _S _RTProps[S]
#define _A _RTProps[A]
#define _Q _RTProps[Q]
#define _D _RTProps[D]
#define _E _RTProps[E]
#define _C _RTProps[C]
/**
* Forage source
* \author Olivier Cado
* \author Nevrax France
* \date 2003
*/
class CHarvestSource
{
NL_INSTANCE_COUNTER_DECL(CHarvestSource);
public:
enum TRealTimeProp
{
S, NoDrop=S, // Source speed (in steps per tick (<1)). Not droppable.
A=1, // Source aperture (RM quantity delivered per step). Request 0 or "care".
Q=2, ReduceDmg=Q, // Average quality of the delivered RM
NbPosRTProps,
D = NbPosRTProps, // Level before source is destroyed / deposit is disabled. Request a negative value for "life absorption by player".
E, // Level before damaging events
//C, // Level before creature spawn
NbRTProps
};
enum TTargetRTProp // Subset of TRealTimeProp
{
TargetD,
TargetE,
NbTargetRTProps
};
enum TCareDelta
{
DeltaD,
DeltaE,
//DeltaC,
NbCareDeltas
};
enum TKamiAngerProp
{
ReservedForS,
KamiOffNum,
KamiAngerDec,
NbKamiAngerProps
};
/*enum TStatClassForage
{
BasicPlainAverage, FinePrime, ChoiceSelect, ExcellentSuperb, SupremeMagnificient, NbStatQualities
};*/
struct CReduceDamageEvent
{
NLMISC::TGameCycle Time;
float Ratio;
};
typedef std::vector CRDEvents;
typedef std::vector CForagers;
/// Constructor (a source does not need init() if it's only a template source passed to init())
CHarvestSource();
/// Destructor
~CHarvestSource();
// Change the properties (for a template source)
void setLifetime( NLMISC::TGameCycle t ) { _LifeTime = t; }
void setProspectionExtraExtractionTime( NLMISC::TGameCycle t ) { _ExtraExtractionTime = t + _IncludedBonusExtractionTime; } // Locked is forbidden
void setBonusExtraExtractionTime( NLMISC::TGameCycle t ) { _ExtraExtractionTime += t - _IncludedBonusExtractionTime; _IncludedBonusExtractionTime = t; }
void setS( float p ) { _S = p; }
void setA( float p ) { _A = p; }
void setQ( float p ) { _Q = p; }
void setD( float p ) { _D = p; }
void setE( float p ) { _E = p; }
//void setC( float p ) { _C = p; }
void setN( float p ) { _N = p; }
//void setDistVis( sint32 p ) { _DistanceVisibility = p; }
//void setStealthVis( VISIBILITY_RIGHTS::TVisGroup r ) { _StealthVisibility = r; }
/// Init the source. All pointers must be valid (but forageSite may be NULL). Return false if the current quantity in the deposit is 0.
bool init( const CHarvestSource& ini,
const NLMISC::CVector2f& pos,
CRecentForageSite *forageSite,
CDeposit *depositForK,
const CStaticDepositRawMaterial *rmInfo, float quantityRatio );
/// Set the deposit that has auto-spawned this source (if any). NULL to unlink the curent (if any)
void setDepositAutoSpawn(CDeposit *deposit);
/// Set bonus for quantity ratio
void setBonusForA( uint8 percent ) { _BonusForAPct = percent; }
/**
* Prepare the source as an unpublished entity in mirror. Return false in case of failure.
* Must be called *after* init().
* prospectorDataSetRow must be either null (isNull()) or an accessible row (isAccessible()).
*/
bool spawnBegin( uint8 knowledgePrecision, const TDataSetRow& prospectorDataSetRow, bool isAutoSpawned );
/**
* Complete the source spawn: publish the entity in mirror or delete it
* Caution: if authorized, the source object is deleted!
*/
void spawnEnd( bool authorized );
/// Tick update. Return false if the source's life is ended.
bool update();
/**
* Begin an extraction action. Once the extraction process is started, the source remains in
* extraction mode until the extraction time is elapsed (even if players stop/restart
* extracting). Set isNewbie to true if the extractor should have low risks.
* Return true if the forager is the extractor (the first one on the source)
*/
bool beginExtraction( const TDataSetRow& forager, bool isNewbie=false );
/**
* Update the source state with an extraction.
* Warning: this can lead to the death of the player (e.g. kami wrath threshold reached)
* => player->forageProgress() can become NULL and therefore must be tested.
*
* \param reqPosProps [in/out] Requested positive props (rS, rA, rQ). Can be lowered in output if a drop occurs.
* \param absPosProps [in] Absorption ratio (<=1.0f) of positive props (aS, aA, aQ): a higher value reduces the negative impact of the extraction.
* \param qualityCeilingFactor [in] Factor for quality target value (relative to reqPosProps[Q])
* \param qualitySlowFactor [in] Quality increase speed factor
* \param results [in/out] Resulting positive values (S, A, Q). In input, please provide the previous results.
* \param successFactor [in] The success factor ratio to be used.
* \param lifeAbsorberRatio [in] In not zero, extractingEntityRow will get some damage, converting lifeAbsorberRatio percent of the decrease of D.
* \param extractingEntityRow [in] See lifeAbsorberRatio.
* negative impact on the source life (D).
* \param propDrop [out] NoDrop=all ok; A=quantity drop; Q=quality drop.
*/
void extractMaterial( float *reqPosProps, float *absPosProps, float qualityCeilingFactor, float qualitySlowFactor, float *results, float successFactor, uint8 lifeAbsorberRatio, const TDataSetRow& extractingEntityRow, CHarvestSource::TRealTimeProp& propDrop );
/// Update the source state with a care (DeltaD, DeltaE, DeltaC). Output: isUseful if the care is not from the "begin zone"
void takeCare( float *deltas, bool *isUseful );
/// Reduce the damage of the next blowing up (will work if between ForageReduceDamageTimeWindow and blowing up time)
void reduceBlowingUpDmg( float ratio );
/// Damage an entity
static void hitEntity( RYZOMID::TTypeId aggressorType, CEntityBase *entity, sint32 hpDamageAmount, sint32 hpDamageAmountWithoutArmour, bool isIntentional, sint32 hpAvoided=0 );
/// Recalculate the remaining extraction time depending on the requested quality
void recalcExtractionTime( float requestedQuality );
/**
* Return the prospector or a null datasetrow if there was no prospection (auto-spawn)
* The accessibility of this datasetrow must be checked before use.
*/
const TDataSetRow& getProspectorDataSetRow() const;
// Accessors
const NLMISC::CSheetId& materialSheet() const { return _MaterialSheet; }
const TDataSetRow& rowId() const { return _DataSetRow; }
const NLMISC::CVector2f& pos() const { return _Pos; }
float quantity() const { return _N; }
//NLMISC::TGameCycle extractionTime() const { return _ExtractionTime + _ExtraExtractionTime; }
const NLMISC::TGameCycle& timeToLive() const { return _T; }
bool wasProspected() const { return _ExtraExtractionTime != 0; }
NLMISC::TGameCycle deliveryPeriod() const { return (NLMISC::TGameCycle)(1.0f / _S); }
float speed() const { return _S; }
float aperture() const { return _A; }
float quality() const { return _Q; }
float maxQuality() const { return _MaxQuality; }
const CRecentForageSite *forageSite() const { return _ForageSite; }
CDeposit *depositForK() const { return _DepositForK; }
bool isExtractionInProgress() const { return _IsExtractionInProgress; }
uint8 nbEventTriggered() const { return _NbEventTriggered; }
const CForagers& foragers() const { return _Foragers; }
/// Return the stat quality of the raw material [0..100]
uint16 getStatQuality() const;
// Accessors for testing
float getD() const { return _D; }
float getE() const { return _E; }
//float getC() const { return _C; }
uint getImpactScheme() const { return _IImpactMappingScheme; }
void resetSource( const CHarvestSource& ini ) { _NbExtractions = 0; initFrom( ini ); }
void setSafeSource(bool value) { _SafeSource = value; }
protected:
/// Init dynamic props from template source (except pos, _N and _MaxQuality... see other methods below, and others such as _IImpactMappingScheme).
void initFrom( const CHarvestSource& ini )
{ _LifeTime=ini._LifeTime; _ExtractionTime=ini._ExtractionTime; _ExtraExtractionTime=ini._ExtraExtractionTime; _S=ini._S; _A=ini._A; _Q=ini._Q; _D=ini._D; _E=ini._E; /*_C=ini._C;*/ /*_DistanceVisibility=ini._DistanceVisibility; _StealthVisibility=ini._StealthVisibility;*/ }
/// Set the position
void setPos( const NLMISC::CVector2f& pos ) { _Pos = pos; }
/// Set the link to the forage site
void setForageSite( CRecentForageSite *forageSite ) { _ForageSite = forageSite; }
/// Set the raw material, the initial amount and the max quality, or return false if the current quantity in the deposit is 0.
bool setRawMaterial( const CStaticDepositRawMaterial *rmInfo, float quantityRatio );
/// Update visual properties & related stuff
void updateVisuals();
/// Send a message to all the players extracting on the source
void sendMessageToExtractors( const char *msg );
/// Send a message with a parameter to all the players extracting on the source
void sendMessageToExtractors( const char *msg, sint32 param );
/// When the threshold of E is reached
void makeDamagingEvent();
/// A continuous damaging event
void spawnToxicCloud();
/// A one-time damaging event
void explode();
/// Despawn the source in mirror, and exit from forage site
void despawn();
/// Get the damage factor of a source [0..1] (for explosion or toxic cloud)
float getDamageFactor() const;
/// Inc the number of event triggered
void setEventTriggered() { if ( _NbEventTriggered < 255 ) ++_NbEventTriggered; }
/// Set a new mapping scheme of property impact
void setNewImpactScheme();
/// Impact a realtime prop
void impactRTProp( TTargetRTProp iProp, float targetValue )
{
_TargetRTProps[iProp] = targetValue;
}
private:
/// Raw material
NLMISC::CSheetId _MaterialSheet;
/// Entity representing the source, valid after spawn()
TDataSetRow _DataSetRow;
/// Source position (coordinates in meters)
NLMISC::CVector2f _Pos;
/// Link to forage site (they can't move in memory or be deleted while the source is present). Can be NULL (usually for tests)
CRecentForageSite *_ForageSite;
/// Link to deposit used for kami anger level (they can't move or deleted after init)
CDeposit *_DepositForK;
/// Link to deposit used for auto spawned sources? Should be NULL or same as _DepositForK. Yoyo: I use a CRefPtr for security...
NLMISC::CRefPtr _DepositAutoSpawn;
/// Source remaining Time To Live in ticks (decremented every update when !_IsExtractionInProgress)
NLMISC::TGameCycle _LifeTime;
/// The total time for extraction (_T initial value before it decreases). Locked is forbidden.
NLMISC::TGameCycle _ExtractionTime;
/// Extra time for extraction
NLMISC::TGameCycle _ExtraExtractionTime;
/// Amount of extra time (included in _ExtraExtractionTime) that comes from the extractor's bonus passive bricks
NLMISC::TGameCycle _IncludedBonusExtractionTime;
// Time remaining for extraction (starts to decrease when the 1st extraction begins). Locked until the source is fully spawned.
NLMISC::TGameCycle _T;
/// Quantity of raw material in the source
float _N;
/// Real-time properties
float _RTProps [NbRTProps];
/// Target value for D, E
float _TargetRTProps [NbTargetRTProps];
/// Max quality of the raw material
uint16 _MaxQuality;
/// Mapping of property impact
uint16 _IImpactMappingScheme;
/// Number of extractions done
uint16 _NbExtractions;
/// True if the impact scheme must be a friendly one
bool _IsInNewbieMode;
/// Bonus for quantity rate (aperture)
uint8 _BonusForAPct;
/// Distance of visibility
//sint32 _DistanceVisibility;
/// Stealth mode (visibility priviledges)
//VISIBILITY_RIGHTS::TVisGroup _StealthVisibility;
/// List of foragers
CForagers _Foragers;
/// List of 'reduce damage' events
CRDEvents _Events;
/// True if one or more extractions are in progress
bool _IsExtractionInProgress;
/// Trigger reset of explosion visual fx
sint8 _ExplosionResetCounter;
/// True if the source was auto-spawned
bool _IsAutoSpawned;
/// True if the source is safe (cannot explode)
bool _SafeSource;
/// Number of source risk events triggered
uint8 _NbEventTriggered;
};
/**
* Harvest source manager class
*/
class CHarvestSourceManager : public CSimpleEntityManager
{
NL_INSTANCE_COUNTER_DECL(CHarvestSourceManager);
public:
/// Singleton access
static CHarvestSourceManager *getInstance() { return (CHarvestSourceManager*)_Instance; }
/// Initialization
void init( TDataSetIndex baseRowIndex, TDataSetIndex size );
/// Release
static void release() { delete (CHarvestSourceManager*)_Instance; }
};
#endif // NL_HARVEST_SOURCE_H
/* End of harvest_source.h */