Esempio n. 1
0
void cPlayer::giveGold( quint32 amount, bool inBank )
{
	P_ITEM pCont = NULL;
	if ( !inBank )
		pCont = getBackpack();
	else
		pCont = getBankbox();

	if ( !pCont )
		return;

	// Begin Spawning
	quint32 total = amount;

	while ( total > 0 )
	{
		P_ITEM pile = cItem::createFromScript( "eed" );
		pile->setAmount( wpMin<quint32>( total, static_cast<quint32>( 65535 ) ) );
		total -= pile->amount();

		pCont->addItem( pile );
		if ( !pile->free )
		{
			pile->update();
		}
	}

	goldSound( amount, false );
}
void IDefReader::processScriptItemNode( P_ITEM madeItem, QDomElement &Node )
{
	for( UI16 k = 0; k < Node.childNodes().count(); k++ )
	{
		QDomElement currChild = Node.childNodes().item( k ).toElement();
		if( currChild.nodeName() == "amount" )
		{
			QString Value = QString();
			UI16 i = 0;
			if( currChild.hasChildNodes() ) // <random> i.e.
				for( i = 0; i < currChild.childNodes().count(); i++ )
				{
					if( currChild.childNodes().item( i ).isText() )
						Value += currChild.childNodes().item( i ).toText().data();
					else if( currChild.childNodes().item( i ).isElement() )
						Value += processNode( currChild.childNodes().item( i ).toElement() );
				}
			else
				Value = currChild.nodeValue();

			if( Value.toInt() < 1 )
				Value = QString("1");

			if( madeItem->isPileable() )
				madeItem->setAmount( Value.toInt() );
			else
				for( i = 1; i < Value.toInt(); i++ ) //dupe it n-1 times
					Commands->DupeItem(-1, madeItem, 1);
		}
		else if( currChild.nodeName() == "color" ) //process <color> tags
		{
			QString Value = QString();
			if( currChild.hasChildNodes() ) // colorlist or random i.e.
				for( UI16 i = 0; i < currChild.childNodes().count(); i++ )
				{
					if( currChild.childNodes().item( i ).isText() )
						Value += currChild.childNodes().item( i ).toText().data();
					else if( currChild.childNodes().item( i ).isElement() )
						Value += processNode( currChild.childNodes().item( i ).toElement() );
				}
			else
				Value = currChild.nodeValue();
			
			if( Value.toInt() < 0 )
				Value = QString("0");

			madeItem->setColor( Value.toInt() );
		}
		else if( currChild.nodeName() == "inherit" && currChild.attributes().contains("id") )
		{
			QDomElement* derivalSection = DefManager->getSection( WPDT_ITEM, currChild.attribute("id") );
			if( !derivalSection->isNull() )
				this->applyNodes( madeItem, derivalSection );
		}
	}
}
Esempio n. 3
0
void DragAndDrop::dropOnBeggar( cUOSocket* socket, P_ITEM pItem, P_CHAR pBeggar )
{
	int tempint;

	if( ( pBeggar->hunger() < 6 ) && pItem->type() == 14 )
	{
		pBeggar->talk( tr("*cough* Thank thee!") );
		pBeggar->soundEffect( 0x3A + RandomNum( 1, 3 ) );

		// *You see Snowwhite eating some poisoned apples*
		// Color: 0x0026
		pBeggar->emote( tr( "*You see %1 eating %2*" ).arg( pBeggar->name() ).arg( pItem->getName() ) );

		// We try to feed it more than it needs
		if( pBeggar->hunger() + pItem->amount() > 6 )
		{

//			client->player()->karma += ( 6 - pBeggar->hunger() ) * 10;
			tempint = ( 6 - pBeggar->hunger() ) * 10;
			socket->player()->setKarma( socket->player()->karma() + tempint );

			pItem->setAmount( pItem->amount() - ( 6 - pBeggar->hunger() ) );
			pBeggar->setHunger( 6 );

			// Pack the rest into his backpack
			bounceItem( socket, pItem );
			return;
		}

		pBeggar->setHunger( pBeggar->hunger() + pItem->amount() );
//		client->player()->karma += pItem->amount() * 10;
		tempint = pItem->amount() * 10;
		socket->player()->setKarma( socket->player()->karma() + tempint );

		pItem->remove();
		return;
	}

	// No Food? Then it has to be Gold
	if( pItem->id() != 0xEED )
	{
		pBeggar->talk( tr("Sorry, but i can only use gold.") );
		bounceItem( socket, pItem );
		return;
	}

	pBeggar->talk( tr( "Thank you %1 for the %2 gold!" ).arg( socket->player()->name() ).arg( pItem->amount() ) );
	socket->sysMessage( tr("You have gained some karma!") );

	if( pItem->amount() <= 100 )
		socket->player()->setKarma( socket->player()->karma() + 10 );
	else
		socket->player()->setKarma( socket->player()->karma() + 50 );

	pItem->remove();
}
Esempio n. 4
0
// Item was dropped on a pet
void cDragItems::dropOnPet( P_CLIENT client, P_ITEM pItem, P_CHAR pPet )
{
	// Feed our pets
	if( ( pPet->hunger() >= 6 ) || pItem->type() != 14 )
	{
		client->sysMessage( "It doesn't seem to want your item" );
		bounceItem( client, pItem );
		return;
	}

	// We have three different eating-sounds (I don't like the idea as they sound too human)
	pPet->soundEffect( 0x3A + RandomNum( 1, 3 ) );

	// If you want to poison a pet... Why not
	if( pItem->poisoned && pPet->poisoned() < pItem->poisoned )
	{
		pPet->soundEffect( 0x246 );
		pPet->setPoisoned( pItem->poisoned );
		
		// a lev.1 poison takes effect after 40 secs, a deadly pois.(lev.4) takes 40/4 secs - AntiChrist
		pPet->setPoisontime( uiCurrentTime + ( MY_CLOCKS_PER_SEC * ( 40 / pPet->poisoned() ) ) );
		
		//wear off starts after poison takes effect - AntiChrist
		pPet->setPoisonwearofftime(pPet->poisontime() + ( MY_CLOCKS_PER_SEC * SrvParams->poisonTimer() ) );
		
		// Refresh the health-bar of our target
		impowncreate( client->socket(), pPet, 1 );
	}

	// *You see Snowwhite eating some poisoned apples*
	// Color: 0x0026
	QString emote = QString( "*You see %1 eating %2*" ).arg( pPet->name.c_str() ).arg( pItem->getName() );
	pPet->emote( emote );

	// We try to feed it more than it needs
	if( pPet->hunger() + pItem->amount() > 6 )
	{
		pItem->setAmount( pItem->amount() - ( 6 - pPet->hunger() ) );
		pPet->setHunger( 6 );

		// Pack the rest into his backpack
		bounceItem( client, pItem );
		return;
	}

	pPet->setHunger( pPet->hunger() + pItem->amount() );
	Items->DeleItem( pItem );
}
Esempio n. 5
0
// Food was dropped on a pet
void cDragItems::dropFoodOnChar( cUOSocket* socket, P_ITEM pItem, P_CHAR pChar )
{
	// Feed our pets
	if( pChar->hunger() >= 6 || pItem->type2() == 0 || !( pChar->nutriment() & ( 1 << (pItem->type2()-1) ) ) )
	{
		socket->sysMessage( tr("It doesn't seem to want your item") );
		bounceItem( socket, pItem );
		return;
	}

	// We have three different eating-sounds (I don't like the idea as they sound too human)
	pChar->soundEffect( 0x3A + RandomNum( 1, 3 ) );

	// If you want to poison a pet... Why not
	if( pItem->poisoned() && pChar->poisoned() < pItem->poisoned() )
	{
		pChar->soundEffect( 0x246 );
		pChar->setPoisoned( pItem->poisoned() );
		
		// a lev.1 poison takes effect after 40 secs, a deadly pois.(lev.4) takes 40/4 secs - AntiChrist
		pChar->setPoisonTime( uiCurrentTime + ( MY_CLOCKS_PER_SEC * ( 40 / pChar->poisoned() ) ) );
		
		//wear off starts after poison takes effect - AntiChrist
		pChar->setPoisonWearOffTime(pChar->poisonTime() + ( MY_CLOCKS_PER_SEC * SrvParams->poisonTimer() ) );
		
		// Refresh the health-bar of our target
		pChar->resend( false );
	}

	// *You see Snowwhite eating some poisoned apples*
	// Color: 0x0026
	pChar->emote( tr( "*You see %1 eating %2*" ).arg( pChar->name() ).arg( pItem->getName() ) );

	// We try to feed it more than it needs
	if( pChar->hunger() + pItem->amount() > 6 )
	{
		pItem->setAmount( pItem->amount() - ( 6 - pChar->hunger() ) );
		pChar->setHunger( 6 );

		// Pack the rest into his backpack
		bounceItem( socket, pItem );
		return;
	}

	pChar->setHunger( pChar->hunger() + pItem->amount() );
	Items->DeleItem( pItem );
}
Esempio n. 6
0
void cNPC::giveGold( Q_UINT32 amount, bool inBank )
{
	P_ITEM pCont = getBackpack();

	if( !pCont )
		return;

	// Begin Spawning
	Q_UINT32 total = amount;

	while( total > 0 )
	{
		P_ITEM pile = cItem::createFromScript( "eed" );
		pile->setAmount( QMIN( total, static_cast<Q_UINT32>(65535) ) );
		pCont->addItem( pile );
		total -= pile->amount();
	}
}
Esempio n. 7
0
void cDragItems::dropOnBeggar( cUOSocket* socket, P_ITEM pItem, P_CHAR pBeggar )
{
	int tempint;
	
	if( ( pBeggar->hunger() < 6 ) && pItem->type() == 14 )
	{
		pBeggar->talk( tr("*cough* Thank thee!") );
		pBeggar->soundEffect( 0x3A + RandomNum( 1, 3 ) );

		// If you want to poison a pet... Why not
		if( pItem->poisoned() && pBeggar->poisoned() < pItem->poisoned() )
		{
			pBeggar->soundEffect( 0x246 );
			pBeggar->setPoisoned( pItem->poisoned() );
			
			// a lev.1 poison takes effect after 40 secs, a deadly pois.(lev.4) takes 40/4 secs - AntiChrist
			pBeggar->setPoisonTime( uiCurrentTime + ( MY_CLOCKS_PER_SEC * ( 40 / pBeggar->poisoned() ) ) );
			
			//wear off starts after poison takes effect - AntiChrist
			pBeggar->setPoisonWearOffTime( pBeggar->poisonTime() + ( MY_CLOCKS_PER_SEC * SrvParams->poisonTimer() ) );
			
			// Refresh the health-bar of our target
			pBeggar->resend( false );
		}


		// *You see Snowwhite eating some poisoned apples*
		// Color: 0x0026
		pBeggar->emote( tr( "*You see %1 eating %2*" ).arg( pBeggar->name() ).arg( pItem->getName() ) );

		// We try to feed it more than it needs
		if( pBeggar->hunger() + pItem->amount() > 6 )
		{
			
//			client->player()->karma += ( 6 - pBeggar->hunger() ) * 10;
			tempint = ( 6 - pBeggar->hunger() ) * 10;
			socket->player()->setKarma( socket->player()->karma() + tempint );

			pItem->setAmount( pItem->amount() - ( 6 - pBeggar->hunger() ) );
			pBeggar->setHunger( 6 );

			// Pack the rest into his backpack
			bounceItem( socket, pItem );
			return;
		}

		pBeggar->setHunger( pBeggar->hunger() + pItem->amount() );
//		client->player()->karma += pItem->amount() * 10;
		tempint = pItem->amount() * 10;
		socket->player()->setKarma( socket->player()->karma() + tempint );

		Items->DeleItem( pItem );
		return;
	}

	// No Food? Then it has to be Gold
	if( pItem->id() != 0xEED )
	{
		pBeggar->talk( tr("Sorry, but i can only use gold.") );
		bounceItem( socket, pItem );
		return;
	}

	pBeggar->talk( tr( "Thank you %1 for the %2 gold!" ).arg( socket->player()->name() ).arg( pItem->amount() ) );
	socket->sysMessage( tr("You have gained some karma!") );
	
	if( pItem->amount() <= 100 )
		socket->player()->setKarma( socket->player()->karma() + 10 );
	else
		socket->player()->setKarma( socket->player()->karma() + 50 );
	
	Items->DeleItem( pItem );
}
Esempio n. 8
0
// New Class implementation
void cDragItems::grabItem( cUOSocket *socket, cUORxDragItem *packet )
{
	// Get our character
	P_PLAYER pChar = socket->player();
	if( !pChar )
		return;

	UINT32 weight = pChar->weight();

	// Fetch the grab information
	UI16 amount = packet->amount();
	if( !amount )
		amount = 1;

	P_ITEM pItem = FindItemBySerial( packet->serial() );

	// If it's an invalid pointer we can't even bounce
	if( !pItem )
		return;

	// Are we already dragging an item ?
	// Bounce it and reject the move
	// (Logged out while dragging an item)
	if( socket->dragging() )
	{
		socket->bounceItem( socket->dragging(), BR_ALREADY_DRAGGING );
		return;
	}

	if( pItem->onPickup( pChar ) )
		return;

	if( pChar->onPickup( pItem ) )
		return;

	// Do we really want to let him break his meditation
	// When he picks up an item ?
	// Maybe a meditation check here ?!?
	pChar->disturbMed(); // Meditation

	P_CHAR itemOwner = pItem->getOutmostChar();

	// Try to pick something out of another characters posessions
	if( !pChar->isGM() && itemOwner && ( itemOwner != pChar ) && ( itemOwner->objectType() == enNPC && dynamic_cast<P_NPC>(itemOwner)->owner() != pChar ) )
	{
		socket->bounceItem( pItem, BR_BELONGS_TO_SOMEONE_ELSE );
		return;
	}

	// Check if the user can grab the item
	if( !pChar->canPickUp( pItem ) )
	{
		socket->bounceItem( pItem, BR_CANNOT_PICK_THAT_UP );
		return;
	}

	// The user can't see the item
	// Basically thats impossible as the socket should deny moving the item
	// if it's not in line of sight but to prevent exploits
	/*if( !line_of_sight( socket->socket(), pChar->pos, pItem->pos, TREES_BUSHES|WALLS_CHIMNEYS|DOORS|ROOFING_SLANTED|FLOORS_FLAT_ROOFING|LAVA_WATER ) )
	{
		socket->sysMessage( "You can't see the item." );
		bounceItem( socket, pItem, true );
		return;
	}*/

	P_ITEM outmostCont = pItem->getOutmostItem();

	// If it's a trade-window, reset the ack-status
	if( outmostCont && ( outmostCont->container() == pChar ) && ( outmostCont->layer() == 0 ) && ( outmostCont->id() == 0x1E5E ) )
	{
		// Get the other sides tradewindow
		P_ITEM tradeWindow = FindItemBySerial( calcserial( outmostCont->moreb1(), outmostCont->moreb2(), outmostCont->moreb3(), outmostCont->moreb4() ) );

		// If one of the trade-windows has the ack-status reset it
		if( tradeWindow && ( tradeWindow->morez() || outmostCont->morez() ) )
		{
			tradeWindow->setMoreZ(0);
			outmostCont->setMoreZ(0);
//			sendtradestatus( tradeWindow, outmostCont );
		}
	}

	// If the top-most container ( thats important ) is a corpse 
	// and looting is a crime, flag the character criminal.
	if( !pChar->isGM() && outmostCont && outmostCont->corpse() )
	{
		// For each item we take out we loose carma
		// if the corpse is innocent and not in our guild
		bool sameGuild = ( GuildCompare( pChar, outmostCont->owner() ) != 0 );

		if( ( outmostCont->more2() == 1 ) && !pChar->Owns( outmostCont ) && !sameGuild )
		{
//			pChar->karma -= 5;
			pChar->setKarma( pChar->karma() - 5 );
			pChar->setCriminalTime( uiCurrentTime + SrvParams->crimtime() * MY_CLOCKS_PER_SEC );
			socket->sysMessage( tr("You lost some karma.") );
		}
	}

	// Check if the item is too heavy
	//if( !pc_currchar->isGMorCounselor() )
	//{
	//} << Deactivated (DarkStorm)

	// ==== Grabbing the Item is allowed here ====
	
	// Remove eventual item-bonusses if we're unequipping something
	if( pItem->container() && pItem->container()->isChar() ) 
	{
		P_CHAR wearer = dynamic_cast<P_CHAR>( pItem->container() );

		if( wearer )
			wearer->removeItemBonus( pItem );

		// resend the stat window
		if( wearer && wearer->objectType() == enPlayer )
		{
			P_PLAYER pp = dynamic_cast<P_PLAYER>(wearer);
			if( pp->socket() )
				pp->socket()->sendStatWindow();
		}
	}

	// Send the user a pickup sound if we're picking it up
	// From a container/paperdoll
	if( !pItem->isInWorld() )
		socket->soundEffect( 0x57, pItem );
	
	// If we're picking up a specific amount of what we got
	// Take that into account
	if( amount < pItem->amount() )
	{
		UI32 pickedAmount = QMIN( amount, pItem->amount() );

		// We only have to split if we're not taking it all
		if( pickedAmount != pItem->amount() )
		{
			P_ITEM splitItem = new cItem( *pItem ); // Create a new item to pick that up
			splitItem->setSerial( World::instance()->findItemSerial() );
			splitItem->setAmount( pItem->amount() - pickedAmount );
			P_ITEM pContainer = dynamic_cast<P_ITEM>(pItem->container());
			if ( pContainer )
				pContainer->addItem( splitItem, false );
			splitItem->SetOwnSerial( pItem->ownSerial() );
			splitItem->SetSpawnSerial( pItem->spawnserial );

			// He needs to see the new item
			splitItem->update();

			// If we're taking something out of a spawn-region it's spawning "flag" is removed isn't it?
			pItem->SetSpawnSerial( INVALID_SERIAL );
			pItem->setAmount( pickedAmount );
		}
	}
	
	// *normally* we should exclude the dragging socket here. but it works so as well.
	pItem->removeFromView( true );

	// Remove it from the World if it is in world, otherwise remove it from it's current container
	if( pItem->isInWorld() )
		MapObjects::instance()->remove( pItem );
	else
		pItem->removeFromCont( true );

	// The item was in a multi
	if( pItem->multis() != INVALID_SERIAL )
	{
		cMulti* pMulti = dynamic_cast< cMulti* >( FindItemBySerial( pItem->multis() ) );
		if( pMulti )
			pMulti->removeItem( pItem );
	}
	
	pChar->addItem( cBaseChar::Dragging, pItem );

	if( weight != pChar->weight() )
		socket->sendStatWindow();
}
Esempio n. 9
0
void cDragItems::dropOnItem( cUOSocket *socket, P_ITEM pItem, P_ITEM pCont, const Coord_cl &dropPos )
{
	P_PLAYER pChar = socket->player();
	
	if( pItem->isMulti() )
	{
		socket->sysMessage( tr( "You cannot put houses in containers" ) );
		cUOTxBounceItem bounce;
		bounce.setReason( BR_NO_REASON );
		socket->send( &bounce );
		Items->DeleItem( pItem );
		return;
	}
	
	if( pItem->onDropOnItem( pCont ) )
	{
		if( socket->dragging() )
			socket->bounceItem( socket->dragging(), BR_NO_REASON );

		return;
	}
	else if( pCont->onDropOnItem( pItem ) )
	{
		if( socket->dragging() )
			socket->bounceItem( socket->dragging(), BR_NO_REASON );

		return;
	}

	// If the target belongs to another character 
	// It needs to be our vendor or else it's denied
	P_CHAR packOwner = pCont->getOutmostChar();

	if( ( packOwner ) && ( packOwner != pChar ) && !pChar->isGM() )
	{
		// For each item someone puts into there 
		// He needs to do a snoop-check
		if( pChar->maySnoop() )
		{
			if( !pChar->checkSkill( SNOOPING, 0, 1000 ) )
			{

				socket->sysMessage( tr( "You fail to put that into %1's pack" ).arg( packOwner->name() ) );
				socket->bounceItem( pItem, BR_NO_REASON );
				return;
			}
		}

		if( packOwner->objectType() == enPlayer || 
			( packOwner->objectType() == enNPC && dynamic_cast<P_NPC>(packOwner)->owner() != pChar ) )
		{
			socket->sysMessage( tr("You cannot put that into the belongings of another player") );
			socket->bounceItem( pItem, BR_NO_REASON );
			return;
		}
	}

	// If we put the item into a trade-window
	// Reset the trade-status for both players
	if( pCont->layer() == 0 && pCont->id() == 0x1E5E &&	pChar->Wears( pCont ) )
	{
		// Trade window???
		P_ITEM tradeWindow = FindItemBySerial( calcserial( pCont->moreb1(), pCont->moreb2(), pCont->moreb3(), pCont->moreb4() ) );

		// If it *IS* a trade-window, replace the status
		if( tradeWindow && ( pCont->morez() || tradeWindow->morez() ) )
		{
			tradeWindow->setMoreZ(0);
			pCont->setMoreZ(0);
//			sendtradestatus( tradeWindow, pCont );
		}
	}
	
	if( !pChar->canPickUp( pItem ) )
	{
		socket->bounceItem( pItem, BR_CANNOT_PICK_THAT_UP );
		return;
	}

	// Trash can
	if( pCont->type()==87 )
	{
		Items->DeleItem( pItem );
		socket->sysMessage( tr( "As you let go of the item it disappears." ) );
		return;
	}

	// Spell Book
	cSpellBook *pBook = dynamic_cast< cSpellBook* >( pCont );
	if( pBook )
 	{
		SI08 spellId = NewMagic->calcSpellId( pItem->id() );

		if( pItem->type() != 1105 || spellId < 0 )
		{
			socket->sysMessage( tr( "You can only put scrolls into a spellbook" ) );
			socket->bounceItem( pItem, BR_NO_REASON );
			return;
		}		

		if( pBook->hasSpell( spellId ) )
		{
			socket->sysMessage( tr( "That spellbook already contains this spell" ) );
			socket->bounceItem( pItem, BR_NO_REASON );
			return;
		}

		if( pItem->amount() > 1 )
		{
			socket->sysMessage( tr( "You can only put 1 scroll into a spellbook at a time" ) );
			socket->bounceItem( pItem, BR_NO_REASON );
			return;
		}
		else
		{	
			pBook->addSpell( spellId );
			Items->DeleItem( pItem );
			pBook->update( socket );
			return;
		}
	}

	// We drop something on the belongings of one of our playervendors
/*	if( ( packOwner != NULL ) && ( packOwner->npcaitype() == 17 ) && packOwner->owner() == pChar )
	{
		socket->sysMessage( tr( "You drop something into your playervendor (unimplemented)" ) );
		socket->bounceItem( pItem, BR_NO_REASON );
		return;
	}*/

	// Playervendors (chest equipped by the vendor - opened to the client)

	/*if( !( pCont->pileable() && pItem->pileable() && pCont->id() == pItem->id() || ( pCont->type() != 1 && pCont->type() != 9 ) ) )
	{
		P_CHAR pc_j = GetPackOwner(pCont);
		if (pc_j != NULL)
		{
			if (pc_j->npcaitype() == 17 && pc_j->isNpc() && pChar->Owns(pc_j))
			{
				pChar->inputitem = pItem->serial;
				pChar->inputmode = cChar::enPricing;
				sysmessage(s, "Set a price for this item.");
			}
		}
	*/

	// We may also drop into *any* locked chest
	// So we can have post-boxes ;o)
	// Spellbooks are containers for us as well
	if( pCont->type() == 1 || pCont->type() == 8 || pCont->type() == 63 || pCont->type() == 65 || pCont->type() == 66 )
	{
		// If we're dropping it onto the closed container
		if( dropPos.distance( pCont->pos() ) == 0 )
		{
			pCont->addItem( pItem );
		}
		else
		{
			pCont->addItem( pItem, false );
			pItem->setPos( dropPos );
		}

		// Dropped on another Container/in another Container
		pChar->soundEffect( 0x57 );
		pItem->update();
		return;
	}
	// Item matching needs to be extended !!! at least Color! (for certain types)
	else if ( pCont->isPileable() && pItem->isPileable() && ( pCont->id() == pItem->id() ) )
	{
		if( pCont->amount() + pItem->amount() <= 65535 )
		{
			pCont->setAmount( pCont->amount() + pItem->amount() );
			
			Items->DeleItem( pItem );
			pCont->update(); // Need to update the amount
			return;
		}
		// We have to *keep* our current item
		else
		{
			pCont->setAmount( 65535 ); // Max out the amount
			pCont->update();

			// The delta between 65535 and pCont->amount() sub our Amount is the
			// new amount
			pItem->setAmount( pItem->amount() - ( 65535 - pCont->amount() ) );
		}
	}

	// We dropped the item NOT on a container
	// And were *un*able to stack it (!)
	// >> Set it to the location of the item we dropped it on and stack it up by 2
	pItem->moveTo( pCont->pos() );
	pItem->setPos( pItem->pos() + Coord_cl(0, 0, 2) );
	pItem->update();

/*	// This needs to be checked
	// It annoyingly shows the spellbook
	// whenever you add a scroll
	// << could it be that addItemToContainer is enough?? >>
	if( pCont->type() == 9 )
		Magic->openSpellBook( pChar, pCont );*/
}
Esempio n. 10
0
// New Class implementation
void cDragItems::grabItem( P_CLIENT client )
{
	// Get our character
	P_CHAR pChar = client->player();
	if( pChar == NULL )
		return;

	// Fetch the grab information
	SERIAL iSerial = LongFromCharPtr( &buffer[ client->socket() ][ 1 ] );
	UI16 amount = ShortFromCharPtr( &buffer[ client->socket() ][ 5 ] );

	P_ITEM pItem = FindItemBySerial( iSerial );

	if( !pItem )
		return;

	// Are we already dragging an item ?
	// Bounce it and reject the move
	// (Logged out while dragging an item)
	if( client->dragging() )
	{
		bounceItem( client, client->dragging() );
		bounceItem( client, pItem, true );
		return;
	}

	// Do we really want to let him break his meditation
	// When he picks up an item ?
	// Maybe a meditation check here ?!?
	pChar->disturbMed( client->socket() ); // Meditation

	P_CHAR itemOwner = GetPackOwner( pItem, 64 );

	// Try to pick something out of another characters posessions
	if( itemOwner && ( itemOwner != pChar ) && ( !pChar->Owns( itemOwner ) ) )
	{
		client->sysMessage( QString( "You have to steal the %1 out of %2's posessions." ).arg( pItem->getName() ).arg( itemOwner->name.c_str() ) );
		bounceItem( client, pItem, true );
		return;
	}

	// Check if the user can grab the item
	if( !pChar->canPickUp( pItem ) )
	{
		client->sysMessage( "You cannot pick that up." );
		bounceItem( client, pItem, true );
		return;
	}

	// The user can't see the item
	// Basically thats impossible as the client should deny moving the item
	// if it's not in line of sight but to prevent exploits
	if( !line_of_sight( client->socket(), pChar->pos, pItem->pos, TREES_BUSHES|WALLS_CHIMNEYS|DOORS|ROOFING_SLANTED|FLOORS_FLAT_ROOFING|LAVA_WATER ) )
	{
		client->sysMessage( "You can't see the item." );
		bounceItem( client, pItem, true );
		return;
	}

	P_ITEM outmostCont = GetOutmostCont( pItem, 64 );  

	// If it's a trade-window, reset the ack-status
	if( outmostCont && ( outmostCont->contserial == pChar->serial ) && ( outmostCont->layer() == 0 ) && ( outmostCont->id() == 0x1E5E ) )
	{
		// Get the other sides tradewindow
		P_ITEM tradeWindow = FindItemBySerial( calcserial( outmostCont->moreb1(), outmostCont->moreb2(), outmostCont->moreb3(), outmostCont->moreb4() ) );

		// If one of the trade-windows has the ack-status reset it
		if( tradeWindow && ( tradeWindow->morez || outmostCont->morez ) )
		{
			tradeWindow->morez = 0;
			outmostCont->morez = 0;
			sendtradestatus( tradeWindow, outmostCont );
		}
	}

	// If the top-most container ( thats important ) is a corpse 
	// and looting is a crime, flag the character criminal.
	if( outmostCont && outmostCont->corpse() )
	{
		// For each item we take out we loose carma
		// if the corpse is innocent and not in our guild
		bool sameGuild = ( GuildCompare( pChar, FindCharBySerial( outmostCont->ownserial ) ) != 0 );

		if( ( outmostCont->more2 == 1 ) && !pChar->Owns( outmostCont ) && !sameGuild )
		{
			pChar->karma -= 5;
			criminal( pChar );
			client->sysMessage( "You lost some karma." );
		}
	}

	// Check if the item is too heavy
	//if( !pc_currchar->isGMorCounselor() )
	//{
	//} << Deactivated (DarkStorm)

	// ==== Grabbing the Item is allowed here ====
	
	// Remove eventual item-bonusses if we're unequipping something
	if( pItem->layer() > 0 ) 
	{
		P_CHAR wearer = FindCharBySerial( pItem->contserial );

		if( wearer )
			wearer->removeItemBonus( pItem );
	}

	// Send the user a pickup sound if we're picking it up
	// From a container/paperdoll
	if( !pItem->isInWorld() )
		soundeffect( client->socket(), 0x00, 0x57 );
	
	// If we're picking up a specific amount of what we got
	// Take that into account
	if( pItem->amount() > 1 )
	{
		UI32 pickedAmount = min( amount, pItem->amount() );

		// We only have to split if we're not taking it all
		if( pickedAmount != pItem->amount() )
		{
			P_ITEM splitItem = new cItem( *pItem ); // Create a new item to pick that up
			splitItem->SetSerial( cItemsManager::getInstance()->getUnusedSerial() );
			splitItem->setAmount( pItem->amount() - pickedAmount );
			splitItem->setContSerial( pItem->contserial );
			splitItem->SetOwnSerial( pItem->ownserial );
			splitItem->SetSpawnSerial( pItem->spawnserial );

			// He needs to see the new item
			RefreshItem( splitItem ); 

			// If we're taking something out of a spawn-region it's spawning "flag" is removed isn't it?
			pItem->SetSpawnSerial( INVALID_SERIAL );
			pItem->setAmount( pickedAmount );
		}
	}
	
	pItem->setContSerial( pChar->serial );
	pItem->SetMultiSerial( INVALID_SERIAL ); 
	pItem->setLayer( 0x1E );
	
	// It's in the equipment of another character
	if( itemOwner && ( itemOwner != pChar ) )
	{
		itemOwner->weight -= pItem->getWeight();
		statwindow( calcSocketFromChar( itemOwner ), itemOwner );
	}

	// If the item is in the bank or any sell-container it's NOT counted as char-weight
	bool inBank = ( outmostCont && 	( outmostCont->contserial == pChar->serial ) && ( outmostCont->layer() >= 0x1A ) );

	// Add the weight if:
	//  - Picked from ground
	//  - Picked out of another character
	//  - Picked out of our bank or any other non-visible container
	if( ( itemOwner != pChar ) || !inBank )
	{
		pChar->weight += pItem->getWeight();	
		statwindow( client->socket(), pChar );
	}
}
Esempio n. 11
0
void cDragItems::dropOnItem( P_CLIENT client, P_ITEM pItem, P_ITEM pCont, const Coord_cl &dropPos )
{
	P_CHAR pChar = client->player();
	
	if( pItem->isMulti() )
	{
		client->sysMessage( "You cannot put houses in containers" );
		bounceItem( client, pItem );
		return;
	}
	
	// If the target belongs to another character 
	// It needs to be our vendor or else it's denied
	P_CHAR packOwner = GetPackOwner( pCont );

	if( ( packOwner != NULL ) && ( packOwner != pChar ) )
	{
		// For each item someone puts into there 
		// He needs to do a snoop-check
		if( pChar->canSnoop() )
		{
			if( !Skills->CheckSkill( pChar, SNOOPING, 0, 1000 ) )
			{

				client->sysMessage( QString( "You fail to put that into %1's pack" ).arg( packOwner->name.c_str() ) );
				bounceItem( client, pItem );
				return;
			}
		}

		if( !packOwner->isNpc() || ( packOwner->npcaitype() != 17 ) || !pChar->Owns( packOwner ) )
		{
			client->sysMessage( "You cannot put that into the belongings of another player" );
			bounceItem( client, pItem );
			return;
		}
	}

	// If we put the item into a trade-window
	// Reset the trade-status for both players
	if( pCont->layer() == 0 && pCont->id() == 0x1E5E &&	pChar->Wears( pCont ) )
	{
		// Trade window???
		P_ITEM tradeWindow = FindItemBySerial( calcserial( pCont->moreb1(), pCont->moreb2(), pCont->moreb3(), pCont->moreb4() ) );

		// If it *IS* a trade-window, replace the status
		if( tradeWindow && ( pCont->morez || tradeWindow->morez ) )
			{
				tradeWindow->morez = 0;
				pCont->morez = 0;
				sendtradestatus( tradeWindow, pCont );
			}
	}
	
	if( !pChar->canPickUp( pItem ) )
	{
		bounceItem( client, pItem );
		return;
	}

	// Trash can
	if( pCont->type()==87 )
	{
		Items->DeleItem( pItem );
		client->sysMessage( "As you let go of the item it disappears." );
		return;
	}

	// Spell Book
	if( pCont->type() == 9 )
	{
		UI08 spellId = Magic->calcSpellId( pItem->id() );

		if( spellId < 0 )
		{
			client->sysMessage( "You can only put scrolls into a spellbook" );
			bounceItem( client, pItem );
			return;
		}		

		if( Magic->hasSpell( pCont, spellId )  )
		{
			client->sysMessage( "That spellbook already contains this spell" );
			bounceItem( client, pItem );
			return;
		}
	}

	// We drop something on the belongings of one of our playervendors
	if( ( packOwner != NULL ) && ( packOwner->npcaitype() == 17 ) && pChar->Owns( packOwner ) )
	{
		client->sysMessage( "You drop something into your playervendor" );
		bounceItem( client, pItem );
		return;
	}

	// Playervendors (chest equipped by the vendor - opened to the client)

	/*if( !( pCont->pileable() && pItem->pileable() && pCont->id() == pItem->id() || ( pCont->type() != 1 && pCont->type() != 9 ) ) )
	{
		P_CHAR pc_j = GetPackOwner(pCont);
		if (pc_j != NULL)
		{
			if (pc_j->npcaitype() == 17 && pc_j->isNpc() && pChar->Owns(pc_j))
			{
				pChar->inputitem = pItem->serial;
				pChar->inputmode = cChar::enPricing;
				sysmessage(s, "Set a price for this item.");
			}
		}
	*/
	
	// We may also drop into *any* locked chest
	// So we can have post-boxes ;o)
	// Spellbooks are containers for us as well
	if( pCont->type() == 9 || pCont->type() == 1 || pCont->type() == 8 || pCont->type() == 63 || pCont->type() == 65 || pCont->type() == 66 )
	{
		pItem->setContSerial( pCont->serial );
		pItem->setLayer( 0 ); // Remove it from our drag-layer

		// Huh ? - Make that random will you!
		pItem->pos = dropPos;
		
		SndRemoveitem( pItem->serial );
		RefreshItem( pItem );
		
		// Dropped on another Container/in another Container
		soundeffect2( pChar, 0x57 );

		return;
	}
	// Item matching needs to be extended !!! at least Color! (for certain types)
	else if ( pCont->isPileable() && pItem->isPileable() && ( pCont->id() == pItem->id() ) )
	{
		if( pCont->amount() + pItem->amount() <= 65535 )
		{
			pCont->setAmount( pCont->amount() + pItem->amount() );
			Items->DeleItem( pItem );

			RefreshItem( pCont ); // Need to update the amount
			return;
		}
		// We have to *keep* our current item
		else
		{
			pCont->setAmount( 65535 ); // Max out the amount
			RefreshItem( pCont );

			// The delta between 65535 and pCont->amount() sub our Amount is the
			// new amount
			pItem->setAmount( pItem->amount() - ( 65535 - pCont->amount() ) );
		}
	}

	// We dropped the item NOT on a container
	// And were *un*able to stack it (!)
	// >> Set it to the location of the item we dropped it on and stack it up by 1
	pItem->moveTo( pCont->pos );
	pItem->pos.z++; // Increase z by 1
	pItem->pos.y++; // To get it visualized do that with y as well
	pItem->setLayer( 0 );
	pItem->setContSerial( pCont->contserial );
	RefreshItem( pItem );
				
	// This needs to be checked
	// It annoyingly shows the spellbook
	// whenever you add a scroll
	if( pCont->type() == 9 )
		Magic->openSpellBook( pChar, pCont );

	// Glowing Objects moved between chars
	if( pItem->glow != INVALID_SERIAL )
	{
		pChar->removeHalo( pItem );
				
		if( packOwner != NULL )
		{
			packOwner->addHalo(pItem);
			packOwner->glowHalo(pItem);
		}
	}
}
Esempio n. 12
0
void DragAndDrop::dropOnItem( cUOSocket* socket, P_ITEM pItem, P_ITEM pCont, const Coord_cl& dropPos )
{
	P_PLAYER pChar = socket->player();

	if ( pItem->isMulti() )
	{
		socket->sysMessage( tr( "You cannot put houses in containers" ) );
		cUOTxBounceItem bounce;
		bounce.setReason( BR_NO_REASON );
		socket->send( &bounce );
		pItem->remove();
		return;
	}

	if ( pItem->onDropOnItem( pCont ) )
	{
		if ( pItem->free )
			return;

		if ( socket->dragging() )
			socket->bounceItem( socket->dragging(), BR_NO_REASON );

		return;
	}
	else if ( pCont->onDropOnItem( pItem ) )
	{
		if ( pItem->free )
			return;

		if ( socket->dragging() )
			socket->bounceItem( socket->dragging(), BR_NO_REASON );

		return;
	}

	// If the target belongs to another character
	// It needs to be our vendor or else it's denied
	P_CHAR packOwner = pCont->getOutmostChar();

	if ( ( packOwner ) && ( packOwner != pChar ) && !pChar->isGM() )
	{
		// For each item someone puts into there
		// He needs to do a snoop-check
		if ( pChar->maySnoop() )
		{
			if ( !pChar->checkSkill( SNOOPING, 0, 1000 ) )
			{
				socket->sysMessage( tr( "You fail to put that into %1's pack" ).arg( packOwner->name() ) );
				socket->bounceItem( pItem, BR_NO_REASON );
				return;
			}
		}

		if ( packOwner->objectType() == enPlayer || ( packOwner->objectType() == enNPC && dynamic_cast<P_NPC>( packOwner )->owner() != pChar ) )
		{
			socket->sysMessage( tr( "You cannot put that into the belongings of another player" ) );
			socket->bounceItem( pItem, BR_NO_REASON );
			return;
		}
	}

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

	// We drop something on the belongings of one of our playervendors
	/*	if( ( packOwner != NULL ) && ( packOwner->npcaitype() == 17 ) && packOwner->owner() == pChar )
	{
	socket->sysMessage( tr( "You drop something into your playervendor (unimplemented)" ) );
	socket->bounceItem( pItem, BR_NO_REASON );
	return;
	}*/

	// Playervendors (chest equipped by the vendor - opened to the client)

	/*if( !( pCont->pileable() && pItem->pileable() && pCont->id() == pItem->id() || ( pCont->type() != 1 && pCont->type() != 9 ) ) )
	{
	P_CHAR pc_j = GetPackOwner(pCont);
	if (pc_j != NULL)
	{
	if (pc_j->npcaitype() == 17 && pc_j->isNpc() && pChar->Owns(pc_j))
	{
	pChar->inputitem = pItem->serial;
	pChar->inputmode = cChar::enPricing;
	sysmessage(s, "Set a price for this item.");
	}
	}
	*/

	// We may also drop into *any* locked chest
	// So we can have post-boxes ;o)
	if ( pCont->type() == 1 )
	{
		// If we're dropping it onto the closed container
		if ( dropPos.x == 0xFFFF && dropPos.y == 0xFFFF )
		{
			pCont->addItem( pItem );
		}
		else
		{
			pCont->addItem( pItem, false );
			pItem->setPos( dropPos );
		}

		// Dropped on another Container/in another Container
		pChar->soundEffect( 0x57 );
		pItem->update();
		return;
	}
	else if ( pCont->canStack( pItem ) )
	{
		if ( pCont->amount() + pItem->amount() <= 65535 )
		{
			pCont->setAmount( pCont->amount() + pItem->amount() );

			pItem->remove();
			pCont->update(); // Need to update the amount
			pCont->resendTooltip();
			return;
		}
		else
		{
			// The delta between 65535 and pCont->amount() sub our Amount is the
			// new amount
			pItem->setAmount( pItem->amount() - ( 65535 - pCont->amount() ) );
			pItem->resendTooltip();

			pCont->setAmount( 65535 ); // Max out the amount
			pCont->update();
			pCont->resendTooltip();
		}
	}

	// We dropped the item NOT on a container
	// And were *un*able to stack it (!)
	// >> Set it to the location of the item we dropped it on and stack it up by 2
	if ( pCont->container() )
	{
		P_ITEM pNewCont = dynamic_cast<P_ITEM>( pCont->container() );

		if ( pNewCont )
		{
			pNewCont->addItem( pItem, false );
			pItem->setPos( pCont->pos() + Coord_cl( 0, 0, 2 ) );
		}
		else
		{
			pChar->getBackpack()->addItem( pItem );
		}
	}
	else
	{
		pItem->removeFromCont();
		pItem->moveTo( pCont->pos() + Coord_cl( 0, 0, 2 ) );
	}

	pItem->update();
}
Esempio n. 13
0
// New Class implementation
void DragAndDrop::grabItem( cUOSocket* socket, cUORxDragItem* packet )
{
	// Get our character
	P_PLAYER pChar = socket->player();
	if ( !pChar )
		return;

	float weight = pChar->weight();

	// Fetch the grab information
	UI16 amount = packet->amount();
	if ( !amount )
		amount = 1;

	P_ITEM pItem = FindItemBySerial( packet->serial() );

	// If it's an invalid pointer we can't even bounce
	if ( !pItem )
		return;

	// Are we already dragging an item ?
	// Bounce it and reject the move
	// (Logged out while dragging an item)
	if ( socket->dragging() )
	{
		socket->bounceItem( socket->dragging(), BR_ALREADY_DRAGGING );
		return;
	}

	// Check if the item can be reached
	if (pItem->getOutmostChar() != pChar && !pChar->lineOfSight(pItem)) {
		socket->bounceItem( pItem, BR_OUT_OF_REACH );
		return;
	}

	if ( pItem->onPickup( pChar ) )
		return;

	if ( pChar->onPickup( pItem ) )
		return;

	// Do we really want to let him break his meditation
	// When he picks up an item ?
	// Maybe a meditation check here ?!?
	pChar->disturbMed(); // Meditation

	P_CHAR itemOwner = pItem->getOutmostChar();

	// Try to pick something out of another characters posessions
	if ( !pChar->isGM() && itemOwner && ( itemOwner != pChar ) && ( itemOwner->objectType() == enNPC && dynamic_cast<P_NPC>( itemOwner )->owner() != pChar ) )
	{
		socket->bounceItem( pItem, BR_BELONGS_TO_SOMEONE_ELSE );
		return;
	}

	// Check if the user can grab the item
	if ( !pChar->canPickUp( pItem ) )
	{
		socket->bounceItem( pItem, BR_CANNOT_PICK_THAT_UP );
		return;
	}

	// The user can't see the item
	// Basically thats impossible as the socket should deny moving the item
	// if it's not in line of sight but to prevent exploits
	/*if( !line_of_sight( socket->socket(), pChar->pos, pItem->pos, TREES_BUSHES|WALLS_CHIMNEYS|DOORS|ROOFING_SLANTED|FLOORS_FLAT_ROOFING|LAVA_WATER ) )
	{
		socket->sysMessage( "You can't see the item." );
		bounceItem( socket, pItem, true );
		return;
	}*/

	P_ITEM outmostCont = pItem->getOutmostItem();

	// If the top-most container ( thats important ) is a corpse
	// and looting is a crime, flag the character criminal.
	if ( !pChar->isGM() && outmostCont && outmostCont->corpse() )
	{
		// For each item we take out we loose carma
		// if the corpse is innocent and not in our guild
		bool sameGuild = true;//( GuildCompare( pChar, outmostCont->owner() ) != 0 );

		if ( outmostCont->hasTag( "notoriety" ) && outmostCont->getTag( "notoriety" ).toInt() == 1 && !pChar->owns( outmostCont ) && !sameGuild )
		{
			//			pChar->karma -= 5;
			pChar->setKarma( pChar->karma() - 5 );
			pChar->setCriminalTime( Server::instance()->time() + Config::instance()->crimtime() * MY_CLOCKS_PER_SEC );
			socket->sysMessage( tr( "You lost some karma." ) );
		}
	}

	// Check if the item is too heavy
	//if( !pc_currchar->isGMorCounselor() )
	//{
	//} << Deactivated (DarkStorm)

	// ==== Grabbing the Item is allowed here ====

	// Send the user a pickup sound if we're picking it up
	// From a container/paperdoll
	if ( !pItem->isInWorld() )
		socket->soundEffect( 0x57, pItem );

	// If we're picking up a specific amount of what we got
	// Take that into account
	if ( amount < pItem->amount() )
	{
		UI32 pickedAmount = QMIN( amount, pItem->amount() );

		// We only have to split if we're not taking it all
		if ( pickedAmount != pItem->amount() )
		{
			P_ITEM splitItem = pItem->dupe(); // Create a new item to pick that up
			splitItem->setAmount( pItem->amount() - pickedAmount );

			// Add tags to the splitted item
			QStringList keys = pItem->getTags();
			QStringList::const_iterator it = keys.begin();
			for ( ; it != keys.end(); ++it )
			{
				splitItem->setTag( *it, pItem->getTag( *it ) );
			}

			P_ITEM pContainer = dynamic_cast<P_ITEM>( pItem->container() );
			if ( pContainer )
				pContainer->addItem( splitItem, false );
			splitItem->SetOwnSerial( pItem->ownSerial() );

			splitItem->setSpawnregion( pItem->spawnregion() );

			// He needs to see the new item
			splitItem->update();

			// If we're taking something out of a spawn-region it's spawning "flag" is removed isn't it?
			pItem->setAmount( pickedAmount );
		}
	}

	// *normally* we should exclude the dragging socket here. but it works so as well.
	pItem->removeFromView( true );

	// Remove from spawnregion
	pItem->setSpawnregion( 0 );

	// Remove it from the World if it is in world, otherwise remove it from it's current container
	if ( pItem->isInWorld() )
		MapObjects::instance()->remove( pItem );
	else
		pItem->removeFromCont( true );

	// Remove eventual item-bonusses if we're unequipping something
	if ( pItem->container() && pItem->container()->isChar() )
	{
		P_CHAR wearer = dynamic_cast<P_CHAR>( pItem->container() );

		// resend the stat window
		if ( wearer && wearer->objectType() == enPlayer )
		{
			P_PLAYER pp = dynamic_cast<P_PLAYER>( wearer );
			if ( pp->socket() )
				pp->socket()->sendStatWindow();
		}
	}

	pChar->addItem( cBaseChar::Dragging, pItem );

	if ( weight != pChar->weight() )
	{
		socket->sendStatWindow();
	}
}