Exemplo n.º 1
0
void DragAndDrop::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 ( !pChar->lineOfSight( pos.losItemPoint(pItem->id()) ) )
	{
		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();

	// Play Sounds for non gold items
	if (pItem->id() != 0xEED) {
		pItem->soundEffect(0x42);
	}
}
Exemplo n.º 2
0
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 );
	}
}
Exemplo n.º 3
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();
}
Exemplo n.º 4
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();
}
Exemplo n.º 5
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();
	}
}