Example #1
0
cParty::~cParty()
{
	P_PLAYER member;
	for ( member = members_.first(); member; member = members_.next() )
	{
		member->setParty( 0 );

		if ( member->socket() )
		{
			cUOTxPartyRemoveMember updateparty;
			updateparty.setSerial( member->serial() );
			member->socket()->send( &updateparty );
			member->socket()->clilocMessage( 1005449 );
		}
	}

	for ( member = canidates_.first(); member; member = canidates_.next() )
	{
		if ( member->socket() )
		{
			cUOTxPartyRemoveMember updateparty;
			updateparty.setSerial( member->serial() );
			member->socket()->send( &updateparty );
			member->socket()->clilocMessage( 1005449 );
		}
	}
}
void Human_Stablemaster::onSpeechInput( P_PLAYER pTalker, const QString& message )
{
	if ( !pTalker->socket() )
		return;

	if ( m_npc->inRange( pTalker, 4 ) && ( VendorChkName( m_npc, message ) || message.contains( tr( "STABLEMASTER" ) ) ) )
	{
		if ( message.contains( tr( " STABLE" ) ) )
		{
			m_npc->talk( tr( "Which pet do you want me to stable?" ) );
			pTalker->socket()->attachTarget( new cStableTarget( m_npc ) );
		}
		else if ( message.contains( tr( " RELEASE" ) ) )
		{
			int gold = pTalker->countBankGold() + pTalker->countGold();
			P_ITEM pPack = m_npc->getBankbox();
			
			cItem::ContainerContent stableitems;
			if ( pPack )
			{
				cItem::ContainerContent content = pPack->content();
				cItem::ContainerContent::const_iterator it( content.begin() );
				while ( it != content.end() )
				{
					if ( !( *it )->hasTag( "player" ) || !( *it )->hasTag( "pet" ) )
						continue;

					if ( ( *it ) && ( uint )( *it )->getTag( "player" ).toInt() == pTalker->serial() )
						stableitems.push_back( ( *it ) );
					++it;
				}
			}

			if ( !stableitems.empty() )
			{
				cItem::ContainerContent::const_iterator it( stableitems.begin() );
				while ( it != stableitems.end() )
				{
					if ( ( *it ) )
					{
						P_NPC pPet = dynamic_cast<P_NPC>( World::instance()->findChar( ( *it )->getTag( "pet" ).toInt() ) );
						if ( pPet )
						{
							pPet->free = false;
							// we need this for db saves
							pPet->setStablemasterSerial( INVALID_SERIAL );
							pPet->moveTo( m_npc->pos() );
							pPet->resend();
						}
						( *it )->remove();
					}
					++it;
				}

				pPack->update();
				m_npc->talk( tr( "Here's your pet back!" ) );
			}
		}
	}
}
float Animal_Wild_Flee::preCondition()
{
	return 0.0f;

	/*
	 * Fleeing from an approaching player has the following preconditions:
	 * - There is a player within flight range.
	 * - There is no character attacking us.
	 * - Our owner is not in range.
	 *
	 */

	if ( m_npc->attackTarget() )
		return 0.0f;

	MapCharsIterator ri = MapObjects::instance()->listCharsInCircle( m_npc->pos(), Config::instance()->animalWildFleeRange() );
	for ( P_CHAR pChar = ri.first(); pChar; pChar = ri.next() )
	{
		P_PLAYER pPlayer = dynamic_cast<P_PLAYER>( pChar );
		if ( pPlayer && !pPlayer->free && !pPlayer->isGMorCounselor() && !pPlayer->isHidden() && !pPlayer->isInvisible() )
		{
			pFleeFromSer = pPlayer->serial();
		}
		if ( pPlayer && m_npc->owner() == pPlayer )
			return 0.0f;
	}

	if ( pFleeFromSer != INVALID_SERIAL )
		return 1.0f;

	return 0.0f;
}
Example #4
0
void cParty::update()
{
	cUOTxPartyUpdate update;

	for ( P_PLAYER player = members_.first(); player; player = members_.next() )
		update.addMember( player->serial() );

	send( &update );
}
Example #5
0
void cParty::send( P_PLAYER from, P_PLAYER target, const QString& message )
{
	cUOTxPartyTellMember tell;
	tell.setSerial( from->serial() );
	tell.setText( message );

	for ( P_PLAYER player = members_.first(); player; player = members_.next() )
		if ( player == target && player->socket() )
			player->socket()->send( &tell );
}
Example #6
0
void cParty::removeMember( P_PLAYER player, bool update )
{
	removeCanidate( player );
	members_.remove( player );
	player->setParty( 0 );

	// Update the party
	if ( update )
	{
		cUOTxPartyRemoveMember removemember;
		removemember.setSerial( player->serial() );
		for ( P_PLAYER member = members_.first(); member; member = members_.next() )
			removemember.addMember( member->serial() );

		send( &removemember );

		if ( player->socket() )
		{
			if ( player == leader_ )
				player->socket()->clilocMessage( 1005456 );

			cUOTxPartyRemoveMember updateparty;
			updateparty.setSerial( player->serial() );
			player->socket()->send( &updateparty );
		}
	}

	// Check if the party can be disbanded
	if ( player == leader_ || ( members_.count() <= 1 && canidates_.count() == 0 ) )
	{
		if ( player != leader_ && leader_->socket() )
			leader_->socket()->clilocMessage( 1005450 );

		delete this;
	}
}
void cAccounts::reload()
{
	QMap< SERIAL, QString > characcnames;
	QStringList sockaccnames;

	cCharIterator iterChars;
	P_CHAR pc;
	for( pc = iterChars.first(); pc; pc = iterChars.next() )
	{
		P_PLAYER pp = dynamic_cast<P_PLAYER>(pc);
		if( pp && pp->account() )
		{
			characcnames.insert( pp->serial(), pp->account()->login() );
		}
	}

	cUOSocket* mSock = NULL;
	for( mSock = cNetwork::instance()->first(); mSock; mSock = cNetwork::instance()->next() )
	{
		if( mSock->account() )
			sockaccnames.push_back( mSock->account()->login() );
		else
			sockaccnames.push_back( QString() );
	}

	clear();
	load();

	QMap< SERIAL, QString >::Iterator it = characcnames.begin();
	while( it != characcnames.end() )
	{
		P_PLAYER pp = dynamic_cast<P_PLAYER>(FindCharBySerial( it.key() ));
		if( pp )
			pp->setAccount( getRecord( it.data() ), false );
		++it;
	}

	QStringList::iterator sit = sockaccnames.begin();
	for( mSock = cNetwork::instance()->first(); mSock; mSock = cNetwork::instance()->next() )
	{
		if( !(*sit).isNull() )
			mSock->setAccount( getRecord( (*sit) ) );
		++sit;
	}
	
}
	virtual void handleResponse( cUOSocket *socket, const gumpChoice_st& choice )
	{
		P_PLAYER player = socket->player();

		if( !player )
			return;

		P_CHAR pChar = FindCharBySerial( choice.button );

		if( !pChar || pChar->dist( player ) > 32 )
			return;

		// Start the refresh-timer
		// Start the wearoff-timer
		player->setTrackingTime( uiCurrentTime + ( 30 * MY_CLOCKS_PER_SEC ) );
		TempEffects::instance()->insert( new cRefreshTracking( player->serial(), choice.button ) );
	}
