void commandWhere( cUOSocket *socket, const QString &command, QStringList &args ) throw()
{
	Q_UNUSED(args);
	Q_UNUSED(command);
	P_PLAYER pChar = socket->player();

	if( !pChar )
		return;

	cTerritory *mRegion = AllTerritories::instance()->region( pChar->pos().x, pChar->pos().y, pChar->pos().map );

	QString message = tr( "You are" );

	if( mRegion )
		message.append( " " + tr( "in %1" ).arg( mRegion->name() ) );

	message.append( " " + tr( "at %1,%2,%3 on map %4" ).arg( pChar->pos().x ).arg( pChar->pos().y ).arg( pChar->pos().z ).arg( pChar->pos().map ) );
	pChar->message( message );
}
void cDragItems::dropItem( cUOSocket *socket, cUORxDropItem *packet )
{
	P_PLAYER pChar = socket->player();

	if( !pChar )
		return;

	// Get the data
	SERIAL contId = packet->cont();

	Coord_cl dropPos = pChar->pos(); // plane
	dropPos.x = packet->x();
	dropPos.y = packet->y();
	dropPos.z = packet->z();

	// Get possible containers
	P_ITEM pItem = FindItemBySerial( packet->serial() );
	
	if( !pItem )
		return;

	P_ITEM iCont = FindItemBySerial( packet->cont() );
	P_CHAR cCont = FindCharBySerial( packet->cont() );

	// >> SEE LORD BINARIES DROPFIX <<

	// A completely invalid Drop packet
	if( !iCont && !cCont && ( dropPos.x == 0xFFFF ) && ( dropPos.y == 0xFFFF ) && ( (unsigned char)dropPos.z == 0xFF ) )
	{
		socket->bounceItem( pItem, BR_NO_REASON );
		return;
	}

	UINT32 weight = pChar->weight();

	// Item dropped on Ground
	if( !iCont && !cCont )
		dropOnGround( socket, pItem, dropPos );

	// Item dropped on another item
	else if( iCont )
		dropOnItem( socket, pItem, iCont, dropPos );

	// Item dropped on char
	else if( cCont )
		dropOnChar( socket, pItem, cCont );

	// Handle the sound-effect
	if( pItem->id() == 0xEED )
		goldsfx( socket, pItem->amount(), true );

	// Update our weight.
	if( weight != pChar->weight() )
		socket->sendStatWindow();
}
Example #3
0
// All ai controlled creatures can be controlled by a gm
// or by their owner if tamed
void AbstractAI::onSpeechInput( P_PLAYER pTalker, const QString &comm ) {
	if (!pTalker->isGM() && (!m_npc->isTamed() || m_npc->owner() != pTalker)) {
		return;
	}

	// too far away to hear us
	if (pTalker->dist(m_npc) > 7) {
		return;
	}
	
	if (comm.contains(" FOLLOW")) {
		if (comm.contains(" ME")) {
			m_npc->setWanderFollowTarget(pTalker);
			m_npc->setWanderType(enFollowTarget);
			m_npc->bark(cBaseChar::Bark_Attacking);
		} else {
			pTalker->socket()->attachTarget(new cFollowTarget(m_npc));
		}
	} else if ((comm.contains(" KILL")) || (comm.contains(" ATTACK"))) {
		if (m_npc->inGuardedArea()) {
			pTalker->message(tr("You can't have pets attack in town!"));
		}
	} else if ((comm.contains(" FETCH")) || (comm.contains(" GET"))) {
		//pPlayer->setGuarded(false);
		// >> LEGACY
		//addx[s]=pPet->serial();
		//target(s, 0, 1, 0, 124, "Click on the object to fetch.");
	} else if (comm.contains(" COME")) {
		m_npc->setWanderDestination(pTalker->pos());
		m_npc->setWanderType(enDestination);
		m_npc->bark(cBaseChar::Bark_Attacking);
	} else if (comm.contains(" GUARD")) {
	} else if ((comm.contains(" STOP")) || (comm.contains(" STAY"))) {
		m_npc->fight(0);
		m_npc->setWanderType( enHalt );
		m_npc->bark(cBaseChar::Bark_Attacking);
	} else if (comm.contains(" TRANSFER")) {
	} else if (comm.contains(" RELEASE")) {
		// Has it been summoned ? Let's dispel it
		if (m_npc->summoned()) {
			m_npc->setSummonTime(uiCurrentTime);
		}

		m_npc->setWanderType(enFreely);
		m_npc->setOwner(0);
		m_npc->setTamed(false);
		m_npc->bark(cBaseChar::Bark_Attacking);
		if (SrvParams->tamedDisappear()) {
			m_npc->soundEffect(0x01Fe);
			cCharStuff::DeleteChar(m_npc);
		}
	}
}
Example #4
0
/////////////////
// name:	response
// purpose:	tries to get a response from an npc standing around
// history:	heavily revamped/rewritten by Duke, Oct 2001
// remark:	The new logic tries to minimize the # of strstr() calls by *first* checking
//			what kind of npcs are standing around and then checking only those keywords
//			that they might be interested in.
//			This is especially usefull in crowded places.
bool Speech::response( cUOSocket* socket, P_PLAYER pPlayer, const QString& comm, QValueVector<Q_UINT16>& keywords )
{
	if ( !pPlayer->socket() || pPlayer->isDead() )
	{
		return false;
	}

	QString speechUpr = comm.upper();

	MapCharsIterator ri = MapObjects::instance()->listCharsInCircle( pPlayer->pos(), 18 );
	for ( P_CHAR pChar = ri.first(); pChar; pChar = ri.next() )
	{
		P_NPC pNpc = dynamic_cast<P_NPC>( pChar );

		// We will only process NPCs here
		if ( !pNpc )
			continue;

		// at least they should be on the screen
		if ( pPlayer->dist( pNpc ) > 16 )
			continue;

		if ( pNpc->canHandleEvent( EVENT_SPEECH ) )
		{
			PyObject* pkeywords = PyTuple_New( keywords.size() );

			// Set Items
			for ( unsigned int i = 0; i < keywords.size(); ++i )
				PyTuple_SetItem( pkeywords, i, PyInt_FromLong( keywords[i] ) );

			PyObject* args = Py_BuildValue( "(NNNO)", pNpc->getPyObject(), pPlayer->getPyObject(), QString2Python( comm ), pkeywords );

			bool result = pNpc->callEventHandler( EVENT_SPEECH, args );

			Py_DECREF( args );
			Py_DECREF( pkeywords );

			if ( result )
				return true;
		}

		if ( pNpc->ai() )
		{
			pNpc->ai()->onSpeechInput( pPlayer, speechUpr );
		}

		if ( QuestionSpeech( socket, pPlayer, pNpc, speechUpr ) )
			return true;
	}

	return false;
}
void cDragItems::dropOnGround( cUOSocket *socket, P_ITEM pItem, const Coord_cl &pos )
{
	P_PLAYER pChar = socket->player();

	// Check if the destination is in line of sight
	if( !lineOfSight( pChar->pos(), pos, WALLS_CHIMNEYS|DOORS|LAVA_WATER ) )
	{
		socket->bounceItem( pItem, BR_OUT_OF_SIGHT );
		return;
	}

	if( !pChar->canPickUp( pItem ) )
	{
		socket->bounceItem( pItem, BR_CANNOT_PICK_THAT_UP );
		return;
	}

	if( pItem->onDropOnGround( pos ) )
	{
		// We're still dragging something
		if( socket->dragging() )
			socket->bounceItem( socket->dragging(), BR_NO_REASON );

		return;
	}

	pItem->removeFromCont();
	pItem->moveTo( pos );
	pItem->update();

	if( pItem->priv() & 0x01 )
		pItem->startDecay();

	// Multi handling
	// Has it been dropped into a multi
	cMulti* pMulti = cMulti::findMulti( pos );
	if( pMulti )
	{
		pMulti->addItem( pItem );
	}
}
/*!
	This handles if a character actually tries to walk (NPC & Player)
*/
bool cMovement::Walking( P_CHAR pChar, Q_UINT8 dir, Q_UINT8 sequence )
{
	if ( !pChar )
		return false;

	// Scripting
	if ( pChar->onWalk( dir, sequence ) )
		return false;

	P_PLAYER player = dynamic_cast<P_PLAYER>( pChar );

	// Is the sequence in order ?
	if ( player && player->socket() && !verifySequence( player->socket(), sequence ) )
		return false;

	// If checking for weight is more expensive, shouldn't we check for frozen first?
	if ( pChar->isFrozen() )
	{
		if ( player && player->socket() )
			player->socket()->denyMove( sequence );
		return false;
	}

	// save our original location before we even think about moving
	const Coord oldpos( pChar->pos() );

	// If the Direction we're moving to is different from our current direction
	// We're turning and NOT moving into a specific direction
	// Clear the running flag here (!)
	// If the direction we're moving is already equal to our current direction
	bool running = dir & 0x80;
	dir = dir & 0x7; // Remove all unneeded stuff

	pChar->setRunning( running );

	bool turning = dir != pChar->direction();

	// This happens if we're moving
	if ( !turning )
	{
		// Note: Do NOT use the copy constructor as it'll create a reference
		Coord newCoord = calcCoordFromDir( dir, pChar->pos() );

		// Check if the stamina parameters
		if ( player && !consumeStamina( player, running ) )
		{
			if ( player->socket() )
				player->socket()->denyMove( sequence );
			return false;
		}

		// Check if we're going to collide with characters
		if ( player )
		{
			// Player vs characters
			if ( player->socket() && player->pos().map == 0 && !player->account()->isStaff() )
			{
				// Currently hard-limiting collisions to Felucca; this should be a server option!
				MapCharsIterator charCollisions = MapObjects::instance()->listCharsAtCoord( newCoord );
				for ( P_CHAR them = charCollisions.first(); them; them = charCollisions.next() )
				{
					if ( them == player )
						continue;

					P_PLAYER otherplayer = dynamic_cast<P_PLAYER>( them );
					if ( otherplayer && otherplayer->account()->isStaff() )
						continue; // no collisions against the staff

					if ( wpAbs<SI08>( newCoord.z - them->pos().z ) < P_M_MAX_Z_CLIMB )
					{
						// to push another char we must have maximum stamina
						if ( player->stamina() >= player->maxStamina() )
						{
							player->socket()->clilocMessage( them->isHidden() ? 1019043 : 1019042 );
							player->setStamina( player->stamina() - 10 );
							break;
						}
						else
						{
							player->socket()->denyMove( sequence );
							return false;
						}
					}
				}
			}
		}
		else
		{
			// NPC vs characters
			P_NPC npc = dynamic_cast<P_NPC>( pChar );
			if ( npc && CheckForCharacterAtXYZ( pChar, newCoord ) )
			{
				npc->clearPath();
				return false;
			}
		}

		// Check if the char can move to those new coordinates
		// It is going to automatically calculate the new coords (!)
		if ( !mayWalk( pChar, newCoord ) )
		{
			if ( player && player->socket() )
				player->socket()->denyMove( sequence );
			return false;
		}
		else
		{
			if ( player && player->socket() )
				player->socket()->allowMove( sequence );
		}

		// We moved so let's update our location
		pChar->moveTo( newCoord );
		pChar->setStepsTaken( pChar->stepsTaken() + 1 );
		pChar->setLastMovement( Server::instance()->time() );
		checkStealth( pChar ); // Reveals the user if neccesary
	}
	else
	{
		if ( player && player->socket() )
			player->socket()->allowMove( sequence );
	}

	// do all of the following regardless of whether turning or moving i guess
	// set the player direction to contain only the cardinal direction bits
	pChar->setDirection( dir );

	Coord upperLeft = pChar->pos() - Coord( ( VISRANGE + 1 ), ( VISRANGE + 1 ) );
	Coord lowerRight = pChar->pos() + Coord( ( VISRANGE + 1 ), ( VISRANGE + 1 ) );

	MapCharsIterator ri = MapObjects::instance()->listCharsInRect( upperLeft, lowerRight );
	for ( P_CHAR observer = ri.first(); observer; observer = ri.next() )
	{
		if ( observer == pChar )
			continue;

		bool wasVisible = observer->pos().distance( oldpos ) < VISRANGE; // We were previously in range
		bool isVisible = pChar->dist( observer ) < VISRANGE; // We are now in range

		// If we are a player, send us new characters
		if ( player && player->socket() )
		{
			// Send the observer to us if he was previously not visible and came into range recently
			if ( !wasVisible && isVisible )
			{
				player->socket()->sendChar( observer );
			}
		}

		// Send our movement to the observer
		P_PLAYER otherplayer = dynamic_cast<P_PLAYER>( observer );

		if ( !otherplayer || !otherplayer->socket() )
		{
			continue; // Skip this character, it's a player.
			// TODO: OnSeePlayer, OnLoosePlayer
		}

		if ( wasVisible )
		{
			if ( isVisible )
			{
				otherplayer->socket()->updateChar( pChar ); // We walked inside the visible range
			}
			else
			{
				otherplayer->socket()->removeObject( pChar ); // We walked out of visible range
			}
		}
		else if ( isVisible )
		{
			otherplayer->socket()->sendChar( pChar ); // We walked into visible range
		}
	}

	// If we really moved handle teleporters and new items
	if ( !turning )
	{
		handleItems( pChar, oldpos );
		handleMultis( pChar, oldpos );
		handleTeleporters( pChar, oldpos );
	}

	return true;
}
Example #7
0
// All ai controlled creatures can be controlled by a gm
// or by their owner if tamed
void AbstractAI::onSpeechInput( P_PLAYER pTalker, const QString& comm )
{
	if ( !pTalker->isGM() && ( !m_npc->isTamed() || m_npc->owner() != pTalker ) )
	{
		return;
	}

	// too far away to hear us
	if ( pTalker->dist( m_npc ) > 7 )
	{
		return;
	}

	if ( comm.contains( " FOLLOW" ) )
	{
		if ( comm.contains( " ME" ) )
		{
			m_npc->setWanderFollowTarget( pTalker );
			m_npc->setWanderType( enFollowTarget );
			m_npc->bark( cBaseChar::Bark_Attacking );
		}
		else
		{
			pTalker->socket()->attachTarget( new cFollowTarget( m_npc ) );
		}
	}
	else if ( ( comm.contains( " KILL" ) ) || ( comm.contains( " ATTACK" ) ) )
	{
		if ( m_npc->inGuardedArea() )
		{
			pTalker->message( tr( "You can't have pets attack in town!" ) );
		}
	}
	else if ( ( comm.contains( " FETCH" ) ) || ( comm.contains( " GET" ) ) )
	{
//#pragma note( Implement me )
		pTalker->message( tr( "Sorry, not implemented yet :(" ) );
	}
	else if ( comm.contains( " COME" ) )
	{
		m_npc->setWanderDestination( pTalker->pos() );
		m_npc->setWanderType( enDestination );
		m_npc->bark( cBaseChar::Bark_Attacking );
	}
	else if ( comm.contains( " GUARD" ) )
	{
	}
	else if ( ( comm.contains( " STOP" ) ) || ( comm.contains( " STAY" ) ) )
	{
		m_npc->fight( 0 );
		m_npc->setWanderType( enHalt );
		m_npc->bark( cBaseChar::Bark_Attacking );
	}
	else if ( comm.contains( " TRANSFER" ) )
	{
	}
	else if ( comm.contains( " RELEASE" ) )
	{
		// Has it been summoned ? Let's dispel it
		if ( m_npc->summoned() )
		{
			m_npc->setSummonTime( Server::instance()->time() );
		}

		m_npc->setWanderType( enFreely );
		m_npc->setOwner( 0 );
		m_npc->setTamed( false );
		m_npc->bark( cBaseChar::Bark_Attacking );
		if ( Config::instance()->tamedDisappear() )
		{
			m_npc->soundEffect( 0x01Fe );
			m_npc->remove();
		}
	}
}
Example #8
0
void cSpeech::talking( P_PLAYER pChar, const QString &lang, const QString &speech, QValueVector< UINT16 > &keywords, UINT16 color, UINT16 font, UINT8 type ) // PC speech
{	
	// handle things like renaming or describing an item
	if( !pChar->socket() )
		return;

	cUOSocket *socket = pChar->socket();

	if( InputSpeech( socket, pChar, speech ) )	
		return;

	// not allowed to talk
	if( pChar->isMuted() )
	{
		socket->sysMessage( tr( "You re squelched and cannot talk" ) );
		return;
	}

	pChar->unhide();
		
	// Check for Bogus Color
	if( !isNormalColor( color ) )
		color = 0x2;

	if( type == 0 || type == 2)
		pChar->setSaycolor( color );

	if( SrvParams->speechLog() )
	{
		QFile lFile( "speech.log" );
		
		if( lFile.open( IO_Append ) )
		{
			QString logMessage( "[%1] %2: %3 [%4, 0x%5]" );
			logMessage = logMessage.arg( QDateTime::currentDateTime().toString() ).arg( pChar->name() ).arg( speech ).arg( pChar->account()->login() ).arg( pChar->serial(), 8, 16 );
			lFile.writeBlock( logMessage.latin1(), logMessage.length() );
			lFile.close();
		}
	}

	if( pChar->onTalk( type, color, font, speech, lang ) )
		return;

	if( ( type == 0x09 ) && ( pChar->mayBroadcast() ) )
	{
		pChar->talk( speech, color, type );
		return;
	}

	pChar->talk( speech, color, type );
		
	QString speechUpr = speech.upper();
	if( response( socket, pChar, speech, keywords ) )
		return;  // Vendor responded already
	
	// 0x0007 -> Speech-id for "Guards"
	for( QValueVector< UINT16 >::const_iterator iter = keywords.begin(); iter != keywords.end(); ++iter )
	{
		UINT16 keyword = *iter;

		if( keyword == 0x07 )
			pChar->callGuards();
	}
	
	// well,i had a strange problem with duplicate speech input
	// its quite easy to understand....
	// the former loop searched for the tiller man and when it
	// was found, the speechInput method of that boat was called.
	// in this method the tiller had been removed from the mapregion
	// and appended to the end of the cell vector... hence, the
	// tiller was found twice...
	// therefore we produce a QPtrList of cBoat* pointers and 
	// then go through it for applying speech --- sereg
	RegionIterator4Items rj( pChar->pos() );
	QPtrList< cBoat >	pboats;
	for( rj.Begin(); !rj.atEnd(); rj++ )
	{
		P_ITEM pi = rj.GetData();

		if( !pi )
			continue;

		if( pi->type() == 117 && pi->tags().get( "tiller" ).toInt() == 1 )
		{
			cBoat* pBoat = dynamic_cast< cBoat* >(FindItemBySerial( pi->tags().get("boatserial").toInt() ));
			if( pBoat )
				pboats.append( pBoat );
		}
	}
	QPtrListIterator< cBoat >	pit( pboats );
	while( pit.current() )
	{
		pit.current()->speechInput( socket, speechUpr );
		++pit;
	}

	// this makes it so npcs do not respond to isDead people - HEALERS ??
	if( pChar->isDead() )
		return;
	
/*	P_CHAR pc = NULL; ???
	P_CHAR pNpc = NULL;
	RegionIterator4Chars ri( pChar->pos() );
	for( ri.Begin(); !ri.atEnd(); ri++ )
	{	
		pc = ri.GetData();
		if (!pc->isSameAs( pChar ) 
			&& pc->isNpc()
			&& pc->dist( pChar ) <= 2)
		{
			pNpc = pc;
			break;
		}
	}
	*/
}
Example #9
0
/////////////////
// name:	response
// purpose:	tries to get a response from an npc standing around
// history:	heavily revamped/rewritten by Duke, Oct 2001
// remark:	The new logic tries to minimize the # of strstr() calls by *first* checking
//			what kind of npcs are standing around and then checking only those keywords
//			that they might be interested in.
//			This is especially usefull in crowded places.
bool cSpeech::response( cUOSocket *socket, P_PLAYER pPlayer, const QString& comm, QValueVector< UINT16 > &keywords )
{
    if( !pPlayer->socket() || pPlayer->isDead() )
		return false;

	QString speechUpr = comm.upper();

	RegionIterator4Chars ri( pPlayer->pos() );
	for( ri.Begin(); !ri.atEnd(); ri++ )
	{
		P_NPC pNpc = dynamic_cast<P_NPC>(ri.GetData());

		// We will only process NPCs here
		if( !pNpc )
			continue;

		// at least they should be on the screen
		if( pPlayer->dist( pNpc ) > 16 )
			continue;

		// Check if the NPC has a script that can handle 
		// speech events and then check if it can handle everything
		// or just certain things
		std::vector< WPDefaultScript* > events = pNpc->getEvents();
		for( std::vector< WPDefaultScript* >::const_iterator iter = events.begin(); iter != events.end(); ++iter )
		{
			WPDefaultScript *script = *iter;
			if( !script->handleSpeech() )
				continue;

			if( script->catchAllSpeech() || script->canHandleSpeech( comm, keywords ) )
				if( script->onSpeech( pNpc, pPlayer, comm, keywords ) )
					return true;
		}

		cNPC_AI* pAI = pNpc->ai();
		if( pAI && pAI->currState() )
		{
			pAI->currState()->speechInput( pPlayer, speechUpr );
			pAI->updateState();
		}

		if( BankerSpeech( socket, pPlayer, pNpc, speechUpr ) )
			return true;

		if( PetCommand( socket, pPlayer, pNpc, speechUpr ) )
			return true;

		if( StableSpeech( socket, pPlayer, pNpc, speechUpr ) )
			return true;
		
		if( UnStableSpeech( socket, pPlayer, pNpc, speechUpr ) )
			return true;
		
		if( ShieldSpeech( socket, pPlayer, pNpc, speechUpr ) )
			return true;
		
		if( QuestionSpeech( socket, pPlayer, pNpc, speechUpr ) )
			return true;
		
		if( TrainerSpeech( socket, pPlayer, pNpc, speechUpr ) )
			return true;
		
		if( PlayerVendorSpeech( socket, pPlayer, pNpc, speechUpr ) )
			return true;
		
	}
	
	return false;
}
Example #10
0
bool InputSpeech( cUOSocket *socket, P_PLAYER pChar, const QString &speech )
{
	if( pChar->inputMode() == cPlayer::enNone )
		return false;

	P_ITEM pItem = FindItemBySerial( pChar->inputItem() );

	if( !pItem )
		return false;

	bool ok;
	INT32 num = speech.toInt( &ok ); // Generally try to convert it
	QString notification;

	switch (pChar->inputMode())
	{
	// Pricing an item - PlayerVendors
	case cPlayer::enPricing:
		if (ok)
		{
			pItem->setPrice( num );
			socket->sysMessage( tr( "This item's price has been set to %1." ).arg( num ) );
		}
		else
			socket->sysMessage( tr( "You have to enter a numeric price" ) );

		pChar->setInputMode(cPlayer::enDescription);
		socket->sysMessage( tr( "Enter a description for this item." ) );
		break;

	// Describing an item
	case cPlayer::enDescription:
		pItem->setDescription( speech );
		socket->sysMessage( tr( "This item is now described as %1." ).arg( speech ) );
		pChar->setInputMode(cPlayer::enNone);
		pChar->setInputItem(INVALID_SERIAL);
		break;

	// Renaming a rune
	case cPlayer::enRenameRune:
		pItem->setName( tr( "Rune to: %1" ).arg( speech ) );
		socket->sysMessage( tr( "Rune renamed to: Rune to: %1" ).arg( speech ) );
		pChar->setInputMode(cPlayer::enNone);
		pChar->setInputItem(INVALID_SERIAL);
		break;

	// Renaming ourself
	case cPlayer::enNameDeed: 
		pChar->setName( speech );
		socket->sysMessage( tr( "Your new name is: %1" ).arg( speech ) );
		pChar->setInputMode(cPlayer::enNone);
		pChar->setInputItem(INVALID_SERIAL);
		break;

	// Renaming a house sign
	case cPlayer::enHouseSign:
		pItem->setName( speech ); 
		socket->sysMessage( tr( "Your house has been renamed to: %1" ).arg( speech ) );
		pChar->setInputMode(cPlayer::enNone);
		pChar->setInputItem(INVALID_SERIAL);
		break;

	// Paging a GM
	case cPlayer::enPageGM:
		{
			cPage* pPage = new cPage( pChar->serial(), PT_GM, speech, pChar->pos() );
			cPagesManager::getInstance()->push_back( pPage );
			notification = tr( "GM Page from %1: %2" ).arg( pChar->name() ).arg( speech );
			
			for ( cUOSocket *mSock = cNetwork::instance()->first(); mSock; mSock = cNetwork::instance()->next())
				if( mSock->player() && mSock->player()->isGM() )
					mSock->sysMessage( notification );
				
				if( cNetwork::instance()->count() > 0 )
					socket->sysMessage( tr( "Available Game Masters have been notified of your request." ) );
				else
					socket->sysMessage( tr( "There was no Game Master available, page queued." ) );
				
				pChar->setInputMode(cPlayer::enNone);
		}
		break;
		
	// Paging a Counselor
	case cPlayer::enPageCouns:
		{
			cPage* pPage = new cPage( pChar->serial(), PT_COUNSELOR, speech, pChar->pos() );
			cPagesManager::getInstance()->push_back( pPage );
			notification = tr( "Counselor Page from %1: %2" ).arg( pChar->name() ).arg( speech );
			
			for ( cUOSocket *mSock = cNetwork::instance()->first(); mSock; mSock = cNetwork::instance()->next())
				if( mSock->player() && (socket->player()->isCounselor() || socket->player()->isGM()) )
					mSock->sysMessage( notification );
				
				if( cNetwork::instance()->count() > 0 )
					socket->sysMessage( tr( "Available Counselors have been notified of your request." ) );
				else
					socket->sysMessage( tr( "There was no Counselor available, page queued." ) );
				
				pChar->setInputMode(cPlayer::enNone);
		}
		break;

	default:
		break;	// do nothing
	}
	
	return true;
}