diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_kill.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_kill.cpp index f9918db2d..8fa18d518 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_kill.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_kill.cpp @@ -69,22 +69,36 @@ class CMissionStepKillFauna : public IMissionStepTemplate _SubSteps.reserve( subs.size() ); for ( uint i = 0; i < subs.size(); i++ ) { + CSubStep subStep; + std::vector< std::string > args; CMissionParser::tokenizeString( subs[i]," \t", args ); - if ( args.size() != 2 ) + + //// Dynamic Mission Args : #dynamic# + if ((args.size() == 2) && (args[0] == "#dynamic#")) { - MISLOGSYNTAXERROR(" *[; ] [: ]"); - return false; + subStep.Dynamic = missionData.Name; + subStep.Quantity = atoi(args[1].c_str()); } - missionData.ChatParams.push_back( make_pair(args[0],STRING_MANAGER::creature_model) ); - CSubStep subStep; - subStep.Sheet = CSheetId( args[0] + ".creature"); - if ( subStep.Sheet == CSheetId::Unknown ) + //// + else { - ret = false; - MISLOGERROR1("invalid sheet '%s'", args[0].c_str()); + if ( args.size() != 2 ) + { + MISLOGSYNTAXERROR(" *[; ] [: ]"); + return false; + } + missionData.ChatParams.push_back( make_pair(args[0],STRING_MANAGER::creature_model) ); + + subStep.Dynamic = ""; + subStep.Sheet = CSheetId( args[0] + ".creature"); + if ( subStep.Sheet == CSheetId::Unknown ) + { + ret = false; + MISLOGERROR1("invalid sheet '%s'", args[0].c_str()); + } + NLMISC::fromString(args[1], subStep.Quantity); } - NLMISC::fromString(args[1], subStep.Quantity); _SubSteps.push_back(subStep); } 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 ) { + nlinfo("Process Event"); + string webAppUrl; + bool ret = true; + _User = PlayerManager.getChar(getEntityIdFromRow(userRow)); + if ( event.Type == CMissionEvent::Kill ) { CMissionEventKill & eventSpe = (CMissionEventKill&)event; CCreature * c = CreatureManager.getCreature( event.TargetEntity ); + CSheetId faunaSheet; + + //// Dynamic Mission Args + if (_SubSteps[subStepIndex].Dynamic.empty()) { + faunaSheet = _SubSteps[subStepIndex].Sheet; + } + else + { + vector 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 ) { LOGMISSIONSTEPERROR("kill_fauna : invalid creature " + toString(event.TargetEntity.getIndex())); } - else if ( _SubSteps[subStepIndex].Sheet == c->getType() ) + else if ( faunaSheet == c->getType() ) { if ( _Place != 0xFFFF ) { @@ -127,6 +180,8 @@ class CMissionStepKillFauna : public IMissionStepTemplate if ( region && region->getId() == _Place ) { + if (!webAppUrl.empty()) + _User->validateDynamicMissionStep(webAppUrl); LOGMISSIONSTEPSUCCESS("kill_fauna"); return 1; } @@ -135,6 +190,8 @@ class CMissionStepKillFauna : public IMissionStepTemplate { if ( places[i] && places[i]->getId() == _Place ) { + if (!webAppUrl.empty()) + _User->validateDynamicMissionStep(webAppUrl); LOGMISSIONSTEPSUCCESS("kill_fauna"); return 1; } @@ -143,11 +200,14 @@ class CMissionStepKillFauna : public IMissionStepTemplate } else { + if (!webAppUrl.empty()) + _User->validateDynamicMissionStep(webAppUrl); LOGMISSIONSTEPSUCCESS("kill_fauna"); return 1; } } } + return 0; } @@ -163,41 +223,82 @@ class CMissionStepKillFauna : public IMissionStepTemplate virtual void getTextParams( uint & nbSubSteps,const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector& subStepStates) { + static const std::string stepTextReact = "MIS_NEED_REACTIVATION"; static const std::string stepText = "MIS_KILL_FAUNA_"; static const std::string stepTextLoc = "MIS_KILL_FAUNA_LOC_"; nlassert( _SubSteps.size() == subStepStates.size() ); + CSheetId faunaSheet; for ( uint i = 0; i < subStepStates.size(); i++ ) { if( subStepStates[i] != 0 ) { - nbSubSteps++; - retParams.push_back(STRING_MANAGER::TParam()); - retParams.back().Type = STRING_MANAGER::creature_model; - retParams.back().SheetId = _SubSteps[i].Sheet; + if (_SubSteps[i].Dynamic.empty()) + { + faunaSheet = _SubSteps[i].Sheet; + } + else + { + //// Dynamic Mission Args + vector 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(); + } + //// + } - retParams.push_back(STRING_MANAGER::TParam()); - retParams.back().Type = STRING_MANAGER::integer; - retParams.back().Int = subStepStates[i]; + nbSubSteps++; + if (faunaSheet != CSheetId::Unknown) + { + retParams.push_back(STRING_MANAGER::TParam()); + retParams.back().Type = STRING_MANAGER::creature_model; + retParams.back().SheetId = faunaSheet; + + retParams.push_back(STRING_MANAGER::TParam()); + retParams.back().Type = STRING_MANAGER::integer; + retParams.back().Int = subStepStates[i]; + } } } - if ( _Place != 0xFFFF ) + if (faunaSheet != CSheetId::Unknown) { - STRING_MANAGER::TParam param; - param.Type = STRING_MANAGER::place; - CPlace * place = CZoneManager::getInstance().getPlaceFromId(_Place); - if ( !place ) + if ( _Place != 0xFFFF ) { - MISLOG("sline:%u ERROR : kill_fauna : Invalid place %u", _SourceLine, _Place); + STRING_MANAGER::TParam param; + param.Type = STRING_MANAGER::place; + CPlace * place = CZoneManager::getInstance().getPlaceFromId(_Place); + if ( !place ) + { + MISLOG("sline:%u ERROR : kill_fauna : Invalid place %u", _SourceLine, _Place); + } + else + { + param.Identifier = place->getName(); + retParams.push_back(param); + } + textPtr = &stepTextLoc; } else - { - param.Identifier = place->getName(); - retParams.push_back(param); - } - textPtr = &stepTextLoc; + textPtr = &stepText; } else - textPtr = &stepText; + textPtr = &stepTextReact; } std::vector< CSubStep > _SubSteps; @@ -330,6 +431,7 @@ class CMissionStepKillRace : public IMissionStepTemplate virtual void getTextParams( uint & nbSubSteps, const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector& subStepStates) { + static const std::string stepTextReact = "MIS_NEED_REACTIVATION"; static const std::string stepText = "MIS_KILL_RACE_"; static const std::string stepTextLoc = "MIS_KILL_RACE_LOC_"; @@ -381,6 +483,7 @@ class CMissionStepKillNpc : public IMissionStepTemplate { struct CSubStep { + string Dynamic; TAIAlias Alias; // NLMISC::TStringId NpcName; }; @@ -401,9 +504,17 @@ class CMissionStepKillNpc : public IMissionStepTemplate for ( uint i = 0; i < subs.size(); i++ ) { CSubStep subStep; - subStep.Alias = CAIAliasTranslator::Invalid; - if ( !CMissionParser::parseBotName(subs[i],subStep.Alias,missionData) ) - ret = false; + //// Dynamic Mission Args : #dynamic# + if (trim(subs[i]) == "#dynamic#") { + subStep.Dynamic = missionData.Name; + } + //// + else + { + subStep.Alias = CAIAliasTranslator::Invalid; + if ( !CMissionParser::parseBotName(subs[i],subStep.Alias,missionData) ) + ret = false; + } _SubSteps.push_back( subStep ); } return ret; @@ -411,6 +522,9 @@ class CMissionStepKillNpc : public IMissionStepTemplate } 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 ) { CMissionEventKill & eventSpe = (CMissionEventKill&)event; @@ -421,18 +535,44 @@ class CMissionStepKillNpc : public IMissionStepTemplate } else { - if ( _SubSteps[subStepIndex].Alias != CAIAliasTranslator::Invalid ) + if (_SubSteps[subStepIndex].Dynamic.empty()) { - if ( _SubSteps[subStepIndex].Alias == c->getAlias() ) + if ( _SubSteps[subStepIndex].Alias != CAIAliasTranslator::Invalid ) + { + if ( _SubSteps[subStepIndex].Alias == c->getAlias() ) + { + LOGMISSIONSTEPSUCCESS("kill_npc"); + return 1; + } + } + else if ( event.TargetEntity == giverRow ) { LOGMISSIONSTEPSUCCESS("kill_npc"); return 1; } } - else if ( event.TargetEntity == giverRow ) + else { - LOGMISSIONSTEPSUCCESS("kill_npc"); - return 1; + //// Dynamic Mission Args + vector 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; + } + } + //// } } } @@ -451,6 +591,7 @@ class CMissionStepKillNpc : public IMissionStepTemplate virtual void getTextParams( uint & nbSubSteps, const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector& subStepStates) { + static const std::string stepTextReact = "MIS_NEED_REACTIVATION"; static const std::string stepText = "MIS_KILL_NPC_"; textPtr = &stepText; nlassert( _SubSteps.size() == subStepStates.size() ); @@ -461,10 +602,34 @@ class CMissionStepKillNpc : public IMissionStepTemplate nbSubSteps++; retParams.push_back(STRING_MANAGER::TParam()); retParams.back().Type = STRING_MANAGER::bot; - if ( _SubSteps[i].Alias != CAIAliasTranslator::Invalid ) - retParams.back().Int = _SubSteps[i].Alias; + if (_SubSteps[i].Dynamic.empty()) + { + if ( _SubSteps[i].Alias != CAIAliasTranslator::Invalid ) + retParams.back().Int = _SubSteps[i].Alias; + else + retParams.back().Identifier = "giver"; + } else - retParams.back().Identifier = "giver"; + { + vector params = _User->getCustomMissionParams(_SubSteps[i].Dynamic); + if (params.size() < 2) + { + nlinfo("kill_npc : invalid dynamic npc"); + textPtr = &stepTextReact; + return; + } + else + { + vector 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"); - - - - // ---------------------------------------------------------------------------- class CMissionStepKillPlayer : public IMissionStepTemplate { diff --git a/code/ryzom/server/src/entities_game_service/phrase_manager/phrase_utilities_functions.cpp b/code/ryzom/server/src/entities_game_service/phrase_manager/phrase_utilities_functions.cpp index 7e32b3060..4c8af6b6c 100644 --- a/code/ryzom/server/src/entities_game_service/phrase_manager/phrase_utilities_functions.cpp +++ b/code/ryzom/server/src/entities_game_service/phrase_manager/phrase_utilities_functions.cpp @@ -1528,21 +1528,21 @@ bool testOffensiveActionAllowed( const NLMISC::CEntityId &actorId, const NLMISC: return false; } - // test target isn't invulnerable - if (target->getContextualProperty().directAccessForStructMembers().invulnerable()) - { - // check target Faction attackable flags - CCreature *creature = dynamic_cast (target); - if (!creature || !creature->checkFactionAttackable(actorId)) - { - errorCode = "BS_TARGET_NOT_ATTACKABLE"; - return false; - } - } - // AI if (actorId.getType() != RYZOMID::player) { + // test target isn't invulnerable + if (target->getContextualProperty().directAccessForStructMembers().invulnerable()) + { + // check target Faction attackable flags + CCreature *creature = dynamic_cast (target); + if (!creature || !creature->checkFactionAttackable(actorId)) + { + errorCode = "BS_TARGET_NOT_ATTACKABLE"; + return false; + } + } + if (mainTarget == true) return true; else diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character_inlines.h b/code/ryzom/server/src/entities_game_service/player_manager/character_inlines.h index 4d9f51fdb..7775c122d 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character_inlines.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/character_inlines.h @@ -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 { return _MpSourceId; @@ -847,7 +854,7 @@ inline uint16 CCharacter::getKilledPvPRegion() //------------------------------------------------------------------------------ -inline bool CCharacter::getSafeInPvPSafeZone() +inline bool CCharacter::getSafeInPvPSafeZone() const { return _PvPSafeZoneActive; } @@ -875,11 +882,26 @@ inline uint32 CCharacter::getLastConnectedTime() const //------------------------------------------------------------------------------ +inline uint32 CCharacter::getLastConnectedDate() const +{ + return _LastConnectedDate; +} + +//------------------------------------------------------------------------------ + inline uint32 CCharacter::getPlayedTime() const { return _PlayedTime; } +//------------------------------------------------------------------------------ + +inline uint32 CCharacter::getOrganization() const +{ + return _Organization; +} + + //------------------------------------------------------------------------------ inline const std::list& CCharacter::getLastLogStats() const diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character_interface.h b/code/ryzom/server/src/entities_game_service/player_manager/character_interface.h index 05958655c..ffa525556 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character_interface.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/character_interface.h @@ -126,6 +126,9 @@ public: virtual void setContactOnlineStatus(const NLMISC::CEntityId &charEid, bool connection) =0; + virtual void setLastConnectionDate(uint32 date) =0; + + virtual void syncContactListWithCharNameChanges(const std::vector &charNameChanges)=0; virtual void updateTargetingChars()=0; diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character_inventory_manipulation.cpp b/code/ryzom/server/src/entities_game_service/player_manager/character_inventory_manipulation.cpp index 6818a8b73..db7d0c22b 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character_inventory_manipulation.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/character_inventory_manipulation.cpp @@ -2443,7 +2443,7 @@ void CCharacter::sendItemInfos( uint16 slotId ) infos.TypeSkillMods = item->getTypeSkillMods(); // 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::size_type sPos = cText.find(" "); @@ -2453,11 +2453,16 @@ void CCharacter::sendItemInfos( uint16 slotId ) string cUrl = cText.substr(sPos, ePos-sPos); infos.CustomText = ucstring("@WEBIG "+cUrl); } - else - infos.CustomText = ""; } else + { infos.CustomText = item->getCustomText(); + } + + if (item->getPetIndex() < MAX_INVENTORY_ANIMAL) + { + infos.PetNumber = item->getPetIndex() + 1; + } CMessage msgout( "IMPULSION_ID" ); CBitMemStream bms; @@ -2912,7 +2917,8 @@ void CCharacter::useItem(uint32 slot) { pair allegeance = getAllegiance(); 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"); return; diff --git a/code/ryzom/server/src/entities_game_service/player_manager/persistent_player_data.cpp b/code/ryzom/server/src/entities_game_service/player_manager/persistent_player_data.cpp index 542135aa9..1ffbc9c81 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/persistent_player_data.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/persistent_player_data.cpp @@ -414,6 +414,10 @@ static void prepareCharacterPositionForStore ( COfflineEntityState & state, cons _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)\ \ + 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(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))\ PROP(bool,IsTpAllowed)\ PROP(TSatiety,Satiety)\ + PROP2(CustomName, ucstring, CustomName, CustomName = val)\ //#pragma message( PERSISTENT_GENERATION_MESSAGE ) #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! - * \author Sébastien 'kxu' Guignot + * \author Sebastien 'kxu' Guignot * \author Nevrax France * \date 2005 */ @@ -1345,6 +1350,7 @@ private: STRUCT_VECT(_TypeSkillMods)\ LPROP_VECT(CSheetId, _Enchantment, VECT_LOGIC(_Enchantment) if (_Enchantment[i]!=CSheetId::Unknown))\ PROP2(_CustomText, ucstring, _CustomText, _CustomText=val)\ + PROP(bool, _LockedByOwner)\ //#pragma message( PERSISTENT_GENERATION_MESSAGE ) #include "game_share/persistent_data_template.h"