void Human_Stablemaster::handleTargetInput( P_PLAYER player, cUORxTarget* target )
{
	if ( !player )
		return;

	P_ITEM pPack = m_npc->getBankbox();
	if ( !pPack )
		return;

	P_NPC pPet = dynamic_cast<P_NPC>( World::instance()->findChar( target->serial() ) );
	if ( !pPet )
	{
		m_npc->talk( tr( "I cannot stable that!" ) );
		return;
	}

	if ( pPet->owner() != player )
	{
		m_npc->talk( tr( "This does not belong to you!" ) );
		return;
	}

	// we spawn a worldgem in the stablemasters bankbox for the pet
	// it does only hold the serial of it, the serial of the owner and the
	// number of refresh signals since begin of stabling
	// the pet becomes "free", which means, that it isnt in the world
	// but will still be saved.
	P_ITEM pGem = new cItem();
	pGem->Init( true );
	pGem->setTag( "player", cVariant( player->serial() ) );
	pGem->setTag( "pet", cVariant( pPet->serial() ) );
	pGem->setId( 0x1ea7 );
	pGem->setName( tr( "petitem: %1" ).arg( pPet->name() ) );
	pGem->setVisible( 2 ); // gm visible
	pPack->addItem( pGem );
	pGem->update();


	//pPet->free = true;
	MapObjects::instance()->remove( pPet );
	pPet->setStablemasterSerial( this->m_npc->serial() );
	pPet->removeFromView();

	// we need this for db saves
    m_npc->talk( tr( "Say release to get your pet back!" ) );
}
Example #10
0
void cNPC::setOwner(P_PLAYER data, bool nochecks)
{
	// We CANT be our own owner
	if( data && ( data->serial() == this->serial() ) )
		return;

	if( !nochecks && owner_ )
	{
		owner_->removePet(this, true);
	}

	owner_ = data;
	changed( TOOLTIP );
	changed_ = true;

	if( !nochecks && owner_ )
	{
		owner_->addPet(this, true);
	}
}
Example #11
0
void cGuild::save()
{
	QStringList fields;
	fields.append( QString::number( serial_ ) );
	fields.append( QString( "'%1'" ).arg( PersistentBroker::instance()->quoteString( name_ ) ) );
	fields.append( QString( "'%1'" ).arg( PersistentBroker::instance()->quoteString( abbreviation_ ) ) );
	fields.append( QString( "'%1'" ).arg( PersistentBroker::instance()->quoteString( charta_ ) ) );
	fields.append( QString( "'%1'" ).arg( PersistentBroker::instance()->quoteString( website_ ) ) );
	fields.append( QString::number( alignment_ ) );
	if ( leader_ )
	{
		fields.append( QString::number( leader_->serial() ) );
	}
	else
	{
		fields.append( "-1" );
	}
	fields.append( QString::number( founded_.toTime_t() ) );
	if ( guildstone_ )
	{
		fields.append( QString::number( guildstone_->serial() ) );
	}
	else
	{
		fields.append( "-1" );
	}

	PersistentBroker::instance()->executeQuery( QString( "INSERT INTO guilds VALUES(%1);" ).arg( fields.join( "," ) ) );

	// Save Members/Canidates
	P_PLAYER player;

	foreach ( player, members_ )
	{
		MemberInfo* info = getMemberInfo( player );
		PersistentBroker::instance()->executeQuery( QString( "INSERT INTO guilds_members VALUES(%1,%2,%3,'%4',%5);" )
			.arg( serial_ ).arg( player->serial() ).arg( info->showSign() ? 1 : 0 )
			.arg( PersistentBroker::instance()->quoteString( info->guildTitle() ) )
			.arg( info->joined() ) );
	}
Example #12
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 #13
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;
}
Example #14
0
void cParty::handlePacket( cUOSocket* socket, cUOPacket* packet )
{
	unsigned char subcommand = ( *packet )[5];
	QString message;
	P_PLAYER leader = 0;
	P_PLAYER player = socket->player();

	switch ( subcommand )
	{
		// Add a member to the party
	case 1:
		socket->clilocMessage( 1005454 );
		socket->attachTarget( new cPartyInvitation( player->serial() ) );
		break;

		// Remove member from party.
	case 2:
		if ( packet->size() == 10 )
		{
			P_PLAYER target = dynamic_cast<P_PLAYER>( World::instance()->findChar( packet->getInt( 6 ) ) );

			if ( target && player->party() && target->party() )
			{
				if ( player->party() == target->party() && player->party()->leader() == player )
				{
					socket->log( LOG_TRACE, tr( "Removed '%1' from the party.\n" ).arg( target->account()->login() ) );
					player->party()->removeMember( target );
				}
				else if ( target == player )
				{
					socket->log( LOG_TRACE, tr( "Left the party.\n" ).arg( player->account()->login() ) );
					player->party()->removeMember( target );
				}
			}
		}
		break;

		// Send a single party member a message
	case 3:
		if ( player->party() )
		{
			P_PLAYER target = dynamic_cast<P_PLAYER>( World::instance()->findChar( packet->getInt( 6 ) ) );
			if ( target )
			{
				socket->log( LOG_TRACE, tr( "Told '%1' in party '%2'.\n" ).arg( target->account()->login() ).arg( message ) );
				QString message = packet->getUnicodeString( 10, packet->size() - 10 );
				player->party()->send( player, target, message );
			}
		}
		break;

		// Send the whole party a message
	case 4:
		if ( player->party() )
		{
			QString message = packet->getUnicodeString( 6, packet->size() - 6 );
			socket->log( LOG_TRACE, tr( "Told the whole party: '%1'.\n" ).arg( message ) );
			player->party()->send( player, message );
		}
		break;

		// Allow or Disallow my party from looting my corpse
	case 6:
		if ( player->party() && packet->size() == 7 )
		{
			bool allowed = ( *packet )[6] != 0;
			player->party()->setLootingAllowed( player, allowed );
			socket->clilocMessage( allowed ? 1005447 : 1005448 );
		}
		break;

		// Accept party invitation
	case 8:
		Timers::instance()->dispel( player, 0, "cancelpartyinvitation", true, false );

		leader = dynamic_cast<P_PLAYER>( World::instance()->findChar( packet->getInt( 6 ) ) );
		if ( leader && leader->party() && leader->party()->canidates().contains( player ) )
		{
			leader->party()->addMember( player );
			socket->log( tr( "Accepted party invitation from '%1'.\n" ).arg( leader->account()->login() ) );
		}
		break;

		// Decline party invitation
	case 9:
		Timers::instance()->dispel( player, 0, "cancelpartyinvitation", true, false );

		leader = dynamic_cast<P_PLAYER>( World::instance()->findChar( packet->getInt( 6 ) ) );
		if ( leader && leader->party() && leader->party()->canidates().contains( player ) )
		{
			leader->socket()->clilocMessageAffix( 1008091, 0, player->name(), 0x3b2, 3, 0, false, true );
			leader->party()->removeMember( player );
			socket->clilocMessage( 1008092 );

			socket->log( LOG_TRACE, tr( "Declined party invitation from '%1'.\n" ).arg( leader->account()->login() ) );
		}
		break;

	default:
		message.sprintf( "Receieved unknown party subcommand: 0x%02x", subcommand );
		message += packet->dump( packet->uncompressed() ) + "\n";
		socket->log( LOG_WARNING, message );
		break;
	};
}
Example #15
0
	bool responsed( cUOSocket* socket, cUORxTarget* target )
	{
		if ( !isCharSerial( target->serial() ) )
		{
			socket->clilocMessage( 1005442 );
		}
		else
		{
			P_PLAYER leader = dynamic_cast<P_PLAYER>( World::instance()->findChar( this->player ) );
			P_CHAR character = World::instance()->findChar( target->serial() );
			P_NPC npc = dynamic_cast<P_NPC>( character );
			P_PLAYER player = dynamic_cast<P_PLAYER>( character );

			if ( !leader || ( leader->party() && leader->party()->leader() != leader ) )
			{
				socket->clilocMessage( 1005453 );
			}
			else if ( leader->party() && leader->party()->members().count() + leader->party()->canidates().count() >= 10 )
			{
				socket->clilocMessage( 1008095 );
				// NPC targetted
			}
			else if ( npc )
			{
				if ( npc->isHuman() )
					socket->clilocMessage( 1005443, 0, npc->saycolor(), 3, npc );
				else
					socket->clilocMessage( 1005444 );
			}
			else if ( leader == player )
			{
				socket->clilocMessage( 1005439 );
			}
			else if ( player && player->party() && player->party() == leader->party() )
			{
				socket->clilocMessage( 1005440 );
			}
			else if ( player && leader->party() && leader->party()->canidates().contains( player ) )
			{
				socket->clilocMessage( 1005440 );
			}
			else if ( player && player->party() )
			{
				socket->clilocMessage( 1005441 );
			}
			else if ( player && player->socket() )
			{
				if ( !leader->party() )
				{
					new cParty( leader );
					leader->party()->update();
				}

				player->socket()->clilocMessageAffix( 1008089, 0, leader->name(), 0x3b2, 3, 0, false, true );
				leader->party()->addCanidate( player );
				socket->log( LOG_TRACE, tr( "Invited '%1' to join his party.\n" ).arg( player->account()->login() ) );

				// Send a party invitation request
				cUOTxPartyInvitation invitation;
				invitation.setSerial( leader->serial() );
				player->socket()->send( &invitation );

				// Attach a tempeffect that'll cancel the invitation after ten seconds
				Timers::instance()->insert( new cPartyCancelInvitation( leader->serial(), player->serial() ) );
			}
		}

		return true;
	}
