Changed: #1433 Merge changes from patch 1.13

This commit is contained in:
kervala 2012-03-04 14:35:44 +01:00
parent 6c1e509898
commit d403d24bb0
6 changed files with 261 additions and 63 deletions

View file

@ -69,15 +69,28 @@ class CMissionStepKillFauna : public IMissionStepTemplate
_SubSteps.reserve( subs.size() ); _SubSteps.reserve( subs.size() );
for ( uint i = 0; i < subs.size(); i++ ) for ( uint i = 0; i < subs.size(); i++ )
{ {
CSubStep subStep;
std::vector< std::string > args; std::vector< std::string > args;
CMissionParser::tokenizeString( subs[i]," \t", args ); CMissionParser::tokenizeString( subs[i]," \t", args );
//// Dynamic Mission Args : #dynamic# <quantity>
if ((args.size() == 2) && (args[0] == "#dynamic#"))
{
subStep.Dynamic = missionData.Name;
subStep.Quantity = atoi(args[1].c_str());
}
////
else
{
if ( args.size() != 2 ) if ( args.size() != 2 )
{ {
MISLOGSYNTAXERROR("<creature> <quantity> *[; <creature> <quantity>] [: <place>]"); MISLOGSYNTAXERROR("<creature> <quantity> *[; <creature> <quantity>] [: <place>]");
return false; return false;
} }
missionData.ChatParams.push_back( make_pair(args[0],STRING_MANAGER::creature_model) ); missionData.ChatParams.push_back( make_pair(args[0],STRING_MANAGER::creature_model) );
CSubStep subStep;
subStep.Dynamic = "";
subStep.Sheet = CSheetId( args[0] + ".creature"); subStep.Sheet = CSheetId( args[0] + ".creature");
if ( subStep.Sheet == CSheetId::Unknown ) if ( subStep.Sheet == CSheetId::Unknown )
{ {
@ -85,6 +98,7 @@ class CMissionStepKillFauna : public IMissionStepTemplate
MISLOGERROR1("invalid sheet '%s'", args[0].c_str()); MISLOGERROR1("invalid sheet '%s'", args[0].c_str());
} }
NLMISC::fromString(args[1], subStep.Quantity); NLMISC::fromString(args[1], subStep.Quantity);
}
_SubSteps.push_back(subStep); _SubSteps.push_back(subStep);
} }
if ( script.size() == 3 ) if ( script.size() == 3 )
@ -105,15 +119,54 @@ class CMissionStepKillFauna : public IMissionStepTemplate
} }
uint processEvent( const TDataSetRow & userRow, const CMissionEvent & event,uint subStepIndex,const TDataSetRow & giverRow ) uint processEvent( const TDataSetRow & userRow, const CMissionEvent & event,uint subStepIndex,const TDataSetRow & giverRow )
{ {
nlinfo("Process Event");
string webAppUrl;
bool ret = true;
_User = PlayerManager.getChar(getEntityIdFromRow(userRow));
if ( event.Type == CMissionEvent::Kill ) if ( event.Type == CMissionEvent::Kill )
{ {
CMissionEventKill & eventSpe = (CMissionEventKill&)event; CMissionEventKill & eventSpe = (CMissionEventKill&)event;
CCreature * c = CreatureManager.getCreature( event.TargetEntity ); CCreature * c = CreatureManager.getCreature( event.TargetEntity );
CSheetId faunaSheet;
//// Dynamic Mission Args
if (_SubSteps[subStepIndex].Dynamic.empty()) {
faunaSheet = _SubSteps[subStepIndex].Sheet;
}
else
{
vector<string> params = _User->getCustomMissionParams(_SubSteps[subStepIndex].Dynamic);
if (params.size() < 2)
{
LOGMISSIONSTEPERROR("kill_fauna : invalid dynamic creature");
return 0;
}
else
{
webAppUrl = params[0];
faunaSheet = CSheetId(params[1]);
if (params.size() > 2) {
string placeStr = CMissionParser::getNoBlankString( params[2] );
CPlace * place = CZoneManager::getInstance().getPlaceFromName( placeStr );
if ( !place )
{
ret = false;
LOGMISSIONSTEPERROR("kill_fauna : invalid place "+params[2]);
}
else
_Place = place->getId();
}
}
////
}
if ( !c ) if ( !c )
{ {
LOGMISSIONSTEPERROR("kill_fauna : invalid creature " + toString(event.TargetEntity.getIndex())); LOGMISSIONSTEPERROR("kill_fauna : invalid creature " + toString(event.TargetEntity.getIndex()));
} }
else if ( _SubSteps[subStepIndex].Sheet == c->getType() ) else if ( faunaSheet == c->getType() )
{ {
if ( _Place != 0xFFFF ) if ( _Place != 0xFFFF )
{ {
@ -127,6 +180,8 @@ class CMissionStepKillFauna : public IMissionStepTemplate
if ( region && region->getId() == _Place ) if ( region && region->getId() == _Place )
{ {
if (!webAppUrl.empty())
_User->validateDynamicMissionStep(webAppUrl);
LOGMISSIONSTEPSUCCESS("kill_fauna"); LOGMISSIONSTEPSUCCESS("kill_fauna");
return 1; return 1;
} }
@ -135,6 +190,8 @@ class CMissionStepKillFauna : public IMissionStepTemplate
{ {
if ( places[i] && places[i]->getId() == _Place ) if ( places[i] && places[i]->getId() == _Place )
{ {
if (!webAppUrl.empty())
_User->validateDynamicMissionStep(webAppUrl);
LOGMISSIONSTEPSUCCESS("kill_fauna"); LOGMISSIONSTEPSUCCESS("kill_fauna");
return 1; return 1;
} }
@ -143,11 +200,14 @@ class CMissionStepKillFauna : public IMissionStepTemplate
} }
else else
{ {
if (!webAppUrl.empty())
_User->validateDynamicMissionStep(webAppUrl);
LOGMISSIONSTEPSUCCESS("kill_fauna"); LOGMISSIONSTEPSUCCESS("kill_fauna");
return 1; return 1;
} }
} }
} }
return 0; return 0;
} }
@ -163,23 +223,61 @@ class CMissionStepKillFauna : public IMissionStepTemplate
virtual void getTextParams( uint & nbSubSteps,const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates) virtual void getTextParams( uint & nbSubSteps,const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates)
{ {
static const std::string stepTextReact = "MIS_NEED_REACTIVATION";
static const std::string stepText = "MIS_KILL_FAUNA_"; static const std::string stepText = "MIS_KILL_FAUNA_";
static const std::string stepTextLoc = "MIS_KILL_FAUNA_LOC_"; static const std::string stepTextLoc = "MIS_KILL_FAUNA_LOC_";
nlassert( _SubSteps.size() == subStepStates.size() ); nlassert( _SubSteps.size() == subStepStates.size() );
CSheetId faunaSheet;
for ( uint i = 0; i < subStepStates.size(); i++ ) for ( uint i = 0; i < subStepStates.size(); i++ )
{ {
if( subStepStates[i] != 0 ) if( subStepStates[i] != 0 )
{ {
if (_SubSteps[i].Dynamic.empty())
{
faunaSheet = _SubSteps[i].Sheet;
}
else
{
//// Dynamic Mission Args
vector<string> params = _User->getCustomMissionParams(_SubSteps[i].Dynamic);
if (params.size() < 2)
{
faunaSheet = CSheetId::Unknown;
}
else
{
faunaSheet = CSheetId(params[1]);
}
if ((_Place == 0xFFFF) && (params.size() > 2))
{
string placeStr = CMissionParser::getNoBlankString( params[2] );
CPlace * place = CZoneManager::getInstance().getPlaceFromName( placeStr );
if ( !place )
{
MISLOG("sline:%u ERROR : kill_fauna : Invalid place %u", _SourceLine, _Place);
}
else
_Place = place->getId();
}
////
}
nbSubSteps++; nbSubSteps++;
if (faunaSheet != CSheetId::Unknown)
{
retParams.push_back(STRING_MANAGER::TParam()); retParams.push_back(STRING_MANAGER::TParam());
retParams.back().Type = STRING_MANAGER::creature_model; retParams.back().Type = STRING_MANAGER::creature_model;
retParams.back().SheetId = _SubSteps[i].Sheet; retParams.back().SheetId = faunaSheet;
retParams.push_back(STRING_MANAGER::TParam()); retParams.push_back(STRING_MANAGER::TParam());
retParams.back().Type = STRING_MANAGER::integer; retParams.back().Type = STRING_MANAGER::integer;
retParams.back().Int = subStepStates[i]; retParams.back().Int = subStepStates[i];
} }
} }
}
if (faunaSheet != CSheetId::Unknown)
{
if ( _Place != 0xFFFF ) if ( _Place != 0xFFFF )
{ {
STRING_MANAGER::TParam param; STRING_MANAGER::TParam param;
@ -199,6 +297,9 @@ class CMissionStepKillFauna : public IMissionStepTemplate
else else
textPtr = &stepText; textPtr = &stepText;
} }
else
textPtr = &stepTextReact;
}
std::vector< CSubStep > _SubSteps; std::vector< CSubStep > _SubSteps;
uint16 _Place; uint16 _Place;
@ -330,6 +431,7 @@ class CMissionStepKillRace : public IMissionStepTemplate
virtual void getTextParams( uint & nbSubSteps, const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates) virtual void getTextParams( uint & nbSubSteps, const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates)
{ {
static const std::string stepTextReact = "MIS_NEED_REACTIVATION";
static const std::string stepText = "MIS_KILL_RACE_"; static const std::string stepText = "MIS_KILL_RACE_";
static const std::string stepTextLoc = "MIS_KILL_RACE_LOC_"; static const std::string stepTextLoc = "MIS_KILL_RACE_LOC_";
@ -381,6 +483,7 @@ class CMissionStepKillNpc : public IMissionStepTemplate
{ {
struct CSubStep struct CSubStep
{ {
string Dynamic;
TAIAlias Alias; TAIAlias Alias;
// NLMISC::TStringId NpcName; // NLMISC::TStringId NpcName;
}; };
@ -401,9 +504,17 @@ class CMissionStepKillNpc : public IMissionStepTemplate
for ( uint i = 0; i < subs.size(); i++ ) for ( uint i = 0; i < subs.size(); i++ )
{ {
CSubStep subStep; CSubStep subStep;
//// Dynamic Mission Args : #dynamic#
if (trim(subs[i]) == "#dynamic#") {
subStep.Dynamic = missionData.Name;
}
////
else
{
subStep.Alias = CAIAliasTranslator::Invalid; subStep.Alias = CAIAliasTranslator::Invalid;
if ( !CMissionParser::parseBotName(subs[i],subStep.Alias,missionData) ) if ( !CMissionParser::parseBotName(subs[i],subStep.Alias,missionData) )
ret = false; ret = false;
}
_SubSteps.push_back( subStep ); _SubSteps.push_back( subStep );
} }
return ret; return ret;
@ -411,6 +522,9 @@ class CMissionStepKillNpc : public IMissionStepTemplate
} }
uint processEvent( const TDataSetRow & userRow, const CMissionEvent & event,uint subStepIndex,const TDataSetRow & giverRow ) uint processEvent( const TDataSetRow & userRow, const CMissionEvent & event,uint subStepIndex,const TDataSetRow & giverRow )
{ {
string webAppUrl;
CCharacter * user = PlayerManager.getChar(getEntityIdFromRow(userRow));
if ( event.Type == CMissionEvent::Kill ) if ( event.Type == CMissionEvent::Kill )
{ {
CMissionEventKill & eventSpe = (CMissionEventKill&)event; CMissionEventKill & eventSpe = (CMissionEventKill&)event;
@ -420,6 +534,8 @@ class CMissionStepKillNpc : public IMissionStepTemplate
LOGMISSIONSTEPERROR("kill_npc : invalid creature " + toString(event.TargetEntity.getIndex())); LOGMISSIONSTEPERROR("kill_npc : invalid creature " + toString(event.TargetEntity.getIndex()));
} }
else else
{
if (_SubSteps[subStepIndex].Dynamic.empty())
{ {
if ( _SubSteps[subStepIndex].Alias != CAIAliasTranslator::Invalid ) if ( _SubSteps[subStepIndex].Alias != CAIAliasTranslator::Invalid )
{ {
@ -435,6 +551,30 @@ class CMissionStepKillNpc : public IMissionStepTemplate
return 1; return 1;
} }
} }
else
{
//// Dynamic Mission Args
vector<string> params = user->getCustomMissionParams(_SubSteps[subStepIndex].Dynamic);
if (params.size() < 2) {
LOGMISSIONSTEPERROR("kill_npc : invalid dynamic npc");
return 0;
}
else
{
webAppUrl = params[0];
string name;
CAIAliasTranslator::getInstance()->getNPCNameFromAlias(c->getAlias(), name);
if ( name == params[1] )
{
user->validateDynamicMissionStep(webAppUrl);
LOGMISSIONSTEPSUCCESS("kill_npc");
return 1;
}
}
////
}
}
} }
return 0; return 0;
} }
@ -451,6 +591,7 @@ class CMissionStepKillNpc : public IMissionStepTemplate
virtual void getTextParams( uint & nbSubSteps, const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates) virtual void getTextParams( uint & nbSubSteps, const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates)
{ {
static const std::string stepTextReact = "MIS_NEED_REACTIVATION";
static const std::string stepText = "MIS_KILL_NPC_"; static const std::string stepText = "MIS_KILL_NPC_";
textPtr = &stepText; textPtr = &stepText;
nlassert( _SubSteps.size() == subStepStates.size() ); nlassert( _SubSteps.size() == subStepStates.size() );
@ -461,11 +602,35 @@ class CMissionStepKillNpc : public IMissionStepTemplate
nbSubSteps++; nbSubSteps++;
retParams.push_back(STRING_MANAGER::TParam()); retParams.push_back(STRING_MANAGER::TParam());
retParams.back().Type = STRING_MANAGER::bot; retParams.back().Type = STRING_MANAGER::bot;
if (_SubSteps[i].Dynamic.empty())
{
if ( _SubSteps[i].Alias != CAIAliasTranslator::Invalid ) if ( _SubSteps[i].Alias != CAIAliasTranslator::Invalid )
retParams.back().Int = _SubSteps[i].Alias; retParams.back().Int = _SubSteps[i].Alias;
else else
retParams.back().Identifier = "giver"; retParams.back().Identifier = "giver";
} }
else
{
vector<string> params = _User->getCustomMissionParams(_SubSteps[i].Dynamic);
if (params.size() < 2)
{
nlinfo("kill_npc : invalid dynamic npc");
textPtr = &stepTextReact;
return;
}
else
{
vector<TAIAlias> aliases;
CAIAliasTranslator::getInstance()->getNPCAliasesFromName( params[1] , aliases );
if ( aliases.empty() )
{
retParams.back().Int = CAIAliasTranslator::Invalid;
return;
}
retParams.back().Int = aliases[0];
}
}
}
} }
} }
@ -892,10 +1057,6 @@ class CMissionStepKillByName : public IMissionStepTemplate
MISSION_REGISTER_STEP(CMissionStepKillByName,"kill_npc_by_name"); MISSION_REGISTER_STEP(CMissionStepKillByName,"kill_npc_by_name");
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class CMissionStepKillPlayer : public IMissionStepTemplate class CMissionStepKillPlayer : public IMissionStepTemplate
{ {

View file

@ -1528,6 +1528,9 @@ bool testOffensiveActionAllowed( const NLMISC::CEntityId &actorId, const NLMISC:
return false; return false;
} }
// AI
if (actorId.getType() != RYZOMID::player)
{
// test target isn't invulnerable // test target isn't invulnerable
if (target->getContextualProperty().directAccessForStructMembers().invulnerable()) if (target->getContextualProperty().directAccessForStructMembers().invulnerable())
{ {
@ -1540,9 +1543,6 @@ bool testOffensiveActionAllowed( const NLMISC::CEntityId &actorId, const NLMISC:
} }
} }
// AI
if (actorId.getType() != RYZOMID::player)
{
if (mainTarget == true) if (mainTarget == true)
return true; return true;
else else

View file

@ -131,6 +131,13 @@ inline const NLMISC::CEntityId & CCharacter::getTeamInvitor() const
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
inline const NLMISC::CEntityId & CCharacter::getLeagueInvitor() const
{
return _LeagueInvitor;
}
//------------------------------------------------------------------------------
inline const NLMISC::CEntityId &CCharacter::harvestedEntity() const inline const NLMISC::CEntityId &CCharacter::harvestedEntity() const
{ {
return _MpSourceId; return _MpSourceId;
@ -847,7 +854,7 @@ inline uint16 CCharacter::getKilledPvPRegion()
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
inline bool CCharacter::getSafeInPvPSafeZone() inline bool CCharacter::getSafeInPvPSafeZone() const
{ {
return _PvPSafeZoneActive; return _PvPSafeZoneActive;
} }
@ -875,11 +882,26 @@ inline uint32 CCharacter::getLastConnectedTime() const
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
inline uint32 CCharacter::getLastConnectedDate() const
{
return _LastConnectedDate;
}
//------------------------------------------------------------------------------
inline uint32 CCharacter::getPlayedTime() const inline uint32 CCharacter::getPlayedTime() const
{ {
return _PlayedTime; return _PlayedTime;
} }
//------------------------------------------------------------------------------
inline uint32 CCharacter::getOrganization() const
{
return _Organization;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
inline const std::list<TCharacterLogTime>& CCharacter::getLastLogStats() const inline const std::list<TCharacterLogTime>& CCharacter::getLastLogStats() const

View file

@ -126,6 +126,9 @@ public:
virtual void setContactOnlineStatus(const NLMISC::CEntityId &charEid, bool connection) =0; virtual void setContactOnlineStatus(const NLMISC::CEntityId &charEid, bool connection) =0;
virtual void setLastConnectionDate(uint32 date) =0;
virtual void syncContactListWithCharNameChanges(const std::vector<NLMISC::CEntityId> &charNameChanges)=0; virtual void syncContactListWithCharNameChanges(const std::vector<NLMISC::CEntityId> &charNameChanges)=0;
virtual void updateTargetingChars()=0; virtual void updateTargetingChars()=0;

View file

@ -2443,7 +2443,7 @@ void CCharacter::sendItemInfos( uint16 slotId )
infos.TypeSkillMods = item->getTypeSkillMods(); infos.TypeSkillMods = item->getTypeSkillMods();
// Special case of web missions items // Special case of web missions items
if (item->getStaticForm()->Name == "Web Transaction" || item->getStaticForm()->Family == ITEMFAMILY::SCROLL) if (item->getStaticForm()->Name == "Web Transaction")
{ {
string cText = item->getCustomText().toString(); string cText = item->getCustomText().toString();
string::size_type sPos = cText.find(" "); string::size_type sPos = cText.find(" ");
@ -2453,11 +2453,16 @@ void CCharacter::sendItemInfos( uint16 slotId )
string cUrl = cText.substr(sPos, ePos-sPos); string cUrl = cText.substr(sPos, ePos-sPos);
infos.CustomText = ucstring("@WEBIG "+cUrl); infos.CustomText = ucstring("@WEBIG "+cUrl);
} }
else
infos.CustomText = "";
} }
else else
{
infos.CustomText = item->getCustomText(); infos.CustomText = item->getCustomText();
}
if (item->getPetIndex() < MAX_INVENTORY_ANIMAL)
{
infos.PetNumber = item->getPetIndex() + 1;
}
CMessage msgout( "IMPULSION_ID" ); CMessage msgout( "IMPULSION_ID" );
CBitMemStream bms; CBitMemStream bms;
@ -2912,7 +2917,8 @@ void CCharacter::useItem(uint32 slot)
{ {
pair<PVP_CLAN::TPVPClan, PVP_CLAN::TPVPClan> allegeance = getAllegiance(); pair<PVP_CLAN::TPVPClan, PVP_CLAN::TPVPClan> allegeance = getAllegiance();
if ((form->TpType == TELEPORT_TYPES::KAMI) && (allegeance.first == PVP_CLAN::Karavan) if ((form->TpType == TELEPORT_TYPES::KAMI) && (allegeance.first == PVP_CLAN::Karavan)
|| (form->TpType == TELEPORT_TYPES::KARAVAN) && (allegeance.first == PVP_CLAN::Kami)) || (form->TpType == TELEPORT_TYPES::KARAVAN) && (allegeance.first == PVP_CLAN::Kami)
|| getOrganization() == 5 ) //marauder
{ {
CCharacter::sendDynamicSystemMessage(_Id, "ALTAR_RESTRICTION"); CCharacter::sendDynamicSystemMessage(_Id, "ALTAR_RESTRICTION");
return; return;

View file

@ -414,6 +414,10 @@ static void prepareCharacterPositionForStore ( COfflineEntityState & state, cons
_FactionPoint[i],\ _FactionPoint[i],\
PVP_CLAN::TPVPClan k=PVP_CLAN::fromString(key); if ((k>=PVP_CLAN::BeginClans) && (k<=PVP_CLAN::EndClans)) _FactionPoint[k-PVP_CLAN::BeginClans]=val)\ PVP_CLAN::TPVPClan k=PVP_CLAN::fromString(key); if ((k>=PVP_CLAN::BeginClans) && (k<=PVP_CLAN::EndClans)) _FactionPoint[k-PVP_CLAN::BeginClans]=val)\
\ \
PROP(uint32,_PvpPoint)\
PROP(uint32,_Organization)\
PROP(uint32,_OrganizationStatus)\
PROP(uint32,_OrganizationPoints)\
PROP2(DeclaredCult,string,PVP_CLAN::toString(_DeclaredCult),_DeclaredCult=PVP_CLAN::fromString(val))\ PROP2(DeclaredCult,string,PVP_CLAN::toString(_DeclaredCult),_DeclaredCult=PVP_CLAN::fromString(val))\
PROP2(DeclaredCiv,string,PVP_CLAN::toString(_DeclaredCiv),_DeclaredCiv=PVP_CLAN::fromString(val))\ PROP2(DeclaredCiv,string,PVP_CLAN::toString(_DeclaredCiv),_DeclaredCiv=PVP_CLAN::fromString(val))\
\ \
@ -688,6 +692,7 @@ static void prepareCharacterPositionForStore ( COfflineEntityState & state, cons
LPROP(bool,IsMounted,if(IsMounted))\ LPROP(bool,IsMounted,if(IsMounted))\
PROP(bool,IsTpAllowed)\ PROP(bool,IsTpAllowed)\
PROP(TSatiety,Satiety)\ PROP(TSatiety,Satiety)\
PROP2(CustomName, ucstring, CustomName, CustomName = val)\
//#pragma message( PERSISTENT_GENERATION_MESSAGE ) //#pragma message( PERSISTENT_GENERATION_MESSAGE )
#include "game_share/persistent_data_template.h" #include "game_share/persistent_data_template.h"
@ -1183,7 +1188,7 @@ static void displayWarning(const std::string& s)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** /**
* This class is used to load old player room inventory, DO NOT BREAK IT! * This class is used to load old player room inventory, DO NOT BREAK IT!
* \author Sébastien 'kxu' Guignot * \author Sebastien 'kxu' Guignot
* \author Nevrax France * \author Nevrax France
* \date 2005 * \date 2005
*/ */
@ -1345,6 +1350,7 @@ private:
STRUCT_VECT(_TypeSkillMods)\ STRUCT_VECT(_TypeSkillMods)\
LPROP_VECT(CSheetId, _Enchantment, VECT_LOGIC(_Enchantment) if (_Enchantment[i]!=CSheetId::Unknown))\ LPROP_VECT(CSheetId, _Enchantment, VECT_LOGIC(_Enchantment) if (_Enchantment[i]!=CSheetId::Unknown))\
PROP2(_CustomText, ucstring, _CustomText, _CustomText=val)\ PROP2(_CustomText, ucstring, _CustomText, _CustomText=val)\
PROP(bool, _LockedByOwner)\
//#pragma message( PERSISTENT_GENERATION_MESSAGE ) //#pragma message( PERSISTENT_GENERATION_MESSAGE )
#include "game_share/persistent_data_template.h" #include "game_share/persistent_data_template.h"