void CTeam::rewardSharing(CRewardSharing * reward) { // if there is a reward add the new it if ( _RewardSharing ) { _RewardSharing->addReward(reward,this); } // otherwise, create a new one else { _RewardSharing = reward; for (list<CEntityId>::const_iterator it = _TeamMembers.begin() ; it != _TeamMembers.end() ; ++it) { CCharacter * user = PlayerManager.getOnlineChar( (*it) ); if (user ) { CMessage msgout ("IMPULSION_ID"); msgout.serial ((CEntityId&)(*it)); CBitMemStream bms; if (!GenericMsgManager.pushNameToStream ("TEAM:SHARE_OPEN", bms)) nlstopex (("Missing TEAM:SHARE_OPEN in msg.xml")); msgout.serialBufferWithSize ((uint8*)bms.buffer(), bms.length()); sendMessageViaMirror ( NLNET::TServiceId((*it).getDynamicId()), msgout); } } _RewardSharing->resetCandidates(this); } }// CTeam::rewardSharing
//----------------------------------------------- // chat // //----------------------------------------------- void CClientChatManager::chat( const ucstring& strIn, bool isChatTeam ) { // Truncate to 255 chars max (because of server restriction) ucstring str= strIn.substr(0,255); // send str to IOS CBitMemStream bms; string msgType; if (isChatTeam) { if (NLGUI::CDBManager::getInstance()->getDbProp("SERVER:GROUP:0:PRESENT")->getValueBool()) msgType = "STRING:CHAT_TEAM"; else return; // don't display team chat message if there is no team chat } else msgType = "STRING:CHAT"; if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) ) { bms.serial( str ); NetMngr.push( bms ); //nlinfo("impulseCallBack : %s %s sent", msgType.c_str(), str.toString().c_str()); } else { nlwarning("<CClientChatManager::chat> unknown message name : %s", msgType.c_str()); } if (UserEntity != NULL) UserEntity->setAFK(false); } // chat //
// *************************************************************************** void CGuildManager::launchAscensor() { // Start the huge list exchange Ascensors.start(); // Increment session id Ascensors.incrementSessionID(); // Send request of the first page to the server specifying the session id CBitMemStream out; if(GenericMsgHeaderMngr.pushNameToStream("GUILD:FIRST_ASCENSOR_PAGE", out)) { uint16 session = Ascensors.getSessionID(); out.serial(session); NetMngr.push(out); //nlinfo("impulseCallBack : GUILD:FIRST_ASCENSOR_PAGE %d sent",session); } else { nlwarning("impulseCallBack : unknown message name : 'GUILD:FIRST_ASCENSOR_PAGE'."); } // Start Ascensor Interface CInterfaceManager *pIM = CInterfaceManager::getInstance(); CGroupContainer *pAC = dynamic_cast<CGroupContainer*>(pIM->getElementFromId(WIN_ASCENSOR)); if (pAC == NULL) return; pAC->setActive(true); pIM->setTopWindow(pAC); }
/* * Push one change to the stream */ void CCDBSynchronised::pushDelta( CBitMemStream& s, CCDBStructNodeLeaf *node, uint32& bitsize ) { TCDBDataIndex index = node->getDataIndex(); // Test if the property type is valid. if ( node->type() > ICDBStructNode::UNKNOWN && node->type() < ICDBStructNode::Nb_Prop_Type ) { // Serialize the Property Value according to the Property Type. uint64 value; value = (uint64)_DataContainer.getValue64( index ); //_DataContainer.archiveCurrentValue( index ); if ( node->type() == ICDBStructNode::TEXT ) { s.serialAndLog2( value, 32 ); bitsize += 32; if ( VerboseDatabase ) nldebug( "CDB: Pushing value %"NL_I64"d (TEXT-32) for index %d prop %s", (sint64)value, index, node->buildTextId().toString().c_str() ); } else { s.serialAndLog2( value, (uint)node->type() ); bitsize += (uint32)node->type(); if ( VerboseDatabase ) nldebug( "CDB: Pushing value %"NL_I64"d (%u bits) for index %d prop %s", (sint64)value, (uint32)node->type(), index, node->buildTextId().toString().c_str() ); } } else nlwarning("CCDBStructNodeLeaf::writeDelta : Property Type Unknown ('%d') -> not serialized.", (uint)node->type()); }
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) { CInterfaceManager *pIM= CInterfaceManager::getInstance(); // Copy SERVER DB to Local selection uint32 outpostSheet= 0; CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:TARGET:CONTEXT_MENU:OUTPOST"); if(node) outpostSheet= node->getValue32(); node= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:BOT_SELECTION"); if(node) node->setValue32(outpostSheet); // Send a msg to server if(outpostSheet) { string sMsg= "OUTPOST:SELECT"; CBitMemStream out; if(GenericMsgHeaderMngr.pushNameToStream(sMsg, out)) { //nlinfo("impulseCallBack : %s %d sent", sMsg.c_str(), outpostSheet); out.serial(outpostSheet); NetMngr.push(out); } else { nlwarning("command : unknown message name : '%s'.", sMsg.c_str()); } } }
//----------------------------------------------- // setChatMode // //----------------------------------------------- void CClientChatManager::setChatMode(CChatGroup::TGroupType group, TChanID dynamicChannelId) { uint8 mode = group; // mode really changed ? if (mode == _ChatMode && dynamicChannelId==_ChatDynamicChannelId) return; // Chat team don't need swap mode if (group != CChatGroup::team) { CBitMemStream bms; string msgType = "STRING:CHAT_MODE"; if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) ) { bms.serial( mode ); bms.serial( dynamicChannelId ); NetMngr.push( bms ); //nlinfo("impulseCallBack : %s %d sent", msgType.c_str(), mode); } else { nlwarning("<CClientChatManager::setChatMode> unknown message name : STRING:CHAT_MODE"); } } // update cache _ChatMode = mode; _ChatDynamicChannelId = dynamicChannelId; if (UserEntity != NULL) UserEntity->setAFK(false); } // filter //
//----------------------------------------------- // tell // //----------------------------------------------- void CClientChatManager::tell( const string& receiverIn, const ucstring& strIn ) { // Truncate to 255 chars max (because of server restriction) string receiver= receiverIn.substr(0,255); ucstring str= strIn.substr(0,255); // *** send str CBitMemStream bms; string msgType = "STRING:TELL"; if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) ) { bms.serial( receiver ); bms.serial( str ); NetMngr.push( bms ); //nlinfo("impulseCallBack : %s %s %s sent", msgType.c_str(), receiver.c_str(), str.toString().c_str()); } else { nlwarning("<CClientChatManager::tell> unknown message name : STRING:TELL"); } // *** manage list of last telled people // remove the telled people from list (if present) std::list<ucstring>::iterator it = _TellPeople.begin(); while(it != _TellPeople.end()) { if (*it == ucstring(receiver)) { it = _TellPeople.erase(it); nlassert(_NumTellPeople != 0); -- _NumTellPeople; } else { ++it; } } // readd to back of the list (most recent telled people) _TellPeople.push_back(receiver); ++ _NumTellPeople; // if too much people, remove the older one if (_NumTellPeople > _MaxNumTellPeople) { -- _NumTellPeople; _TellPeople.pop_front(); } // tell => the user is no more AFK. if (UserEntity != NULL) UserEntity->setAFK(false); } // tell //
void CImpulseDecoder::decode(CBitMemStream &inbox, TPacketNumber receivedPacket, TPacketNumber receivedAck, TPacketNumber nextSentPacket, vector<CLFECOMMON::CAction *> &actions) { uint level; for (level=0; level<3; ++level) { TPacketNumber *lAck; uint channel; switch (level) { case 0: lAck = _LastAck0; channel = 0; break; case 1: lAck = _LastAck1; channel = receivedPacket&1; break; case 2: lAck = _LastAck2; channel = receivedPacket&3; break; } bool keep = true; bool checkOnce = false; uint num = 0; TPacketNumber lastAck = lAck[channel]; for(;;) { bool next; inbox.serial(next); if (!next) break; if (!checkOnce) { checkOnce = true; keep = (receivedAck >= lAck[channel]); if (keep) lAck[channel] = nextSentPacket; } ++num; CAction *action = CActionFactory::getInstance()->unpack(inbox, false); if (keep) { actions.push_back(action); nlinfo("CLIMPD: received new impulsion %d (len=%u) at level %d (channel %d)", action->Code, CActionFactory::getInstance()->size(action), level, channel, num, (keep) ? "" : " (discarded)", lastAck, nextSentPacket); } else { nlinfo("CLIMPD: discarded action %d (len=%u) at level %d (channel %d)", action->Code, CActionFactory::getInstance()->size(action), level, channel, num, (keep) ? "" : " (discarded)", lastAck, nextSentPacket); CActionFactory::getInstance()->remove(action); } } if (checkOnce) nldebug("CLIMPD: at level %d (channel %d), %d actions%s (ReceivedAck=%d/lastAck=%d/nextSentPacket=%d)", level, channel, num, (keep) ? "" : " (discarded)", receivedAck, lastAck, nextSentPacket); } }
//----------------------------------------------- // filter // //----------------------------------------------- void CClientChatManager::filter( uint8 filter ) { CBitMemStream bms; string msgType = "STRING:FILTER"; if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) ) { bms.serial( filter ); NetMngr.push( bms ); //nlinfo("impulseCallBack : %s %d sent", msgType.c_str(), filter); } else { nlwarning("<CClientChatManager::filter> unknown message name : STRING:FILTER"); } if (UserEntity != NULL) UserEntity->setAFK(false); } // filter //
// *************************************************************************** void COutpostManager::endPvpJoinProposal(bool bNeutral, OUTPOSTENUMS::TPVPSide pvpSide) { // send msg string sMsg= "OUTPOST:SIDE_CHOSEN"; CBitMemStream out; if(GenericMsgHeaderMngr.pushNameToStream(sMsg, out)) { //nlinfo("impulseCallBack : %s %d %s sent", sMsg.c_str(), bNeutral, OUTPOSTENUMS::toString(pvpSide).c_str()); out.serial(bNeutral); uint8 sideAsInt = (uint8)pvpSide; out.serial(sideAsInt); NetMngr.push(out); } else { nlwarning("command : unknown message name : '%s'.", sMsg.c_str()); } // Abort any timer _EndTickForPvpJoinProposal= 0; }
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) { CInterfaceManager *pIM= CInterfaceManager::getInstance(); // read current outpost sheet uint32 outpostSheet= 0; CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:OUTPOST_SELECTED:SHEET", false); if(node) outpostSheet= node->getValue32(); // read wanted GMT attack period uint8 wantedAttHour= 0; node= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:DECLARE_WAR_ATTACK_PERIOD", false); if(node) wantedAttHour= (uint8)node->getValue32(); // read result Att Period Time (NB: for final server check: ensure that the user will get what it sees) uint32 startAttackTime= 0; node= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:DECLARE_WAR_ACK_TIME_RANGE_ATT", false); if(node) startAttackTime= node->getValue32(); // send a DECLARE_WAR_VALIDATE message to server string sMsg= "OUTPOST:DECLARE_WAR_VALIDATE"; CBitMemStream out; if(GenericMsgHeaderMngr.pushNameToStream(sMsg, out)) { //nlinfo("impulseCallBack : %s %d %d %d sent", sMsg.c_str(), outpostSheet, wantedAttHour, startAttackTime); out.serial(outpostSheet); out.serial(wantedAttHour); out.serial(startAttackTime); NetMngr.push(out); } else { nlwarning("command : unknown message name : '%s'.", sMsg.c_str()); } }
//----------------------------------------------- // readDelta // //----------------------------------------------- void CCDBSynchronised::readDelta( NLMISC::TGameCycle gc, CBitMemStream& s, TCDBBank bank ) { nldebug("Update DB"); if( _Database == 0 ) { nlwarning("<CCDBSynchronised::readDelta> the database has not been initialized"); return; } //displayBitStream2( f, f.getPosInBit(), f.getPosInBit() + 64 ); uint16 propertyCount = 0; s.serial( propertyCount ); if ( VerboseDatabase ) nlinfo( "CDB: Reading delta (%hu changes)", propertyCount ); NbDatabaseChanges += propertyCount; for( uint i=0; i!=propertyCount; ++i ) { _Database->readAndMapDelta( gc, s, bank ); } /*// Read "client only" property changes bool hasCOPropChanges; s.serialBit( hasCOPropChanges ); if ( hasCOPropChanges ) { uint32 nbCOPropChanges; s.serial( nbCOPropChanges, 4 ); if ( nbCOPropChanges == 15 ) { s.serial( nbCOPropChanges ); } for ( uint i=0; i!=nbCOPropChanges; ++i ) { string propName; //TEMP sint64 value; //TEMP s.serial( propName ); s.serial( value ); setProp( propName, value ); } }*/ } // readDelta //
//----------------------------------------------- // readDelta //----------------------------------------------- void CCDBNodeLeaf::readDelta(TGameCycle gc, CBitMemStream & f ) { // If the property Type is valid. if(_Type > UNKNOWN && _Type < Nb_Prop_Type) { // Read the Property Value according to the Property Type. uint64 recvd = 0; uint bits; if (_Type == TEXT) bits = 32; else if (_Type <= I64) bits = _Type; else bits = _Type - 64; f.serial(recvd, bits); // if the DB update is older than last DB update, abort (but after the read!!) if(gc<_LastChangeGC) return; // bkup _oldProperty _oldProperty = _Property; // setup new one _Property = (sint64)recvd; // if signed if (! ((_Type == TEXT) || (_Type <= I64))) { // extend bit sign sint64 mask = (((sint64)1)<<bits)-(sint64)1; if( (_Property >> (bits-1))==1 ) { _Property |= ~mask; } }
//--------------------------------------------------- // 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(); }
//----------------------------------------------- // getString // //----------------------------------------------- ucstring CClientChatManager::getString( CBitMemStream& bms, ucstring& ucstr ) { // deal with parameters uint32 dynParamIdx = 0; bool dynParamSearch = true; char chTmp[1024]; while( dynParamSearch ) { // search if a parameter exists in the string sprintf(chTmp,"$%d",dynParamIdx); ucstring ucstrTmp( chTmp ); ucstring::size_type idx = ucstr.find(ucstrTmp); // if there's a parameter in the string if( idx != ucstring::npos ) { char c = (char)ucstr[idx+ucstrTmp.size()]; switch( c ) { // parameter is an entry in the dynamic database case 'e': { bool huff; bms.serialBit(huff); const ucstring dynStr("???"); if( huff ) { nldebug("<CClientChatManager::getString> receiving huffman dynamic parameter in static string"); // #ifdef OLD_STRING_SYSTEM // _DynamicDB.decodeString( dynStr, bms ); // #endif } else { //if( (sint32)bms.length()*8 - bms.getPosInBit() >= 32 ) { uint32 nameIndex; bms.serial(nameIndex); // #ifdef OLD_STRING_SYSTEM // dynStr = _DynamicDB.getDynamicStringInfos(nameIndex)->Str; // #endif } } ucstr.replace( idx, ucstrTmp.size()+1, dynStr ); } break; // parameter is a string case 's': { string dynStr; bms.serial( dynStr ); ucstring ucDynStr(dynStr); ucstr.replace( idx, ucstrTmp.size()+1, ucDynStr ); } break; // parameter is an unsigned integer case 'u': { uint32 nb; bms.serial( nb ); ucstr.replace( idx, ucstrTmp.size()+1, ucstring(toString(nb)) ); } break; /* case 'u': { uint i = idx + strTmp.size() + 1; string bitCountStr; while( isdigit(str[i]) ) { bitCountStr += str[i]; i++; } nlassert( !bitCountStr.empty() ); uint32 bitCount; fromString(bitCountStr, bitCount); nlassert( bitCount <= 64 ); uint64 nb; bms.serial( nb, bitCount ); str.replace( idx, strTmp.size() + 1 + bitCountStr.size(), toString(nb) ); } break; */ // parameter is a signed integer case 'i': { sint32 nb; bms.serial( nb ); ucstr.replace( idx, ucstrTmp.size()+1, ucstring(toString(nb)) ); } break; /* case 'i': { uint i = idx + strTmp.size() + 1; string bitCountStr; while( isdigit(str[i]) ) { bitCountStr += str[i]; i++; } nlassert( !bitCountStr.empty() ); uint32 bitCount; fromString(bitCountStr, bitCount); nlassert( bitCount <= 64 ); uint64 nb; bms.serial( nb, bitCount ); str.replace( idx, strTmp.size() + 1 + bitCountStr.size(), toString(nb) ); } break; */ // parameter is a float case 'f': { float nb; bms.serial( nb ); ucstr.replace( idx, ucstrTmp.size()+1, ucstring(toString(nb)) ); } break; // parameter type is unknown default : { nlwarning("<CClientChatManager::getString> The dynamic type %c is unknown",c); } } dynParamIdx++; } else { dynParamSearch = false; } }; return ucstr; } // getString //
//----------------------------------------------- // writeDelta // //----------------------------------------------- bool CCDBSynchronised::writeDelta( CBitMemStream& s, uint32 maxBitSize ) { //if ( ! _DataStructRoot ) // nlwarning("<CCDBSynchronised::writeDelta> the database has not been initialized"); // return; // Test the changed property count and make room to store the number of property pushed (poked later) uint origChangedPropertyCount = getChangedPropertyCount(); if ( origChangedPropertyCount == 0 ) return false; uint bitposOfNbChanges = s.getPosInBit(); uint32 dummy = 0; s.serial( dummy, CDBChangedPropertyCountBitSize ); // optimising s.reserveBits( CDBChangedPropertyCountBitSize ) // Browse changes and write them uint32 bitsize = CDBChangedPropertyCountBitSize; // initialize with the size of the reserved bits for the number of changes TCDBDataIndex dataIndex; while ( ((dataIndex = _DataContainer.getFirstChanged()) != CDB_LAST_CHANGED) && (bitsize < maxBitSize) ) { // Retrieve the structure node corresponding to the index ICDBStructNode *node = CCDBStructBanks::instance()->getNodeFromDataIndex( _Bank, dataIndex ); nlassert( node ); if ( node->isAtomic() ) // counts for 1 change { #ifdef NL_DEBUG nlassert( dynamic_cast<CCDBStructNodeBranch*>(node) ); // should not be leaf because the main tracker pushes the atom group index for atomic leaves #endif // Build and push the binary atom id ICDBStructNode::CBinId binId; (static_cast<CCDBStructNodeBranch*>(node))->buildBinIdFromLeaf( binId ); bitsize += binId.writeToBitMemStream( s ); //nlinfo( "CDB/ATOM: Written bin id %s", binId.toString().c_str() ); //_DataContainer.displayAtomChanges( node->getDataIndex() ); // Make room to store the atom bitfield uint bitposOfAtomBitfield = s.getPosInBit(); uint indexInAtom = 0; node->foreachLeafCall( cbNop, indexInAtom, NULL ); // count the number of siblings uint nbAtomElements = indexInAtom; s.reserveBits( nbAtomElements ); bitsize += nbAtomElements; //nlinfo( "CDB/ATOM: Reserved %u bits (%d)", nbAtomElements, s.getPosInBit()-bitposOfAtomBitfield ); // Browse the siblings of the atom node, and push the deltas for the properties marked as changes, updating the bitfield TPushAtomChangeStruct arg; arg.CdbSync = this; arg.BitSize = &bitsize; arg.S = &s; arg.AtomBitfield.resize( nbAtomElements ); indexInAtom = 0; node->foreachLeafCall( cbPushDeltaOfLeafInAtomIfChanged, indexInAtom, (void*)&arg ); // Fill the placeholder with the bitfield s.pokeBits( arg.AtomBitfield, bitposOfAtomBitfield ); if ( VerboseDatabase ) { nldebug( "CDB/ATOM: Bitfield: %s", arg.AtomBitfield.toString().c_str() ); } // Pop the changes out of the tracker TCDBDataIndex atomGroupIndex = node->getDataIndex(); TCDBDataIndex leafDataIndex; while ( (leafDataIndex = _DataContainer.popChangedIndexInAtom( atomGroupIndex )) != CDB_LAST_CHANGED ); } else { #ifdef NL_DEBUG nlassert( dynamic_cast<CCDBStructNodeLeaf*>(node) ); #endif // Push the binary property id bitsize += static_cast<CCDBStructNodeLeaf*>(node)->binLeafId().writeToBitMemStream( s ); // Push the value pushDelta( s, static_cast<CCDBStructNodeLeaf*>(node), bitsize ); } _DataContainer.popFirstChanged(); } // Fill the placeholder with the number of changes uint32 nbChanges = origChangedPropertyCount - getChangedPropertyCount(); s.poke( nbChanges, bitposOfNbChanges, CDBChangedPropertyCountBitSize ); //s.displayStream( "writeDelta" ); NbDatabaseChanges += nbChanges; // Check if all has been popped _DataContainer.quickCleanChanges(); _NotSentYet = false; #ifdef TRACE_SET_VALUE if ( VerboseDatabase ) nldebug( "%u: CDB: Delta pushed (%u changes written, %u remaining)", CTickEventHandler::getGameCycle(), nbChanges, getChangedPropertyCount() ); #endif return true; } // writeDelta //
//--------------------------------------------------- // CTeam addCharacter //--------------------------------------------------- void CTeam::addCharacter(CCharacter *newCharacter) { // check already done nlassert(newCharacter); // init new character DB // newCharacter->_PropertyDatabase.setProp( "USER:TEAM_MEMBER", 1 ); CBankAccessor_PLR::getUSER().setTEAM_MEMBER(newCharacter->_PropertyDatabase, true); // newCharacter->_PropertyDatabase.setProp( "USER:TEAM_LEADER", 0 ); CBankAccessor_PLR::getUSER().setTEAM_LEADER(newCharacter->_PropertyDatabase, false); // newCharacter->_PropertyDatabase.setProp( "GROUP:LEADER_INDEX", 0 ); CBankAccessor_PLR::getGROUP().setLEADER_INDEX(newCharacter->_PropertyDatabase, 0); if ( _TeamMembers.size() == 1 ) { _SuccessorId = newCharacter->getId(); // newCharacter->_PropertyDatabase.setProp( "GROUP:SUCCESSOR_INDEX", -1 ); CBankAccessor_PLR::getGROUP().setSUCCESSOR_INDEX(newCharacter->_PropertyDatabase, 0xf); } else { // newCharacter->_PropertyDatabase.setProp( "GROUP:SUCCESSOR_INDEX", 1 ); CBankAccessor_PLR::getGROUP().setSUCCESSOR_INDEX(newCharacter->_PropertyDatabase, 1); } // update all member's DB // char buffer[256]; uint position = (uint)_TeamMembers.size()-1; uint i =0; for (std::list<CEntityId>::const_iterator it = _TeamMembers.begin() ; it != _TeamMembers.end() ; ++it) { uint8 hp, sap, stamina; uint32 nameId; CCharacter* character = PlayerManager.getOnlineChar( (*it) ); if (character != NULL) { // update the current character team slot ///\todo: can be done outside the loop if ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max != 0) hp = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Current ) ) / ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max ) ); else hp = 0; if ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::sap ].Max != 0) sap = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::sap ].Current ) ) / ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::sap ].Max ) ); else sap = 0; if ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max != 0) stamina = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::stamina ].Current ) ) / ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max ) ); else stamina = 0; CMirrorPropValueRO<uint32> nameIndexValue1( TheDataset, newCharacter->getId(), "NameIndex" ); nameId = nameIndexValue1(); CBankAccessor_PLR::TGROUP::TArray &arrayItem = CBankAccessor_PLR::getGROUP().getArray(position); // sprintf(buffer, "GROUP:%d:HP",position ); // character->_PropertyDatabase.setProp( buffer, hp ); arrayItem.setHP(character->_PropertyDatabase, hp); // sprintf(buffer, "GROUP:%d:SAP",position ); // character->_PropertyDatabase.setProp( buffer, sap ); arrayItem.setSAP(character->_PropertyDatabase, sap); // sprintf(buffer, "GROUP:%d:STA",position ); // character->_PropertyDatabase.setProp( buffer, stamina ); arrayItem.setSTA(character->_PropertyDatabase, stamina); // sprintf(buffer, "GROUP:%d:NAME",position ); // character->_PropertyDatabase.setProp( buffer, nameId ); arrayItem.setNAME(character->_PropertyDatabase, nameId); // sprintf(buffer, "GROUP:%d:UID",position ); // character->_PropertyDatabase.setProp( buffer, newCharacter->getEntityRowId().getCompressedIndex() ); arrayItem.setUID(character->_PropertyDatabase, newCharacter->getEntityRowId().getCompressedIndex()); // sprintf(buffer, "GROUP:%d:PRESENT",position ); // character->_PropertyDatabase.setProp( buffer, (uint8)1 ); arrayItem.setPRESENT(character->_PropertyDatabase, true); // update the new character team slot corresponding to character if ( character->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max != 0) hp = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( character->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Current ) ) / ( character->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max ) ); else hp = 0; if ( character->getPhysScores()._PhysicalScores[ SCORES::sap ].Max != 0) sap = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( character->getPhysScores()._PhysicalScores[ SCORES::sap ].Current ) ) / ( character->getPhysScores()._PhysicalScores[ SCORES::sap ].Max ) ); else sap = 0; if ( character->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max != 0) stamina = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( character->getPhysScores()._PhysicalScores[ SCORES::stamina ].Current ) ) / ( character->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max ) ); else stamina = 0; CMirrorPropValueRO<uint32> nameIndexValue2( TheDataset, character->getId(), "NameIndex" ); nameId = nameIndexValue2(); CBankAccessor_PLR::TGROUP::TArray &newArrayItem = CBankAccessor_PLR::getGROUP().getArray(i); // sprintf(buffer, "GROUP:%d:HP",i ); // newCharacter->_PropertyDatabase.setProp( buffer, hp ); newArrayItem.setHP(newCharacter->_PropertyDatabase, hp); // sprintf(buffer, "GROUP:%d:SAP",i ); // newCharacter->_PropertyDatabase.setProp( buffer, sap ); newArrayItem.setSAP(newCharacter->_PropertyDatabase, sap); // sprintf(buffer, "GROUP:%d:STA",i ); // newCharacter->_PropertyDatabase.setProp( buffer, stamina ); newArrayItem.setSTA(newCharacter->_PropertyDatabase, stamina); // sprintf(buffer, "GROUP:%d:NAME",i ); // newCharacter->_PropertyDatabase.setProp( buffer, nameId ); newArrayItem.setNAME(newCharacter->_PropertyDatabase, nameId); // sprintf(buffer, "GROUP:%d:UID",i ); // newCharacter->_PropertyDatabase.setProp( buffer, character->getEntityRowId().getCompressedIndex() ); newArrayItem.setUID(newCharacter->_PropertyDatabase, character->getEntityRowId().getCompressedIndex()); // sprintf(buffer, "GROUP:%d:PRESENT",i ); // newCharacter->_PropertyDatabase.setProp( buffer, (uint8)1 ); newArrayItem.setPRESENT(newCharacter->_PropertyDatabase, true); } else nlwarning("<CTeam::addCharacter> Unknown character %s", (*it).toString().c_str() ); ++i; } // insert new member _TeamMembers.push_back( newCharacter->getId() ); ++_NbMembers; // set the character team newCharacter->setTeamId(_TeamId); // Add character to chat group TGroupId idGroupe = CHAT_GROUPS_IDS::getTeamChatGroupId(_TeamId); CMessage msgout("ADD_TO_GROUP"); msgout.serial( idGroupe ); msgout.serial( const_cast<CEntityId&> (newCharacter->getId()) ); sendMessageViaMirror( "IOS", msgout ); // send messages to members SM_STATIC_PARAMS_1(params, STRING_MANAGER::player); // to new member //CCharacter::sendMessageToClient(newCharacter->getId(),"OPS_JOIN_TEAM_E",_LeaderId); params[0].setEId( _LeaderId ); PHRASE_UTILITIES::sendDynamicSystemMessage(newCharacter->getEntityRowId(), "TEAM_YOU_JOIN", params); params[0].setEIdAIAlias( newCharacter->getId(), CAIAliasTranslator::getInstance()->getAIAlias( newCharacter->getId()) ); set<CEntityId> exclude; exclude.insert( newCharacter->getId() ); this->sendDynamicMessageToMembers("TEAM_ACCEPT",params,exclude); // update the reward share if needed if ( _RewardSharing ) { CMessage msgout ("IMPULSION_ID"); msgout.serial ((CEntityId&)(newCharacter->getId())); CBitMemStream bms; if (!GenericMsgManager.pushNameToStream ("TEAM:SHARE_OPEN", bms)) nlstopex (("Missing TEAM:SHARE_OPEN in msg.xml")); msgout.serialBufferWithSize ((uint8*)bms.buffer(), bms.length()); sendMessageViaMirror ( NLNET::TServiceId(newCharacter->getId().getDynamicId()), msgout); _RewardSharing->resetCandidates(this); } // update positions updateMembersPositions(true); /*TGroupId groupId = TGroupId idGroupe = CHAT_GROUPS_IDS::getTeamChatGroupId(_TeamId); string msgName = "OPS_JOIN_TEAM_ACCEPT_E"; CMessage msggroup("STATIC_STRING"); msggroup.serial( groupId ); msggroup.serialCont( exclude); msggroup.serial( msgName ); msggroup.serial( const_cast<CEntityId&>(newCharacter->getId()) ); sendMessageViaMirror( "IOS", msggroup ); */ // tell progression system this player has joigned this team PROGRESSIONPVE::CCharacterProgressionPVE::getInstance()->playerJoinsTeam(newCharacter->getId(), _TeamId); PROGRESSIONPVP::CCharacterProgressionPVP::getInstance()->playerJoinsTeam(newCharacter, _TeamId); newCharacter->updateTargetingChars(); }// CTeam addCharacter
//--------------------------------------------------- // CTeam removeCharacter //--------------------------------------------------- void CTeam::removeCharacter( CCharacter * player ) { // check already done nlassert(player); const CEntityId & charId = player->getId(); uint16 teamId = player->getTeamId(); // check if the character is in the team and remove him uint formerPos = 0; bool found = false; for ( std::list<NLMISC::CEntityId>::iterator it = _TeamMembers.begin(); it != _TeamMembers.end(); ++it ) { if ( charId == *it ) { clearPlayerTeamDB(charId); _TeamMembers.erase(it); --_NbMembers; found = true; break; } formerPos++; } if ( !found ) { nlwarning("<CTeam removeCharacter> charId %s not found in the team", charId.toString().c_str() ); return; } if ( _RewardSharing ) { CMessage msgout ("IMPULSION_ID"); msgout.serial ((CEntityId&)(player->getId())); CBitMemStream bms; if (!GenericMsgManager.pushNameToStream ("TEAM:SHARE_CLOSE", bms)) nlstopex (("Missing TEAM:SHARE_CLOSE in msg.xml")); msgout.serialBufferWithSize ((uint8*)bms.buffer(), bms.length()); sendMessageViaMirror (NLNET::TServiceId(player->getId().getDynamicId()), msgout); _RewardSharing->resetCandidates(this); } ///\todo give him a player team Id player->setTeamId( CTEAM::InvalidTeamId ); player->updateTargetingChars(); // tell progression system this player has been removed from his team PROGRESSIONPVE::CCharacterProgressionPVE::getInstance()->playerLeavesTeam(charId, _TeamId); PROGRESSIONPVP::CCharacterProgressionPVP::getInstance()->playerLeavesTeam(player, _TeamId); if ( player->getPVPInterface().isValid() ) player->getPVPInterface().leavePVP( IPVP::QuitTeam ); // check if the team must be removed if ( _NbMembers == 1 ) { const uint size = (uint)_Missions.size(); uint count = 0; while ( !_Missions.empty() && count < size ) { _Missions[0]->onFailure(true); count++; } // send a message to the last team member PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset.getDataSetRow(_TeamMembers.front()), "TEAM_DISOLVED"); // clear the player DB clearPlayerTeamDB( *_TeamMembers.begin() ); CCharacter * lastPlayer = PlayerManager.getOnlineChar( *_TeamMembers.begin() ); if ( lastPlayer ) lastPlayer->setTeamId( CTEAM::InvalidTeamId ); else { nlwarning("<CTeam removeCharacter> charId %s not found in the team", (*_TeamMembers.begin()).toString().c_str() ); return; } // remove the team chat group TGroupId idGroupe = CHAT_GROUPS_IDS::getTeamChatGroupId(_TeamId); CMessage msgRemoveGroup("REMOVE_GROUP"); msgRemoveGroup.serial( idGroupe ); sendMessageViaMirror( "IOS", msgRemoveGroup ); // release the team release(); //remove the team from the manager TeamManager.removeTeam(teamId); // let the last player continue his escort mission (with a fake team) if he has one CMissionManager::getInstance()->updateEscortTeam( lastPlayer->getId() ); return; } // if that was the leader, get another one else if ( _LeaderId == charId ) { _LeaderId = _SuccessorId; _SuccessorId = CEntityId::Unknown; for (list<CEntityId>::const_iterator it = _TeamMembers.begin(); it != _TeamMembers.end(); ++it) { if ( (*it) != _LeaderId ) { _SuccessorId = (*it ); break; } } // switch dyn chat speaker CMissionManager::getInstance()->switchDynChatSpeaker(player,_LeaderId); // inform the new leader SM_STATIC_PARAMS_1(params1, STRING_MANAGER::player); params1[0].setEId( charId ); PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset.getDataSetRow(_LeaderId), "TEAM_YOU_NEW_LEADER", params1); // inform the group SM_STATIC_PARAMS_2(params, STRING_MANAGER::player, STRING_MANAGER::player); params[0].setEId( charId ); params[1].setEId( _LeaderId ); set<CEntityId> exclude; exclude.insert( _LeaderId ); exclude.insert( charId ); sendDynamicMessageToMembers("TEAM_NEW_LEADER", params, exclude); // update leader DB CCharacter *leader = PlayerManager.getOnlineChar( _LeaderId ); if (leader) { // leader->_PropertyDatabase.setProp( "GROUP:LEADER_INDEX", -1 ); CBankAccessor_PLR::getGROUP().setLEADER_INDEX(leader->_PropertyDatabase, 0xf); // leader->_PropertyDatabase.setProp( "GROUP:SUCCESSOR_INDEX", 0 ); CBankAccessor_PLR::getGROUP().setSUCCESSOR_INDEX(leader->_PropertyDatabase, 0); } else nlwarning("<CTeam removeCharacter> invalid new leader %s", _LeaderId.toString().c_str() ); } // if that was the successor, inform the new one /* else if ( formerPos == 1 && _NbMembers > 2) { list<CEntityId>::iterator itTmp = _TeamMembers.begin(); ++itTmp; const CEntityId & successorId = *(itTmp); CCharacter *successor = PlayerManager.getOnlineChar( successorId ); if (successor) { successor->_PropertyDatabase.setProp( "GROUP:SUCCESSOR_INDEX", -1 ); } else nlwarning("<CTeam removeCharacter> invalid new successor %s", successorId.toString().c_str() ); } */ else if ( _SuccessorId == charId ) { for (list<CEntityId>::const_iterator it = _TeamMembers.begin(); it != _TeamMembers.end(); ++it) { if ( (*it) != _LeaderId ) { _SuccessorId = (*it ); CCharacter *successor = PlayerManager.getOnlineChar( _SuccessorId ); if (successor) { // successor->_PropertyDatabase.setProp( "GROUP:SUCCESSOR_INDEX", -1 ); CBankAccessor_PLR::getGROUP().setSUCCESSOR_INDEX(successor->_PropertyDatabase, 0xf); } break; } } } for (std::list<NLMISC::CEntityId>::iterator it = _TeamMembers.begin() ; it != _TeamMembers.end() ; ++it) { uint8 hp, sap, stamina; uint32 nameId; uint pos = 0; // char buffer[256]; CCharacter * ch1 = PlayerManager.getOnlineChar( (*it) ); ///\todo log if nothing if (ch1) { for (std::list<NLMISC::CEntityId>::iterator it2 = _TeamMembers.begin() ; it2 != _TeamMembers.end() ; ++it2) { if ( (*it) == (*it2) ) continue; CBankAccessor_PLR::TGROUP::TArray &groupItem = CBankAccessor_PLR::getGROUP().getArray(pos); CCharacter * ch2 = PlayerManager.getOnlineChar( (*it2) ); if (ch2 != NULL) { // update new char for old char if ( ch2->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max != 0) hp = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( ch2->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Current ) ) / ( ch2->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max ) ); else hp = 0; if ( ch2->getPhysScores()._PhysicalScores[ SCORES::sap ].Max != 0) sap = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( ch2->getPhysScores()._PhysicalScores[ SCORES::sap ].Current ) ) / ( ch2->getPhysScores()._PhysicalScores[ SCORES::sap ].Max ) ); else sap = 0; if ( ch2->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max != 0) stamina = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( ch2->getPhysScores()._PhysicalScores[ SCORES::stamina ].Current ) ) / ( ch2->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max ) ); else stamina = 0; CMirrorPropValueRO<uint32> nameIndexValue( TheDataset, ch2->getId(), "NameIndex" ); nameId = nameIndexValue(); // sprintf(buffer, "GROUP:%d:HP",pos ); // ch1->_PropertyDatabase.setProp( buffer, hp ); groupItem.setHP(ch1->_PropertyDatabase, hp); // sprintf(buffer, "GROUP:%d:SAP",pos ); // ch1->_PropertyDatabase.setProp( buffer, sap ); groupItem.setSAP(ch1->_PropertyDatabase, sap); // sprintf(buffer, "GROUP:%d:STA",pos ); // ch1->_PropertyDatabase.setProp( buffer, stamina ); groupItem.setSTA(ch1->_PropertyDatabase, stamina); // sprintf(buffer, "GROUP:%d:NAME",pos ); // ch1->_PropertyDatabase.setProp( buffer, nameId ); groupItem.setNAME(ch1->_PropertyDatabase, nameId); // sprintf(buffer, "GROUP:%d:UID",pos ); // ch1->_PropertyDatabase.setProp( buffer, ch2->getEntityRowId().getCompressedIndex() ); groupItem.setUID(ch1->_PropertyDatabase, ch2->getEntityRowId().getCompressedIndex()); // sprintf(buffer, "GROUP:%d:PRESENT",pos ); // ch1->_PropertyDatabase.setProp( buffer, (uint8)1 ); groupItem.setPRESENT(ch1->_PropertyDatabase, true); } pos++; } CBankAccessor_PLR::TGROUP::TArray &groupItem = CBankAccessor_PLR::getGROUP().getArray(pos); // sprintf(buffer, "GROUP:%d:PRESENT",pos ); // ch1->_PropertyDatabase.setProp( buffer, (uint8)0 ); groupItem.setHP(ch1->_PropertyDatabase, 0); // sprintf(buffer, "GROUP:%d:NAME",pos ); // ch1->_PropertyDatabase.setProp( buffer, (uint32)0 ); groupItem.setNAME(ch1->_PropertyDatabase, 0); // sprintf(buffer, "GROUP:%d:UID",pos ); // ch1->_PropertyDatabase.setProp( buffer, (uint32)CLFECOMMON::INVALID_CLIENT_DATASET_INDEX ); groupItem.setUID(ch1->_PropertyDatabase, CLFECOMMON::INVALID_CLIENT_DATASET_INDEX); } } if ( _RewardSharing ) _RewardSharing->resetCandidates(this); // update positions updateMembersPositions(); // remove character from chat group TGroupId idGroupe = CHAT_GROUPS_IDS::getTeamChatGroupId(_TeamId); CMessage msgRemoveGroup("REMOVE_FROM_GROUP"); msgRemoveGroup.serial( idGroupe ); msgRemoveGroup.serial( const_cast<CEntityId&> ( charId ) ); sendMessageViaMirror( "IOS", msgRemoveGroup ); }// CTeam removeCharacter
// **************************************************************************** void CHugeListObs::update(ICDBNode * /* node */) { nlassert((uint) _Category < ListTypeCount); // must call setListType // if botchat is not active, dont care with update if ((_Category == Trading) || (_Category == ItemForMissions) || (_Category == Missions)) { if (!CBotChatManager::getInstance()->getCurrPage()) return; } if (!init()) { nlwarning("Can't do init"); return; } // check if good session if (_Session->getValue16() != _CurrentSessionNb) { // msg from a previous session, dont care return; } TItemVect *itemPages = &_ItemsPages; uint pageID = (uint) _PageID->getValue16(); if (pageID >= TRADE_MAX_NUM_PAGES) return; // bad page index if (pageID >= itemPages->size()) { // expand items list itemPages->resize(pageID + 1); } // if 'has_next' flag is set, then ask server for more pages (if it is not a page update) if (_HasNext->getValueBool()) { static const char *msgItemForMoney = "BOTCHAT:NEXT_PAGE_ITEM"; static const char *msgItemForMission = "TRADE:NEXT_PAGE_MISSION_ITEM"; static const char *msgAscensor = "GUILD:NEXT_ASCENSOR_PAGE"; static const char *msgMissions; if(_MType==MISSION_DESC::ZCCharge) msgMissions= "BOTCHAT:NEXT_PAGE_DUTY"; else msgMissions= "BOTCHAT:NEXT_PAGE_MISSION"; const char* msgName; switch(_Category) { case Trading: msgName = msgItemForMoney; break; case ItemForMissions: msgName = msgItemForMission; break; case Ascensor: msgName = msgAscensor; break; case Missions: msgName = msgMissions; break; default: nlassert(0); // You have to provide message for ping-pong behavior break; } CBitMemStream out; if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) { out.serial(_CurrentSessionNb); NetMngr.push(out); //nlinfo("impulseCallBack : %s %d sent", msgName, _CurrentSessionNb); } else { nlwarning("<CHandlerAcceptExchange::execute> unknown message name '%s'", msgName); } } else { _DownloadComplete = true; } CItemPage &page = (*itemPages)[pageID]; uint k; // copy items page into temporary stuff for (k = 0; k < TRADE_PAGE_NUM_ITEMS; ++k) { switch(_Category) { case Trading: { page.Items[k].SlotType = (TRADE_SLOT_TYPE::TTradeSlotType) _Items[k].SlotType->getValue32(); page.Items[k].Quality = (uint16) _Items[k].Quality->getValue16(); page.Items[k].SheetIDOrSkill = (uint32) _Items[k].SheetIDOrSkill->getValue32(); page.Items[k].Price = (uint32) _Items[k].Price->getValue32(); page.Items[k].Weight= (uint16) _Items[k].Weight->getValue16(); page.Items[k].NameId= (uint32) _Items[k].NameId->getValue32(); page.Items[k].UserColor = _Items[k].UserColor->getValue32(); page.Items[k].Enchant = _Items[k].Enchant->getValue32(); page.Items[k].RMClassType = _Items[k].RMClassType->getValue32(); page.Items[k].RMFaberStatType = _Items[k].RMFaberStatType->getValue32(); page.Items[k].PrerequisitValid = _Items[k].PrerequisitValid->getValue32(); page.Items[k].InfoVersion= (uint16) _Items[k].InfoVersion->getValue16(); page.Items[k].Quantity= (uint16) _Items[k].Quantity->getValue16(); page.Items[k].PriceRetire= (uint32) _Items[k].PriceRetire->getValue32(); page.Items[k].ResaleTimeLeft= (uint32) _Items[k].ResaleTimeLeft->getValue32(); page.Items[k].VendorNameId= (uint32) _Items[k].VendorNameId->getValue32(); page.Items[k].FactionType= (uint32) _Items[k].FactionType->getValue32(); page.Items[k].FactionPointPrice= (uint32) _Items[k].FactionPointPrice->getValue32(); page.Items[k].SellerType= (uint32) _Items[k].SellerType->getValue32(); // is the sheet is a phrase sheet, discard it if already known /* CEntitySheet *sheet = SheetMngr.get(CSheetId(page.Items[k].SheetIDOrSkill)); if (sheet && sheet->Type == CEntitySheet::SPHRASE) { CSPhraseSheet *ps = (CSPhraseSheet *) sheet; CSPhraseCom pc; pc.Bricks.swap(ps->Bricks); // substitute brick in the object (for the time of comparison) if (CSPhraseManager::getInstance()->isPhraseKnown(pc)) { page.Items[k].SheetIDOrSkill = 0; // already known, do not show in list } pc.Bricks.swap(ps->Bricks); // restore list of sheet } */ } break; case ItemForMissions: page.Items[k].SlotType = (TRADE_SLOT_TYPE::TTradeSlotType) _Items[k].SlotType->getValue32(); page.Items[k].Quality = (uint16) _Items[k].Quality->getValue16(); page.Items[k].SheetIDOrSkill = (uint32) _Items[k].SheetIDOrSkill->getValue32(); page.Items[k].LogicTextID = (uint32) _Items[k].LogicTextID->getValue32(); page.Items[k].DescTextID = (uint32) _Items[k].DescTextID->getValue32(); page.Items[k].Weight= (uint16) _Items[k].Weight->getValue16(); page.Items[k].NameId= (uint32) _Items[k].NameId->getValue32(); page.Items[k].UserColor = _Items[k].UserColor->getValue32(); page.Items[k].Enchant = _Items[k].Enchant->getValue32(); page.Items[k].RMClassType = _Items[k].RMClassType->getValue32(); page.Items[k].RMFaberStatType = _Items[k].RMFaberStatType->getValue32(); page.Items[k].InfoVersion= (uint16) _Items[k].InfoVersion->getValue16(); break; case Ascensor: page.Items[k].GuildIcon = (uint64) _Items[k].GuildIcon->getValue64(); page.Items[k].GuildName = (uint32) _Items[k].GuildName->getValue32(); break; case Missions: page.Items[k].MissionText = (uint32) _Items[k].MissionText->getValue64(); page.Items[k].MissionDetailText = (uint32) _Items[k].MissionDetailText->getValue64(); page.Items[k].MissionIcon = (uint32) _Items[k].MissionIcon->getValue32(); page.Items[k].MissionPreReqState = (uint32) _Items[k].MissionPreReqState->getValue32(); break; default: nlassert(0); // You have to provide code for element that you want to be copied break; } } page.PageLoaded = true; page.PageVisible = false; // force update, even if shown before uint numLoadedPages; // In the display we want a contiguous set of items. Not For Trading, because of Resale if(_Category==Trading) { numLoadedPages= (uint)itemPages->size(); } else { for(numLoadedPages = 0; numLoadedPages < itemPages->size(); ++numLoadedPages) { if ((*itemPages)[numLoadedPages].PageLoaded == false && numLoadedPages != pageID) break; } } // for(k = 0; k < numLoadedPages; ++k) { // still must test if page really loaded if ( (*itemPages)[k].PageLoaded && (*itemPages)[k].PageVisible == false) { updateUIItemPage(k); (*itemPages)[k].PageVisible = true; } } // **** Special RoleMaster Trading _PhraseClientFillNumPhrase= 0; _PhraseClientFillFlags= 0; _PhraseClientFillRace= 0; _PhraseClientFill= false; // clientFill must at least be possible if(_Category==Trading && _PhrasePriceUpdateAndMaybeClientFill && _RoleMasterFlagDB && _RoleMasterRaceDB) { _PhraseClientFillFlags= _RoleMasterFlagDB->getValue32(); _PhraseClientFillRace= _RoleMasterRaceDB->getValue32(); _PhraseClientFill= _PhraseClientFillFlags!=0; if(_PhraseClientFill) { clientGenerateAllPhrases(); recomputeAllPhrasePrices(); } } }
//--------------------------------------------------- // joinProposal : //--------------------------------------------------- void CTeamManager::joinProposal( CCharacter * leader, const CEntityId &targetId) { //check already done nlassert(leader); const NLMISC::CEntityId &leaderId = leader->getId(); if (targetId == leaderId ) { nlwarning("<CTeamManager joinProposal> Player %s invited himself in his team, cancel", leaderId.toString().c_str() ); 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 joinProposal> 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 = isInvitableBy(invitedPlayer,leader); if ( code == AlreadyInvited ) { CCharacter::sendDynamicSystemMessage( leader->getId(),"TEAM_ALREADY_INVITED" ); return; } else if ( code == AlreadyInTeam ) { CCharacter::sendDynamicSystemMessage( leader->getId(),"TEAM_TARGET_ALREADY_IN_TEAM" ); return; } else if ( code == CantInviteEnemy ) { CCharacter::sendDynamicSystemMessage( leader->getId(),"TEAM_CANT_INVITE_ENEMY" ); return; } else if ( code == CantInvite ) { CCharacter::sendDynamicSystemMessage( leader->getId(),"TEAM_CANT_INVITE" ); 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->setTeamInvitor(leaderId); //send the appropriate string to the client SM_STATIC_PARAMS_1(params, STRING_MANAGER::player); params[0].setEIdAIAlias( leaderId, CAIAliasTranslator::getInstance()->getAIAlias( leaderId ) ); uint32 strId = STRING_MANAGER::sendStringToClient(TheDataset.getDataSetRow(targetId),"TEAM_PROPOSAL", params); //send the invitation msg to the target, with the id of the built string CMessage msgout( "IMPULSION_ID" ); CBitMemStream bms; CEntityId targetIdToSerial = targetId; msgout.serial( targetIdToSerial ); if ( ! GenericMsgManager.pushNameToStream( "TEAM:INVITATION", bms) ) { nlwarning("<CTeamManager joinProposal> Msg name TEAM:INVITATION not found"); return; } bms.serial(strId); msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length()); sendMessageViaMirror( NLNET::TServiceId(targetId.getDynamicId()), msgout ); // TVectorParamCheck params; // params.resize(1); // inform the team leader // params[0].Type = STRING_MANAGER::player; params[0].setEIdAIAlias( targetId, CAIAliasTranslator::getInstance()->getAIAlias( targetId ) ); PHRASE_UTILITIES::sendDynamicSystemMessage(leader->getEntityRowId(), "TEAM_INVITE", params); leader->updateTarget(); } // joinProposal //