Example #16
0
void cSkills::RandomSteal( cUOSocket* socket, SERIAL victim )
{
	P_PLAYER pChar = socket->player();
	P_CHAR pVictim = FindCharBySerial( victim );

	if ( !pVictim || !pChar )
		return;

	if ( pVictim->serial() == pChar->serial() )
	{
		socket->sysMessage( tr( "Why don't you simply take it?" ) );
		return;
	}

	/*	if( pVictim->npcaitype() == 17 )
		{
			socket->sysMessage( tr( "You cannot steal from Playervendors." ) );
			return;
		}
	*/
	if ( pVictim->objectType() == enPlayer )
	{
		P_PLAYER pp = dynamic_cast<P_PLAYER>( pVictim );
		if ( pp->isGMorCounselor() )
			socket->sysMessage( tr( "You can't steal from game masters." ) );
		return;
	}

	if ( !pChar->inRange( pVictim, 1 ) )
	{
		socket->sysMessage( tr( "You are too far away to steal from that person." ) );
		return;
	}

	P_ITEM pBackpack = pVictim->getBackpack();

	if ( !pBackpack )
	{
		socket->sysMessage( tr( "Bad luck, your victim doesn't have a backpack." ) );
		return;
	}

	float maxWeight = ( float ) QMIN( 1, pChar->skillValue( STEALING ) ); // We can steal max. 10 Stones when we are a GM
	// 1000 Skill == 100 Weight == 10 Stones

	QPtrList<cItem> containment = pBackpack->getContainment();
	Q_UINT32 chance = containment.count();

	P_ITEM pItem = containment.first();
	P_ITEM pToSteal = 0;
	bool sawOkItem = false;

	while ( !pToSteal )
	{
		// We have nothing that could be stolen?
		if ( !pItem && !sawOkItem )
		{
			socket->sysMessage( tr( "Your victim posesses nothing you could steal." ) );
			return;
		}
		// Jump back to the beginning
		else if ( !pItem && sawOkItem )
		{
			pItem = containment.first();
		}

		// Check if our chance becomes true (no spellbooks!)
		if ( pItem->totalweight() <= maxWeight && !pItem->isLockedDown() && !pItem->newbie() && pItem->type() != 9 )
		{
			sawOkItem = true; // We have items that could be stolen (just in case we reach the end of our list)

			// We have the chance of 1/chance that we reached our desired item
			if ( RandomNum( 1, ( int )chance ) == ( int )chance )
			{
				pToSteal = pItem;
				break;
			}
		}

		pItem = containment.next();
	}

	socket->sysMessage( tr( "You reach into %1's backpack and try to steal something..." ).arg( pVictim->name() ) );

	// The success of our Theft depends on the weight of the stolen item
	bool success = pChar->checkSkill( STEALING, 0, ( long int )pToSteal->weight() );
	bool caught = false;

	if ( success )
	{
		socket->sysMessage( tr( "You successfully steal %1." ).arg( pToSteal->getName() ) );
		P_ITEM pPack = pChar->getBackpack();
		pPack->addItem( pToSteal );
		// Update item onyl if still existent
		if ( !pToSteal->free )
			pToSteal->update();

		caught = pChar->skillValue( STEALING ) < rand() % 1001;
	}
	else
	{
		socket->sysMessage( tr( "You fail to steal the item." ) );

		// 1 in 5 Chance if we failed
		caught = RandomNum( 1, 5 ) == 1;
	}

	// Did we get caught?
	if ( caught )
	{
		socket->sysMessage( tr( "You have been cought!" ) );

		// Human non red NPCs need special handling
		if ( pVictim->objectType() == enNPC && pVictim->isInnocent() && pVictim->isHuman() )
		{
			P_NPC pn = dynamic_cast<P_NPC>( pVictim );
			pVictim->talk( tr( "Guards! A thief is amoung us!" ), 0xFFFF, 0x09 );
			if ( pVictim->region() && pVictim->region()->isGuarded() )
				pn->callGuards();
		}

		if ( pVictim->notoriety( pChar ) == 0x01 )
			pChar->makeCriminal();

		// Our Victim always notices it.
		if ( pVictim->objectType() == enPlayer )
		{
			P_PLAYER pp = dynamic_cast<P_PLAYER>( pVictim );
			if ( pp->socket() )
				pp->socket()->showSpeech( pChar, tr( "You notice %1 trying to steal %2 from you." ).arg( pChar->name() ).arg( pToSteal->getName( true ) ) );
		}

		QString message = tr( "You notice %1 trying to steal %2 from %3." ).arg( pChar->name() ).arg( pItem->getName() ).arg( pVictim->name() );

		for ( cUOSocket*mSock = Network::instance()->first(); mSock; mSock = Network::instance()->next() )
		{
			// Everyone within 7 Tiles notices us
			if ( mSock != socket && mSock->player() && mSock->player()->serial() != pVictim->serial() && mSock->player()->inRange( pChar, 7 ) )
				mSock->showSpeech( pChar, message );
		}
	}
}