//--------------------------------------------------- // removeNpcFromGroup //--------------------------------------------------- void CCreatureManager::removeNpcFromGroup( TAIAlias groupAlias, TAIAlias npcAlias ) { CHashMap< unsigned int,CNPCGroup >::iterator it = _NpcGroups.find( groupAlias ); if ( it == _NpcGroups.end() ) { nlwarning("<CCreatureManager removeNpcFromGroup> Invalid NPC group %s", CPrimitivesParser::aliasToString(groupAlias).c_str()); } else { CNPCGroup & group = (*it).second; group.Members.erase( npcAlias ); const bool groupWiped = (group.Members.empty()); CMissionManager::getInstance()->checkEscortFailure(groupAlias, groupWiped); if (groupWiped) { // group is wiped, time to trigger mission event vector<uint16> processedTeams; for ( uint i = 0; i < group.TeamKillers.size(); i++ ) { CTeam * team = TeamManager.getRealTeam( group.TeamKillers[i] ); if ( team ) { CCharacter * user = PlayerManager.getChar( team->getLeader() ); if ( user ) { CMissionEventKillGroup event(groupAlias,CMissionEvent::NoSolo); if ( user->processMissionEvent( event ) ) { // the event has been processed for this team. We add the team to the processed team processedTeams.push_back( group.TeamKillers[i] ); } } } } for ( uint i = 0; i < group.PlayerKillers.size(); i++ ) { CCharacter * user = PlayerManager.getChar( group.PlayerKillers[i] ); if ( user ) { if ( std::find( processedTeams.begin(),processedTeams.end(),user->getTeamId() ) == processedTeams.end() ) { CMissionEventKillGroup event( groupAlias,CMissionEvent::NoGroup ); user->processMissionEvent( event ); } } } _NpcGroups.erase(it); } else CMissionManager::getInstance()->checkEscortFailure(groupAlias,false); } } // removeNpcFromGroup
//---------------------------------------------------------------------------- void cbClientGroupAbandonMission( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) { CEntityId userId; uint8 index; msgin.serial(userId,index); if (!checkPlayer(userId, "cbClientGroupAbandonMission")) return; CCharacter * user = PlayerManager.getChar( userId ); user->setAfkState(false); CTeam * team = TeamManager.getRealTeam( user->getTeamId() ); if ( !team ) { MISLOG("user:%s cbClientGroupAbandonMission : Invalid team", userId.toString().c_str()); return; } if ( team->getLeader() != userId ) { CCharacter::sendDynamicSystemMessage( user->getEntityRowId(), "REQ_LEADER_TO_ABANDON_MISSION" ); return; } if ( index >= team->getMissions().size() ) { MISLOG("user:%s cbClientGroupAbandonMission : Invalid group mission %u ( count %u )", userId.toString().c_str(), index, team->getMissions().size()); return; } CMissionTeam* mission = team->getMissions()[index]; nlassert(mission); if ( mission->getFinished() == false ) { CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( mission->getTemplateId() ); if ( !templ ) { MISLOG("user:%s cbClientGroupAbandonMission : invalid group mission alias %u", userId.toString().c_str(), mission->getTemplateId()); return; } if ( templ->Tags.NonAbandonnable ) { MISLOG("user:%s cbClientGroupAbandonMission : group mission alias %u is not abandonnable but user tries to abandon it", userId.toString().c_str(), mission->getTemplateId()); return; } set<CEntityId> excluded; excluded.insert( userId ); team->sendDynamicMessageToMembers( "ABANDON_GROUP_MISSION",TVectorParamCheck(), excluded ); } team->removeMission( index, mr_abandon ); }
//--------------------------------------------------- // isLeagueInvitableBy : //--------------------------------------------------- CTeamManager::TInviteRetCode CTeamManager::isLeagueInvitableBy(CCharacter * invited, CCharacter * invitor ) { // check must be done before nlassert( invited ); nlassert( invitor ); if ( !TheDataset.isAccessible(invited->getEntityRowId()) || !TheDataset.isAccessible(invitor->getEntityRowId())) return CantInvite; // check that the invitor is in team CTeam * team = getRealTeam( invitor->getTeamId() ); if (!team) return CantInvite; // check that the invitor is the leader if (team->getLeader() != invitor->getId() ) return CantInvite; // check that the invited don't have league if (invited->getLeagueId() != DYN_CHAT_INVALID_CHAN) return AlreadyInLeague; // check if target is not already invited if( invited->getLeagueInvitor() != CEntityId::Unknown ) return AlreadyInvited; // get the target team team = getRealTeam( invited->getTeamId() ); if (!team) return NotInTeam; // check that the invited is the leader if (team->getLeader() != invited->getId() ) return NotLeader; return Ok; }
//---------------------------------------------------------------------------- void cbClientMissionGroupWake( NLNET::CMessage& msgin, const std::string & serviceName, NLNET::TServiceId serviceId ) { CEntityId userId; msgin.serial(userId); uint8 missionGroupIndex; msgin.serial(missionGroupIndex); CCharacter * user = PlayerManager.getChar(userId); if ( !user || !user->getEnterFlag() ) return; user->setAfkState(false); CTeam * team = TeamManager.getRealTeam( user->getTeamId() ); if ( !team ) { MISLOG("user:%s cbClientMissionGroupWake : Invalid team", userId.toString().c_str()); return; } if ( team->getLeader() != userId ) { return; } if ( missionGroupIndex >= team->getMissions().size() ) { MISLOG("user:%s cbClientMissionGroupWake : Invalid group mission %u ( count %u )", userId.toString().c_str(), missionGroupIndex, team->getMissions().size()); return; } CMissionTeam* mission = team->getMissions()[missionGroupIndex]; nlassert(mission); if ( mission->getFinished() == false ) { CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( mission->getTemplateId() ); if ( !templ ) { MISLOG("user:%s cbClientGroupAbandonMission : invalid group mission alias %u", userId.toString().c_str(), mission->getTemplateId()); return; } CMissionQueueManager::getInstance()->playerWakesUp (userId, templ->Alias ); } }
//--------------------------------------------------- // processMissionTeamEvent : //--------------------------------------------------- CTeamManager::TInviteRetCode CTeamManager::isInvitableBy(CCharacter * invited, CCharacter * invitor ) { // check must be done before nlassert( invited ); nlassert( invitor ); // check if target is not already invited if( invited->getTeamInvitor() != CEntityId::Unknown ) { return AlreadyInvited; } // get the target team, which must be fake CTeam * team = getRealTeam( invited->getTeamId() ); if( team ) { return AlreadyInTeam; } // check that the invitor is alone or a group leader team = getRealTeam( invitor->getTeamId() ); if (team && team->getLeader()!= invitor->getId()) { return CantInvite; } // check faction of invitor and invited, player can't invite an enemy in team. if ( !TheDataset.isAccessible(invited->getEntityRowId()) || !TheDataset.isAccessible(invitor->getEntityRowId())) return CantInvite; // cannot invite enemy in faction PvP zones /* if( CPVPManager2::getInstance()->isOffensiveActionValid( invited, invitor, true ) ) if( invited->getPvPRecentActionFlag() || invitor->getPvPRecentActionFlag() ) return CantInviteEnemy;*/ return Ok; }
//--------------------------------------------------- // leagueJoinProposal : //--------------------------------------------------- void CTeamManager::joinLeagueProposal( CCharacter * leader, const CEntityId &targetId) { //check already done nlassert(leader); const NLMISC::CEntityId &leaderId = leader->getId(); if (targetId == leaderId ) { CCharacter::sendDynamicSystemMessage( leader->getId(),"INVALID_LEAGUE_TARGET" ); return; } // get targeted player CCharacter *invitedPlayer = PlayerManager.getOnlineChar( targetId ); if ( invitedPlayer == NULL ) { CCharacter::sendDynamicSystemMessage( leader->getId(),"INVALID_LEAGUE_TARGET" ); return; } // god player are forbidden to team if (leader->godMode() || invitedPlayer->godMode()) { nlwarning("<CTeamManager joinLeagueProposal> Player %s invited %s, but at least on of them is god, forbidden", leaderId.toString().c_str(), targetId.toString().c_str()); CCharacter::sendDynamicSystemMessage( leader->getId(),"TEAM_GOD_FORBIDDEN" ); return; } TInviteRetCode code = isLeagueInvitableBy(invitedPlayer,leader); if ( code == AlreadyInvited ) { CCharacter::sendDynamicSystemMessage( leader->getId(),"LEAGUE_ALREADY_INVITED" ); return; } else if ( code == AlreadyInLeague ) { CTeam * team = getRealTeam( invitedPlayer->getTeamId() ); CCharacter::sendDynamicSystemMessage( leader->getId(),"LEAGUE_ALREADY_IN_LEAGUE" ); return; } else if ( code == NotLeader ) { CTeam * team = getRealTeam( invitedPlayer->getTeamId() ); joinLeagueProposal(leader, team->getLeader()); return; } else if ( code == CantInvite ) { CCharacter::sendDynamicSystemMessage( leader->getId(),"LEAGUE_INVITOR_NOT_LEADER" ); return; } /// the invitor must not be in the ignore list of the target if(invitedPlayer->hasInIgnoreList(leaderId)) { SM_STATIC_PARAMS_1( params1, STRING_MANAGER::player ); params1[0].setEIdAIAlias( targetId, CAIAliasTranslator::getInstance()->getAIAlias( targetId) ); // Use the standard "player declines your offer". Don't use specific message because // maybe not a good idea to inform a player that someone ignores him CCharacter::sendDynamicSystemMessage( leaderId, "TEAM_DECLINE", params1 ); return; } //set the target's invitor invitedPlayer->setLeagueInvitor(leaderId); CEntityId msgTargetEId = targetId; //send the appropriate string to the client SM_STATIC_PARAMS_1(params, STRING_MANAGER::player); params[0].setEIdAIAlias( leaderId, CAIAliasTranslator::getInstance()->getAIAlias(leaderId) ); uint32 txt = STRING_MANAGER::sendStringToClient(TheDataset.getDataSetRow(targetId), "LEAGUE_PROPOSAL", params ); CMessage msgout( "IMPULSION_ID" ); msgout.serial( const_cast<CEntityId&>(msgTargetEId) ); CBitMemStream bms; nlverify ( GenericMsgManager.pushNameToStream( "PVP_CHALLENGE:INVITATION", bms) ); bms.serial( txt ); msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length()); sendMessageViaMirror( NLNET::TServiceId(msgTargetEId.getDynamicId()), msgout ); params[0].setEIdAIAlias( targetId, CAIAliasTranslator::getInstance()->getAIAlias( targetId ) ); PHRASE_UTILITIES::sendDynamicSystemMessage(leader->getEntityRowId(), "LEAGUE_INVITE", params); leader->updateTarget(); }
//--------------------------------------------------- // removeCharacter : //--------------------------------------------------- void CTeamManager::removeCharacter( const CEntityId &charId ) { CCharacter * player = PlayerManager.getOnlineChar( charId ); if ( player == NULL ) { nlwarning("<CTeamManager removeCharacter> Player %s is invalid", charId.toString().c_str() ); return; } player->setAfkState(false); CTeam * team = getRealTeam( player->getTeamId() ); if ( team == NULL ) { nlwarning("<CTeamManager removeCharacter> Player %s has an invalid team id %d", charId.toString().c_str(), player->getTeamId() ); return; } uint16 nbMembers = team->getTeamSize(); // send message to former member SM_STATIC_PARAMS_1(params, STRING_MANAGER::player); if (nbMembers > 2) { if (charId != team->getLeader()) { params[0].setEIdAIAlias( team->getLeader(), CAIAliasTranslator::getInstance()->getAIAlias(team->getLeader()) ); PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset.getDataSetRow(charId), "TEAM_YOU_LEAVE", params); } else { const list<CEntityId> &members = team->getTeamMembers(); CEntityId eId(team->getSuccessor()); params[0].setEIdAIAlias( eId, CAIAliasTranslator::getInstance()->getAIAlias(eId) ); PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset.getDataSetRow(charId), "TEAM_YOU_LEAVE_LEADER", params); } } else if(nbMembers==2) { params[0].setEIdAIAlias( team->getLeader(), CAIAliasTranslator::getInstance()->getAIAlias(team->getLeader()) ); PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset.getDataSetRow(charId), "TEAM_YOU_LEAVE_DISOLVE", params); } // send message to all other team members params[0].setEIdAIAlias( charId, CAIAliasTranslator::getInstance()->getAIAlias(charId) ); set<CEntityId> exclude; exclude.insert( charId ); team->sendDynamicMessageToMembers("TEAM_LEAVE", params, exclude); // remove the player from his team team->removeCharacter( player ); /* TGroupId groupId =CHAT_GROUPS_IDS::getTeamChatGroupId(player->getTeamId()); string msgName = "OPS_LEAVE_TEAM_E"; CMessage msggroup("STATIC_STRING"); msggroup.serial( groupId ); std::set<CEntityId> exclude; exclude.insert( charId ); msggroup.serialCont( exclude); msggroup.serial( msgName ); msggroup.serial( (CEntityId&) charId ); sendMessageViaMirror( "IOS", msggroup ); */ } // removeCharacter //
//--------------------------------------------------- // kickCharacter : //--------------------------------------------------- void CTeamManager::kickCharacter( CCharacter * leader, uint8 memberIndex ) { // check must be done before nlassert(leader); const NLMISC::CEntityId & leaderId = leader->getId(); // get the leader's team CTeam * team = getRealTeam( leader->getTeamId() ); if ( team == NULL ) { nlwarning("<CTeamManager kickCharacter> Player %s has an invalid team id %d", leaderId.toString().c_str(), leader->getTeamId() ); return; } // only leaders can kick if ( leaderId != team->getLeader() ) { nlwarning("<CTeamManager kickCharacter> Player %s tries kicking but is not the leader", leaderId.toString().c_str() ); return; } // increment the target index as the leader is not in its team list memberIndex++; const std::list< NLMISC::CEntityId > & members = team->getTeamMembers(); std::list< NLMISC::CEntityId >::const_iterator it = members.begin(); uint i = 0; for (; i < memberIndex; i++ ) { if ( it == members.end() ) { nlwarning("<CTeamManager kickCharacter> Player %s kicks teammate %d but there are %d members", leaderId.toString().c_str(), memberIndex,i+1 ); return; } ++it; } if ( it == members.end() ) { nlwarning("<CTeamManager kickCharacter> Player %s kicks teammate %d but there are %d members", leaderId.toString().c_str(), memberIndex,i+1 ); return; } CCharacter * kickedChar = PlayerManager.getOnlineChar( (*it) ); if ( kickedChar == NULL ) { nlwarning("<CTeamManager kickCharacter> kicked Player %d is invalid", memberIndex ); return; } // inform the kicked player SM_STATIC_PARAMS_1(params, STRING_MANAGER::player); params[0].setEIdAIAlias( leaderId, CAIAliasTranslator::getInstance()->getAIAlias( leaderId ) ); PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset.getDataSetRow(*it), "TEAM_KICKED_YOU", params); // inform other team members params[0].setEIdAIAlias( *it, CAIAliasTranslator::getInstance()->getAIAlias( *it ) ); set<CEntityId> exclude; exclude.insert(*it); team->sendDynamicMessageToMembers("TEAM_KICKED", params, exclude); // remove the kicked player from team team->removeCharacter( kickedChar ); leader->updateTarget(); /* TGroupId groupId = CEntityId(RYZOMID::chatGroup, leader->getTeamId() + 1); string msgName = "OPS_KICKED_TEAM_E"; CMessage msggroup("STATIC_STRING"); msggroup.serial( groupId ); std::set<CEntityId> exclude; exclude.insert(*it); msggroup.serialCont( exclude); msggroup.serial( msgName ); msggroup.serial( (CEntityId&)(*it) ); sendMessageViaMirror( "IOS", msggroup ); */ CMissionManager::getInstance()->updateEscortTeam( kickedChar->getId() ); }// kickCharacter