diff --git a/code/ryzom/server/src/ai_service/child_container.h b/code/ryzom/server/src/ai_service/child_container.h index 657f822b3..79ffa832c 100644 --- a/code/ryzom/server/src/ai_service/child_container.h +++ b/code/ryzom/server/src/ai_service/child_container.h @@ -311,6 +311,7 @@ public: uint32 getChildIndexByAlias(uint32 alias) const; TChld* getChildByAlias(uint32 alias) const; TChld* getChildByName(std::string const& name) const; + TChld* getFirstChild() const; CAliasTreeOwner* getAliasChildByAlias(uint32 alias) const; CAliasTreeOwner* addAliasChild(CAliasTreeOwner* child); @@ -523,6 +524,19 @@ TChld* CAliasCont::getChildByName(std::string const& name) const return NULL; } +template +TChld* CAliasCont::getFirstChild() const +{ + size_t size = this->_Childs.size(); + for (size_t i=0; i_Childs[i]; + if (child!=NULL) + return child; + } + return NULL; +} + template CAliasTreeOwner* CAliasCont::getAliasChildByAlias(uint32 alias) const { diff --git a/code/ryzom/server/src/ai_service/nf_grp_npc.cpp b/code/ryzom/server/src/ai_service/nf_grp_npc.cpp index 15261d0d9..9d663e95c 100644 --- a/code/ryzom/server/src/ai_service/nf_grp_npc.cpp +++ b/code/ryzom/server/src/ai_service/nf_grp_npc.cpp @@ -1280,18 +1280,30 @@ void setPlayerController_ss_(CStateInstance* entity, CScriptStack& stack) { CGroup* grp = NULL; CSpawnBotNpc* bot = NULL; - if ((bot = dynamic_cast(CAIEntityPhysicalLocator::getInstance()->getEntity(botId))) - && (&bot->getPersistent().getGroup())==entity->getGroup()) + CAIEntityPhysicalLocator *inst = CAIEntityPhysicalLocator::getInstance(); + if (inst) { - CBotPlayer* player = NULL; - if (playerId!=NLMISC::CEntityId::Unknown - && (player = dynamic_cast(CAIEntityPhysicalLocator::getInstance()->getEntity(playerId)))) + CAIEntityPhysical *botEntity = inst->getEntity(botId); + if (botEntity) { - bot->setPlayerController(player); + if ((bot = dynamic_cast(botEntity)) + && (&bot->getPersistent().getGroup())==entity->getGroup()) + { + CBotPlayer* player = NULL; + if (playerId!=NLMISC::CEntityId::Unknown + && (player = dynamic_cast(CAIEntityPhysicalLocator::getInstance()->getEntity(playerId)))) + { + bot->setPlayerController(player); + } + else + bot->setPlayerController(NULL); + } } else - bot->setPlayerController(NULL); + nlwarning("Bot entity not found"); } + else + nlwarning("Instance not found"); } } @@ -2002,7 +2014,12 @@ static CSpawnBot* getSpawnBotFromGroupByName(CGroupNpc* const group, const std:: CSpawnBot* spawnBot=0; CAliasCont const& bots = group->bots(); - CBot* child=bots.getChildByName(botname); + CCont & cc_bots = group->bots(); + CBot* child; + if (botname == "") + child = bots.getFirstChild(); + else + child = bots.getChildByName(botname); if (!child) { return 0; } spawnBot = child->getSpawnObj(); @@ -2291,6 +2308,37 @@ void emote_css_(CStateInstance* entity, CScriptStack& stack) NLNET::CUnifiedNetwork::getInstance()->send( "EGS", msgout ); } + +void emote_ss_(CStateInstance* entity, CScriptStack& stack) +{ + string emoteName = (string)stack.top(); stack.pop(); + NLMISC::CEntityId botId = NLMISC::CEntityId((std::string)stack.top()); + + if (botId == NLMISC::CEntityId::Unknown) + { + return; + } + + // Is the emote valid + uint32 emoteId = CAIS::instance().getEmotNumber(emoteName); + if (emoteId == ~0) + { + return; + } + + // Get the behaviour Id + MBEHAV::EBehaviour behaviourId = (MBEHAV::EBehaviour)(emoteId + MBEHAV::EMOTE_BEGIN); + + // Change the behaviour + NLNET::CMessage msgout("SET_BEHAVIOUR"); + msgout.serial(botId); + MBEHAV::CBehaviour bh(behaviourId); + bh.Data = (uint16)(CTimeInterface::gameCycle()); + msgout.serial(bh); + + NLNET::CUnifiedNetwork::getInstance()->send( "EGS", msgout ); +} + //---------------------------------------------------------------------------- /** @page code @@ -2429,6 +2477,7 @@ std::map nfGetNpcGroupNativeFunctions() REGISTER_NATIVE_FUNC(functions, talkTo_sc_); REGISTER_NATIVE_FUNC(functions, facing_cscs_); REGISTER_NATIVE_FUNC(functions, emote_css_); + REGISTER_NATIVE_FUNC(functions, emote_ss_); REGISTER_NATIVE_FUNC(functions, npcSay_css_); REGISTER_NATIVE_FUNC(functions, dssMessage_fsss_); REGISTER_NATIVE_FUNC(functions, despawnBotByAlias_s_); diff --git a/code/ryzom/server/src/ai_service/nf_static.cpp b/code/ryzom/server/src/ai_service/nf_static.cpp index 4d4b6f870..0168d80ad 100644 --- a/code/ryzom/server/src/ai_service/nf_static.cpp +++ b/code/ryzom/server/src/ai_service/nf_static.cpp @@ -30,6 +30,8 @@ #include "nf_helpers.h" +#include "nel/misc/md5.h" + using std::string; using std::vector; using namespace NLMISC; @@ -655,6 +657,31 @@ void pow_ff_f(CStateInstance* entity, CScriptStack& stack) //---------------------------------------------------------------------------- /** @page code +@subsection md5sum_s_s +Returns the md5 sum of a string. + +Arguments: s(string) -> s(string) +@param[in] string is a string +@param[out] md5sum is a string + +@code +($sum)strlen($str); +@endcode + +*/ +// none +void md5sum_s_s(CStateInstance* entity, CScriptStack& stack) +{ + std::string str = (std::string)stack.top(); + + std::string value = NLMISC::getMD5((uint8*)&str[0], str.size() ).toString(); + nlinfo(value.c_str()); + stack.top() = value; +} + +//---------------------------------------------------------------------------- +/** @page code + @subsection strlen_s_f Returns the length of a string. @@ -1291,6 +1318,7 @@ std::map nfGetStaticNativeFunctions() REGISTER_NATIVE_FUNC(functions, sqrt_f_f); REGISTER_NATIVE_FUNC(functions, exp_f_f); REGISTER_NATIVE_FUNC(functions, pow_ff_f); + REGISTER_NATIVE_FUNC(functions, md5sum_s_s); REGISTER_NATIVE_FUNC(functions, strlen_s_f); REGISTER_NATIVE_FUNC(functions, substr_sff_s); REGISTER_NATIVE_FUNC(functions, strtof_s_f); diff --git a/code/ryzom/server/src/entities_game_service/admin.cpp b/code/ryzom/server/src/entities_game_service/admin.cpp index e83bce37f..d582ca0d3 100644 --- a/code/ryzom/server/src/entities_game_service/admin.cpp +++ b/code/ryzom/server/src/entities_game_service/admin.cpp @@ -91,6 +91,7 @@ #include "dyn_chat_egs.h" #include "pvp_manager/pvp.h" +#include "pvp_manager/pvp_manager_2.h" #include "player_manager/admin_properties.h" #include "shop_type/offline_character_command.h" #include "player_manager/item_service_manager.h" @@ -107,6 +108,10 @@ // Externs // + +// Max number of user channel character can be have +#define NB_MAX_USER_CHANNELS 2 + extern CPlayerManager PlayerManager; extern CCreatureManager CreatureManager; extern CPlayerService *PS; @@ -158,6 +163,8 @@ AdminCommandsInit[] = // player character accessible commands "teamInvite", true, "guildInvite", true, + "roomInvite", true, + "roomKick", true, "setGuildMessage", true, "clearGuildMessage", true, "dodge", true, @@ -166,6 +173,8 @@ AdminCommandsInit[] = "resurrected", true, "validateRespawnPoint", true, "summonPet", true, + "connectUserChannel", true, + "addPetAnimal", true, "addSkillPoints", true, @@ -344,12 +353,14 @@ AdminCommandsInit[] = "eventSetBotName", true, "eventSetBotScale", true, "eventSetNpcGroupAggroRange", true, + "eventSetNpcGroupEmote", true, "eventSetFaunaBotAggroRange", true, "eventResetFaunaBotAggroRange", true, "eventSetBotCanAggro", true, "eventSetItemCustomText", true, "eventResetItemCustomText", true, "eventSetBotSheet", true, +// "eventSetBotVPx", true, "eventSetBotFaction", true, "eventSetBotFameByKill", true, "dssTarget", true, //ring stuff @@ -2812,6 +2823,13 @@ void cbClientAdmin (NLNET::CMessage& msgin, const std::string &serviceName, NLNE return; } + if (onTarget && !c->haveAnyPrivilege()) + { + nlinfo("ADMIN: Player %s doesn't have privilege to execute /b command onTarget '%s' ", eid.toString().c_str(), cmdName.c_str()); + chatToPlayer (eid, "You don't have privilege to execute this command"); + return; + } + if (!cmd->ForwardToservice.empty()) { // we need to forward the command to another service @@ -2849,12 +2867,14 @@ void cbClientAdmin (NLNET::CMessage& msgin, const std::string &serviceName, NLNE { log_Command_ExecOnTarget(c->getTarget(), cmdName, arg); res += c->getTarget().toString(); + targetEid = c->getTarget(); targetName = NLMISC::toString("(%s,%s)", c->getTarget().toString().c_str(), CEntityIdTranslator::getInstance()->getByEntity(c->getTarget()).toString().c_str()); } else { log_Command_Exec(cmdName, arg); res += eid.toString(); + targetEid = eid; targetName = string("Himself"); } res += " "; @@ -2865,7 +2885,11 @@ void cbClientAdmin (NLNET::CMessage& msgin, const std::string &serviceName, NLNE TLogContext_Item_Command itemCtx(onTarget ? c->getTarget() : eid); TLogContext_Character_BuyRolemasterPhrase characterCtx(onTarget ? c->getTarget() : eid); std::string csName = CEntityIdTranslator::getInstance()->getByEntity(eid).toString(); - + + NLMISC::CSString cs_res = CSString(res); + cs_res = cs_res.replace("#player", eid.toString().c_str()); + cs_res = cs_res.replace("#target", targetEid.toString().c_str()); + res = (string)cs_res; nlinfo ("ADMIN: Player (%s,%s) will execute client admin command '%s' on target %s", eid.toString().c_str(), csName.c_str(), res.c_str(), targetName.c_str()); CLightMemDisplayer *CmdDisplayer = new CLightMemDisplayer("CmdDisplayer"); @@ -2941,6 +2965,13 @@ void cbClientAdminOffline (NLNET::CMessage& msgin, const std::string &serviceNam return; } + if (!c->haveAnyPrivilege()) + { + nlinfo("ADMIN: Player %s doesn't have privilege to execute /c command '%s' ", eid.toString().c_str(), cmdName.c_str()); + chatToPlayer (eid, "You don't have privilege to execute this command"); + return; + } + // find the character eid CEntityId charEid = CEntityIdTranslator::getInstance()->getByEntity(characterName); if (charEid == CEntityId::Unknown) @@ -4161,22 +4192,80 @@ ENTITY_VARIABLE (Invulnerable, "Invulnerable mode, invulnerability too all") } //---------------------------------------------------------------------------- -ENTITY_VARIABLE (ShowFactionChannels, "Show faction channels") +NLMISC_COMMAND (ShowFactionChannels, "Show faction channels", " <0|1>") { - ENTITY_GET_CHARACTER + if (args.size() != 3) + return false; + GET_CHARACTER - if (get) +// PVP_CLAN::TPVPClan channelClan = PVP_CLAN::fromString( args[1] ); + + bool display = (args[2]=="1" || strlwr(args[2])=="on" || strlwr(args[2])=="true" ); + + TChanID channel = CPVPManager2::getInstance()->getFactionDynChannel(args[1]); + if (channel == DYN_CHAT_INVALID_CHAN) { - value = c->showFactionChannelsMode()?"1":"0"; + log.displayNL("Invalid Faction name: '%s'", args[1].c_str()); + return false; } + CPVPManager2::getInstance()->addRemoveFactionChannelToUserWithPriviledge(channel, c, display); + nlinfo ("%s %s now in show %s channel mode", eid.toString().c_str(), display?"is":"isn't", channel.toString().c_str()); + + return true; + +} + +//---------------------------------------------------------------------------- +// If channel not exists create it +NLMISC_COMMAND (connectUserChannel, "Connect to user channels", " []") +{ + if ((args.size() < 2) || (args.size() > 3)) + return false; + GET_CHARACTER + + CPVPManager2 *inst = CPVPManager2::getInstance(); + + string pass; + string name = NLMISC::toLower(args[1]); + TChanID channel = CPVPManager2::getInstance()->getUserDynChannel(name); + + if (args.size() < 3) + pass = name; else + pass = args[2]; + + if ( (channel == DYN_CHAT_INVALID_CHAN) && (pass != string("*")) && (pass != string("***")) ) + channel = inst->createUserChannel(name, pass); + + if (channel != DYN_CHAT_INVALID_CHAN) { - if (value=="1" || value=="on" || strlwr(value)=="true" ) - c->setShowFactionChannelsMode(true); - else if (value=="0" || value=="off" || strlwr(value)=="false" ) - c->setShowFactionChannelsMode(false); - nlinfo ("%s %s now in show faction channel mode", entity.toString().c_str(), c->showFactionChannelsMode()?"is":"isn't"); + string channelPass = inst->getPassUserChannel(channel); + + if ( (channel != DYN_CHAT_INVALID_CHAN) && (pass == string("***")) && (c->havePriv(":DEV:") || c->havePriv(":SGM:") || c->havePriv(":GM:") || c->havePriv(":EM:"))) + { + inst->deleteUserChannel(name); + } + else if (channelPass == pass) + { + std::vector userChannels = inst->getCharacterUserChannels(c); + if (userChannels.size() >= NB_MAX_USER_CHANNELS) + { + inst->removeFactionChannelForCharacter(userChannels[0], c, true); + } + inst->addFactionChannelToCharacter(channel, c, true, true); + } + else if (pass == string("*")) + { + inst->removeFactionChannelForCharacter(channel, c, true); + } + else + log.displayNL("You don't have rights to connect to channel %s", name.c_str()); + + return true; } + + return false; + } //---------------------------------------------------------------------------- @@ -4194,6 +4283,8 @@ ENTITY_VARIABLE (PriviledgePVP, "Priviledge Pvp Mode") c->setPriviledgePVP(true); else if (value=="0" || value=="off" || strlwr(value)=="false" ) c->setPriviledgePVP(false); +// c->setPVPRecentActionFlag(); + CPVPManager2::getInstance()->setPVPModeInMirror(c); nlinfo ("%s %s now in pvp mode", entity.toString().c_str(), c->priviledgePVP()?"is":"isn't"); } } @@ -4382,6 +4473,90 @@ NLMISC_COMMAND(listGuildMembers, "display guild members list", " ") +{ + if(args.size() != 2 ) + return false; + + CEntityId eId; + eId.fromString(args[0].c_str()); + + CCharacter * user = PlayerManager.getChar( eId ); + if (!user) + { + log.displayNL("'%s' is not a valid char. Cant process command",eId.toString().c_str()); + return true; + } + if (!user->getEnterFlag()) + { + log.displayNL("'%s' is not entered", eId.toString().c_str()); + return true; + } + if (!TheDataset.isAccessible(user->getEntityRowId())) + { + log.displayNL("'%s' is not valid in mirror", eId.toString().c_str()); + return true; + } + + CCharacter * target = PlayerManager.getCharacterByName(CShardNames::getInstance().makeFullNameFromRelative(user->getHomeMainlandSessionId(), args[1])); + + if(target == 0 || target->getEnterFlag() == false ) + { + CCharacter::sendDynamicSystemMessage( user->getId(), "TEAM_INVITED_CHARACTER_MUST_BE_ONLINE" ); + return true; + } + + + SM_STATIC_PARAMS_1(params, STRING_MANAGER::player); + params[0].setEIdAIAlias( user->getId(), CAIAliasTranslator::getInstance()->getAIAlias(user->getId()) ); + CCharacter::sendDynamicSystemMessage(target->getId(), "ROOM_INVITED_BY", params); + params[0].setEIdAIAlias( target->getId(), CAIAliasTranslator::getInstance()->getAIAlias(target->getId()) ); + CCharacter::sendDynamicSystemMessage(user->getId(), "ROOM_YOU_INVITE", params); + + user->addRoomAccessToPlayer(target->getId()); + + return true; +} + +//---------------------------------------------------------------------------- +NLMISC_COMMAND(roomKick, "kick player from room", " ") +{ + if(args.size() != 2 ) + return false; + + CEntityId eId; + eId.fromString(args[0].c_str()); + + CCharacter * user = PlayerManager.getChar( eId ); + if (!user) + { + log.displayNL("'%s' is not a valid char. Cant process command",eId.toString().c_str()); + return true; + } + if (!user->getEnterFlag()) + { + log.displayNL("'%s' is not entered", eId.toString().c_str()); + return true; + } + if (!TheDataset.isAccessible(user->getEntityRowId())) + { + log.displayNL("'%s' is not valid in mirror", eId.toString().c_str()); + return true; + } + CCharacter * target = PlayerManager.getCharacterByName(CShardNames::getInstance().makeFullNameFromRelative(user->getHomeMainlandSessionId(), args[1])); + + if(target == 0 || target->getEnterFlag() == false ) + { + CCharacter::sendDynamicSystemMessage( user->getId(), "TEAM_KICKED_CHARACTER_MUST_BE_ONLINE" ); + return true; + } + + user->removeRoomAccesToPlayer(target->getId(), false); + + return true; +} + //---------------------------------------------------------------------------- NLMISC_COMMAND(guildInvite, "send a guild invite to a player character", " ") { @@ -5280,7 +5455,7 @@ NLMISC_COMMAND(eventCreateNpcGroup, "create an event npc group", " < { orientation = (sint32)(e->getHeading() * 1000.0); } - else + else if (args[5] != "random") { NLMISC::fromString(args[5], orientation); orientation = (sint32)((double)orientation / 360.0 * (NLMISC::Pi * 2.0) * 1000.0); @@ -5393,6 +5568,36 @@ NLMISC_COMMAND(eventSetNpcGroupAggroRange, "changes the aggro range of a npc gro return true; } +//---------------------------------------------------------------------------- +NLMISC_COMMAND(eventSetNpcGroupEmote, "Set emote animation to a npc group", " ") +{ + if (args.size() < 2) return false; + GET_ENTITY + + CEntityId entityId(args[0]); + + uint32 instanceNumber = e->getInstanceNumber(); + + std::vector args2; + + args2.push_back(args[0]); + args2.push_back(NLMISC::toString("()emote(\"%s\",\"%s\");", entityId.toString().c_str(), args[1].c_str())); + + uint32 nbString = (uint32)args2.size(); + + CMessage msgout("EVENT_NPC_GROUP_SCRIPT"); + uint32 messageVersion = 1; + msgout.serial(messageVersion); + msgout.serial(nbString); + for (uint32 i=0; i [ []]") { @@ -5495,6 +5700,27 @@ NLMISC_COMMAND(eventSetBotSheet, "Change the sheet of a bot", " ") +{ + if (args.size() < 2) return false; + GET_ENTITY + + uint32 instanceNumber = e->getInstanceNumber(); + + uint32 messageVersion = 3; + string botName = args[0]; + string vpx = args[1]; + + CMessage msgout("EVENT_BOT_VPX"); + msgout.serial(messageVersion); + msgout.serial(botName); + msgout.serial(vpx); + CWorldInstances::instance().msgToAIInstance2(instanceNumber, msgout); + + return true; +} +*/ //---------------------------------------------------------------------------- extern sint32 clientEventSetItemCustomText(CCharacter* character, INVENTORIES::TInventory inventory, uint32 slot, ucstring const& text); diff --git a/code/ryzom/server/src/entities_game_service/building_manager/building_manager.cpp b/code/ryzom/server/src/entities_game_service/building_manager/building_manager.cpp index 7525a8c08..24a42b355 100644 --- a/code/ryzom/server/src/entities_game_service/building_manager/building_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/building_manager/building_manager.cpp @@ -753,8 +753,13 @@ void CBuildingManager::triggerTeleport(CCharacter * user, uint16 index) IDestination * dest = entry.Destination; uint16 ownerIdx = entry.OwnerIndex; - // remove the request - _TriggerRequests.erase( it ); + // remove the requests + while ( it != _TriggerRequests.end() ) + { + _TriggerRequests.erase( it ); + it = _TriggerRequests.find( user->getEntityRowId() ); + } + if ( !dest->isUserAllowed(user,ownerIdx) ) { return; diff --git a/code/ryzom/server/src/entities_game_service/building_manager/building_physical.cpp b/code/ryzom/server/src/entities_game_service/building_manager/building_physical.cpp index 289875292..9fb0f13ab 100644 --- a/code/ryzom/server/src/entities_game_service/building_manager/building_physical.cpp +++ b/code/ryzom/server/src/entities_game_service/building_manager/building_physical.cpp @@ -75,7 +75,7 @@ bool IBuildingPhysical::build( const NLLIGO::IPrimitive* prim, CBuildingParseDat } //---------------------------------------------------------------------------- -bool IBuildingPhysical::addUser(CCharacter * user,uint16 roomIdx,uint16 ownerIdx, sint32 & cellId) +bool IBuildingPhysical::addUser(CCharacter * user, uint16 roomIdx, uint16 ownerIdx, sint32 & cellId) { /// simply get the cell matching the parameters if ( roomIdx >= _Rooms.size() ) @@ -88,6 +88,18 @@ bool IBuildingPhysical::addUser(CCharacter * user,uint16 roomIdx,uint16 ownerIdx nlwarning("Invalid owner idx %u count is %u",ownerIdx,_Rooms[roomIdx].Cells.size()); return false; } + + CCharacter *owner; + if (ownerIdx < _Players.size()) + { + owner = PlayerManager.getChar(_Players[ownerIdx] ); + } + else + { + owner = user; + } + + // if the room is not already instanciated, we have to do it if ( _Rooms[roomIdx].Cells[ownerIdx] == 0 ) { @@ -101,7 +113,7 @@ bool IBuildingPhysical::addUser(CCharacter * user,uint16 roomIdx,uint16 ownerIdx // init the room if( !roomInstance->create(this,roomIdx,ownerIdx, _Rooms[roomIdx].Cells[ownerIdx]) ) return false; - roomInstance->addUser(user); + roomInstance->addUser(user, owner); } else { @@ -111,7 +123,7 @@ bool IBuildingPhysical::addUser(CCharacter * user,uint16 roomIdx,uint16 ownerIdx nlwarning("%s invalid room cell %d.",user->getId().toString().c_str(),_Rooms[roomIdx].Cells[ownerIdx]); return false; } - roomInstance->addUser(user); + roomInstance->addUser(user, owner); } user->setBuildingExitZone( _DefaultExitSpawn ); @@ -517,7 +529,12 @@ bool CBuildingPhysicalPlayer::isUserAllowed(CCharacter * user, uint16 ownerId, u { nlassert(user); nlassert(ownerId < _Players.size() ); - return ( user->getId() == _Players[ownerId] ); + + CCharacter * owner = PlayerManager.getChar( _Players[ownerId] ); + if (owner) + return ( (user->getId() == _Players[ownerId]) || owner->playerHaveRoomAccess(user->getId()) ); + else + return false; } //---------------------------------------------------------------------------- diff --git a/code/ryzom/server/src/entities_game_service/building_manager/building_physical.h b/code/ryzom/server/src/entities_game_service/building_manager/building_physical.h index 134db9b07..d37966aeb 100644 --- a/code/ryzom/server/src/entities_game_service/building_manager/building_physical.h +++ b/code/ryzom/server/src/entities_game_service/building_manager/building_physical.h @@ -110,6 +110,9 @@ protected: /// the players in the building std::vector _UsersInside; + + // list of players + std::vector _Players; }; @@ -191,7 +194,7 @@ public: private: virtual void initRooms(); - std::vector _Players; + }; #include "building_physical_inline.h" diff --git a/code/ryzom/server/src/entities_game_service/building_manager/room_instance.cpp b/code/ryzom/server/src/entities_game_service/building_manager/room_instance.cpp index 8b5ad1a86..44ebac226 100644 --- a/code/ryzom/server/src/entities_game_service/building_manager/room_instance.cpp +++ b/code/ryzom/server/src/entities_game_service/building_manager/room_instance.cpp @@ -59,7 +59,7 @@ void CRoomInstanceCommon::removeUser( CCharacter* user ) } //---------------------------------------------------------------------------- -void CRoomInstanceCommon::addUser( CCharacter* user ) +void CRoomInstanceCommon::addUser( CCharacter* user, CCharacter* owner ) { BOMB_IF( !user, " null character!", return ); @@ -100,7 +100,7 @@ void CRoomInstanceGuild::removeUser( CCharacter* user ) } //---------------------------------------------------------------------------- -void CRoomInstanceGuild::addUser( CCharacter* user ) +void CRoomInstanceGuild::addUser( CCharacter* user, CCharacter* owner ) { BOMB_IF( !user, " null character!", return ); @@ -141,21 +141,64 @@ void CRoomInstancePlayer::removeUser( CCharacter* user ) return; } + TVectorParamCheck titleParams; + TVectorParamCheck textParams; + uint32 userId = PlayerManager.getPlayerId( user->getId() ); + std::string name = "CLOSE_URL"; + //send command to close webig + ucstring phrase = ucstring("CLOSE_URL(){[WEB : app_ryzhome action=quit_room]}"); + NLNET::CMessage msgout("SET_PHRASE"); + msgout.serial(name); + msgout.serial(phrase); + sendMessageViaMirror("IOS", msgout); + + uint32 titleId = STRING_MANAGER::sendStringToUser(userId, "ANSWER_OK", titleParams); + uint32 textId = STRING_MANAGER::sendStringToUser(userId, "CLOSE_URL", textParams); + PlayerManager.sendImpulseToClient(user->getId(), "USER:POPUP", titleId, textId); + --_RefCount; if ( _RefCount == 0 ) { - playerBuilding->resetRoomCell( _RoomIdx , user->getId() ); + playerBuilding->resetRoomCell( _RoomIdx , user->getInRoomOfPlayer()); release(); } + user->setInRoomOfPlayer(CEntityId::Unknown); } //---------------------------------------------------------------------------- -void CRoomInstancePlayer::addUser( CCharacter* user ) +void CRoomInstancePlayer::addUser( CCharacter* user, CCharacter* owner ) { BOMB_IF( !user, " null character!", return ); // open room inventory window PlayerManager.sendImpulseToClient(user->getId(), "ITEM:OPEN_ROOM_INVENTORY"); + if (owner) + { + owner->removeRoomAccesToPlayer(user->getId(),false); + user->setInRoomOfPlayer(owner->getId()); + } + else + { + // Very rare case + owner = user; + } + // solve bot names for title and text + TVectorParamCheck titleParams; + TVectorParamCheck textParams; + // send the popup message + uint32 userId = PlayerManager.getPlayerId( user->getId() ); + + std::string name = "RYZHOME_URL"; + ucstring phrase = "RYZHOME_URL(){[WEB : app_ryzhome user=" + owner->getName().toString() + "]}"; + NLNET::CMessage msgout("SET_PHRASE"); + msgout.serial(name); + msgout.serial(phrase); + sendMessageViaMirror("IOS", msgout); + + uint32 titleId = STRING_MANAGER::sendStringToUser(userId, "ANSWER_OK", titleParams); + uint32 textId = STRING_MANAGER::sendStringToUser(userId, "RYZHOME_URL", textParams); + PlayerManager.sendImpulseToClient(user->getId(), "USER:POPUP", titleId, textId); + ++_RefCount; } diff --git a/code/ryzom/server/src/entities_game_service/building_manager/room_instance.h b/code/ryzom/server/src/entities_game_service/building_manager/room_instance.h index 2a99d0b0e..055f88db6 100644 --- a/code/ryzom/server/src/entities_game_service/building_manager/room_instance.h +++ b/code/ryzom/server/src/entities_game_service/building_manager/room_instance.h @@ -37,7 +37,7 @@ public: /// remove a user from the room virtual void removeUser( CCharacter* user ) = 0; /// add a user in the room - virtual void addUser( CCharacter* user ) = 0; + virtual void addUser( CCharacter* user, CCharacter* owner ) = 0; /// create the room from a building virtual bool create( IBuildingPhysical * building, uint16 roomIdx, uint16 ownerIdx , sint32 cell); /// return true if the room is valid @@ -79,7 +79,7 @@ public: private: virtual void removeUser( CCharacter* user ); - virtual void addUser( CCharacter* user ); + virtual void addUser( CCharacter* user, CCharacter* owner ); }; /// a guild room @@ -99,7 +99,7 @@ public: private: virtual bool create( IBuildingPhysical * building, uint16 roomIdx, uint16 ownerIdx , sint32 cell); virtual void removeUser( CCharacter* user ); - virtual void addUser( CCharacter* user ); + virtual void addUser( CCharacter* user, CCharacter* owner ); EGSPD::TGuildId _GuildId; }; @@ -117,7 +117,7 @@ public: private: virtual bool create( IBuildingPhysical * building, uint16 roomIdx, uint16 ownerIdx , sint32 cell); virtual void removeUser( CCharacter* user ); - virtual void addUser( CCharacter* user ); + virtual void addUser( CCharacter* user, CCharacter* owner ); /// owner player NLMISC::CEntityId _Player; }; diff --git a/code/ryzom/server/src/entities_game_service/database_plr.cpp b/code/ryzom/server/src/entities_game_service/database_plr.cpp index d7de2d4fa..42876cf60 100644 --- a/code/ryzom/server/src/entities_game_service/database_plr.cpp +++ b/code/ryzom/server/src/entities_game_service/database_plr.cpp @@ -359,6 +359,10 @@ void CBankAccessor_PLR::TUSER::init(ICDBStructNode *parent) nlassert(node != NULL); _DEFAULT_WEIGHT_HANDS = node; + node = parent->getNode( ICDBStructNode::CTextId("IS_INVISIBLE"), false ); + nlassert(node != NULL); + _IS_INVISIBLE = node; + node = parent->getNode( ICDBStructNode::CTextId("COUNTER"), false ); nlassert(node != NULL); _COUNTER = node; diff --git a/code/ryzom/server/src/entities_game_service/database_plr.h b/code/ryzom/server/src/entities_game_service/database_plr.h index 5cab2bea7..4df8c37a4 100644 --- a/code/ryzom/server/src/entities_game_service/database_plr.h +++ b/code/ryzom/server/src/entities_game_service/database_plr.h @@ -490,6 +490,7 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C ICDBStructNode *_IS_NEWBIE; ICDBStructNode *_IS_TRIAL; ICDBStructNode *_DEFAULT_WEIGHT_HANDS; + ICDBStructNode *_IS_INVISIBLE; ICDBStructNode *_COUNTER; TSKILL_POINTS_ _SKILL_POINTS_[4]; TFACTION_POINTS_ _FACTION_POINTS_[6]; @@ -975,6 +976,20 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C { return _COUNTER; } + + void setIS_INVISIBLE(CCDBSynchronised &dbGroup, bool value, bool forceSending = false) + { + _setProp(dbGroup, _IS_INVISIBLE, value, forceSending); + } + + bool getIS_INVISIBLE(const CCDBSynchronised &dbGroup) + { + bool value; + _getProp(dbGroup, _IS_INVISIBLE, value); + + return value; + } + TSKILL_POINTS_ &getSKILL_POINTS_(uint32 index) { nlassert(index < 4); diff --git a/code/ryzom/server/src/entities_game_service/dyn_chat_egs.cpp b/code/ryzom/server/src/entities_game_service/dyn_chat_egs.cpp index 4b123083e..884c5da98 100644 --- a/code/ryzom/server/src/entities_game_service/dyn_chat_egs.cpp +++ b/code/ryzom/server/src/entities_game_service/dyn_chat_egs.cpp @@ -197,8 +197,7 @@ bool CDynChatEGS::addSession(TChanID chan, const TDataSetRow &client, bool write CEntityBase *eb = CEntityBaseManager::getEntityBasePtr(client); if (!eb) { - nlwarning("no client %s",client.toString().c_str()); - addClient(client); + return false; } CDynChatSession *session = _DynChat.addSession(chan, client); if (!session) diff --git a/code/ryzom/server/src/entities_game_service/egs_variables.cpp b/code/ryzom/server/src/entities_game_service/egs_variables.cpp index 91157ad99..454ba6665 100644 --- a/code/ryzom/server/src/entities_game_service/egs_variables.cpp +++ b/code/ryzom/server/src/entities_game_service/egs_variables.cpp @@ -389,6 +389,7 @@ CVariable ForageExplosionDamage( "egs","ForageExplosionDamage", "Max HP h CVariable FameByKill( "egs","FameByKill", "Number of fame point lost for a kill", -5000, true ); +CVariable PVPFameRequired ("egs","PVPFameRequired", "Minimum of positive or negative fame for PVP", 25, 0, true ); NLMISC::CVariableDuelQueryDuration ("egs","DuelQueryDuration", "duration in ticks of a duel requests", 600, 0, true ); NLMISC::CVariable PVPZoneEnterBufferTime ("egs","PVPZoneEnterBufferTime", "duration in ticks of the time buffer triggered when someone enters a PVP zone", 300, 0, true ); NLMISC::CVariable PVPZoneLeaveBufferTime ("egs","PVPZoneLeaveBufferTime", "duration in ticks of the time buffer triggered when someone leaves a PVP zone", 9000, 0, true ); diff --git a/code/ryzom/server/src/entities_game_service/egs_variables.h b/code/ryzom/server/src/entities_game_service/egs_variables.h index 875769d45..bfda8d1bb 100644 --- a/code/ryzom/server/src/entities_game_service/egs_variables.h +++ b/code/ryzom/server/src/entities_game_service/egs_variables.h @@ -318,6 +318,7 @@ extern NLMISC::CVariable CristalMoneyFactor; /// PVP extern NLMISC::CVariable AllowPVP; +extern NLMISC::CVariable PVPFameRequired; extern NLMISC::CVariable DuelQueryDuration ; extern NLMISC::CVariable PVPZoneEnterBufferTime; extern NLMISC::CVariable PVPZoneLeaveBufferTime; diff --git a/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp b/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp index 61a44b134..4be66250c 100644 --- a/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp +++ b/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp @@ -529,10 +529,6 @@ void cbClientReady( CMessage& msgin, const std::string &serviceName, NLNET::TSer } } c->onConnection(); - - CPVPManager2::getInstance()->sendFactionWarsToClient( c ); - CPVPManager2::getInstance()->addOrRemoveFactionChannel( c ); - } // cbClientReady // @@ -681,10 +677,15 @@ void finalizeClientReady( uint32 userId, uint32 index ) } } + CPVPManager2::getInstance()->updateFactionChannel( c ); + CPVPManager2::getInstance()->setPVPModeInMirror( c ); + c->updatePVPClanVP(); // for GM player, trigger a 'infos' command to remember their persistent state if (!PlayerManager.getPlayer(uint32(c->getId().getShortId())>>4)->getUserPriv().empty()) CCommandRegistry::getInstance().execute(toString("infos %s", c->getId().toString().c_str()).c_str(), InfoLog(), true); + + c->setFinalized(true); } // finalizeClientReady // diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.cpp b/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.cpp index 06cfc5571..fab2ffd2a 100644 --- a/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.cpp +++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.cpp @@ -336,7 +336,7 @@ void CGuildMemberModule::_inviteCharacterInGuild(CGuildCharProxy& invitor, CGuil { SM_STATIC_PARAMS_2( params, STRING_MANAGER::player, STRING_MANAGER::faction ); params[0].setEIdAIAlias( target.getId(), CAIAliasTranslator::getInstance()->getAIAlias( target.getId()) ); - params[1].Enum = invitedAllegiance.first; + params[1].Enum = PVP_CLAN::getFactionIndex(invitedAllegiance.first); invitor.sendSystemMessage("GUILD_ICOMPATIBLE_ALLEGIANCE",params); return; } @@ -344,7 +344,7 @@ void CGuildMemberModule::_inviteCharacterInGuild(CGuildCharProxy& invitor, CGuil { SM_STATIC_PARAMS_2( params, STRING_MANAGER::player, STRING_MANAGER::faction ); params[0].setEIdAIAlias( target.getId(), CAIAliasTranslator::getInstance()->getAIAlias( target.getId()) ); - params[1].Enum = invitedAllegiance.second; + params[1].Enum = PVP_CLAN::getFactionIndex(invitedAllegiance.second); invitor.sendSystemMessage("GUILD_ICOMPATIBLE_ALLEGIANCE",params); return; } diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_ai.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_ai.cpp index 7075c6678..fdbadd619 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_ai.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_ai.cpp @@ -174,7 +174,7 @@ bool CMissionStepAIMsg::buildStep( uint32 line, const std::vector< std::string > MISLOGSYNTAXERROR(""); return false; } - Msg = CMissionParser::getNoBlankString(script[1]); + _Msg = CMissionParser::getNoBlankString(script[1]); return true; } @@ -185,8 +185,8 @@ uint CMissionStepAIMsg::processEvent( const TDataSetRow & userRow, const CMissio if( event.Type == CMissionEvent::AIMsg ) { CMissionEventAIMsg & eventSpe = (CMissionEventAIMsg &) event; - nlwarning("CMissionStepAIMsg : Message from event = '%s', message of mission = '%s'", eventSpe.Msg.c_str(), Msg.c_str()); - if ( eventSpe.Msg == Msg ) + nlwarning("CMissionStepAIMsg : Message from event = '%s', message of mission = '%s'", eventSpe.Msg.c_str(), _Msg.c_str()); + if ( eventSpe.Msg == _Msg ) { LOGMISSIONSTEPSUCCESS("wait_msg"); return 1; diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_ai.h b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_ai.h index 6e7565aa6..106718f85 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_ai.h +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_ai.h @@ -56,7 +56,7 @@ class CMissionStepEscort : public IMissionStepTemplate class CMissionStepAIMsg : public IMissionStepTemplate { - std::string Msg; + std::string _Msg; virtual bool buildStep( uint32 line, const std::vector< std::string > & script, CMissionGlobalParsingData & globalData, CMissionSpecificParsingData & missionData ); diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_team.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_team.cpp index e23eb74ab..ef4ea2ff2 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_team.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_team.cpp @@ -52,7 +52,11 @@ void CMissionTeam::updateUsersJournalEntry() void CMissionTeam::clearUsersJournalEntry() { CTeam * team = TeamManager.getRealTeam( _TeamId ); - nlassert(team); + if ( !team ) + { + nlwarning( "cant find team ID : %d", _TeamId ); + return; + } for ( list::const_iterator it = team->getTeamMembers().begin(); it != team->getTeamMembers().end();++it ) { diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp index 1f93c30ba..10eebf0d4 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp @@ -1555,15 +1555,18 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos logOnFail = false; } } - - uint k = 0; - for ( ; k < team->getMissions().size(); k++ ) + else { - if ( team->getMissions()[k]->getTemplateId() == templ->Alias ) + + uint k = 0; + for ( ; k < team->getMissions().size(); k++ ) + { + if ( team->getMissions()[k]->getTemplateId() == templ->Alias ) + break; + } + if (k != team->getMissions().size()) break; } - if (k != team->getMissions().size()) - break; } } if ( j == Prerequisits.RunningMissions[i].Missions.size() ) diff --git a/code/ryzom/server/src/entities_game_service/phrase_manager/faber_phrase.cpp b/code/ryzom/server/src/entities_game_service/phrase_manager/faber_phrase.cpp index 2386a32b2..98f1a39ba 100644 --- a/code/ryzom/server/src/entities_game_service/phrase_manager/faber_phrase.cpp +++ b/code/ryzom/server/src/entities_game_service/phrase_manager/faber_phrase.cpp @@ -395,7 +395,7 @@ void CFaberPhrase::apply() uint32 nbMpNeedeInPlan = 0; uint32 neededMp = (uint32)_RootFaberPlan->Faber->NeededMps.size(); - for( uint mp = 0; mp < _RootFaberPlan->Faber->NeededMps.size(); ++mp ) + for( uint mp = 0; mp < neededMp; ++mp ) { //for each type of Mp needed nbMpNeedeInPlan += _RootFaberPlan->Faber->NeededMps[ mp ].Quantity; @@ -411,15 +411,15 @@ void CFaberPhrase::apply() nbMp = (sint32)_MpsFormula.size(); - nbMpNeedeInPlan = 0; + uint32 nbMpForumulaNeedeInPlan = 0; neededMp = (uint32)_RootFaberPlan->Faber->NeededMpsFormula.size(); - for( uint mp = 0; mp < _RootFaberPlan->Faber->NeededMpsFormula.size(); ++mp ) + for( uint mp = 0; mp < neededMp; ++mp ) { //for each type of Mp needed - nbMpNeedeInPlan += _RootFaberPlan->Faber->NeededMpsFormula[ mp ].Quantity; + nbMpForumulaNeedeInPlan += _RootFaberPlan->Faber->NeededMpsFormula[ mp ].Quantity; } - if( nbMpNeedeInPlan != _MpsFormula.size() ) + if( nbMpForumulaNeedeInPlan != _MpsFormula.size() ) { nlwarning(" Craft plan %s need %d Raw Material Formula and client send %d Raw Material Formula", c->getCraftPlan().toString().c_str(), _RootFaberPlan->Faber->NeededMpsFormula.size(), _MpsFormula.size() ); PHRASE_UTILITIES::sendDynamicSystemMessage(_ActorRowId, "RAW_MATERIAL_MISSING"); @@ -454,6 +454,105 @@ void CFaberPhrase::apply() return; } + neededMp = _RootFaberPlan->Faber->NeededMps.size(); + EGSPD::CPeople::TPeople civRestriction = _RootFaberPlan->CivRestriction; + uint32 usedMp=0; + vector< const CStaticItem * > usedMps = _Mps; + + for( uint mp = 0; mp < neededMp; ++mp ) + { + nlinfo("MP #%d\n", mp); + //for each type of Mp needed + for( uint k = 0; k < _RootFaberPlan->Faber->NeededMps[ mp ].Quantity; ++k ) + { + nlinfo(" usedmps : %d", usedMps.size()); + bool found_mp = false; + for(uint u_mp = 0; u_mp < usedMps.size(); ++u_mp) + { + // for each Mp of one type (we have Quantity by type) + uint32 NumMpParameters = (uint32)usedMps[u_mp]->Mp->MpFaberParameters.size(); + + // for each Faber parameters in Mp + for( uint j = 0; j < NumMpParameters; ++j ) + { + // check if Mp Type match with Faber waiting Type + if( _RootFaberPlan->Faber->NeededMps[mp].MpType == usedMps[u_mp]->Mp->MpFaberParameters[j].MpFaberType ) + { + found_mp = true; + usedMp++; + break; + } + } + + if (found_mp) + { + + // Bypass if : Plan is common + if ( civRestriction != EGSPD::CPeople::Common ) + { + switch (usedMps[u_mp]->Mp->Ecosystem) + { + // I can't found some thing to do this ugly translation. + case ECOSYSTEM::desert: + if (civRestriction != EGSPD::CPeople::Fyros) + { + nlwarning( " bad civilisation mp for plan brick %s", _RootFaberPlan->SheetId.toString().c_str() ); + stop(); + return; + } + break; + case ECOSYSTEM::forest: + if (civRestriction != EGSPD::CPeople::Matis) + { + nlwarning( " bad civilisation mp for plan brick %s", _RootFaberPlan->SheetId.toString().c_str() ); + stop(); + return; + } + break; + case ECOSYSTEM::lacustre: + if (civRestriction != EGSPD::CPeople::Tryker) + { + nlwarning( " bad civilisation mp for plan brick %s", _RootFaberPlan->SheetId.toString().c_str() ); + stop(); + return; + } + break; + case ECOSYSTEM::jungle: + if (civRestriction != EGSPD::CPeople::Zorai) + { + nlwarning( " bad civilisation mp for plan brick %s", _RootFaberPlan->SheetId.toString().c_str() ); + stop(); + return; + } + break; + } + } + usedMps.erase(usedMps.begin()+u_mp); + break; + } + } + + if (!found_mp) + { + nlinfo("NOT FOUND : wanted %d\n", _RootFaberPlan->Faber->NeededMps[ mp ].MpType); + } + } + } + if (!usedMps.empty()) + { + nlinfo("final usedmps : %d", usedMps.size()); + nlwarning( " could not build action for plan brick %s", _RootFaberPlan->SheetId.toString().c_str() ); + stop(); + return; + } + + if (usedMp != nbMpNeedeInPlan) + { + nlwarning( " could not build action for plan brick %s", _RootFaberPlan->SheetId.toString().c_str() ); + stop(); + return; + } + // spend energies SCharacteristicsAndScores &focus = c->getScores()._PhysicalScores[SCORES::focus]; if ( focus.Current != 0) diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character.cpp b/code/ryzom/server/src/entities_game_service/player_manager/character.cpp index 24cbf2173..96802b11d 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character.cpp +++ b/code/ryzom/server/src/entities_game_service/player_manager/character.cpp @@ -364,6 +364,13 @@ CCharacter::CCharacter(): CEntityBase(false), _NbStaticActiveEffects = 0; _StaticActionInProgress = false; + _NbUserChannels = 0; + + _LoadingFinish = false; + + _PVPFlagAlly = 0; + _PVPFlagEnemy = 0; + // init faber plans // _KnownFaberPlans.resize(64,(uint64)0); //64*64 bits @@ -630,12 +637,13 @@ CCharacter::CCharacter(): CEntityBase(false), _HaveToUpdatePVPMode = false; _SessionId = TSessionId(0); _CurrentSessionId = _SessionId; - _FactionChannelMode = true; _PvPSafeZoneActive = false; // For client/server contact list communication _ContactIdPool= 0; + _inRoomOfPlayer = CEntityId::Unknown; + for(uint i = 0; i < BRICK_FAMILIES::NbFamilies; ++i ) _BrickFamilyBitField[i] = 0; _InterfacesFlagsBitField = 0; @@ -762,17 +770,77 @@ void CCharacter::initPDStructs() //----------------------------------------------- void CCharacter::updatePVPClanVP() const { + TYPE_PVP_CLAN propPvpClanTemp = 0; + uint32 maxFameCiv = 0; + uint8 civOfMaxFame = 255; + uint32 maxFameCult = 0; + uint8 cultOfMaxFame = 255; + + for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++) + { + sint32 fame = CFameInterface::getInstance().getFameIndexed(_Id, fameIdx); + if (fameIdx < 4) + { + if ((uint32)abs(fame) >= maxFameCiv) + { + civOfMaxFame = fameIdx; + maxFameCiv = abs(fame); + } + } + else + { + if ((uint32)abs(fame) >= maxFameCult) + { + cultOfMaxFame = fameIdx - 4; + maxFameCult = abs(fame); + } + } + + if (fame >= PVPFameRequired*6000) + { + propPvpClanTemp |= (TYPE_PVP_CLAN(1) << (2*TYPE_PVP_CLAN(fameIdx))); + } + else if (fame <= -PVPFameRequired*6000) + { + propPvpClanTemp |= (TYPE_PVP_CLAN(1) << ((2*TYPE_PVP_CLAN(fameIdx))+1)); + } + if (getPvPRecentActionFlag()) + { + uint8 flagAlly = (_PVPFlagAlly & (1 << TYPE_PVP_CLAN(fameIdx))) >> TYPE_PVP_CLAN(fameIdx); + uint8 flagEnemy = (_PVPFlagEnemy & (1 << TYPE_PVP_CLAN(fameIdx))) >> TYPE_PVP_CLAN(fameIdx); + propPvpClanTemp |= flagAlly << (2*TYPE_PVP_CLAN(fameIdx)); + propPvpClanTemp |= flagEnemy << ((2*TYPE_PVP_CLAN(fameIdx))+1); + } + + } + propPvpClanTemp |= TYPE_PVP_CLAN(civOfMaxFame) << (2*TYPE_PVP_CLAN(7)); + propPvpClanTemp |= TYPE_PVP_CLAN(cultOfMaxFame) << (2*TYPE_PVP_CLAN(8)); CMirrorPropValue propPvpClan( TheDataset, TheDataset.getDataSetRow(_Id), DSPropertyPVP_CLAN ); - if( getAllegiance().first >= PVP_CLAN::BeginCults && getAllegiance().first <= PVP_CLAN::EndCults ) - { - propPvpClan = (uint8) getAllegiance().first; - } - else - { - propPvpClan = (uint8) getAllegiance().second; - } + + propPvpClan = (uint32)propPvpClanTemp; } +TYPE_PVP_CLAN CCharacter::getPVPFamesAllies() +{ + TYPE_PVP_CLAN propPvpClanTemp = 0; + for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++) + if (CFameInterface::getInstance().getFameIndexed(_Id, fameIdx) >= PVPFameRequired*6000) + propPvpClanTemp |= TYPE_PVP_CLAN(1) << TYPE_PVP_CLAN(fameIdx); + if (getPvPRecentActionFlag()) + return propPvpClanTemp | _PVPFlagAlly; + return propPvpClanTemp; +} + +TYPE_PVP_CLAN CCharacter::getPVPFamesEnemies() +{ + TYPE_PVP_CLAN propPvpClanTemp = 0; + for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++) + if (CFameInterface::getInstance().getFameIndexed(_Id, fameIdx) <= -PVPFameRequired*6000) + propPvpClanTemp |= TYPE_PVP_CLAN(1) << TYPE_PVP_CLAN(fameIdx); + if (getPvPRecentActionFlag()) + return propPvpClanTemp | _PVPFlagEnemy; + return propPvpClanTemp; +} //----------------------------------------------- @@ -1382,7 +1450,8 @@ uint32 CCharacter::tickUpdate() if (_PVPFlagLastTimeChange + waitTime < CTickEventHandler::getGameCycle()) { CPVPManager2::getInstance()->setPVPModeInMirror(this); - CPVPManager2::getInstance()->addOrRemoveFactionChannel(this); + CPVPManager2::getInstance()->updateFactionChannel(this); + updatePVPClanVP(); _HaveToUpdatePVPMode = false; } } @@ -1393,6 +1462,7 @@ uint32 CCharacter::tickUpdate() if( propPvpMode.getValue()&PVP_MODE::PvpFactionFlagged ) { CPVPManager2::getInstance()->setPVPModeInMirror(this); + updatePVPClanVP(); } } } @@ -2829,117 +2899,88 @@ void CCharacter::postLoadTreatment() // if EId translator has been initialized by SU, check contact list { - H_AUTO(ValidateContactList); - validateContactList(); + H_AUTO(ValidateContactList); + validateContactList(); } { - H_AUTO(UpdateFlagForActiveEffect); - /* update flags for active effects */ - if( _ForbidAuraUseEndDate>0 && _ForbidAuraUseStartDate==0 ) - { - // thus timer won't look like infinte on client(can happen due to old save file where startDate didn't exist) - _ForbidAuraUseStartDate = CTickEventHandler::getGameCycle(); - } - setPowerFlagDates(); - setAuraFlagDates(); - updateBrickFlagsDBEntry(); - _ModifiersInDB.writeInDatabase(_PropertyDatabase); + H_AUTO(UpdateFlagForActiveEffect); + /* update flags for active effects */ + if( _ForbidAuraUseEndDate>0 && _ForbidAuraUseStartDate==0 ) + { + // thus timer won't look like infinte on client(can happen due to old save file where startDate didn't exist) + _ForbidAuraUseStartDate = CTickEventHandler::getGameCycle(); + } + setPowerFlagDates(); + setAuraFlagDates(); + updateBrickFlagsDBEntry(); + _ModifiersInDB.writeInDatabase(_PropertyDatabase); } { - H_AUTO(AddCreationBricks); - /* add starting bricks if any modification has been done */ - addCreationBricks(); + H_AUTO(AddCreationBricks); + /* add starting bricks if any modification has been done */ + addCreationBricks(); } { - H_AUTO(CheckCharacterAndScoresValues); - /* check character and scores are as they are supposed to be according to bricks possessed */ - checkCharacAndScoresValues(); + H_AUTO(CheckCharacterAndScoresValues); + /* check character and scores are as they are supposed to be according to bricks possessed */ + checkCharacAndScoresValues(); } { - H_AUTO(ComputeBestSkill); - /* compute player best skill */ - computeBestSkill(); + H_AUTO(ComputeBestSkill); + /* compute player best skill */ + computeBestSkill(); } { - H_AUTO(ComputeSkillUsedForDodge); - /* compute player best skill to use for dodge */ - computeSkillUsedForDodge(); + H_AUTO(ComputeSkillUsedForDodge); + /* compute player best skill to use for dodge */ + computeSkillUsedForDodge(); } { - H_AUTO(UpdateMagicProtectionAndResistance); - /* compute resists scores*/ - updateMagicProtectionAndResistance(); + H_AUTO(UpdateMagicProtectionAndResistance); + /* compute resists scores*/ + updateMagicProtectionAndResistance(); } { - H_AUTO(LoadedMissionPostLoad); - /* Call the postLoad methods for the loaded missions */ - for ( map::iterator it = getMissionsBegin(); it != getMissionsEnd(); ++it ) - { - BOMB_IF( (*it).second == NULL, "Mission is NULL after load", continue ); - (*it).second->onLoad(); - } + H_AUTO(LoadedMissionPostLoad); + /* Call the postLoad methods for the loaded missions */ + for ( map::iterator it = getMissionsBegin(); it != getMissionsEnd(); ++it ) + { + BOMB_IF( (*it).second == NULL, "Mission is NULL after load", continue ); + (*it).second->onLoad(); + } } /* setup the implicit visual property fields */ SET_STRUCT_MEMBER(_VisualPropertyA,PropertySubData.Sex,getGender()); { - H_AUTO(ComputeForageBonus); - /* compute the forage bonuses */ - computeForageBonus(); + H_AUTO(ComputeForageBonus); + /* compute the forage bonuses */ + computeForageBonus(); } { - H_AUTO(ComputeMiscBonus); - /* compute misc bonuses */ - computeMiscBonus(); + H_AUTO(ComputeMiscBonus); + /* compute misc bonuses */ + computeMiscBonus(); } { - H_AUTO(CItemServiceManager); - CItemServiceManager::getInstance()->initPersistentServices(this); + H_AUTO(CItemServiceManager); + CItemServiceManager::getInstance()->initPersistentServices(this); } { - H_AUTO(CheckPvPTagValidity); - if( _DeclaredCult == PVP_CLAN::Neutral || _DeclaredCult == PVP_CLAN::None ) - { - if( _PVPFlag ) - { - // if no cult declared and civ is not in war we remove pvp tag - if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCiv ) == false ) - { - _PVPFlag = false; - _PVPFlagLastTimeChange = 0; - _PVPFlagTimeSettedOn = 0; - setPVPFlagDatabase(); - _HaveToUpdatePVPMode = true; - } - } - } + H_AUTO(CheckPvPTagValidity); - if( _DeclaredCiv == PVP_CLAN::Neutral || _DeclaredCiv == PVP_CLAN::None ) - { - if( _PVPFlag ) - { - // if no civ declared and cult is not in war we remove pvp tag - if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCult ) == false ) - { - _PVPFlag = false; - _PVPFlagLastTimeChange = 0; - _PVPFlagTimeSettedOn = 0; - setPVPFlagDatabase(); - _HaveToUpdatePVPMode = true; - } - } - } + _HaveToUpdatePVPMode = true; } } @@ -13666,6 +13707,36 @@ void CCharacter::setFameValuePlayer(uint32 factionIndex, sint32 playerFame, sint // _PropertyDatabase.setProp( toString("FAME:PLAYER%d:THRESHOLD", fameIndexInDatabase), sint64(float(fameMax)/FameAbsoluteMax*100) ); CBankAccessor_PLR::getFAME().getPLAYER(fameIndexInDatabase).setTHRESHOLD(_PropertyDatabase, checkedCast(float(fameMax)/FameAbsoluteMax*100) ); } + + bool canPvp = false; + for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++) + { + sint32 fame = CFameInterface::getInstance().getFameIndexed(_Id, fameIdx); + + if (fame >= PVPFameRequired*6000) { + canPvp = true; + } else if (fame <= -PVPFameRequired*6000) { + canPvp = true; + } + } + + if (_LoadingFinish) + { + if(!canPvp && (_PVPFlag || getPvPRecentActionFlag()) ) + { + _PVPFlag = false; + _PVPFlagLastTimeChange = 0; + _PVPFlagTimeSettedOn = 0; + _PVPRecentActionTime = 0; + _HaveToUpdatePVPMode = true; + } + updatePVPClanVP(); + setPVPFlagDatabase(); + + // handle with faction channel + CPVPManager2::getInstance()->updateFactionChannel(this); + } + } //----------------------------------------------- @@ -14288,6 +14359,63 @@ void CCharacter::syncContactListWithCharNameChanges(const std::vectorisCharacterOnlineAbroad(id))) + { + // player not found => message + PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, "OPERATION_OFFLINE"); + return; + } + } + + // check not already in list + const uint size = (uint)_RoomersList.size(); + for ( uint i =0 ; i < size ; ++i) + { + if ( _RoomersList[i].getShortId() == id.getShortId()) + { + return; + } + } + + uint32 playerId = PlayerManager.getPlayerId(id); + _RoomersList.push_back(id); +} + //-------------------------------------------------------------- // CCharacter::addPlayerToFriendList() //-------------------------------------------------------------- @@ -14296,9 +14424,12 @@ void CCharacter::addPlayerToFriendList(const NLMISC::CEntityId &id) // if player not found if (id == CEntityId::Unknown || PlayerManager.getChar(id)==NULL) { - // player not found => message - PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, "OPERATION_OFFLINE"); - return; + if ( ! (IShardUnifierEvent::getInstance() && IShardUnifierEvent::getInstance()->isCharacterOnlineAbroad(id))) + { + // player not found => message + PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, "OPERATION_OFFLINE"); + return; + } } // check not already in list @@ -14487,6 +14618,42 @@ void CCharacter::removePlayerFromIgnoreListByIndex(uint16 index) sendMessageViaMirror ("IOS", msgName); } +//-------------------------------------------------------------- +// CCharacter::removeRoomAccesToPlayer() +//-------------------------------------------------------------- +void CCharacter::removeRoomAccesToPlayer(const NLMISC::CEntityId &id, bool kick) +{ + if (id == NLMISC::CEntityId::Unknown) + return; + + CCharacter *target = PlayerManager.getChar(id); + + for ( uint i = 0 ; i < _RoomersList.size() ; ++i) + { + if ( _RoomersList[i].getShortId() == id.getShortId() ) + { + _RoomersList.erase(_RoomersList.begin() + i); + return; + } + } + + if (kick & (target->getInRoomOfPlayer().getShortId() == getId().getShortId())) + { + target->setInRoomOfPlayer(CEntityId::Unknown); + if (!TheDataset.isAccessible(getEntityRowId())) + return; + + const CTpSpawnZone * zone = CZoneManager::getInstance().getTpSpawnZone(target->getBuildingExitZone()); + if (zone) + { + sint32 x,y,z; + float heading; + zone->getRandomPoint(x,y,z,heading); + target->tpWanted(x,y,z,true,heading); + } + } +} + //-------------------------------------------------------------- // CCharacter::removePlayerFromFriendListByEntityId() //-------------------------------------------------------------- @@ -16568,7 +16735,21 @@ void CCharacter::setPVPFlag( bool pvpFlag ) if( pvpFlag == true ) { - if( (_DeclaredCult == PVP_CLAN::Neutral || _DeclaredCult == PVP_CLAN::None ) && (_DeclaredCiv == PVP_CLAN::Neutral || _DeclaredCiv == PVP_CLAN::None ) ) + + +// NEW PVP : Check fames + bool havePvpFame = false; + for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++) + { + sint32 fame = CFameInterface::getInstance().getFameIndexed(_Id, fameIdx); + if ((fame >= PVPFameRequired*6000) || (fame <= -PVPFameRequired*6000)) + havePvpFame = true; + } + + +//- if( (_DeclaredCult == PVP_CLAN::Neutral || _DeclaredCult == PVP_CLAN::None ) && (_DeclaredCiv == PVP_CLAN::Neutral || _DeclaredCiv == PVP_CLAN::None ) ) + + if (!havePvpFame) { // character can set it's tag pvp on if he have no allegiance. SM_STATIC_PARAMS_1(params, STRING_MANAGER::integer); @@ -16578,7 +16759,8 @@ void CCharacter::setPVPFlag( bool pvpFlag ) return; } - if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCult ) == false && +// OLD PVP +/* if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCult ) == false && CPVPManager2::getInstance()->isFactionInWar( _DeclaredCiv ) == false) { // character can set it's tag pvp on if none of his clan is in war @@ -16588,8 +16770,10 @@ void CCharacter::setPVPFlag( bool pvpFlag ) CBankAccessor_PLR::getCHARACTER_INFO().getPVP_FACTION_TAG().setCOUNTER(_PropertyDatabase, uint8(++_PvPDatabaseCounter)); return; } + */ } + // if player changed it's decision before timer if finished if( pvpFlag != _PVPFlag && actualPvpFlag == pvpFlag ) { @@ -16711,12 +16895,28 @@ void CCharacter::setPVPFlagDatabase() CBankAccessor_PLR::getCHARACTER_INFO().getPVP_FACTION_TAG().setACTIVATION_TIME(_PropertyDatabase, activationTime ); // _PropertyDatabase.setProp("CHARACTER_INFO:PVP_FACTION_TAG:COUNTER", ++_PvPDatabaseCounter ); CBankAccessor_PLR::getCHARACTER_INFO().getPVP_FACTION_TAG().setCOUNTER(_PropertyDatabase, uint8(++_PvPDatabaseCounter) ); + + CBankAccessor_PLR::getCHARACTER_INFO().getPVP_FACTION_TAG().setFLAG_PVP_TIME_LEFT(_PropertyDatabase, _PVPRecentActionTime + PVPActionTimer ); } //----------------------------------------------------------------------------- -void CCharacter::setPVPRecentActionFlag() +void CCharacter::setPVPRecentActionFlag(CCharacter *target) { + if (!getPvPRecentActionFlag()) + { + _PVPFlagAlly = 0; + _PVPFlagEnemy = 0; + } + _PVPRecentActionTime = CTickEventHandler::getGameCycle(); + + if (target != NULL) + { + _PVPFlagAlly |= target->getPVPFamesAllies(); + _PVPFlagEnemy |= target->getPVPFamesEnemies(); + updatePVPClanVP(); + } + // _PropertyDatabase.setProp("CHARACTER_INFO:PVP_FACTION_TAG:FLAG_PVP_TIME_LEFT", _PVPRecentActionTime + PVPActionTimer ); CBankAccessor_PLR::getCHARACTER_INFO().getPVP_FACTION_TAG().setFLAG_PVP_TIME_LEFT(_PropertyDatabase, _PVPRecentActionTime + PVPActionTimer ); @@ -16750,7 +16950,7 @@ bool CCharacter::setDeclaredCult(PVP_CLAN::TPVPClan newClan) CFameManager::getInstance().setAndEnforceTribeFameCap(this->getId(), this->getAllegiance()); // handle with faction channel - CPVPManager2::getInstance()->addOrRemoveFactionChannel(this); + CPVPManager2::getInstance()->updateFactionChannel(this); // write new allegiance in database // _PropertyDatabase.setProp("FAME:CULT_ALLEGIANCE", newClan); @@ -16758,21 +16958,22 @@ bool CCharacter::setDeclaredCult(PVP_CLAN::TPVPClan newClan) _LastCultPointWriteDB = ~0; - if( _DeclaredCult == PVP_CLAN::Neutral || _DeclaredCult == PVP_CLAN::None ) - { - if( _PVPFlag ) +// if( _DeclaredCult == PVP_CLAN::Neutral || _DeclaredCult == PVP_CLAN::None ) +// { + if( _PVPFlag || getPvPRecentActionFlag() ) { // if no cult declared and civ is not in war we remove pvp tag - if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCiv ) == false ) - { +// if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCiv ) == false ) +// { _PVPFlag = false; _PVPFlagLastTimeChange = 0; _PVPFlagTimeSettedOn = 0; + _PVPRecentActionTime = 0; setPVPFlagDatabase(); _HaveToUpdatePVPMode = true; - } +// } } - } +// } // Update PvP clan in mirror for faction PvP updatePVPClanVP(); @@ -16811,27 +17012,31 @@ bool CCharacter::setDeclaredCiv(PVP_CLAN::TPVPClan newClan) // set tribe fame threshold and clamp fame if necessary CFameManager::getInstance().setAndEnforceTribeFameCap(this->getId(), this->getAllegiance()); + // handle with faction channel + CPVPManager2::getInstance()->updateFactionChannel(this); + // write new allegiance in database // _PropertyDatabase.setProp("FAME:CIV_ALLEGIANCE", newClan); CBankAccessor_PLR::getFAME().setCIV_ALLEGIANCE(_PropertyDatabase, newClan); _LastCivPointWriteDB = ~0; - if( _DeclaredCiv == PVP_CLAN::Neutral || _DeclaredCiv == PVP_CLAN::None ) - { - if( _PVPFlag ) +// if( _DeclaredCiv == PVP_CLAN::Neutral || _DeclaredCiv == PVP_CLAN::None ) +// { + if( _PVPFlag || getPvPRecentActionFlag() ) { // if no civ declared and cult is not in war we remove pvp tag - if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCult ) == false ) - { +// if( CPVPManager2::getInstance()->isFactionInWar( _DeclaredCult ) == false ) +// { _PVPFlag = false; _PVPFlagLastTimeChange = 0; _PVPFlagTimeSettedOn = 0; + _PVPRecentActionTime = 0; setPVPFlagDatabase(); _HaveToUpdatePVPMode = true; - } +// } } - } +// } // Update PvP clan in mirror for faction PvP updatePVPClanVP(); @@ -19505,9 +19710,10 @@ void CCharacter::channelAdded( bool b ) //------------------------------------------------------------------------------ -void CCharacter::setShowFactionChannelsMode(bool s) +void CCharacter::setShowFactionChannelsMode(TChanID channel, bool s) { - _FactionChannelMode = s; CPVPManager2::getInstance()->addRemoveFactionChannelToUserWithPriviledge(this); + _FactionChannelsMode[channel] = s; + CPVPManager2::getInstance()->addRemoveFactionChannelToUserWithPriviledge(channel, this, s); } diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character.h b/code/ryzom/server/src/entities_game_service/player_manager/character.h index 76bf8c64d..b989a321f 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/character.h @@ -1859,6 +1859,19 @@ public: void removePlayerFromFriendListByContactId(uint32 contactId); void removePlayerFromFriendListByEntityId(const NLMISC::CEntityId &id); + void setInRoomOfPlayer(const NLMISC::CEntityId &id); + const NLMISC::CEntityId& getInRoomOfPlayer(); + + /// get if player have acces to room + bool playerHaveRoomAccess(const NLMISC::CEntityId &id); + + /// add room acces to player + void addRoomAccessToPlayer(const NLMISC::CEntityId &id); + + /// remove room acces to player + void removeRoomAccesToPlayer(const NLMISC::CEntityId &id, bool kick); + + /// remove player from ignore list void removePlayerFromIgnoreListByContactId(uint32 contactId); void removePlayerFromIgnoreListByEntityId(const NLMISC::CEntityId &id); @@ -2217,6 +2230,8 @@ public: void enterPVPZone(uint32 pvpZoneType) const; /// character enter in versus pvp zone, player must choose a clan void openPVPVersusDialog() const; + /// get priviledgePvp + bool getPriviledgePVP() const {return _PriviledgePvp;}; /// get character pvp flag bool getPVPFlag( bool updatePVPModeInMirror = true ) const; /// change pvp flag @@ -2228,7 +2243,7 @@ public: /// set database pvp flag void setPVPFlagDatabase(); /// set PVP recent action flag - void setPVPRecentActionFlag(); + void setPVPRecentActionFlag(CCharacter *target = NULL); /// get PvP recent action flag (true if player involved in PVP action recently) bool getPvPRecentActionFlag() const; /// character are killed in PvP situation @@ -2250,6 +2265,10 @@ public: void setPvPSafeZoneActive(); /// clear pvp zone safe flag void clearSafeInPvPSafeZone(); + /// get pvp fames allies + TYPE_PVP_CLAN getPVPFamesAllies(); + /// get pvp fames ennemys + TYPE_PVP_CLAN getPVPFamesEnemies(); /// update the clan in visuale property void updatePVPClanVP() const; //@} @@ -2296,13 +2315,17 @@ public: void channelAdded( bool b ); bool isChannelAdded(); + uint8 getNbUserChannels() { return _NbUserChannels; }; + void addUserChannel() { _NbUserChannels++; }; + void removeUserChannel() { _NbUserChannels--; }; + std::vector lookForSpecialItemEffects(ITEM_SPECIAL_EFFECT::TItemSpecialEffect effectType) const; /// return true if the given item is an xp catalyser which has been activated bool isAnActiveXpCatalyser( CGameItemPtr item ); - void setShowFactionChannelsMode(bool s); - bool showFactionChannelsMode(); + void setShowFactionChannelsMode(TChanID channel, bool s); + bool showFactionChannelsMode(TChanID channel) const; // from offline command void contactListRefChangeFromCommand(const NLMISC::CEntityId &id, const std::string &operation); @@ -2840,7 +2863,10 @@ public: bool TestProgression; - bool isShopingListInProgress() const { return _ShoppingList != 0; } + bool isShopingListInProgress() const { return _ShoppingList != 0; }; + + void setFinalized(bool isFinalized) { _LoadingFinish = isFinalized; }; + bool isFinalized() const { return _LoadingFinish; }; ////////////////// // Private members @@ -3193,8 +3219,11 @@ private: NLMISC::CEntityId EntityId; // Id used for server/storage uint32 ContactId; // Id used for client/server communication }; - uint32 _ContactIdPool; - + uint32 _ContactIdPool; + + std::vector _RoomersList; // Players who have acces to player's room + NLMISC::CEntityId _inRoomOfPlayer; + // friends list std::vector _FriendsList; // ignore list @@ -3342,6 +3371,9 @@ private: NLMISC::TGameCycle _PVPFlagTimeSettedOn; // time of the last PVP action made (for prevent PVE / PVP exploits) NLMISC::TGameCycle _PVPRecentActionTime; + // all pvp flags (ally and enemy) when players do a pvp curative action + uint32 _PVPFlagAlly; + uint32 _PVPFlagEnemy; // character safe if is in pvp safe zone bool _PvPSafeZoneActive; // player changed his faction tag, we have to update pvp mode @@ -3362,8 +3394,10 @@ private: bool _ChannelAdded; + bool _LoadingFinish; + /// if true, enable display of channel faction for users with priviledge - bool _FactionChannelMode; + std::map _FactionChannelsMode; /// time when user left outpost zone (0 means not valid) NLMISC::TGameCycle _OutpostLeavingTime; @@ -3574,7 +3608,11 @@ private: public: bool getInvisibility() const { return _Invisibility;} /// Set the invisibility flag, NB : just for persistence, do not change nothing. - void setInvisibility(bool invisible) { _Invisibility = invisible;} + void setInvisibility(bool invisible) + { + _Invisibility = invisible; + CBankAccessor_PLR::getUSER().setIS_INVISIBLE(_PropertyDatabase, _Invisibility); + } sint8 getAggroableSave() const { return _AggroableSave;} /// Set the aggroable save flag, NB : just for persistence, do not change nothing. 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 de8aa0ce1..4d9f51fdb 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 @@ -896,9 +896,13 @@ inline bool CCharacter::isChannelAdded() //------------------------------------------------------------------------------ -inline bool CCharacter::showFactionChannelsMode() +inline bool CCharacter::showFactionChannelsMode(TChanID channel) const { - return _FactionChannelMode; + std::map::const_iterator it = _FactionChannelsMode.find(channel); + if (it != _FactionChannelsMode.end()) + return (*it).second; + else + return false; } //------------------------------------------------------------------------------ diff --git a/code/ryzom/server/src/entities_game_service/progression/progression_pvp.cpp b/code/ryzom/server/src/entities_game_service/progression/progression_pvp.cpp index 633c41a2e..227b92dd2 100644 --- a/code/ryzom/server/src/entities_game_service/progression/progression_pvp.cpp +++ b/code/ryzom/server/src/entities_game_service/progression/progression_pvp.cpp @@ -1102,7 +1102,7 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter return; // check if victim and final blower are in PvP Faction (by tag or by a pvp versus zone) - if(!CPVPManager2::getInstance()->factionWarOccurs(victimFaction, finalBlowerFaction)) + /* if(!CPVPManager2::getInstance()->factionWarOccurs(victimFaction, finalBlowerFaction)) { CPVPVersusZone * zone = dynamic_cast(const_cast(victimChar->getPVPInterface()).getPVPSession()); if( zone == 0 ) @@ -1110,7 +1110,7 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter PVP_RELATION::TPVPRelation pvpRelation = zone->getPVPRelation(victimChar, const_cast(finalBlower)); if( pvpRelation != PVP_RELATION::Ennemy ) return; - } + }*/ // a dead player loses his damage points clearDamages(victimChar, true); @@ -1684,7 +1684,7 @@ bool CDamageScoreManager::playerInFactionPvP(const CCharacter * playerChar, PVP_ else if( playerChar->getPVPFlag() ) { pair allegiance = playerChar->getAllegiance(); - if( CPVPManager2::getInstance()->isFactionInWar( allegiance.first ) ) + if( (allegiance.first != PVP_CLAN::Neutral) && (allegiance.first != PVP_CLAN::None) ) { if (faction) *faction = allegiance.first; @@ -1692,14 +1692,14 @@ bool CDamageScoreManager::playerInFactionPvP(const CCharacter * playerChar, PVP_ *withFactionPoints = true; return true; } - if ( CPVPManager2::getInstance()->isFactionInWar( allegiance.second ) ) + /*if ( allegiance.second != PVP_CLAN::Neutral) { if (faction) *faction = allegiance.second; if (withFactionPoints) *withFactionPoints = true; return true; - } + }*/ } return false; } diff --git a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_faction.cpp b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_faction.cpp index 2e0e43ad6..95bdf73a4 100644 --- a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_faction.cpp +++ b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_faction.cpp @@ -35,86 +35,84 @@ CVariable ResPawnPVPInSameRegionForbiden("egs","ResPawnPVPInSameRegionForb //---------------------------------------------------------------------------- PVP_RELATION::TPVPRelation CPVPFaction::getPVPRelation( CCharacter * actor, CEntityBase * target, bool curative ) const { - // init relation reminders + // Init relation reminders CPVPManager2::getInstance()->setPVPFactionAllyReminder( false ); CPVPManager2::getInstance()->setPVPFactionEnemyReminder( false ); - // check actor and target validity - if( actor == 0 || target == 0 ) + // Check actor and target validity + if (actor == 0 || target == 0) { - nlwarning(" actor: %p target: %p",actor,target); + nlwarning(" actor: %p target: %p", actor, target); return PVP_RELATION::Unknown; } CCharacter * pTarget = dynamic_cast(target); - if( pTarget == 0 ) - { + if (pTarget == 0) return PVP_RELATION::Unknown; - } // if target is not tagged then he's neutral - if( pTarget->getPVPFlag() == false && pTarget->getPvPRecentActionFlag() == false ) - { + if (!pTarget->getPVPFlag() && !pTarget->getPvPRecentActionFlag()) return PVP_RELATION::Neutral; - } - if( CPVPManager2::getInstance()->inSafeZone( pTarget->getPosition() ) ) + // Check safe zones + if (CPVPManager2::getInstance()->inSafeZone(pTarget->getPosition())) { - if( pTarget->getSafeInPvPSafeZone() ) - { + if (pTarget->getSafeInPvPSafeZone()) return PVP_RELATION::NeutralPVP; - } } - // get Faction allegiance - pair actorAllegiance = actor->getAllegiance(); - pair targetAllegiance = pTarget->getAllegiance(); - - if( CPVPManager2::getInstance()->inSafeZone( actor->getPosition() ) ) + if( CPVPManager2::getInstance()->inSafeZone(actor->getPosition())) { - if( actor->getSafeInPvPSafeZone() ) - { + if( actor->getSafeInPvPSafeZone()) return PVP_RELATION::NeutralPVP; - } } + // Check fames if( actor->getPVPFlag() || actor->getPvPRecentActionFlag() ) { - // check if he's an enemy (or neutral pvp) - if( actorAllegiance != targetAllegiance ) + // In same Team + if ((pTarget->getTeamId() != CTEAM::InvalidTeamId) && (actor->getTeamId() != CTEAM::InvalidTeamId) && (actor->getTeamId() == pTarget->getTeamId())) { - if( CPVPManager2::getInstance()->factionWarOccurs( actorAllegiance, targetAllegiance ) ) + CPVPManager2::getInstance()->setPVPFactionAllyReminder( true ); + return PVP_RELATION::Ally; + } + + // In same Guild + if ((pTarget->getGuildId() != 0) && (actor->getGuildId() != 0) && (actor->getGuildId() == pTarget->getGuildId())) + { + CPVPManager2::getInstance()->setPVPFactionAllyReminder( true ); + return PVP_RELATION::Ally; + } + + // check if he's an ennemy + if ((actor->getPVPFamesAllies() & pTarget->getPVPFamesEnemies()) || (actor->getPVPFamesEnemies() & pTarget->getPVPFamesAllies())) + { + // Actor can heal an ennemi if not PvPRecentActionFlaged + if (curative && !pTarget->getPvPRecentActionFlag()) { - if( !curative || (curative && pTarget->getPvPRecentActionFlag()) ) - { - CPVPManager2::getInstance()->setPVPFactionEnemyReminder( true ); - return PVP_RELATION::Ennemy; - } - else - return PVP_RELATION::Neutral; + return PVP_RELATION::Neutral; } - else if( actorAllegiance.first != targetAllegiance.first && actorAllegiance.second != actorAllegiance.second ) + else { - if( pTarget->getPvPRecentActionFlag() ) - { - // here target is engaged in another faction war - return PVP_RELATION::NeutralPVP; - } + CPVPManager2::getInstance()->setPVPFactionEnemyReminder(true); + return PVP_RELATION::Ennemy; } } - // they are ally - CPVPManager2::getInstance()->setPVPFactionAllyReminder( true ); - return PVP_RELATION::Ally; + // check if he's an ally + else if ((actor->getPVPFamesAllies() & pTarget->getPVPFamesAllies()) || (actor->getPVPFamesEnemies() & pTarget->getPVPFamesEnemies())) + { + CPVPManager2::getInstance()->setPVPFactionAllyReminder(true); + return PVP_RELATION::Ally; + } } else { - if( pTarget->getPvPRecentActionFlag() ) - { - // here target is engaged in a faction war, but player is not tagged + // Check if actor is not PvPFlag and try to heal a PvPRecentActionFlag + if (curative && pTarget->getPvPRecentActionFlag()) return PVP_RELATION::NeutralPVP; - } } + // default is neutral return PVP_RELATION::Neutral; } diff --git a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_faction_reward_manager/pvp_faction_reward_manager.cpp b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_faction_reward_manager/pvp_faction_reward_manager.cpp index 4f1f8978c..0b5da3b8a 100644 --- a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_faction_reward_manager/pvp_faction_reward_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_faction_reward_manager/pvp_faction_reward_manager.cpp @@ -66,8 +66,8 @@ CPVPFactionRewardManager::CPVPFactionRewardManager() //---------------------------------------------------------------------------- void CPVPFactionRewardManager::_BuildTotemBasesRec( const IPrimitive* prim, - std::map >& neighboursNames, - map& totemBasesPerName ) + std::map >& neighboursNames, + std::map& totemBasesPerName ) { if ( !prim ) return; @@ -441,11 +441,11 @@ bool CPVPFactionRewardManager::destroyTotem( uint16 regionIndex, TDataSetRow kil // Send message to faction channel params[2].Int = 1; - TChanID channelId = CPVPManager2::getInstance()->getFactionDynChannel(pTotemBase->getOwnerFaction()); - if( channelId != DYN_CHAT_INVALID_CHAN ) - { + // TODO TChanID channelId = CPVPManager2::getInstance()->getFactionDynChannel(pTotemBase->getOwnerFaction()); +// if( channelId != DYN_CHAT_INVALID_CHAN ) +// { // TODO Send message PVP_SPIRE_DESTROYED to faction channel and enemies factions - } +// } } @@ -665,11 +665,11 @@ void CPVPFactionRewardManager::tickUpdate() // Send it in faction channel too params[2].Int = 1; - TChanID channelId = CPVPManager2::getInstance()->getFactionDynChannel(pTotem->getOwnerFaction()); - if( channelId != DYN_CHAT_INVALID_CHAN ) - { + //TODO TChanID channelId = CPVPManager2::getInstance()->getFactionDynChannel(pTotem->getOwnerFaction()); + //if( channelId != DYN_CHAT_INVALID_CHAN ) + //{ // TODO Send message PVP_SPIRE_BUILD_FINISHED to faction channel - } + //} } } } diff --git a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp index 32e3c7fcb..0100753be 100644 --- a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp +++ b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.cpp @@ -25,6 +25,7 @@ #include "game_share/utils.h" #include "game_share/msg_client_server.h" +#include "game_share/fame.h" #include "pvp_manager/pvp_manager_2.h" #include "pvp_manager/pvp_manager.h" @@ -70,9 +71,6 @@ void CPVPManager2::init() IPVPInterface * pvpFaction = new CPVPFaction(); BOMB_IF(pvpFaction == 0, "Can't allocate CPVPFaction", nlstop ); _Instance->_PVPInterface.push_back(pvpFaction); - // add war between kami and karavan faction (must be controled by GM tools later - _Instance->addFactionWar(PVP_CLAN::Kami, PVP_CLAN::Karavan); - // instantiate pvp duel class IPVPInterface * pvpDuel = new CPVPDuel(); BOMB_IF(pvpDuel == 0, "Can't allocate CPVPDuel", nlstop ); @@ -144,146 +142,301 @@ void CPVPManager2::tickUpdate() } //---------------------------------------------------------------------------- -TChanID CPVPManager2::getFactionDynChannel( PVP_CLAN::TPVPClan faction ) +// TODO : Add extra factions +//------- +TChanID CPVPManager2::getFactionDynChannel( const std::string& channelName) { - TMAPFactionChannel::iterator it = _FactionChannel.find( faction ); - if( it != _FactionChannel.end() ) + // Search first in extra faction channels + TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find(channelName); + if( it != _ExtraFactionChannel.end() ) { return (*it).second; } - return DYN_CHAT_INVALID_CHAN; -} - -//---------------------------------------------------------------------------- -TChanID CPVPManager2::getCharacterChannel(CCharacter * user) -{ -// if( user->getPVPFlag(false) ) // new specs: we not need be tagged for have channel, only allegiance is required. - { - PVP_CLAN::TPVPClan faction = user->getAllegiance().first; - if( faction != PVP_CLAN::Neutral ) - { - if( isFactionInWar(faction) ) - { - TMAPFactionChannel::iterator it = _FactionChannel.find(faction); - if( it != _FactionChannel.end() ) - { - return (*it).second; - } - } - } - } - return DYN_CHAT_INVALID_CHAN; -} - -//---------------------------------------------------------------------------- -TChanID CPVPManager2::getCharacterRegisteredChannel(CCharacter * user) -{ - map< NLMISC::CEntityId, TChanID >::iterator it = _CharacterChannel.find(user->getId()); - if( it != _CharacterChannel.end() ) - { - return (*it).second; - } - return DYN_CHAT_INVALID_CHAN; -} - -//---------------------------------------------------------------------------- -void CPVPManager2::addOrRemoveFactionChannel(CCharacter * user, bool b ) -{ - TChanID channelHave = getCharacterRegisteredChannel(user); - TChanID channelMustHave = getCharacterChannel(user); - if( channelHave != DYN_CHAT_INVALID_CHAN ) - { - if( channelHave != channelMustHave) - { - removeFactionChannelForCharacter(user); - } - } - - if( channelMustHave != DYN_CHAT_INVALID_CHAN ) - { - if(channelMustHave != channelHave ) - { - addFactionChannelToCharacter(user); - } - } - if( b ) - addRemoveFactionChannelToUserWithPriviledge(user); -} - -//---------------------------------------------------------------------------- -void CPVPManager2::addFactionChannelToCharacter(CCharacter * user) -{ - TChanID channel = getCharacterChannel(user); - if( channel != DYN_CHAT_INVALID_CHAN ) - { - DynChatEGS.addSession( channel, user->getEntityRowId(), true); - _CharacterChannel.insert( make_pair(user->getId(), channel) ); - } -} - -//---------------------------------------------------------------------------- -void CPVPManager2::removeFactionChannelForCharacter(CCharacter * user) -{ - TChanID channel = getCharacterRegisteredChannel(user); - if( channel != DYN_CHAT_INVALID_CHAN ) - { - DynChatEGS.removeSession(channel, user->getEntityRowId()); - std::map< NLMISC::CEntityId, TChanID >::iterator it = _CharacterChannel.find(user->getId()); - if( it != _CharacterChannel.end() ) - { - _CharacterChannel.erase(it); - } - } -} - -//---------------------------------------------------------------------------- -void CPVPManager2::addRemoveFactionChannelToUserWithPriviledge(CCharacter * user) -{ - const CAdminCommand * cmd = findAdminCommand("ShowFactionChannels"); - if (!cmd) - { - return; - } - - if (!user->havePriv(cmd->Priv)) - { - return; - } - - if( user->showFactionChannelsMode() ) - { - removeFactionChannelForCharacter(user); - - bool writeRight = user->havePriv(FactionChannelModeratorWriteRight); - for( uint32 i = PVP_CLAN::BeginClans; i <= PVP_CLAN::EndClans; ++i ) - { - if( isFactionInWar((PVP_CLAN::TPVPClan)i) ) - { - TMAPFactionChannel::iterator it = _FactionChannel.find((PVP_CLAN::TPVPClan)i); - if( it != _FactionChannel.end() ) - { - DynChatEGS.addSession((*it).second, user->getEntityRowId(), writeRight); - } - } - } - } else { - for( uint32 i = PVP_CLAN::BeginClans; i <= PVP_CLAN::EndClans; ++i ) + PVP_CLAN::TPVPClan channelClan = PVP_CLAN::fromString( channelName ); + if( channelClan < PVP_CLAN::BeginClans || channelClan > PVP_CLAN::EndClans ) + return DYN_CHAT_INVALID_CHAN; + TMAPFactionChannel::iterator it = _FactionChannel.find( channelClan ); + if( it != _FactionChannel.end() ) { - if( isFactionInWar((PVP_CLAN::TPVPClan)i) ) + return (*it).second; + } + } + return DYN_CHAT_INVALID_CHAN; +} + +TChanID CPVPManager2::getUserDynChannel( const std::string& channelName) +{ + // Search in user channels + TMAPExtraFactionChannel::iterator it = _UserChannel.find(channelName); + if( it != _UserChannel.end() ) + return (*it).second; + else + return DYN_CHAT_INVALID_CHAN; +} + +const std::string & CPVPManager2::getPassUserChannel( TChanID channelId) +{ + // Search in user channels + TMAPPassChannel::iterator it = _PassChannels.find(channelId); + if( it != _PassChannels.end() ) + return (*it).second; + else + return DYN_CHAT_INVALID_NAME; +} + +//---------------------------------------------------------------------------- +std::vector CPVPManager2::getCharacterChannels(CCharacter * user) +{ +// if( user->getPVPFlag(false) ) // new specs: we not need be tagged for have channel, only allegiance is required. +// { + std::vector result; + result.clear(); + + PVP_CLAN::TPVPClan faction = user->getAllegiance().first; + if( faction != PVP_CLAN::Neutral ) + { + TMAPFactionChannel::iterator it = _FactionChannel.find(faction); + if( it != _FactionChannel.end() ) + { + result.push_back((*it).second); + } + } + + faction = user->getAllegiance().second; + if( faction != PVP_CLAN::Neutral ) + { + TMAPFactionChannel::iterator it = _FactionChannel.find(faction); + if( it != _FactionChannel.end() ) + { + result.push_back((*it).second); + } + } + + bool matis = CFameInterface::getInstance().getFameIndexed(user->getId(), 0) >= PVPFameRequired*6000; + bool fyros = CFameInterface::getInstance().getFameIndexed(user->getId(), 1) >= PVPFameRequired*6000; + bool tryker = CFameInterface::getInstance().getFameIndexed(user->getId(), 2) >= PVPFameRequired*6000; + bool zorai = CFameInterface::getInstance().getFameIndexed(user->getId(), 3) >= PVPFameRequired*6000; + bool kami = CFameInterface::getInstance().getFameIndexed(user->getId(), 4) >= PVPFameRequired*6000; + bool kara = CFameInterface::getInstance().getFameIndexed(user->getId(), 6) >= PVPFameRequired*6000; + + bool amatis = CFameInterface::getInstance().getFameIndexed(user->getId(), 0) <= -PVPFameRequired*6000; + bool afyros = CFameInterface::getInstance().getFameIndexed(user->getId(), 1) <= -PVPFameRequired*6000; + bool atryker = CFameInterface::getInstance().getFameIndexed(user->getId(), 2) <= -PVPFameRequired*6000; + bool azorai = CFameInterface::getInstance().getFameIndexed(user->getId(), 3) <= -PVPFameRequired*6000; + bool akami = CFameInterface::getInstance().getFameIndexed(user->getId(), 4) <= -PVPFameRequired*6000; + bool akara = CFameInterface::getInstance().getFameIndexed(user->getId(), 6) <= -PVPFameRequired*6000; + + if (matis && fyros && tryker && zorai) + { + TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find("hominists"); + if( it != _ExtraFactionChannel.end() ) + { + result.push_back((*it).second); + } + } + + if (amatis && afyros && atryker && azorai) + { + TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find("marauders"); + if( it != _ExtraFactionChannel.end() ) + { + result.push_back((*it).second); + } + } + + if (kami && kara) + { + TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find("urasies"); + if( it != _ExtraFactionChannel.end() ) + { + result.push_back((*it).second); + } + } + + if (akami && akara) + { + TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find("agnos"); + if( it != _ExtraFactionChannel.end() ) + { + result.push_back((*it).second); + } + } +// } + return result; +} + +//---------------------------------------------------------------------------- +std::vector CPVPManager2::getCharacterRegisteredChannels(CCharacter * user) +{ + std::vector result; + result.clear(); + + TCharacterChannels::iterator it = _CharacterChannels.find(user->getId()); + if( it != _CharacterChannels.end() ) + return (*it).second; // return a vector + + return result; +} + +//---------------------------------------------------------------------------- +std::vector CPVPManager2::getCharacterUserChannels(CCharacter * user) +{ + std::vector result; + result.clear(); + + TCharacterChannels::iterator it = _CharacterUserChannels.find(user->getId()); + if( it != _CharacterUserChannels.end() ) + return (*it).second; // return a vector + + return result; +} + +//---------------------------------------------------------------------------- +void CPVPManager2::updateFactionChannel(CCharacter * user, bool b ) +{ + std::vector channelsHave = getCharacterRegisteredChannels(user); + std::vector channelsMustHave = getCharacterChannels(user); + std::vector userChannelsMustHave = getCharacterUserChannels(user); + + // Remove unwanted channels + + for (uint i = 0; i < channelsHave.size(); i++) + { + bool have = false; + for (uint j = 0; j < channelsMustHave.size(); j++) + if (channelsHave[i] == channelsMustHave[j]) + have = true; + for (uint j = 0; j < userChannelsMustHave.size(); j++) + if (channelsHave[i] == userChannelsMustHave[j]) + have = true; + if (!have) + removeFactionChannelForCharacter(channelsHave[i], user); + } + + // Add wanted channels + for (uint i = 0; i < channelsMustHave.size(); i++) + { + bool have = false; + for (uint j = 0; j < channelsHave.size(); j++) + if( channelsMustHave[i] == channelsHave[j]) + have = true; + if (!have) + addFactionChannelToCharacter(channelsMustHave[i], user); + } + + // Add wanted user channels + for (uint i = 0; i < userChannelsMustHave.size(); i++) + { + bool have = false; + for (uint j = 0; j < channelsHave.size(); j++) + if (userChannelsMustHave[i] == channelsHave[j]) + have = true; + if (!have) + addFactionChannelToCharacter(userChannelsMustHave[i], user); + } + + + + /*if( b ) + addRemoveFactionChannelToUserWithPriviledge(user); + */ +} + +//---------------------------------------------------------------------------- +void CPVPManager2::addFactionChannelToCharacter(TChanID channel, CCharacter * user, bool writeRight, bool userChannel) +{ + if( channel != DYN_CHAT_INVALID_CHAN ) + { + if (DynChatEGS.addSession(channel, user->getEntityRowId(), writeRight)) + { + std::vector currentChannels = getCharacterRegisteredChannels(user); + currentChannels.push_back(channel); + _CharacterChannels.erase(user->getId()); + _CharacterChannels.insert( make_pair(user->getId(), currentChannels) ); + if (userChannel) { - TMAPFactionChannel::iterator it = _FactionChannel.find((PVP_CLAN::TPVPClan)i); - if( it != _FactionChannel.end() ) + currentChannels = getCharacterUserChannels(user); + currentChannels.push_back(channel); + _CharacterUserChannels.erase(user->getId()); + _CharacterUserChannels.insert( make_pair(user->getId(), currentChannels) ); + } + } + } +} + +//---------------------------------------------------------------------------- +void CPVPManager2::removeFactionChannelForCharacter(TChanID channel, CCharacter * user, bool userChannel) +{ + std::vector currentChannels = getCharacterRegisteredChannels(user); + for (uint i = 0; i < currentChannels.size(); i++) + { + if (currentChannels[i] == channel) + { + DynChatEGS.removeSession(channel, user->getEntityRowId()); + if (userChannel && (DynChatEGS.getSessionCount(channel) == 0)) + { + DynChatEGS.removeChan(channel); + TMAPPassChannel::iterator it = _PassChannels.find(channel); + if (it != _PassChannels.end()) + _PassChannels.erase(it); + + for (TMAPExtraFactionChannel::iterator it2 = _UserChannel.begin(); it2 != _UserChannel.end(); ++it2) { - DynChatEGS.removeSession((*it).second, user->getEntityRowId()); + if ((*it2).second == channel) + _UserChannel.erase(it2); + } + } + + // Update channel list for player + currentChannels.erase(currentChannels.begin() + i); + std::map< NLMISC::CEntityId, std::vector >::iterator it = _CharacterChannels.find(user->getId()); + if( it != _CharacterChannels.end() ) + { + _CharacterChannels.erase(user->getId()); + _CharacterChannels.insert(make_pair(user->getId(), currentChannels)); + } + } + } + + if (userChannel) + { + currentChannels = getCharacterUserChannels(user); + for (uint i = 0; i < currentChannels.size(); i++) + { + if (currentChannels[i] == channel) + { + // Update channel list for player + currentChannels.erase(currentChannels.begin() + i); + std::map< NLMISC::CEntityId, std::vector >::iterator it = _CharacterUserChannels.find(user->getId()); + if( it != _CharacterUserChannels.end() ) + { + _CharacterUserChannels.erase(user->getId()); + _CharacterUserChannels.insert(make_pair(user->getId(), currentChannels)); } } } - addOrRemoveFactionChannel( user, false ); } } +//---------------------------------------------------------------------------- +void CPVPManager2::addRemoveFactionChannelToUserWithPriviledge(TChanID channel, CCharacter * user, bool s) +{ + const CAdminCommand * cmd = findAdminCommand("ShowFactionChannels"); + if (!cmd) + return; + + if (!user->havePriv(cmd->Priv)) + return; + + if (s) + addFactionChannelToCharacter(channel, user, user->havePriv(FactionChannelModeratorWriteRight)); + else + removeFactionChannelForCharacter(channel, user); + +} + //---------------------------------------------------------------------------- void CPVPManager2::playerDisconnects(CCharacter * user) { @@ -293,7 +446,9 @@ void CPVPManager2::playerDisconnects(CCharacter * user) CPVPManager::getInstance()->playerDisconnects(user); - removeFactionChannelForCharacter(user); + // Remove all channels + removeFactionChannelForCharacter(DYN_CHAT_INVALID_CHAN, user); + _CharacterChannels.erase(user->getId()); } //---------------------------------------------------------------------------- @@ -316,6 +471,12 @@ void CPVPManager2::setPVPModeInMirror( const CCharacter * user ) const nlassert(user); uint8 pvpMode = 0; + // Full pvp + if ( user->getPriviledgePVP() ) + { + pvpMode |= PVP_MODE::PvpChallenge; + } + // faction { if( user->getPVPFlag(false) ) @@ -377,9 +538,12 @@ bool CPVPManager2::inSafeZone(const NLMISC::CVector & v) const return false; } +//---------------------------------------------------------------------------- +// Main method for get Pvp Relation //---------------------------------------------------------------------------- PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEntityBase * target, bool curative ) const { + // Default relation PVP_RELATION::TPVPRelation relation = PVP_RELATION::Neutral; // init reminders, these help to know if faction pvp recent action flag need to be set @@ -390,13 +554,27 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn _Instance->_PVPOutpostAllyReminder = false; _Instance->_PVPOutpostEnemyReminder = false; - /// temp : until new manager is finished we have to check the char pvp session too + CCharacter * pTarget = dynamic_cast(target); if( pTarget ) { + // priviledgePVP is Full PVP, only ally of teammates anf guildmates + if (pTarget->priviledgePVP() || actor->priviledgePVP()) + { + if ((pTarget->getTeamId() != CTEAM::InvalidTeamId) && (actor->getTeamId() != CTEAM::InvalidTeamId) && (actor->getTeamId() == pTarget->getTeamId())) + return PVP_RELATION::Ally; + + if ((pTarget->getGuildId() != 0) && (actor->getGuildId() != 0) && (actor->getGuildId() == pTarget->getGuildId())) + return PVP_RELATION::Ally; + + return PVP_RELATION::Ennemy; + } + if( IsRingShard ) return relation; // disable PVP on Ring shards (only if target is a CCharacter, because we must let attack NPCs) + // ////////////////////////////////////////////////////// + // temp : until new manager is finished we have to check the char pvp session too IPVP * pvpSession = pTarget->getPVPInterface().getPVPSession(); if( pvpSession ) { @@ -424,24 +602,28 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn } } } + //////////////////////////////////////////////////////// } PVP_RELATION::TPVPRelation relationTmp = PVP_RELATION::Neutral; uint i; for( i=0; i<_PVPInterface.size(); ++i ) { + // Get relation for this Pvp Interface (faction, zone, outpost, ...) relationTmp = _PVPInterface[i]->getPVPRelation( actor, target, curative ); if( relationTmp == PVP_RELATION::Unknown ) return PVP_RELATION::Unknown; - // ennemy has the highest priority + // Ennemy has the highest priority if( relationTmp == PVP_RELATION::Ennemy ) return PVP_RELATION::Ennemy; - // neutral pvp + + // Neutral pvp if( relationTmp == PVP_RELATION::NeutralPVP ) relation = PVP_RELATION::NeutralPVP; - // check if ally (neutralpvp has priority over ally) + + // Check if ally (neutralpvp has priority over ally) if( relationTmp == PVP_RELATION::Ally && relation != PVP_RELATION::NeutralPVP ) relation = PVP_RELATION::Ally; } @@ -484,19 +666,20 @@ bool CPVPManager2::isCurativeActionValid( CCharacter * actor, CEntityBase * targ if( actionValid && !checkMode ) { + CCharacter * pTarget = dynamic_cast(target); + if(pTarget) + actor->clearSafeInPvPSafeZone(); + + // propagate faction pvp flag if( pvpRelation == PVP_RELATION::Ally ) { - CCharacter * pTarget = dynamic_cast(target); - if(pTarget) - actor->clearSafeInPvPSafeZone(); - // propagate faction pvp flag if( _PVPFactionAllyReminder ) { if( pTarget ) { if( pTarget->getPvPRecentActionFlag() ) { - actor->setPVPRecentActionFlag(); + actor->setPVPRecentActionFlag(pTarget); TeamManager.pvpHelpOccursInTeam( actor, pTarget ); actor->pvpActionMade(); pTarget->pvpActionMade(); @@ -509,6 +692,10 @@ bool CPVPManager2::isCurativeActionValid( CCharacter * actor, CEntityBase * targ { actor->refreshOutpostLeavingTimer(); } + + // propagate full pvp + if( pTarget->priviledgePVP() ) + actor->setPriviledgePVP(true); } } return actionValid; @@ -592,13 +779,13 @@ bool CPVPManager2::canApplyAreaEffect(CCharacter* actor, CEntityBase * areaTarge switch( pvpRelation ) { case PVP_RELATION::Ally : - actionValid = !offensive; + actionValid = true; break; case PVP_RELATION::Ennemy : actionValid = offensive; break; case PVP_RELATION::Neutral : - actionValid = !offensive; + actionValid = true; break; case PVP_RELATION::NeutralPVP : actionValid = false; @@ -630,7 +817,7 @@ bool CPVPManager2::canApplyAreaEffect(CCharacter* actor, CEntityBase * areaTarge { if( pTarget->getPvPRecentActionFlag() ) { - actor->setPVPRecentActionFlag(); + actor->setPVPRecentActionFlag(pTarget); TeamManager.pvpHelpOccursInTeam( actor, pTarget ); } } @@ -753,40 +940,28 @@ bool CPVPManager2::addFactionWar( PVP_CLAN::TPVPClan clan1, PVP_CLAN::TPVPClan c /// create the faction chat channel when IOS mirror ready void CPVPManager2::onIOSMirrorUp() { - // for each pvp war, create the related char channel - for (uint i=0; i<_FactionWarOccurs.size(); ++i) + // create extra factions channels + createExtraFactionChannel("hominists"); + createExtraFactionChannel("urasies"); + createExtraFactionChannel("marauders"); + createExtraFactionChannel("agnos"); + + for (uint i = PVP_CLAN::BeginClans; i <= PVP_CLAN::EndClans; i++) { - PVP_CLAN::TPVPClan clan1 = _FactionWarOccurs[i].Clan1; - PVP_CLAN::TPVPClan clan2 = _FactionWarOccurs[i].Clan2; - - // create dynamic channel for faction war if not already exist - createFactionChannel(clan1); - createFactionChannel(clan2); - - // send start of faction war to all clients, and add faction channel to character with concerned allegiance - for( CPlayerManager::TMapPlayers::const_iterator it = PlayerManager.getPlayers().begin(); it != PlayerManager.getPlayers().end(); ++it ) + //createFactionChannel(PVP_CLAN::getClanFromIndex(i)); + createFactionChannel((PVP_CLAN::TPVPClan)i); + } + + for( CPlayerManager::TMapPlayers::const_iterator it = PlayerManager.getPlayers().begin(); it != PlayerManager.getPlayers().end(); ++it ) + { + CPlayerManager::SCPlayer scPlayer=(*it).second; + + if (scPlayer.Player) { - CPlayerManager::SCPlayer scPlayer=(*it).second; - - if (scPlayer.Player) + CCharacter *activePlayer=scPlayer.Player->getActiveCharacter(); + if (activePlayer) { - CCharacter *activePlayer=scPlayer.Player->getActiveCharacter(); - if (activePlayer) - { - CMessage msgout( "IMPULSION_ID" ); - CEntityId id = activePlayer->getId(); - msgout.serial( id ); - CBitMemStream bms; - nlverify ( GenericMsgManager.pushNameToStream( "PVP_FACTION:PUSH_FACTION_WAR", bms) ); - bms.serialEnum( clan1 ); - bms.serialEnum( clan2 ); - msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length()); - sendMessageViaMirror( NLNET::TServiceId(id.getDynamicId()), msgout ); - - // add faction channel to character if needed - addFactionChannelToCharacter( activePlayer ); - addRemoveFactionChannelToUserWithPriviledge( activePlayer ); - } + updateFactionChannel(activePlayer); } } } @@ -796,43 +971,6 @@ void CPVPManager2::onIOSMirrorUp() //---------------------------------------------------------------------------- bool CPVPManager2::stopFactionWar( PVP_CLAN::TPVPClan clan1, PVP_CLAN::TPVPClan clan2 ) { - vector< PVP_CLAN::CFactionWar >::iterator it; - for( it=_FactionWarOccurs.begin(); it!=_FactionWarOccurs.end(); ++it ) - { - if( (*it).inPvPFaction( clan1, clan2 ) ) - { - // send end of faction war to all clients, and remove faction channel if needed - for( CPlayerManager::TMapPlayers::const_iterator it2 = PlayerManager.getPlayers().begin(); it2 != PlayerManager.getPlayers().end(); ++it2 ) - { - CPlayerManager::SCPlayer scPlayer=(*it2).second; - - if (scPlayer.Player) - { - CCharacter *activePlayer=scPlayer.Player->getActiveCharacter(); - if (activePlayer) - { - CMessage msgout( "IMPULSION_ID" ); - CEntityId id = activePlayer->getId(); - msgout.serial( id ); - CBitMemStream bms; - nlverify ( GenericMsgManager.pushNameToStream( "PVP_FACTION:POP_FACTION_WAR", bms) ); - bms.serialEnum( clan1 ); - bms.serialEnum( clan2 ); - msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length()); - sendMessageViaMirror( NLNET::TServiceId(id.getDynamicId()), msgout ); - - removeFactionChannelForCharacter(activePlayer); - } - } - } - - // erase war - _FactionWarOccurs.erase(it); - removeFactionChannel(clan1); - removeFactionChannel(clan2); - return true; - } - } return false; } @@ -842,10 +980,7 @@ void CPVPManager2::createFactionChannel(PVP_CLAN::TPVPClan clan) TMAPFactionChannel::iterator it = _FactionChannel.find(clan); if( it == _FactionChannel.end() ) { - ucstring title; string name = NLMISC::strupr( string("Faction_") + PVP_CLAN::toString(clan) ); -// title.fromUtf8(name); -// TChanID factionChannelId = DynChatEGS.addChan(name, title ); TChanID factionChannelId = DynChatEGS.addLocalizedChan(name); // set historic size of the newly created channel DynChatEGS.setHistoricSize( factionChannelId, FactionChannelHistoricSize ); @@ -854,15 +989,60 @@ void CPVPManager2::createFactionChannel(PVP_CLAN::TPVPClan clan) } } +void CPVPManager2::createExtraFactionChannel(const std::string & channelName) +{ + + TMAPExtraFactionChannel::iterator it = _ExtraFactionChannel.find(channelName); + if( it == _ExtraFactionChannel.end() ) + { + string name = NLMISC::strupr( string("Faction_") + channelName ); + TChanID factionChannelId = DynChatEGS.addLocalizedChan(name); + // set historic size of the newly created channel + DynChatEGS.setHistoricSize( factionChannelId, FactionChannelHistoricSize ); + + _ExtraFactionChannel.insert( make_pair(channelName, factionChannelId) ); + } +} + +TChanID CPVPManager2::createUserChannel(const std::string & channelName, const std::string & pass) +{ + + TMAPExtraFactionChannel::iterator it = _UserChannel.find(channelName); + if( it == _UserChannel.end() ) + { + string channelTitle; + if (channelName.substr(0, 1) == "#") + channelTitle = channelName.substr(5); + else + channelTitle = channelName; + + TChanID factionChannelId = DynChatEGS.addChan(channelName, channelTitle); + DynChatEGS.setHistoricSize( factionChannelId, FactionChannelHistoricSize ); + + _UserChannel.insert( make_pair(channelName, factionChannelId) ); + _PassChannels.insert( make_pair(factionChannelId, pass) ); + return factionChannelId; + } + + return DYN_CHAT_INVALID_CHAN; +} + +void CPVPManager2::deleteUserChannel(const std::string & channelName) +{ + TMAPExtraFactionChannel::iterator it = _UserChannel.find(channelName); + if( it != _UserChannel.end() ) + { + DynChatEGS.removeChan( (*it).second ); + TMAPPassChannel::iterator it2 = _PassChannels.find((*it).second); + if( it2 != _PassChannels.end() ) + _PassChannels.erase(it2); + _UserChannel.erase(it); + } +} + //---------------------------------------------------------------------------- void CPVPManager2::removeFactionChannel(PVP_CLAN::TPVPClan clan) { - for( uint32 i = 0; i < _FactionWarOccurs.size(); ++i ) - { - if( _FactionWarOccurs[ i ].Clan1 == clan || _FactionWarOccurs[ i ].Clan2 == clan) - return; - } - TMAPFactionChannel::iterator it = _FactionChannel.find( clan ); if( it != _FactionChannel.end() ) { @@ -874,48 +1054,18 @@ void CPVPManager2::removeFactionChannel(PVP_CLAN::TPVPClan clan) //---------------------------------------------------------------------------- bool CPVPManager2::factionWarOccurs( PVP_CLAN::TPVPClan clan1, PVP_CLAN::TPVPClan clan2 ) const { - if( clan1 != PVP_CLAN::Neutral && clan2 != PVP_CLAN::Neutral ) - { - uint32 factionWarOccursSize = (uint32)_FactionWarOccurs.size(); - for( uint32 i = 0; i < factionWarOccursSize; ++i ) - { - if( _FactionWarOccurs[ i ].inPvPFaction( clan1, clan2 ) ) - return true; - } - } return false; } //---------------------------------------------------------------------------- bool CPVPManager2::factionWarOccurs( pair allegiance1, pair allegiance2 ) const { - bool warOccurs = false; - if( allegiance1.first != PVP_CLAN::Neutral ) - { - if( allegiance2.first != PVP_CLAN::Neutral && allegiance1.first != allegiance2. first ) - warOccurs |= factionWarOccurs( allegiance1.first, allegiance2.first ); - if( allegiance2.second != PVP_CLAN::Neutral && allegiance1.first != allegiance2.second ) - warOccurs |= factionWarOccurs( allegiance1.first, allegiance2.second ); - } - if( allegiance1.second != PVP_CLAN::Neutral ) - { - if( allegiance2.first != PVP_CLAN::Neutral && allegiance1.second != allegiance2.first ) - warOccurs |= factionWarOccurs( allegiance1.second, allegiance2.first ); - if( allegiance2.second != PVP_CLAN::Neutral && allegiance1.second != allegiance2.second ) - warOccurs |= factionWarOccurs( allegiance1.second, allegiance2.second ); - } - return warOccurs; + return false; } //---------------------------------------------------------------------------- bool CPVPManager2::isFactionInWar( PVP_CLAN::TPVPClan clan ) { - uint32 factionWarOccursSize = (uint32)_FactionWarOccurs.size(); - for( uint32 i = 0; i < factionWarOccursSize; ++i ) - { - if( _FactionWarOccurs[ i ].Clan1 == clan || _FactionWarOccurs[ i ].Clan2 == clan ) - return true; - } return false; } @@ -925,6 +1075,7 @@ bool CPVPManager2::isFactionInWar( PVP_CLAN::TPVPClan clan ) //----------------------------------------------- void CPVPManager2::sendFactionWarsToClient( CCharacter * user ) { +/** Old Pvp nlassert(user); CMessage msgout( "IMPULSION_ID" ); @@ -947,6 +1098,7 @@ void CPVPManager2::sendFactionWarsToClient( CCharacter * user ) msgout.serialBufferWithSize( (uint8*)bms.buffer(), bms.length() ); CUnifiedNetwork::getInstance()->send( NLNET::TServiceId(id.getDynamicId()), msgout ); + */ } @@ -1264,7 +1416,8 @@ NLMISC_COMMAND(setFactionWar, "Start/stop current wars between faction", " PVP_CLAN::EndClans ) { diff --git a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.h b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.h index f28bcaeed..2b68d9d7a 100644 --- a/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.h +++ b/code/ryzom/server/src/entities_game_service/pvp_manager/pvp_manager_2.h @@ -41,6 +41,8 @@ class CPVPManager2 NL_INSTANCE_COUNTER_DECL(CPVPManager2); public: typedef std::map< PVP_CLAN::TPVPClan, TChanID > TMAPFactionChannel; + typedef std::map< std::string, TChanID > TMAPExtraFactionChannel; + typedef std::map< TChanID, std::string > TMAPPassChannel; ///\name LOW LEVEL MANAGEMENT //@{ @@ -55,21 +57,27 @@ public: /// callback called at each tick void tickUpdate(); /// return dynamic channel TChanID attribued to a faction - TChanID getFactionDynChannel( PVP_CLAN::TPVPClan faction); + TChanID getFactionDynChannel( const std::string& channelName ); + /// return dynamic channel TChanID attribued to an user + TChanID getUserDynChannel( const std::string& channelName); + /// return dynamic channel TChanID attribued to a faction + const std::string &getPassUserChannel( TChanID channelId); /// return dynamic channel TChanID character must have, DYN_CHAT_INVALID_CHAN if he must don't have faction channel - TChanID getCharacterChannel(CCharacter * user); + std::vector getCharacterChannels(CCharacter * user); /// return dynamic channel TChanId subscribed by character, DYN_CHAT_INVALID_CHAN if character have no faction channel - TChanID getCharacterRegisteredChannel(CCharacter * user); + std::vector getCharacterRegisteredChannels(CCharacter * user); + /// return dynamic user channel TChanId subscribed by character, DYN_CHAT_INVALID_CHAN if character have no user channel + std::vector getCharacterUserChannels(CCharacter * user); // add faction channel to character if needed - void addFactionChannelToCharacter(CCharacter * user); + void addFactionChannelToCharacter(TChanID channel, CCharacter * user, bool writeRight = true, bool userChannel = false); // remove faction channel for character - void removeFactionChannelForCharacter(CCharacter * user); + void removeFactionChannelForCharacter(TChanID channel, CCharacter * user, bool userChannel = false); // add/remove faction channel to this character with privilege - void addRemoveFactionChannelToUserWithPriviledge(CCharacter * user ); + void addRemoveFactionChannelToUserWithPriviledge(TChanID channel, CCharacter * user, bool s = true ); /// handle player disconnection void playerDisconnects(CCharacter * user); /// handle to add or remove faction channel to player of needed - void addOrRemoveFactionChannel(CCharacter * user, bool b = true ); + void updateFactionChannel(CCharacter * user, bool b = true ); /// handle player death void playerDies(CCharacter * user); /// handle player teleportation @@ -113,6 +121,12 @@ public: bool stopFactionWar( PVP_CLAN::TPVPClan clan1, PVP_CLAN::TPVPClan clan2 ); // create a faction channel if not already exist void createFactionChannel(PVP_CLAN::TPVPClan clan); + // create an extra faction channel if not already exist (for marauders, agnos, urasiens and hominits) + void createExtraFactionChannel(const std::string & channelName); + // create an user channel if not already exist + TChanID createUserChannel(const std::string & channelName, const std::string & pass); + // remove a user channel + void deleteUserChannel(const std::string & channelName); // remove a fation channel if faction is no more involved in a war void removeFactionChannel(PVP_CLAN::TPVPClan clan); // return true if faction war occurs between the 2 factions @@ -165,8 +179,13 @@ private: TFactionWars _FactionWarOccurs; /// channel for faction in war TMAPFactionChannel _FactionChannel; + TMAPExtraFactionChannel _ExtraFactionChannel; + TMAPExtraFactionChannel _UserChannel; + TMAPPassChannel _PassChannels; /// character registered channel - std::map< NLMISC::CEntityId, TChanID > _CharacterChannel; + typedef std::map< NLMISC::CEntityId, std::vector > TCharacterChannels; + TCharacterChannels _CharacterChannels; + TCharacterChannels _CharacterUserChannels; /// if a player does an offensive(curative) action on a faction pvp enemy(ally) we must update flag bool _PVPFactionAllyReminder; bool _PVPFactionEnemyReminder; diff --git a/code/ryzom/server/src/entities_game_service/shop_type/character_shopping_list.cpp b/code/ryzom/server/src/entities_game_service/shop_type/character_shopping_list.cpp index 2f655c180..39af9c988 100644 --- a/code/ryzom/server/src/entities_game_service/shop_type/character_shopping_list.cpp +++ b/code/ryzom/server/src/entities_game_service/shop_type/character_shopping_list.cpp @@ -253,6 +253,7 @@ bool CCharacterShoppingList::passThruFilter(TItemTradePtr itemTrade, bool dynnam case ITEMFAMILY::HARVEST_TOOL: case ITEMFAMILY::CRAFTING_TOOL: case ITEMFAMILY::COSMETIC: + case ITEMFAMILY::CONSUMABLE: if( form->Type != _Character->getItemTypeFilter() ) return false; break; @@ -269,7 +270,8 @@ bool CCharacterShoppingList::passThruFilter(TItemTradePtr itemTrade, bool dynnam form->Family != ITEMFAMILY::COSMETIC && form->Family != ITEMFAMILY::TELEPORT && form->Family != ITEMFAMILY::SERVICE && - form->Family != ITEMFAMILY::GENERIC_ITEM + form->Family != ITEMFAMILY::GENERIC_ITEM && + form->Family != ITEMFAMILY::CONSUMABLE ) { if( _Character->getMinClassItemFilter() != RM_CLASS_TYPE::Unknown && itemEnergy != ~0u ) @@ -387,6 +389,7 @@ uint32 CCharacterShoppingList::getSellPrice( const TItemTradePtr itemTrade, bool case ITEMFAMILY::SHIELD: case ITEMFAMILY::JEWELRY: case ITEMFAMILY::RAW_MATERIAL: + case ITEMFAMILY::CONSUMABLE: priceFactor *= 4.0f; break; case ITEMFAMILY::COSMETIC: diff --git a/code/ryzom/server/src/entities_game_service/shop_type/shop_type_manager.cpp b/code/ryzom/server/src/entities_game_service/shop_type/shop_type_manager.cpp index 7db4c5d6b..3c463075b 100644 --- a/code/ryzom/server/src/entities_game_service/shop_type/shop_type_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/shop_type/shop_type_manager.cpp @@ -580,6 +580,7 @@ IShopUnit * CShopTypeManager::getDynamicShopUnit( const TItemTradePtr& item, uin case ITEMFAMILY::JEWELRY: case ITEMFAMILY::CRYSTALLIZED_SPELL: case ITEMFAMILY::ITEM_SAP_RECHARGE: + case ITEMFAMILY::CONSUMABLE: { uint32 itemType = itemForm->Type; uint32 itemOrigin = itemForm->Origin; diff --git a/code/ryzom/server/src/entities_game_service/team_manager/team.cpp b/code/ryzom/server/src/entities_game_service/team_manager/team.cpp index 178d34d6d..904cb7327 100644 --- a/code/ryzom/server/src/entities_game_service/team_manager/team.cpp +++ b/code/ryzom/server/src/entities_game_service/team_manager/team.cpp @@ -863,7 +863,12 @@ void CTeam::removeMission( uint idx, TMissionResult result) result = mr_fail; } - const CMissionTemplate *tpl = CMissionManager::getInstance()->getTemplate(_Missions[idx]->getTemplateId()); + CMissionTemplate *tpl = CMissionManager::getInstance()->getTemplate(_Missions[idx]->getTemplateId()); + + if ( tpl && !tpl->Tags.NoList ) + { + _Missions[idx]->clearUsersJournalEntry(); + } /*Bsi.append( StatPath, NLMISC::toString("[MIT%s] %u %s", MissionResultStatLogTag[result], @@ -877,7 +882,6 @@ void CTeam::removeMission( uint idx, TMissionResult result) tpl->getMissionName().c_str()); */ // EGSPD::missionTeamLog(MissionResultStatLogTag[result], this->_TeamId, tpl->getMissionName()); - _Missions[idx]->clearUsersJournalEntry(); CMissionManager::getInstance()->deInstanciateMission(_Missions[idx]); delete _Missions[idx]; _Missions.erase(_Missions.begin() + idx) ; diff --git a/code/ryzom/server/src/entities_game_service/zone_manager.cpp b/code/ryzom/server/src/entities_game_service/zone_manager.cpp index 7e4bc519f..e4186da2b 100644 --- a/code/ryzom/server/src/entities_game_service/zone_manager.cpp +++ b/code/ryzom/server/src/entities_game_service/zone_manager.cpp @@ -90,6 +90,14 @@ void cbSetZoneState( NLNET::CMessage& msgin, const std::string &serviceName, NLN CZoneManager *pZM = &CZoneManager::getInstance(); + // get the places + CPlace *place = pZM->getPlaceFromName(sZoneName); + if (place != NULL) + if (place->isGooPath()) + place->setGooActive(nState != 0); + + + // get the deposit zone (linear search) const vector &rDeps = pZM->getDeposits(); for (uint32 i = 0; i < rDeps.size(); ++i) @@ -267,6 +275,7 @@ bool CPlace::build(const NLLIGO::CPrimPath * path, uint16 id) _CenterX = sint32 ( ( minX + maxX ) *1000.0f / 2.0f ); _CenterY = sint32 ( ( minY + maxY ) *1000.0f / 2.0f ); _GooPath = true; + _GooActive = true; _Reported = false; return true; @@ -331,6 +340,7 @@ bool CPlace::build(const NLLIGO::CPrimZone * zone,uint16 id, bool reportAutorise _CenterX = sint32 ( ( minX + maxX ) *1000.0f / 2.0f ); _CenterY = sint32 ( ( minY + maxY ) *1000.0f / 2.0f ); _GooPath = false; + _GooActive = false; // get place_type of re-spawn point PLACE_TYPE::TPlaceType placeType; diff --git a/code/ryzom/server/src/entities_game_service/zone_manager.h b/code/ryzom/server/src/entities_game_service/zone_manager.h index 87392e17b..5aeb2a4a0 100644 --- a/code/ryzom/server/src/entities_game_service/zone_manager.h +++ b/code/ryzom/server/src/entities_game_service/zone_manager.h @@ -148,9 +148,11 @@ public: ///\return center coords inline sint32 getCenterX(){ return _CenterX;} inline sint32 getCenterY(){ return _CenterY;} + inline void setGooActive(bool state) { _GooActive = state; } bool getReported() const { return _Reported; } bool isGooPath() const { return _GooPath; } + bool isGooActive() const { return _GooActive; } bool isMainPlace() const { return _MainPlace; } TAIAlias getAlias()const{ return _Alias; } @@ -169,6 +171,7 @@ private: bool _Reported; /// Flag indicate this place is a goo path bool _GooPath; + bool _GooActive; /// true if the place is the main place where a user can be bool _MainPlace; /// respawn points validated when a user enters the place diff --git a/code/ryzom/server/src/input_output_service/chat_manager.cpp b/code/ryzom/server/src/input_output_service/chat_manager.cpp index e45bcd14f..51db34b4d 100644 --- a/code/ryzom/server/src/input_output_service/chat_manager.cpp +++ b/code/ryzom/server/src/input_output_service/chat_manager.cpp @@ -1417,8 +1417,15 @@ void CChatManager::sendChat( CChatGroup::TGroupType senderChatMode, const TDataS { if (itCl->second->getId().getType() == RYZOMID::player) { - if (itCl->second->isInIgnoreList(sender)) + bool havePriv = false; + if (charInfos && charInfos->HavePrivilege) + { + havePriv = true; + } + if ( ! havePriv && itCl->second->isInIgnoreList(sender)) + { return; + } uint32 senderNameIndex; // if the sender exists @@ -1605,8 +1612,15 @@ void CChatManager::sendChat2Ex( CChatGroup::TGroupType senderChatMode, const TDa { if (itCl->second->getId().getType() == RYZOMID::player) { - if (itCl->second->isInIgnoreList(sender)) + bool havePriv = false; + if (charInfos && charInfos->HavePrivilege) + { + havePriv = true; + } + if ( ! havePriv && itCl->second->isInIgnoreList(sender)) + { return; + } // send the chat phrase to the client // send the string to FE @@ -1655,6 +1669,7 @@ void CChatManager::sendChatCustomEmote( const TDataSetRow &sender, const TDataSe TDataSetRow senderFake = TDataSetRow::createFromRawIndex( INVALID_DATASET_ROW ); CCharacterInfos * receiverInfos = IOS->getCharInfos( TheDataset.getEntityId(receiver) ); + CCharacterInfos * senderInfos = IOS->getCharInfos( TheDataset.getEntityId(sender) ); if( receiverInfos ) { TClientInfoCont::iterator itCl = _Clients.find( receiver ); @@ -1662,8 +1677,15 @@ void CChatManager::sendChatCustomEmote( const TDataSetRow &sender, const TDataSe { if (itCl->second->getId().getType() == RYZOMID::player) { - if (itCl->second->isInIgnoreList(sender)) + bool havePriv = false; + if (senderInfos && senderInfos->HavePrivilege) + { + havePriv = true; + } + if ( ! havePriv && itCl->second->isInIgnoreList(sender)) + { return; + } // send the string to FE CMessage msgout( "IMPULS_CH_ID" ); @@ -1752,8 +1774,8 @@ void CChatManager::tell2( const TDataSetRow& sender, const TDataSetRow& receiver return; } - // check if the sender is not in the ignore list of the receiver - if( !itCl->second->isInIgnoreList(sender) ) + // check if the sender is CSR or is not in the ignore list of the receiver + if(senderInfos->HavePrivilege || !itCl->second->isInIgnoreList(sender) ) { // send the chat phrase to the client TVectorParamCheck params; @@ -1850,7 +1872,7 @@ void CChatManager::tell( const TDataSetRow& sender, const string& receiverIn, co } // check if the sender is not in the ignore list of the receiver - if( !itCl->second->isInIgnoreList(sender) ) + if(senderInfos->HavePrivilege || !itCl->second->isInIgnoreList(sender) ) { // check if user is afk if ( receiverInfos->DataSetIndex.isValid() && TheDataset.isDataSetRowStillValid( receiverInfos->DataSetIndex ) ) @@ -2018,8 +2040,9 @@ void CChatManager::farTell( const NLMISC::CEntityId &senderCharId, const ucstrin return; } - // check if the sender is not in the ignore list of the receiver - if( !itCl->second->isInIgnoreList(senderCharId) ) + CCharacterInfos * senderInfos = IOS->getCharInfos(senderName); + // check if the sender is CSR is not in the ignore list of the receiver + if((senderInfos && senderInfos->HavePrivilege) || !itCl->second->isInIgnoreList(senderCharId) ) { // check if user is afk // if ( receiverInfos->DataSetIndex.isValid() && TheDataset.isDataSetRowStillValid( receiverInfos->DataSetIndex ) ) @@ -2311,8 +2334,25 @@ ucstring CChatManager::filterClientInput(ucstring &text) // any double white skipped if (text[pos] == '&') { - // filter out '&' to remove system color code (like '&SYS&' ) - result += '.'; + // Special case if there is or at the beginning + bool hasBrackets = false; + if (pos >= 5) + { + hasBrackets = (text[pos-1] == '>') && + (text[pos-5] == '<'); + } + // Filter out '&' at the first non-whitespace position to remove + // system color code (like '&SYS&' ) + bool disallowAmpersand = (result.size() == 0) || hasBrackets; + if (disallowAmpersand) + { + result += '.'; + } + else + { + // authorized ampersand + result += '&'; + } } else if (text[pos] == '@' && pos < text.size()-1 && text[pos+1] == '{') {