Пример #1
0
void cChar::glowHalo(P_ITEM pi)
{
	if (pi->glow != INVALID_SERIAL)
	{
		P_ITEM pHalo=FindItemBySerial(pi->glow);
		if (!pHalo) return;
		
		pHalo->layer=pi->layer; // copy layer information of the glowing item to the invisible light emitting object
		
		if(pHalo->layer==0 && pi->isInWorld()) // unequipped -> light source coords = item coords
		{
			pHalo->dir=29;
			pHalo->pos.x=pi->pos.x;
			pHalo->pos.y=pi->pos.y;
			pHalo->pos.z=pi->pos.z;
		} else if (pHalo->layer==0 && !pi->isInWorld()) // euqipped -> light source coords = players coords
		{
			pHalo->pos.x=this->pos.x;
			pHalo->pos.y=this->pos.y;
			pHalo->pos.z=this->pos.z+4;
			pHalo->dir=99; // gives no light in backpacks
		} else
		{
			pHalo->pos.x=this->pos.x;
			pHalo->pos.y=this->pos.y;
			pHalo->pos.z=this->pos.z+4;
			pHalo->dir=29;
		}
		RefreshItem(pHalo);//AntiChrist
	}
}
Пример #2
0
	PITEM_VECTOR* getNearbyItems( cObject* pObject, UI32 range, UI32 flags )
	{
		PITEM_VECTOR* 	pvItemsInRange	= 0;
		LOGICAL		validCall	= false;
		P_ITEM		pSelf		= 0;

		if( pObject != 0 )
		{
			if( isItemSerial( pObject->getSerial32() ) )
			{
				pSelf = static_cast<P_ITEM>(pObject);
				if( pSelf->isInWorld() )
				{
					validCall = true;
				}
			}
			else
			{
				validCall = true;
			}
			if( validCall )
				pvItemsInRange = getNearbyItems( pObject->getPosition().x, pObject->getPosition().y, range, flags, pSelf );
		}
		return pvItemsInRange;
	}
Пример #3
0
	/*!
	\brief removes an item from items pointer and from the vector of his container
	\author Luxor
	\param pi the item
	*/
	void delItem(P_ITEM pi)
	{
		VALIDATEPI(pi);

		if (pi->isInWorld())
		{
#ifdef SPAR_I_LOCATION_MAP
			pointers::delFromLocationMap(pi);
#else
			mapRegions->remove(pi);
#endif
		}

		objects.eraseObject(pi);

		eraseContainerInfo( pi->getSerial32() );

		SERIAL cont=pi->getContSerial();
		if ( cont > INVALID ) {

			std::map<SERIAL, vector <P_ITEM> >::iterator vect( pContMap.find( cont ) );
			if( ( vect!=pContMap.end() ) && !vect->second.empty() ) {

				vector<P_ITEM>::iterator contIter;
				contIter = find( vect->second.begin(), vect->second.end(), pi);
				if( contIter != vect->second.end() )
					vect->second.erase(contIter);
			}

		}
	}
Пример #4
0
static void item_bounce5(const UOXSOCKET s, const P_ITEM pi)
{
	item_bounce3(pi);
	if(pi->isInWorld())
	{
		if (pi->id1>=0x40)
			senditem(s, pi);
	}
	else
		senditem(s, pi);
}
Пример #5
0
void cDragItems::bounceItem( cUOSocket* socket, P_ITEM pItem, bool denyMove )
{
	// Reject the move of the item
	socket->bounceItem( pItem, BR_NO_REASON );

	// If the Client is *not* dragging the item we don't need to reset it to it's original location
	if( !socket->dragging() )
		return;

	// Sends the item to the backpack of char (client)
	pItem->toBackpack( socket->player() );

	// When we're dropping the item to the ground let's play a nice sound-effect
	// to all in-range sockets
	if( pItem->isInWorld() )
	{
		for( cUOSocket *mSock = cNetwork::instance()->first(); mSock; mSock = cNetwork::instance()->next() )
			if( mSock->inRange( socket ) )
				mSock->soundEffect( 0x42, pItem );
	}
	else
		socket->soundEffect( 0x57, pItem );
}
Пример #6
0
void cDragItems::bounceItem( P_CLIENT client, P_ITEM pItem, bool denyMove )
{
	// Reject the move of the item
	cBounceItem pBounce( denyMove );
	pBounce.send( client->socket() );

	// If the Client is *not* dragging the item we don't need to reset it to it's original location
	if( !client->dragging() )
		return;

	// Sends the item to the backpack of char (client)
	pItem->toBackpack( client->player() );

	// When we're dropping the item to the ground let's play a nice sound-effect
	// to all in-range sockets
	if( pItem->isInWorld() )
	{
		for( UOXSOCKET s = 0; s < now; s++ )
			if( inrange2( s, pItem ) )
				soundeffect( s, 0x00, 0x42 );
	}
	else
		soundeffect( client->socket(), 0x00, 0x57 );
}
/*!
\brief Double click
\author Ripper, rewrite by Endymion
\param ps client of player dbclick
\note Completely redone by Morrolan 20-07-99
\warning I use a define CASE for make more readable the code, if you change name of P_ITEM pi chage also the macro
\todo los
*/
void doubleclick(NXWCLIENT ps)
{

	if(ps==NULL) return;
	P_CHAR pc = ps->currChar();
	VALIDATEPC( pc );
	NXWSOCKET s = ps->toInt();

	// the 0x80 bit in the first byte is used later for "keyboard" and should be ignored
	SERIAL serial = LongFromCharPtr(buffer[s] +1) & 0x7FFFFFFF;

	if (isCharSerial(serial))
	{
		P_CHAR pd=pointers::findCharBySerial(serial);
		if(ISVALIDPC(pd))
			dbl_click_character(ps, pd);
		return;
	}

	P_ITEM pi = pointers::findItemBySerial(serial);
	VALIDATEPI(pi);

	if (pi->amxevents[EVENT_IONDBLCLICK]!=NULL) {
		g_bByPass = false;
		pi->amxevents[EVENT_IONDBLCLICK]->Call( pi->getSerial32(), pc->getSerial32() );
		if (g_bByPass==true)
			return;
	}
	/*
	g_bByPass = false;
	pi->runAmxEvent( EVENT_IONDBLCLICK, pi->getSerial32(), s );
	if (g_bByPass==true)
		return;
	*/

	if (!checkItemUsability(pc , pi, ITEM_USE_DBLCLICK))
		return;

	Location charpos= pc->getPosition();

	if (pc->IsHiddenBySpell()) return;	//Luxor: cannot use items if under invisible spell

	if ( !pc->IsGM() && pc->objectdelay >= uiCurrentTime )
	{
		pc->sysmsg(TRANSLATE("You must wait to perform another action."));
		return;
	}
	else
		pc->objectdelay = SrvParms->objectdelay * MY_CLOCKS_PER_SEC + uiCurrentTime;

	///MODIFY, CANT CLICK ITEM AT DISTANCE >2//////////////
	if ( (pc->distFrom(pi)>2) && !pc->IsGM() && !(pc->nxwflags[0] & cChar::flagSpellTelekinesys) ) //Luxor: let's check also for the telekinesys spell
	{
		pc->sysmsg( TRANSLATE("Must be closer to use this!"));
		pc->objectdelay=0;
		return;
	}


//<Anthalir> VARIAIBLI

	tile_st item;

	P_ITEM pack= pc->getBackpack();
	VALIDATEPI( pack );


	data::seekTile( pi->getId(), item );
//////FINEVARIABILI
	if ( ServerScp::g_nEquipOnDclick )
	{
		// equip the item only if it is in the backpack of the player
		if ((pi->getContSerial() == pack->getSerial32()) && (item.quality != 0) && (item.quality != LAYER_BACKPACK) && (item.quality != LAYER_MOUNT))
		{
			int drop[2]= {-1, -1};	// list of items to drop, there no reason for it to be larger
			int curindex= 0;

			NxwItemWrapper wea;
			wea.fillItemWeared( pc, true, true, true );
			for( wea.rewind(); !wea.isEmpty(); wea++ )
			{

				P_ITEM pj=wea.getItem();
				if(!ISVALIDPI(pj))
					continue;
				if ((item.quality == LAYER_1HANDWEAPON) || (item.quality == LAYER_2HANDWEAPON))// weapons
				{
					if (pi->itmhand == 2) // two handed weapons or shield
					{
						if (pj->itmhand == 2)
							drop[curindex++]= DEREF_P_ITEM(pj);
						if ( (pj->itmhand == 1) || (pj->itmhand == 3) )
							drop[curindex++]= DEREF_P_ITEM(pj);
					}
					if (pi->itmhand == 3)
					{
						if ((pj->itmhand == 2) || pj->itmhand == 3)
							drop[curindex++]= DEREF_P_ITEM(pj);
					}
					if ((pi->itmhand == 1) && ((pj->itmhand == 2) || (pj->itmhand == 1)))
						drop[curindex++]= DEREF_P_ITEM(pj);
				}
				else	// not a weapon
				{
					if (pj->layer == item.quality)
						drop[curindex++]= DEREF_P_ITEM(pj);
				}
			}

			if (ServerScp::g_nUnequipOnReequip)
			{
				if (drop[0] > -1)	// there is at least one item to drop
				{
					for (int i= 0; i< 2; i++)
					{
						if (drop[i] > -1)

						{

							P_ITEM p_drop=MAKE_ITEM_REF(drop[i]);

							if(ISVALIDPI(p_drop))
								pc->UnEquip( p_drop );

						}
					}
				}
				pc->playSFX( itemsfx(pi->getId()) );
				pc->Equip( pi );
			}
			else
			{
				if (drop[0] == -1)
				{
					pc->playSFX( itemsfx(pi->getId()) );
					pc->Equip( pi );
				}
			}
			return;
		}
	} // </Anthalir>


	//<Luxor>: Circle of transparency bug fix
	P_ITEM pCont;
	Location dst;

	pCont = pi->getOutMostCont();

	if(pCont->isInWorld()) {
		dst = pCont->getPosition();
	} else {
		P_CHAR pg_dst = pointers::findCharBySerial( pCont->getContSerial() );
		VALIDATEPC(pg_dst);
		dst = pg_dst->getPosition();
	}

	Location charPos = pc->getPosition();
	charPos.z = dst.z;
	charPos.dispz = dst.dispz;

	if ( !pc->IsGM() && !lineOfSight( charPos, dst ) && !(pc->nxwflags[0] & cChar::flagSpellTelekinesys) ) {
		pc->sysmsg( TRANSLATE( "You cannot reach the item" ) );
		return;
	}
	//</Luxor>

	P_CHAR itmowner = pi->getPackOwner();

	if(!pi->isInWorld()) {
		if (isItemSerial(pi->getContSerial()) && pi->type != ITYPE_CONTAINER)
		{// Cant use stuff that isn't in your pack.

			if ( ISVALIDPC(itmowner) && (itmowner->getSerial32()!=pc->getSerial32()) )
					return;
		}
		else
			if (isCharSerial(pi->getContSerial()) && pi->type!=(UI32)INVALID)
			{// in a character.
				P_CHAR wearedby = pointers::findCharBySerial(pi->getContSerial());
				if (ISVALIDPC(wearedby))
					if (wearedby->getSerial32()!=pc->getSerial32() && pi->layer!=LAYER_UNUSED_BP && pi->type!=ITYPE_CONTAINER)
						return;
			}
	}

	if ((pi->magic==4) && (pi->secureIt==1))
	{
		if (!pc->isOwnerOf(pi) || !pc->IsGMorCounselor())
		{
			pc->sysmsg( TRANSLATE("That is a secured chest!"));
			return;
		}
	}

	if (pi->magic == 4)
	{
		pc->sysmsg( TRANSLATE("That item is locked down."));
		return;
	}

	if (pc->dead && pi->type!=ITYPE_RESURRECT) // if you are dead and it's not an ankh, FORGET IT!
	{
		pc->sysmsg(TRANSLATE("You may not do that as a ghost."));
		return;
	}
	else if (!pc->IsGMorCounselor() && pi->layer!=0 && !pc->IsWearing(pi))
	{// can't use other people's things!
		if (!(pi->layer==LAYER_BACKPACK  && SrvParms->rogue==1)) // bugfix for snooping not working, LB
		{
			pc->sysmsg(TRANSLATE("You cannot use items equipped by other players."));
			return;
		}
	}


	// Begin checking objects that we force an object delay for (std objects)
	// start trigger stuff
	if (pi->trigger > 0)
	{
		if (pi->trigtype == 0)
		{
			if ( TIMEOUT( pi->disabled ) ) // changed by Magius(CHE) §
			{
				triggerItem(s, pi, TRIGTYPE_DBLCLICK); // if players uses trigger
				return;
			}
			else
			{
				if ( pi->disabledmsg!=NULL )
					pc->sysmsg("%s", pi->disabledmsg->c_str());
				else
					pc->sysmsg(TRANSLATE("That doesnt seem to work right now."));
				return;
			}
		}
		else
		{
			pc->sysmsg( TRANSLATE("You are not close enough to use that."));
			return;
		}
	}

	// check this on trigger in the event that the .trigger property is not set on the item
	// trigger code.  Check to see if item is envokable by id
	else if (checkenvoke( pi->getId() ))
	{
		pc->envokeitem = pi->getSerial32();
		pc->envokeid = pi->getId();
		P_TARGET targ = clientInfo[s]->newTarget( new cObjectTarget() );
		targ->code_callback=target_envoke;
		targ->send( ps );
		ps->sysmsg( TRANSLATE("What will you use this on?"));
		return;
	}
	// end trigger stuff
	// BEGIN Check items by type

	int los = 0;


	BYTE map1[20] = "\x90\x40\x01\x02\x03\x13\x9D\x00\x00\x00\x00\x13\xFF\x0F\xFF\x01\x90\x01\x90";
	BYTE map2[12] = "\x56\x40\x01\x02\x03\x05\x00\x00\x00\x00\x00";
	// By Polygon: This one is needed to show the location on treasure maps
	BYTE map3[12] = "\x56\x40\x01\x02\x03\x01\x00\x00\x00\x00\x00";


	P_TARGET targ = NULL;

	switch (pi->type)
	{
	case ITYPE_RESURRECT:
		// Check for 'resurrect item type' this is the ONLY type one can use if dead.
		if (pc->dead)
		{
			pc->resurrect();
			pc->sysmsg(TRANSLATE("You have been resurrected."));
			return;
		}
		else
		{
			pc->sysmsg(TRANSLATE("You are already living!"));
			return;
		}
	case ITYPE_BOATS:// backpacks - snooping a la Zippy - add check for SrvParms->rogue later- Morrolan

		if (pi->type2 == 3)
		{
			switch( pi->getId() & 0xFF ) {
				case 0x84:
				case 0xD5:
				case 0xD4:
				case 0x89:
					Boats->PlankStuff(pc, pi);
					break;
				default:
					pc->sysmsg( TRANSLATE("That is locked."));
					break;
			}
			return;
		}
	case ITYPE_CONTAINER: // bugfix for snooping not working, lb
	case ITYPE_UNLOCKED_CONTAINER:
		// Wintermute: GMs or Counselors should be able to open trapped containers always
		if (pi->moreb1 > 0 && !pc->IsGMorCounselor()) {
			magic::castAreaAttackSpell(pi->getPosition("x"), pi->getPosition("y"), magic::SPELL_EXPLOSION);
			pi->moreb1--;
		}
		//Magic->MagicTrap(currchar[s], pi); // added by AntiChrist
		// only 1 and 63 can be trapped, so pleaz leave it here :) - Anti
	case ITYPE_NODECAY_ITEM_SPAWNER: // nodecay item spawner..Ripper
	case ITYPE_DECAYING_ITEM_SPAWNER: // decaying item spawner..Ripper
		if (pi->isInWorld() || (pc->IsGMorCounselor()) || // Backpack in world - free access to everyone
			( isCharSerial(pi->getContSerial()) && pi->getContSerial()==pc->getSerial32()))	// primary pack
		{
			pc->showContainer(pi);
			pc->objectdelay=0;
			return;
		}
		else if( isItemSerial(pi->getContSerial()) )
		{
			P_ITEM pio = pi->getOutMostCont();
			if (pio->getContSerial()==pc->getSerial32() || pio->isInWorld() )
			{
				pc->showContainer(pi);
				pc->objectdelay=0;
				return;
			}
		}
		if(ISVALIDPC(itmowner))
			snooping(pc, pi );
		return;
	case ITYPE_TELEPORTRUNE:
		targ = clientInfo[s]->newTarget( new cLocationTarget() );
		targ->code_callback = target_tele;
		targ->send( ps );
		ps->sysmsg( TRANSLATE("Select teleport target."));
		return;
	case ITYPE_KEY:
		targ = clientInfo[s]->newTarget( new cItemTarget() );
		targ->code_callback = target_key;
		targ->buffer[0]= pi->more1;
		targ->buffer[1]= pi->more2;
		targ->buffer[2]= pi->more3;
		targ->buffer[3]= pi->more4;
		targ->send( ps );
		ps->sysmsg( TRANSLATE("Select item to use the key on."));
		return;
	case ITYPE_LOCKED_ITEM_SPAWNER:
	case ITYPE_LOCKED_CONTAINER:

		// Added traps effects by AntiChrist
		// Wintermute: GMs or Counselors should be able to open locked containers always
		if ( !pc->IsGMorCounselor() )
		{
			if (pi->moreb1 > 0 ) {
				magic::castAreaAttackSpell(pi->getPosition().x, pi->getPosition().y, magic::SPELL_EXPLOSION);
				pi->moreb1--;
			}

			pc->sysmsg(TRANSLATE("This item is locked."));
			return;
		}
		else
		{
			pc->showContainer(pi);
 			return;
		}
	case ITYPE_SPELLBOOK:
		if (ISVALIDPI(pack)) // morrolan
			if(pi->getContSerial()==pack->getSerial32() || pc->IsWearing(pi))
				ps->sendSpellBook(pi);
			else
				pc->sysmsg(TRANSLATE("If you wish to open a spellbook, it must be equipped or in your main backpack."));
			return;
	case ITYPE_MAP:
		LongToCharPtr(pi->getSerial32(), map1 +1);
		map2[1] = map1[1];
		map2[2] = map1[2];
		map2[3] = map1[3];
		map2[4] = map1[4];
/*
		By Polygon:
		Assign areas and map size before sending
*/
		map1[7] = pi->more1;	// Assign topleft x
		map1[8] = pi->more2;
		map1[9] = pi->more3;	// Assign topleft y
		map1[10] = pi->more4;
		map1[11] = pi->moreb1;	// Assign lowright x
		map1[12] = pi->moreb2;
		map1[13] = pi->moreb3;	// Assign lowright y
		map1[14] = pi->moreb4;
		int width, height;		// Tempoary storage for w and h;
		width = 134 + (134 * pi->morez);	// Calculate new w and h
		height = 134 + (134 * pi->morez);
		ShortToCharPtr(width, map1 +15);
		ShortToCharPtr(height, map1 +17);
//		END OF: By Polygon

		Xsend(s, map1, 19);
//AoS/		Network->FlushBuffer(s);
		Xsend(s, map2, 11);
//AoS/		Network->FlushBuffer(s);
		return;
	case ITYPE_BOOK:
		Books::DoubleClickBook(s, pi);
		return;
	case ITYPE_DOOR:
		dooruse(s, pi);
		return;
	case ITYPE_LOCKED_DOOR:
		// Wintermute: GMs or Counselors should be able to open locked doors always
		if ( pc->IsGMorCounselor())
 		{
 			dooruse(s, pi);
 			return;
 		}

		if (ISVALIDPI(pack))
		{
			NxwItemWrapper si;
			si.fillItemsInContainer( pack );
			for( si.rewind(); !si.isEmpty(); si++ )
			{
				P_ITEM pj = si.getItem();
				if (ISVALIDPI(pj) && pj->type==ITYPE_KEY)
					if (((pj->more1 == pi->more1) && (pj->more2 == pi->more2) &&
						 (pj->more3 == pi->more3) && (pj->more4 == pi->more4)) )
					{
						pc->sysmsg(TRANSLATE("You quickly unlock, use, and then relock the door."));
						dooruse(s, pi);
						return;
					}
			}
		}
		pc->sysmsg(TRANSLATE("This door is locked."));
		return;
	case ITYPE_FOOD:

		if (pc->hunger >= 6)
		{
			pc->sysmsg( TRANSLATE("You are simply too full to eat any more!"));
			return;
		}
		else
		{
			switch (RandomNum(0, 2))
			{
				case 0: pc->playSFX(0x3A); break;
				case 1: pc->playSFX(0x3B); break;
				case 2: pc->playSFX(0x3C); break;
			}

			switch (pc->hunger)
			{
				case 0:  pc->sysmsg( TRANSLATE("You eat the food, but are still extremely hungry.")); break;
				case 1:  pc->sysmsg( TRANSLATE("You eat the food, but are still extremely hungry.")); break;
				case 2:  pc->sysmsg( TRANSLATE("After eating the food, you feel much less hungry.")); break;
				case 3:  pc->sysmsg( TRANSLATE("You eat the food, and begin to feel more satiated.")); break;
				case 4:  pc->sysmsg( TRANSLATE("You feel quite full after consuming the food.")); break;
				case 5:  pc->sysmsg( TRANSLATE("You are nearly stuffed, but manage to eat the food."));	break;
				default: pc->sysmsg( TRANSLATE("You are simply too full to eat any more!")); break;
			}

			if (pi->poisoned)
			{
				pc->sysmsg(TRANSLATE("The food was poisoned!"));
				pc->applyPoison(PoisonType(pi->poisoned));

			}

			pi->ReduceAmount(1);
		    pc->hunger++;
		}
		return;
	case ITYPE_WAND: // -Fraz- Modified and tuned up, Wands must now be equipped or in pack
	case ITYPE_MANAREQ_WAND: // magic items requiring mana (xan)
		if (ISVALIDPI(pack))
		{
			if (pi->getContSerial() == pack->getSerial32() || pc->IsWearing(pi))
			{
				if (pi->morez != 0)
				{
					pi->morez--;
					if (magic::beginCasting(
						static_cast<magic::SpellId>((8*(pi->morex - 1)) + pi->morey - 1),
						ps,
						(pi->type==ITYPE_WAND) ? magic::CASTINGTYPE_ITEM : magic::CASTINGTYPE_NOMANAITEM))
						{
							if (pi->morez == 0)
							{
								pi->type = pi->type2;
								pi->morex = 0;
								pi->morey = 0;
								pi->offspell = 0;
							}
						}
				}
			}
			else
			{
				pc->sysmsg(TRANSLATE("If you wish to use this, it must be equipped or in your backpack."));
			}
		}
		return; // case 15 (magic items)
/*////////////////////REMOVE/////////////////////////////////////
	case 18: // crystal ball?
		switch (RandomNum(0, 9))
		{
		case 0: itemmessage(s, TRANSLATE("Seek out the mystic llama herder."), pi->getSerial32());									break;
		case 1: itemmessage(s, TRANSLATE("Wherever you go, there you are."), pi->getSerial32());									break;
		case 4: itemmessage(s, TRANSLATE("The message appears to be too cloudy to make anything out of it."), pi->getSerial32());	break;
		case 5: itemmessage(s, TRANSLATE("You have just lost five strength.. not!"), pi->getSerial32());							break;
		case 6: itemmessage(s, TRANSLATE("You're really playing a game you know"), pi->getSerial32());								break;
		case 7: itemmessage(s, TRANSLATE("You will be successful in all you do."), pi->getSerial32());								break;
		case 8: itemmessage(s, TRANSLATE("You are a person of culture."), pi->getSerial32());										break;
		default: itemmessage(s, TRANSLATE("Give me a break! How much good fortune do you expect!"), pi->getSerial32());				break;
		}// switch
		soundeffect2(pc_currchar, 0x01EC);
		return;// case 18 (crystal ball?)
*/////////////////////ENDREMOVE/////////////////////////////////////
	case ITYPE_POTION: // potions
			if (pi->morey != 3)
				pc->drink(pi);   //Luxor: delayed potions drinking
			else    //explosion potion
				usepotion(pc, pi);
			return;
	case ITYPE_RUNE:
			if (pi->morex==0 && pi->morey==0 && pi->morez==0)
			{
				pc->sysmsg( TRANSLATE("That rune is not yet marked!"));
			}
			else
			{
				pc->runeserial = pi->getSerial32();
				pc->sysmsg( TRANSLATE("Enter new rune name."));
			}
			return;
	case ITYPE_SMOKE:
			pc->smoketimer = pi->morex*MY_CLOCKS_PER_SEC + getclock();
			pi->ReduceAmount(1);
			return;
	case ITYPE_RENAME_DEED:
			pc->namedeedserial = pi->getSerial32();
			pc->sysmsg( TRANSLATE("Enter your new name."));
			pi->ReduceAmount(1);
			return;
	case ITYPE_POLYMORPH:
			pc->setId( pi->morex );
			pc->teleport();
			pi->type = ITYPE_POLYMORPH_BACK;
			return;
	case ITYPE_POLYMORPH_BACK:
			pc->setId( pc->getOldId() );
			pc->teleport();
			pi->type = ITYPE_POLYMORPH;
			return;
	case ITYPE_ARMY_ENLIST:
			enlist(s, pi->morex);
			pi->Delete();
			return;
	case ITYPE_TELEPORT:
			pc->MoveTo( pi->morex,pi->morey,pi->morez );
			pc->teleport();
			return;
	case ITYPE_DRINK:
			switch (rand()%2)
			{
				case 0: pc->playSFX(0x0031); break;
				case 1: pc->playSFX(0x0030); break;
			}
			pi->ReduceAmount(1);
			pc->sysmsg( TRANSLATE("Gulp !"));
			return;
	case ITYPE_GUILDSTONE:
			if ( pi->getId() == 0x14F0  ||  pi->getId() == 0x1869 )	// Check for Deed/Teleporter + Guild Type
			{
				pc->fx1 = DEREF_P_ITEM(pi);
				Guilds->StonePlacement(s);
				return;
			}
			else if (pi->getId() == 0x0ED5)	// Check for Guildstone + Guild Type
			{
				pc->fx1 = DEREF_P_ITEM(pi);
				Guilds->Menu(s, 1);
				return;
			}
			else
				WarnOut("Unhandled guild item type named: %s with ID of: %X\n", pi->getCurrentNameC(), pi->getId());
			return;
	case ITYPE_PLAYER_VENDOR_DEED:			// PlayerVendors deed
			{
			P_CHAR vendor = npcs::AddNPCxyz(-1, 2117, charpos.x, charpos.y, charpos.z);
			if ( !ISVALIDPC(vendor) )
			{
				WarnOut("npc-script couldnt find vendor !\n");
				return;
			}

			los = 0;
			vendor->npcaitype = NPCAI_PLAYERVENDOR;
			vendor->MakeInvulnerable();
			vendor->unHide();
			vendor->stealth=INVALID;
			vendor->dir = pc->dir;
			vendor->npcWander = WANDER_NOMOVE;
			vendor->SetInnocent();
			vendor->setOwnerSerial32( pc->getSerial32() );
			vendor->tamed = false;
			pi->Delete();
			vendor->teleport();
			char temp[TEMP_STR_SIZE]; //xan -> this overrides the global temp var
			sprintf( temp, TRANSLATE("Hello sir! My name is %s and i will be working for you."), vendor->getCurrentNameC());
			vendor->talk(s, temp, 0);

			return;
			}
	case ITYPE_TREASURE_MAP:
			Skills::Decipher(pi, s);
			return;

	case ITYPE_DECIPHERED_MAP:
			map1[ 1] = map2[1] = map3[1] = pi->getSerial().ser1;
			map1[ 2] = map2[2] = map3[2] = pi->getSerial().ser2;
			map1[ 3] = map2[3] = map3[3] = pi->getSerial().ser3;
			map1[ 4] = map2[4] = map3[4] = pi->getSerial().ser4;
			map1[ 7] = pi->more1;	// Assign topleft x
			map1[ 8] = pi->more2;
			map1[ 9] = pi->more3;	// Assign topleft y
			map1[10] = pi->more4;
			map1[11] = pi->moreb1;	// Assign lowright x
			map1[12] = pi->moreb2;
			map1[13] = pi->moreb3;	// Assign lowright y
			map1[14] = pi->moreb4;
			ShortToCharPtr(0x0100, map1 +15);			// Let width and height be 256
			ShortToCharPtr(0x0100, map1 +17);
			Xsend(s, map1, 19);
//AoS/			Network->FlushBuffer(s);

			Xsend(s, map2, 11);
//AoS/			Network->FlushBuffer(s);

			// Generate message to add a map point
			SI16 posx, posy;					// tempoary storage for map point
			SI16 tlx, tly, lrx, lry;				// tempoary storage for map extends
			tlx = (pi->more1 << 8) | pi->more2;
			tly = (pi->more3 << 8) | pi->more4;
			lrx = (pi->moreb1 << 8) | pi->moreb2;
			lry = (pi->moreb3 << 8) | pi->moreb4;
			posx = (256 * (pi->morex - tlx)) / (lrx - tlx);		// Generate location for point
			posy = (256 * (pi->morey - tly)) / (lry - tly);
			ShortToCharPtr(posx, map3 +7);				// Store the point position
			ShortToCharPtr(posy, map3 +9);
			Xsend(s, map3, 11);					// Fire data to client :D
//AoS/			Network->FlushBuffer(s);
			return;
		default:
			break;
	}
	///END IDENTIFICATION BY TYPE

/////////////////READ UP :D////////////////////////////////

	///BEGIN IDENTIFICATION BY ID
	if (pi->IsSpellScroll())
	{
		if (ISVALIDPI(pack))
			if( pi->getContSerial()==pack->getSerial32()) {
				magic::SpellId spn = magic::spellNumberFromScrollId(pi->getId());	// avoid reactive armor glitch
				if ((spn>=0)&&(magic::beginCasting(spn, ps, magic::CASTINGTYPE_SCROLL)))
					pi->ReduceAmount(1);							// remove scroll if successful
			}
			else pc->sysmsg(TRANSLATE("The scroll must be in your backpack to envoke its magic."));
	}
	CASE(IsAnvil) {
		targ = clientInfo[s]->newTarget( new cItemTarget() );
		targ->code_callback=Skills::target_repair;
		targ->send( ps );
		ps->sysmsg( TRANSLATE("Select item to be repaired."));
	}
	CASE(IsAxe) {
		targ = clientInfo[s]->newTarget( new cTarget() );
		targ->code_callback=target_axe;
		targ->buffer[0]=pi->getSerial32();
		targ->send( ps );
		ps->sysmsg( TRANSLATE("What would you like to use that on ?"));
	}
	CASEOR(IsFeather, IsShaft) {
		targ = clientInfo[s]->newTarget( new cItemTarget() );
		targ->buffer[0]= pi->getSerial32();
		targ->code_callback=Skills::target_fletching;
		targ->send( ps );
		ps->sysmsg( TRANSLATE("What would you like to use this with?"));
	}
Пример #8
0
/*!
\brief Steal something
\author Unknow, completly rewritten by Endymion
\param ps the client
*/
void Skills::target_stealing( NXWCLIENT ps, P_TARGET t )
{
	P_CHAR thief = ps->currChar();
	VALIDATEPC(thief);
	SERIAL target_serial = t->getClicked();

	AMXEXECSVTARGET( thief->getSerial32(),AMXT_SKITARGS,STEALING,AMX_BEFORE);

	//steal a char
	if ( isCharSerial(target_serial) )
	{
		Skills::target_randomSteal(ps,t);
        	return;
	}

	const P_ITEM pi = pointers::findItemBySerial( target_serial );
	VALIDATEPI(pi);

	//steal a pickpocket, a steal training dummy
	if( pi->getId() == 0x1E2D || pi->getId() == 0x1E2C )
	{
		Skills::PickPocketTarget(ps);
        	return;
	}

	//no stealing for items on layers other than 0 (equipped!) , newbie items, and items not being in containers allowed !
	if ( pi->layer!=0 || pi->isNewbie() || pi->isInWorld() )
	{
       	thief->sysmsg(TRANSLATE("You cannot steal that."));
       	return;
	}

	P_CHAR victim = pi->getPackOwner();
	VALIDATEPC(victim);

	if (victim->npcaitype == NPCAI_PLAYERVENDOR)
	{
		thief->sysmsg(TRANSLATE("You cannot steal from player vendors."));
       	return;
	}

	if ( (thief->getSerial32() == victim->getSerial32()) || (thief->getSerial32()==victim->getOwnerSerial32()) )
	{
		thief->sysmsg(TRANSLATE("You catch yourself red handed."));
		return;
	}

	if (thief->distFrom( victim ) == 1)
	{

		int result;

		R32 we = pi->getWeightActual();
		int bonus= (int)( (1800 - we)/5 );
		if ( thief->checkSkill( STEALING,0,(1000-bonus)) )
		{
			// 0 stealing 2 stones, 10  3 stones, 99.9 12 stones, 100 17 stones !!!
			int cansteal = thief->skill[STEALING] > 999 ? 1700 : thief->skill[STEALING] + 200;

			if ( we > cansteal )
			{
        		thief->sysmsg(TRANSLATE("That is too heavy."));
        		return;
			}

			
			if (pi->amxevents[EVENT_IONSTOLEN]!=NULL)
			{
				g_bByPass = false;
				pi->amxevents[EVENT_IONSTOLEN]->Call(pi->getSerial32(), thief->getSerial32(), victim->getSerial32());
				if (g_bByPass==true)
					return;
			}

			if (victim->amxevents[EVENT_CHR_ONSTOLEN])
			{
				g_bByPass = false;
				victim->amxevents[EVENT_CHR_ONSTOLEN]->Call(victim->getSerial32(), thief->getSerial32());
				if (g_bByPass==true)
					return;
			}
			/*

			pi->runAmxEvent( EVENT_IONSTOLEN, pi->getSerial32(), s, victim->getSerial32() );
			if (g_bByPass==true)
				return;

			victim->runAmxEvent( EVENT_CHR_ONSTOLEN, victim->getSerial32(), s );
			if (g_bByPass==true)
				return;
			*/

			P_ITEM pack= thief->getBackpack();
			VALIDATEPI(pack);

			pi->setContSerial( pack->getSerial32() );

			thief->sysmsg(TRANSLATE("You successfully steal the item."));
			pi->Refresh();
			
			result=+200;
			//all_items(s); why all item?
		}
		else
		{
			thief->sysmsg( TRANSLATE("You failed to steal the item."));
			result=-200;
			//Only onhide when player is caught!
		}

		if ( rand()%1000 > ( thief->skill[STEALING] + result )  )
		{
			thief->unHide();
			thief->sysmsg(TRANSLATE("You have been caught!"));
			thief->IncreaseKarma(ServerScp::g_nStealKarmaLoss);
			thief->modifyFame(ServerScp::g_nStealFameLoss);

			if ( victim->IsInnocent() && thief->attackerserial != victim->getSerial32() && Guilds->Compare(thief,victim)==0)
				setCrimGrey(thief, ServerScp::g_nStealWillCriminal); //Blue and not attacker and not same guild


			std::string itmname ( "" );
			char temp[TEMP_STR_SIZE]; //xan -> this overrides the global temp var
			char temp2[TEMP_STR_SIZE]; //xan -> this overrides the global temp var
			if ( pi->getCurrentName() != "#" )
				itmname = pi->getCurrentName();
			else
			{
				pi->getName( temp );
				itmname = temp;
			}
			sprintf(temp,TRANSLATE("You notice %s trying to steal %s from you!"), thief->getCurrentNameC(), itmname.c_str());
			sprintf(temp2,TRANSLATE("You notice %s trying to steal %s from %s!"), thief->getCurrentNameC(), itmname.c_str(), victim->getCurrentNameC());

			if ( victim->npc )
				if( victim->HasHumanBody() )
					victim->talkAll(TRANSLATE( "Guards!! A thief is amoung us!"),0);
			else
				victim->sysmsg(temp);

			//send to all player temp2 = thief are stealing victim if are more intelligent and a bonus of luck :D
			NxwSocketWrapper sw;
			sw.fillOnline( thief, true );
			for( sw.rewind(); !sw.isEmpty(); sw++ ) {
				
				NXWCLIENT ps_i=sw.getClient();
				if(ps_i==NULL ) continue;

				P_CHAR pc_i=ps_i->currChar();
				if ( ISVALIDPC(pc_i) )
					if( (rand()%10+10==17) || ( (rand()%2==1) && (pc_i->in>=thief->in)))
						pc_i->sysmsg(temp2);
			}
		}
	}
	else 
	{
		thief->sysmsg(TRANSLATE("You are too far away to steal that item."));
	}

	AMXEXECSVTARGET( thief->getSerial32(),AMXT_SKITARGS,STEALING,AMX_AFTER);
}
Пример #9
0
void cDragdrop::get_item(P_CLIENT ps) // Client grabs an item
{
	int npc=-1, amount, update = 0, serial;
	UOXSOCKET s = ps->GetSocket();
	int cc = ps->GetCurrChar();
	P_CHAR pc_currchar = MAKE_CHARREF_LR(cc);
	
	
	serial = calcserial(buffer[s][1], buffer[s][2], buffer[s][3], buffer[s][4]);
	if (serial == INVALID_SERIAL || buffer[s][1] < 0x40)
		return;	// landscape or a character
	P_ITEM pi = FindItemBySerial(serial);
	if (pi == NULL)
		return;
	
	pc_currchar->disturbMed(s); // Meditation
	
	// Zippy's stealing changes  
	P_ITEM px = pi;
	if (!px->isInWorld())  // Find character owning item
	{
		unsigned long loopexit = 0;
		do  // Find character owning item
		{
			if (isCharSerial(px->contserial))
			{
				npc = calcCharFromSer(px->contserial);
			}
			else  // its an item
			{
				if (px->isInWorld())
				{
					npc=-1;
					break;
				}
				px = FindItemBySerial(px->contserial);
				// ANTICHRIST -- SECURE TRADE FIX
				if (px != NULL) // LB overwriting x is essential here, dont change it!!!
				{
					if (px->layer == 0 && px->id() == 0x1E5E)
					{
						// Trade window???
						serial = calcserial(px->moreb1, px->moreb2, px->moreb3, px->moreb4);
						if (serial == INVALID_SERIAL)
							return;
						P_ITEM pi_z = FindItemBySerial(serial);
						if ( pi_z != NULL )
							if ((pi_z->morez || px->morez))
							{
								pi_z->morez = 0;
								px->morez = 0;
								sendtradestatus(pi_z, px);
							}
					}
					// Blackwinds Looting is crime implementation
					// changed slightly by Ripper
					if (px->corpse != 0 && !pc_currchar->Owns(px)) 
					{ 
						P_CHAR co = FindCharBySerial(px->ownserial);
						if (px->more2 == 1 && Guilds->Compare(DEREF_P_CHAR(pc_currchar), DEREF_P_CHAR(co)) == 0) 
						{ 
							pc_currchar->karma -= 5; 
							criminal(DEREF_P_CHAR(pc_currchar));
							sysmessage(s, "You lost some karma!"); 
						} 
						npc = 0;
					} // Criminal stuff
					if (px->corpse != 0)
						npc = 0;
				} // end if x!=-1
				
				if (px == NULL)
					npc = 0; 
			}
		} while ((npc==-1) &&(++loopexit < MAXLOOPS));
	}
	
	if (npc>0) // 0=corpse, hence >0 ..
	{
		if (!(pc_currchar->isGM()) && npc != DEREF_P_CHAR(pc_currchar) && ! pc_currchar->Owns(&chars[npc]))
		{// Own serial stuff by Zippy -^ Pack aniamls and vendors.
			bounce[1] = 0;
			Xsend(s, bounce, 2);
			if (ps->IsDragging())
			{
				ps->ResetDragging();
				item_bounce3(pi);
				pi->magic = 3;
			} 
			return;
		}
	}
	// End Zippy's change
	
	// Boats->
	if (px != NULL && npc!=-1)
	{
		if (px->multis>0)
			imultisp.remove(px->multis, px->serial);
		px->startDecay();
		// End Boats Change
		
		// AntiChrist -- for poisoned items
		if (px->layer>0)
		{
			chars[npc].removeItemBonus(px);	// remove BONUS STATS given by equipped special items
		}
		if ((px->trigon==1) && (px->layer != 0) && (px->layer != 15) && (px->layer < 19))// -Frazurbluu- Trigger Type 2 is my new trigger type *-
		{
			Trig->triggerwitem(s, pi, 1); // trigger is fired
		}	
	}
	if (pi != NULL)
	{
		if (pi->corpse != 1)
		{
			UpdateStatusWindow(s, pi);
			if (!pc_currchar->canPickUp(pi))
			{
				bounce[1] = 0;
				Xsend(s, bounce, 2);
				if (ps->IsDragging()) // only restore item if it got draggged before !!!
				{
					ps->ResetDragging();
					item_bounce4(s, pi);
				}
			}
			else
			{
				// AntiChrist bugfix for the bad bouncing bug ( disappearing items when bouncing )
				DRAGGED[s] = 1;
				
				pi->oldx = pi->pos.x;	// first let's save the position
				pi->oldy = pi->pos.y;
				pi->oldz = pi->pos.z;
				pi->oldcontserial = pi->contserial;	// then let's save the container
				pi->oldlayer = pi->layer;	// then the layer
				
				pi->layer = 0;
				if (!pi->isInWorld())
					soundeffect(s, 0x00, 0x57);
				if (pi->amount>1)
				{
					amount = (buffer[s][5] << 8) + buffer[s][6];
					if (amount>pi->amount)
						amount = pi->amount;
					if (amount < pi->amount)
					{
						P_ITEM pi_c = Items->MemItemFree();
						//	pi_c->Init(0);
#pragma note("Replace by a copy constructor before finishing items[]")
						memcpy(pi_c, pi, sizeof(cItem));  // Tauriel reduce code faster too
						pi_c->SetSerial(cItemsManager::getItemsManager().getUnusedSerial());

						pi_c->amount = pi->amount - amount;
						pi_c->SetContSerial(pi_c->contserial);
						pi_c->SetOwnSerial(pi_c->ownserial);
						pi_c->SetSpawnSerial(pi_c->spawnserial);
						
						statwindow(s,DEREF_P_CHAR(pc_currchar));
						RefreshItem(pi_c);//AntiChrist
					}
					
					if (pi->id() == 0x0EED) // gold coin
					{
						P_ITEM packnum = packitem(currchar[s]);
						if (packnum != NULL) // lb
							if (pi->contserial == packnum->serial)
								update = 1;
					}
					
					pi->amount = amount;
					
				}
				
			/*	int amt = 0, wgt; bool tooheavy=false;				
				wgt = (int)Weight->LockeddownWeight(pi, &amt, 0);
				if(pi->contserial>0)
				{
					if (( (pc_currchar->weight+wgt) > (pc_currchar->st*WEIGHT_PER_STR)+30)) // LB -> added: drop item if too heavy
					{
					  float res=float( (pc_currchar->weight+wgt) - ((pc_currchar->st*WEIGHT_PER_STR)+30))*2;
					  int diff = pc_currchar->st;
					  diff -= (int)res;
					  if (diff<=0 && !pc_currchar->isGM() )					   
					  {
						 tooheavy=true;						 						 

						 bounce[1] = 0;
						 Xsend(s, bounce, 2);
						 if (ps->IsDragging()) // only restore item if it got dragged before !!!
						 {
						   ps->ResetDragging();
						   item_bounce4(s, pi);
						 }
						 sysmessage(s, "you can't pick this up, this is too heavy");					 
						 return;
					 }
					}
				} 

                if (!tooheavy) pc_currchar->weight+=wgt;				   
				update = 1;	*/				

				// LB remark: drop item if too heavy is a good solution,
				// but there's still a small bug remaining.
				// added weight from items picked up, but not put to bp, pd,  in other words hold in ones hand, 
				// is NOT subtracted when being dropped again to ground/other chars/other chars' bp's.
				// but this bug doesnt show up becasue weight is re-calculated automatically all 10 secs.
				// without adding weight of the item curently carrying in hand.
				// a correct solutions need the weight of item in hand being stored
				// , added to auto-re-calculation all x-secs code, and being subtracted if dropped.
				// because it's now only happening for leight weight items, because heavy weight itms cant be picke up anymore
				// I haven't corrected this yet. 			
				
				// Tauriel remove item from world mapcells
				mapRegions->Remove(pi); // remove this item from a map cell				
				pi->pos.x = 0;
				pi->pos.y = 0;
				pi->pos.z = 0;
				
				pi->flags.isBeeingDragged=true;
				pi->SetContSerial(-1);
			
			
			}
		}
	} // end of if i!=-1
	if (update) statwindow(s, DEREF_P_CHAR(pc_currchar));
}
Пример #10
0
/*!
\brief Get an item
\author Unknow, revamped by Endymion
\param client the client
*/
void get_item( NXWCLIENT client ) // Client grabs an item
{
	if ( client == NULL)
		return;

	P_CHAR pc_currchar = client->currChar();
	VALIDATEPC( pc_currchar );

	NXWSOCKET s = client->toInt();

	P_ITEM pi = pointers::findItemBySerPtr(buffer[s]+1);
	VALIDATEPI(pi);

	//Luxor: not-movable items
	/*if (pi->magic == 2 || (isCharSerial(pi->getContSerial()) && pi->getContSerial() != pc_currchar->getSerial32()) ) {
		if (isCharSerial(pi->getContSerial())) {
			P_CHAR pc_i = pointers::findCharBySerial(pi->getContSerial());
			if (ISVALIDPC(pc_i))
				pc_i->sysmsg("Warning, backpack bug located!");
		}
		if (client->isDragging()) {
        		client->resetDragging();
			UpdateStatusWindow(s,pi);
        	}
		pi->setContSerial( pi->getContSerial(true) );
		pi->setPosition( pi->getOldPosition() );
		pi->layer = pi->oldlayer;
		pi->Refresh();
		return;
	}*/

	pc_currchar->disturbMed(); // Meditation

	tile_st item;
 	data::seekTile( pi->getId(), item );

	// Check if item is equiped
 	if( pi->getContSerial() == pc_currchar->getSerial32() && pi->layer == item.quality )
 	{
 		if( pc_currchar->UnEquip( pi, 1 ) == 1 )	// bypass called
 		{
 			if( client->isDragging() )
 			{
 				UI08 cmd[1]= {0x29};
 				client->resetDragging();
 				Xsend(s, cmd, 1);
				UpdateStatusWindow(s,pi);
//AoS/				Network->FlushBuffer(s);
 			}
 			return;
 		}
 	}


	P_CHAR owner=NULL;
	P_ITEM container=NULL;
	if ( !pi->isInWorld() ) { // Find character owning item

		if ( isCharSerial( pi->getContSerial()))
		{
			owner = pointers::findCharBySerial( pi->getContSerial());
		}
		else  // its an item
		{
			//Endymion Bugfix:
			//before check the container.. but if this cont is a subcont?
			//so get the outmostcont and check it else:
			//can loot without lose karma in subcont
			//can steal in trade ecc
			//not very good :P
			container = pi->getOutMostCont();
			if( isCharSerial( container->getContSerial() ) )
				owner=pointers::findCharBySerial( container->getContSerial() );
		}

		if ( ISVALIDPC( owner ) && owner->getSerial32()!=pc_currchar->getSerial32() )
		{
			if ( !pc_currchar->IsGM() && owner->getOwnerSerial32() != pc_currchar->getSerial32() )
			{// Own serial stuff by Zippy -^ Pack aniamls and vendors.
				UI08 bounce[2]= { 0x27, 0x00 };
				Xsend(s, bounce, 2);
//AoS/				Network->FlushBuffer(s);
				if (client->isDragging())
				{
					client->resetDragging();
					pi->setContSerial(pi->getContSerial(),true,false);
					item_bounce3(pi);
					UpdateStatusWindow(s,pi);
				}
				return;
			}
		}
	}

	if ( ISVALIDPI( container ) )
	{

		if ( container->layer == 0 && container->getId() == 0x1E5E)
		{
			// Trade window???
			SERIAL serial = calcserial( pi->moreb1, pi->moreb2, pi->moreb3, pi->moreb4);
			if ( serial == INVALID )
				return;

			P_ITEM piz = pointers::findItemBySerial(serial );
			if ( ISVALIDPI( piz ) )
				if ( piz->morez || container->morez )
				{
					piz->morez = 0;
					container->morez = 0;
					sendtradestatus( piz, container );
				}


			//<Luxor>
			if (pi->amxevents[EVENT_ITAKEFROMCONTAINER]!=NULL)
			{
				g_bByPass = false;
				pi->amxevents[EVENT_ITAKEFROMCONTAINER]->Call( pi->getSerial32(), pi->getContSerial(), pc_currchar->getSerial32() );
				if (g_bByPass)
				{
					Sndbounce5(s);
					if (client->isDragging())
					{
						client->resetDragging();
						UpdateStatusWindow(s,pi);
					}
					pi->setContSerial( pi->getContSerial(true) );
					pi->setPosition( pi->getOldPosition() );
					pi->layer = pi->oldlayer;
					pi->Refresh();
					return;
            	}
			}
			//</Luxor>

			/*
			//<Luxor>
			g_bByPass = false;
			pi->runAmxEvent( EVENT_ITAKEFROMCONTAINER, pi->getSerial32(), pi->getContSerial(), s );
			if (g_bByPass)
			{
				Sndbounce5(s);
				if (client->isDragging())
				{
					client->resetDragging();
					UpdateStatusWindow(s,pi);
				}
				pi->setContSerial( pi->getContSerial(true) );
				pi->setPosition( pi->getOldPosition() );
				pi->layer = pi->oldlayer;
				pi->Refresh();
				return;
			}
			//</Luxor>
			*/

			if ( container->corpse )
			{
				if ( container->getOwnerSerial32() != pc_currchar->getSerial32())
				{ //Looter :P

					pc_currchar->unHide();
					bool bCanLoot = false;
					if( pc_currchar->party!=INVALID ) {
						P_CHAR dead = pointers::findCharBySerial( container->getOwnerSerial32() ) ;
						if( ISVALIDPC( dead ) && dead->party==pc_currchar->party ) {
							P_PARTY party = Partys.getParty( pc_currchar->party );
							if( party!=NULL ) {
								P_PARTY_MEMBER member = party->getMember( pc_currchar->getSerial32() );
								if( member!=NULL )
									bCanLoot = member->canLoot;
							}
						}
					}
					if ( !bCanLoot && container->more2==1 )
					{
						pc_currchar->IncreaseKarma(-5);
						setCrimGrey(pc_currchar, ServerScp::g_nLootingWillCriminal);
						pc_currchar->sysmsg( TRANSLATE("You are loosing karma!"));
					}
				}
			} // corpse stuff

			container->SetMultiSerial(INVALID);

			//at end reset decay of container
			container->setDecayTime();

		} // end cont valid
	}

	if ( !pi->corpse )
	{
		UpdateStatusWindow(s, pi);

		tile_st tile;
		data::seekTile( pi->getId(), tile);

		if (!pc_currchar->IsGM() && (( pi->magic == 2 || ((tile.weight == 255) && ( pi->magic != 1))) && !pc_currchar->canAllMove() )  ||
			(( pi->magic == 3|| pi->magic == 4) && !pc_currchar->isOwnerOf( pi )))
		{
			UI08 bounce[2]={ 0x27, 0x00 };
			Xsend(s, bounce, 2);
//AoS/			Network->FlushBuffer(s);
			if (client->isDragging()) // only restore item if it got draggged before !!!
			{
				client->resetDragging();
				item_bounce4(s, pi );
			}
		} // end of can't get
		else
		{
			// AntiChrist bugfix for the bad bouncing bug ( disappearing items when bouncing )
			client->setDragging();
			pi->setOldPosition( pi->getPosition() ); // first let's save the position

			pi->oldlayer = pi->layer;	// then the layer
			pi->layer = 0;

			if (!pi->isInWorld())
				pc_currchar->playSFX(0x0057);

			if (pi->amount>1)
			{
				UI16 amount = ShortFromCharPtr(buffer[s] +5);
				if (amount > pi->amount)
					amount = pi->amount;
				else if (amount < pi->amount)
				{ //get not all but a part of item ( piled? ), but anyway make a new one item

					P_ITEM pin =archive::item::New();
					(*pin)=(*pi);

					pin->amount = (UI16)( pi->amount - amount);

					pin->setContSerial(pi->getContSerial());	//Luxor
					pin->setPosition( pi->getPosition() );

					/*if( !pin->isInWorld() && isItemSerial( pin->getContSerial() ) )
						pin->SetRandPosInCont( (P_ITEM)pin->getContainer() );*/

					if ( pin->getOwnerSerial32() != INVALID )
						pin->setOwnerSerial32( pi->getOwnerSerial32() );

					statwindow(pc_currchar,pc_currchar);
					pin->Refresh();//AntiChrist
				}

				if ( pi->getId() == ITEMID_GOLD)
				{
					P_ITEM pack= pc_currchar->getBackpack();
					if (ISVALIDPI(pack)) // lb
						if ( pi->getContSerial() == pack->getSerial32())
							statwindow(pc_currchar, pc_currchar);
				}

				pi->amount = amount;

			} // end if corpse
#ifdef SPAR_I_LOCATION_MAP
			pointers::delFromLocationMap( pi );
#else
			mapRegions->remove( pi );
#endif
			pi->setPosition( 0, 0, 0 );
			pi->setContSerial( INVALID, false );
		}
	}

	int amt = 0, wgt;
	if ( container == NULL )
	{
		wgt = (int)weights::LockeddownWeight( pi, &amt);
		pc_currchar->weight += wgt;
		statwindow(pc_currchar, pc_currchar);
	}
}
Пример #11
0
void pack_item(P_CLIENT ps, PKGx08 *pp) // Item is put into container
{
	int j, serial;
	bool abort=false;
	UOXSOCKET s=ps->GetSocket();
	CHARACTER cc=ps->GetCurrChar();
	P_CHAR pc_currchar = MAKE_CHARREF_LR(cc);
	
	serial=pp->Tserial;
	if(serial == INVALID_SERIAL) abort=true;
	const P_ITEM pCont= FindItemBySerial( serial );
	
	serial=pp->Iserial;
	if(serial == INVALID_SERIAL) abort=true;
	const P_ITEM pItem = FindItemBySerial( serial );
	
	if (pCont == NULL)
	{
		RefreshItem(pCont);//AntiChrist
		return;
	} 
	
	if (pItem == NULL || pCont == NULL) return; //LB
	pItem->flags.isBeeingDragged=false;

	if (pItem->id1>=0x40) 
	{ 
	   abort=true; // LB crashfix that prevents moving multi objcts in BP's
       sysmessage(s,"Hey, putting houses in your pack crashes your back and client!");
	}
	j=DEREF_P_CHAR(GetPackOwner(pCont));
	if (j>-1)
		if (chars[j].npcaitype==17 && chars[j].isNpc() && !pc_currchar->Owns(&chars[j]))
		{
			abort=true;
			sysmessage(s, "This aint your vendor!");				
		}

	if(abort)
	{//AntiChrist to preview item disappearing
		item_bounce6(ps,pItem);
		return;
	}

	if (pCont->layer==0 && pCont->id() == 0x1E5E &&
		pc_currchar->Wears(pCont))
	{
		// Trade window???
		serial=calcserial(pCont->moreb1, pCont->moreb2, pCont->moreb3, pCont->moreb4);
		if(serial == INVALID_SERIAL) return;
		P_ITEM pi_z = FindItemBySerial( serial );
		
		if (pi_z != NULL)
			if ((pi_z->morez || pCont->morez))
			{
				pi_z->morez=0;
				pCont->morez=0;
				sendtradestatus(pi_z, pCont);
			}
	}
	
	//
	//AntiChrist - Special Bank Stuff
	//
	//if morey==123  - gold only bank	
	//
	if(SrvParms->usespecialbank)//only if special bank is activated
	{
		if(pCont->morey==123 && pCont->morex==1 && pCont->type==1)
		{
			if ( pItem->id() == 0x0EED )
			{//if they're gold ok
				goldsfx(s, 2);
			} else
			{//if they're not gold..bounce on ground
				sysmessage(s,"You can only put golds in this bank box!");

				pItem->SetContSerial(-1);
				pItem->MoveTo(pc_currchar->pos.x,pc_currchar->pos.y,pc_currchar->pos.z);
				RefreshItem(pItem);//AntiChrist
				itemsfx(s,pItem->id());
				return;
			}
		}
	}
	
	//testing UOP Blocking Tauriel 1-12-99
	if (!pItem->isInWorld())
	{
		item_bounce6(ps,pItem);
		return;
	}
	
	if (!pc_currchar->canPickUp(pItem))
	{
		Sndbounce5(s);
		if (ps->IsDragging())
		{
			ps->ResetDragging();
			item_bounce3(pItem);
			if (pCont->id1>=0x40)
				senditem(s, pCont);
		}
		return;
	}
	// - Trash container
	if (pCont->type==87)
	{
		Items->DeleItem(pItem);
		sysmessage(s, "As you let go of the item it disappears.");
		return;
	}
	// - Spell Book
	if (pCont->type==9)
	{
		if (!IsSpellScroll72(pItem->id()))
		{
			sysmessage(s, "You can only place spell scrolls in a spellbook!");
			Sndbounce5(s);
			if (ps->IsDragging())
			{
				ps->ResetDragging();
				item_bounce3(pItem);
			}
			if (pCont->id1>=0x40)
				senditem(s, pCont);
			return;
		}
		P_ITEM pBackpack = Packitem(pc_currchar);
		if (pBackpack != NULL) // lb
		{
			if (!pc_currchar->Wears(pCont) &&
				(!(pCont->contserial==pBackpack->serial)) && (!(pc_currchar->canSnoop())))
			{
				sysmessage(s, "You cannot place spells in other peoples spellbooks.");
				item_bounce6(ps,pItem);
				return;
			}
			
			if(pItem->name[0]=='#')
				pItem->getName(temp2);
			else
				strcpy((char*)temp2,pItem->name);

			vector<SERIAL> vecContainer = contsp.getData(pCont->serial);
			for (unsigned int i = 0; i < vecContainer.size(); i++) // antichrist , bugfix for inscribing scrolls
			{
				P_ITEM pi = FindItemBySerial(vecContainer[i]);
				if (pi != NULL)
				{
					if(pi->name[0]=='#')
						pi->getName(temp);
					else
						strcpy((char*)temp, pi->name);

					if(!(strcmp((char*)temp,(char*)temp2)) || !(strcmp((char*)temp,"All-Spell Scroll")))
					{
						sysmessage(s,"You already have that spell!");
						item_bounce6(ps,pItem);
						return;
					}
				}
			}
		}
	}
	
	// player run vendors
	if (!(pCont->pileable && pItem->pileable && pCont->id()==pItem->id()
		|| (pCont->type!=1 && pCont->type!=9)))
	{
		j=DEREF_P_CHAR(GetPackOwner(pCont));
		if (j>-1) // bugkilling, LB, was j=!-1, arghh, C !!!
		{
			if (chars[j].npcaitype==17 && chars[j].isNpc() && pc_currchar->Owns(&chars[j]))
			{
				pc_currchar->inputitem = pItem->serial;
				pc_currchar->inputmode = cChar::enPricing;
				sysmessage(s, "Set a price for this item.");
			}
		}

		short xx=pp->TxLoc;
		short yy=pp->TyLoc;

		pCont->AddItem(pItem,xx,yy);
		
		itemsfx(s, pItem->id());// see itemsfx() for details - Dupois Added Oct 09, 1998
		statwindow(s,DEREF_P_CHAR(pc_currchar));
	}
	// end of player run vendors
	
	else
		// - Unlocked item spawner or unlockable item spawner
		if (pCont->type==63 || pCont->type==65 || pCont->type==66)
		{
			pItem->SetContSerial(pp->Tserial);

			// lb bugfix
			pItem->pos.x=pp->TxLoc;
			pItem->pos.y=pp->TyLoc;
			pItem->pos.z=pp->TzLoc;
			
			SndRemoveitem(pItem->serial);
			RefreshItem(pItem);//AntiChrist
			itemsfx(s, pItem->id());
			
		}
		else  // - Pileable
			if (pCont->pileable && pItem->pileable && pCont->id()==pItem->id())
			{		
				if ((pCont->amount+pItem->amount) > 65535)
				{
					pItem->amount -= (65535-pCont->amount);
					Commands->DupeItem(s, pCont, pItem->amount);
					pCont->amount = 65535;
					Items->DeleItem(pItem);
				}
				else
				{
					pCont->amount=pCont->amount+pItem->amount;
					itemsfx(s, pItem->id());
					Items->DeleItem(pItem);
				}
				SndRemoveitem(pItem->serial);
				RefreshItem(pCont);//AntiChrist
			}
			else
			{
				pItem->pos.x=pp->TxLoc;
				pItem->pos.y=pp->TyLoc;
				pItem->pos.z=pp->TzLoc;
//				pItem->SetContSerial(-1);
				pItem->SetContSerial(pp->Tserial);
				// Tauriel add item to world mapcells
				mapRegions->Add(pItem); //add this item to a map cell
				
				SndRemoveitem(pItem->serial);
				RefreshItem(pCont);//AntiChrist
			}
			
			// - Spell Book
	
			if (pCont->type==9)
				Magic->SpellBook(s, pCont); // LB, bugfix for showing(!) the wrong spell (clumsy) when a new spell is put into opened spellbook

			if (pItem->glow>0) // LB's glowing items stuff
			{
				int p = DEREF_P_CHAR(GetPackOwner(pCont)); 
				pc_currchar->removeHalo(pItem); // if gm put glowing object in another pack, handle glowsp correctly !
				if (p!=-1) 
				{
					chars[p].addHalo(pItem);
					chars[p].glowHalo(pItem);
				}		   
				
			}	
}
Пример #12
0
bool cNewMagic::checkTarget( P_CHAR pCaster, stNewSpell *sInfo, cUORxTarget *target )
{
	cUOSocket *socket;
	if( pCaster->objectType() == enPlayer )
		socket = dynamic_cast<P_PLAYER>(pCaster)->socket();

	P_CHAR pChar = FindCharBySerial( target->serial() );
	P_ITEM pItem = FindItemBySerial( target->serial() );

	if( sInfo->targets & (TARGET_CHAR|TARGET_ITEM) && !pItem && !pChar )
	{
		socket->sysMessage( tr( "Please target an object" ) );
		return false;
	}

	if( sInfo->targets & TARGET_CHAR && !pChar )
	{
		socket->sysMessage( tr( "Please target a living creature." ) );
		return false;
	}

	if( sInfo->targets & TARGET_ITEM && !pItem )
	{
		socket->sysMessage( tr( "Please target an item." ) );
		return false;
	}

	// Several checks (Get the correct position of the target and do NOT trust the position transmitted by the client)
	Coord_cl pos = socket->player()->pos();
	if( pChar )
		pos = pChar->pos();
	else if( pItem )
		pos = pItem->pos();
	else
	{
		pos.x = target->x();
		pos.y = target->y();
		pos.z = target->z();
	}


	if( pItem && !pItem->isInWorld() )
	{
		P_CHAR pOut = pItem->getOutmostChar();
		
		if( pOut == socket->player() )
			return true;
		else
		{
			socket->clilocMessage( 0x7A258, "", 0x3b2 ); // You cannot reach that
			return false;
		}
	}
	else
	{
		// Distance check (VisRange + 5 for macros)
		if( pos.distance( socket->player()->pos() ) > ( socket->player()->visualRange() + 5 ) )
		{
			socket->sysMessage( tr( "You can't see the target." ) );
			return false;
		}
	
		// Line of Sight check
		if( !lineOfSight( pos, socket->player()->pos()+Coord_cl( 0, 0, 13 ), WALLS_CHIMNEYS|TREES_BUSHES|ROOFING_SLANTED|LAVA_WATER|DOORS ) )
		{
			socket->sysMessage( tr( "You can't see the target." ) );
			return false;
		}
	}
	
	// Visibility check (Chars)
	if( pChar && pChar->isHidden() && !socket->player()->isGM() )
	{
		socket->sysMessage( tr( "You can't see this character." ) );
		return false;
	}

	// Visibility check (Items)
	if( pItem && ( ( pItem->visible() == 1 && !socket->player()->Owns( pItem ) ) || pItem->visible() == 2 ) && !socket->player()->isGM() )
	{
		socket->sysMessage( tr( "You can't see this item." ) );
		return false;
	}

	return true;
}
Пример #13
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 );
	}
}
Пример #14
0
void get_item(P_CLIENT ps) // Client grabs an item
{
	int x,  npc=-1, c, amount, update = 0, serial;
//	tile_st tile;
	int z;// antichrist for trade fix
	UOXSOCKET s = ps->GetSocket();
	int cc = ps->GetCurrChar();
	P_CHAR pc_currchar = MAKE_CHARREF_LR(cc);
	
	
	serial = calcserial(buffer[s][1], buffer[s][2], buffer[s][3], buffer[s][4]);
	if (serial == INVALID_SERIAL || buffer[s][1] < 0x40)
		return;	// landscape or a character
	P_ITEM pi = FindItemBySerial(serial);
	if (pi == NULL)
		return;
	
	pc_currchar->disturbMed(s); // Meditation
	
	// Zippy's stealing changes  
	x = DEREF_P_ITEM(pi);
	if (!items[x].isInWorld())  // Find character owning item
	{
		int loopexit = 0;
		do  // Find character owning item
		{
			if (isCharSerial(items[x].contserial))
			{
				npc = calcCharFromSer(items[x].contserial);
			}
			else  // its an item
			{
				if (items[x].isInWorld())
				{
					npc=-1;
					break;
				}
				x = calcItemFromSer(items[x].contserial);
				// ANTICHRIST -- SECURE TRADE FIX
				if (x!=-1) // LB overwriting x is essential here, dont change it!!!
				{
					if (items[x].layer == 0 && items[x].id() == 0x1E5E)
					{
						// Trade window???
						serial = calcserial(items[x].moreb1, items[x].moreb2, items[x].moreb3, items[x].moreb4);
						if (serial == INVALID_SERIAL)
							return;
						z = calcItemFromSer(serial);
						if (z!=-1)
							if ((items[z].morez || items[x].morez))
							{
								items[z].morez = 0;
								items[x].morez = 0;
								sendtradestatus(z, x);
							}
					}
					// Blackwinds Looting is crime implementation
					// changed slightly by Ripper
					if (items[x].corpse != 0 && !pc_currchar->Owns(&items[x])) 
					{ 
						P_CHAR co = FindCharBySerial(items[x].ownserial);
						if (items[x].more2 == 1 && Guilds->Compare(cc, DEREF_P_CHAR(co)) == 0) 
						{ 
							pc_currchar->karma -= 5; 
							criminal(cc);
							sysmessage(s, "You lost some karma!"); 
						} 
						npc = 0;
					} // Criminal stuff
					if (items[x].corpse != 0)
						npc = 0;
				} // end if x!=-1
				
				if (x==-1)
					npc = 0; 
			}
		} while ((npc==-1) &&(++loopexit < MAXLOOPS));
	}
	
	if (npc>0) // 0=corpse, hence >0 ..
	{
		if (!(pc_currchar->isGM()) && npc != cc && ! pc_currchar->Owns(&chars[npc]))
		{// Own serial stuff by Zippy -^ Pack aniamls and vendors.
			bounce[1] = 0;
			Xsend(s, bounce, 2);
			if (ps->IsDragging())
			{
				ps->ResetDragging();
				item_bounce3(pi);
				pi->magic = 3;
			} 
			return;
		}
	}
	// End Zippy's change
	
	// Boats->
	if (x!=-1 && npc!=-1)
	{
		if (items[x].multis>0)
			imultisp.remove(items[x].multis, items[x].serial);
		items[x].startDecay();
		// End Boats Change
		
		// AntiChrist -- for poisoned items
		if (items[x].layer>0)
		{
			chars[npc].removeItemBonus(&items[x]);	// remove BONUS STATS given by equipped special items
		}
		if ((items[x].trigon==1) && (items[x].layer != 0) && (items[x].layer != 15) && (items[x].layer < 19))// -Frazurbluu- Trigger Type 2 is my new trigger type *-
		{
			triggerwitem(s, DEREF_P_ITEM(pi), 1); // trigger is fired
		}	
			// AntiChrist -- for poisoned items
		if (items[x].poisoned)
		{
			chars[npc].poison -= items[x].poisoned;
			if (chars[npc].poison < 0)
				chars[npc].poison = 0;
		}
	}
	if (pi != NULL)
	{
		if (pi->corpse != 1)
		{
			UpdateStatusWindow(s, pi);
			if (!pc_currchar->canPickUp(pi))
			{
				bounce[1] = 0;
				Xsend(s, bounce, 2);
				if (ps->IsDragging()) // only restore item if it got draggged before !!!
				{
					ps->ResetDragging();
					item_bounce4(s, pi);
				}
			}
			else
			{
				// AntiChrist bugfix for the bad bouncing bug ( disappearing items when bouncing )
				DRAGGED[s] = 1;
				
				pi->oldx = pi->pos.x;	// first let's save the position
				pi->oldy = pi->pos.y;
				pi->oldz = pi->pos.z;
				pi->oldcontserial = pi->contserial;	// then let's save the container
				pi->oldlayer = pi->layer;	// then the layer
				
				pi->layer = 0;
				if (!pi->isInWorld())
					soundeffect(s, 0x00, 0x57);
				if (pi->amount>1)
				{
					amount = (buffer[s][5] << 8) + buffer[s][6];
					if (amount>pi->amount)
						amount = pi->amount;
					if (amount < pi->amount)
					{
						c=Items->MemItemFree();
						items[c].Init(0);
						memcpy(&items[c], pi, sizeof(cItem));  // Tauriel reduce code faster too
						items[c].SetSerial(itemcount2);
						itemcount2++;

						items[c].amount = pi->amount - amount;
						// Tauriel sorry, there is no way to make this call the item creation stuff
// Why doing it twice?
//						setptr(&itemsp[itemcount2%HASHMAX], c);
//						itemcount2++; // important bugfix for items disappearing, lb
						if (!items[c].isInWorld())
							contsp.insert(items[c].contserial, items[c].serial);
						if (items[c].ownserial!=-1)
							setptr(&ownsp[items[c].ownserial%HASHMAX], c);
						if (items[c].spawnserial!=-1)
							setptr(&spawnsp[items[c].spawnserial%HASHMAX], c);
						
						statwindow(s,cc);
						RefreshItem(c);//AntiChrist
					}
					
					if (pi->id() == 0x0EED) // gold coin
					{
						int packnum = packitem(currchar[s]);
						if (packnum!=-1) // lb
							if (pi->contserial == items[packnum].serial)
								update = 1;
					}
					
					pi->amount = amount;
				}
				
				// Tauriel remove item from world mapcells
				mapRegions->Remove(pi); // remove this item from a map cell
				pi->pos.x = 0;
				pi->pos.y = 0;
				pi->pos.z = 0;
				
				pi->flags.isBeeingDragged=true;
				pi->SetContSerial(-1);
				if (pi != NULL) // Ripper...adds weight to the players cursor when carrying a item.
				{
					int amt = 0, wgt;
					wgt = (int)Weight->LockeddownWeight(pi, &amt, 0);
					pc_currchar->weight += wgt;
					update = 1;
				}
			}
		}
	} // end of if i!=-1
	if (update)
		statwindow(s, DEREF_P_CHAR(pc_currchar));
}
Пример #15
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();
	}
}
void dbl_click_item(cUOSocket* socket, SERIAL target_serial) throw()
{
	SERIAL serial = target_serial;
	P_PLAYER pc_currchar = socket->player();

	if( !pc_currchar->isGM() && /*pc_currchar->objectDelay() > 10 && ???*/ pc_currchar->objectDelay() >= uiCurrentTime )
	{
		socket->sysMessage(tr("You must wait to perform another action."));
		return;
	}
	else
		pc_currchar->setObjectDelay( SrvParams->objectDelay() * MY_CLOCKS_PER_SEC + uiCurrentTime );


	P_ITEM pi = FindItemBySerial( serial );

	if( !pi )
		return;

	if( pi->container() && pi->container()->isItem() && pi->type() != 1 && !pi->isInWorld())
	{ // Cant use stuff that isn't in your pack.
		P_CHAR pc_p = pi->getOutmostChar();
		if( pc_p && pc_currchar != pc_p )
				return;
	}
	else if( pi->container() && pi->container()->isChar() && pi->type() != 1 && !pi->isInWorld() )
	{	// in a character.
		P_CHAR pc_p = dynamic_cast<P_CHAR>(pi->container());
		if (pc_p != NULL)
			if( pc_p != pc_currchar && pi->layer() != 15 && pi->type() != 1 )
				return;
	}

	// Criminal for looting an innocent corpse & unhidden if not owner...
	if( pi->corpse() )
	{
		if (!pc_currchar->Owns(pi) && !pc_currchar->isGM()) {
			pc_currchar->unhide();
		}

		// TODO: Add a XML option for this
		if(!pc_currchar->Owns(pi) && !pc_currchar->isGM() && pc_currchar->isInnocent())
		{
			// Innocent Corpse and not in the same party && party allowance for looting?
			if (pi->hasTag("notoriety") && pi->getTag("notoriety").toInt() == 0x01) {
				P_PLAYER owner = dynamic_cast<P_PLAYER>(pi->owner());
				bool allowed = false;

				if (owner && owner->party() && owner->party() == pc_currchar->party()) {
					// Check if the player allowed looting his corpse by party members
					if (owner->party()->lootingAllowed().contains(owner)) {
						allowed = true;
					}
				}

				if (!allowed) {
					pc_currchar->makeCriminal();
				}
			}
		}
	}

	// Secure containers
	if( pi->isLockedDown() && pi->secured() )
	{
		if( !pc_currchar->Owns( pi ) && !pc_currchar->isGM() )
		{
			socket->sysMessage( tr( "That is a secured chest!" ) );
			return;
		}
	}

	// Dead ppl can only use ankhs
	if( pc_currchar->isDead() && pi->type() != 16 )
	{
		socket->sysMessage( tr( "Your ghostly hand passes trough the object." ) );
		return;
	}

	// You can only use equipment on your own char
	if( !pc_currchar->isGM() && pi->container() && pi->container()->isChar() && pi->container() != pc_currchar )
	{
		if( pi->layer() != 15 || !SrvParams->stealingEnabled() )
		{
			socket->sysMessage( tr( "You cannot use items equipped by other players." ) );
			return;
		}
	}

	// Call both events here
	if( pc_currchar->onUse( pi ) )
		return;

	if( pi->onUse( pc_currchar ) )
		return;

	// Check item behaviour by it's tpye
	switch (pi->type())
	{
	case 1: // normal containers
		{
			pc_currchar->setObjectDelay( 0 );	// no delay for opening containers

			if( pc_currchar->isGM() )
			{
				socket->sendContainer( pi );
				return;
			}

			if( pi->layer() > 0x18 )
			{
				socket->sysMessage( tr( "You can't see this." ) );
				return;
			}

			if( isInLockedItem( pi ) )
			{
				socket->sysMessage( tr( "You have to unlock it before taking a look." ) );
				return;
			}

			if( !pi->container() )
			{
				if( !pi->inRange( pc_currchar, 2 ) )
				{
					socket->clilocMessage( 0x7A258, "", 0x3b2 ); // You cannot reach that
					return;
				} else if(!pc_currchar->lineOfSight(pi, true)) {
					socket->clilocMessage( 0x7A258, "", 0x3b2 ); // You cannot reach that
					return;
				}

				socket->sendContainer( pi );
				return;
			}
			else if( pi->container()->isItem() )
			{
				P_ITEM pOCont = pi->getOutmostItem();

				// Check if we can reach the top-container
				if( !pOCont->container() )
				{
					if( !pOCont->inRange( pc_currchar, 2 ) )
					{
						socket->clilocMessage( 0x7A258, "", 0x3b2 ); // You cannot reach that
						return;
					}

					socket->sendContainer( pi );
				}
				else
				{
					P_CHAR pChar = dynamic_cast< P_CHAR >( pOCont->container() );
					if( pChar && pChar != pc_currchar )
					{
						if( !pChar->inRange( pc_currchar, 2 ) )
							socket->sysMessage( tr( "You must stand nearer to snoop!" ) );
						else
							Skills->Snooping( pc_currchar, pi );
					}
					else if( pChar == pc_currchar )
						socket->sendContainer( pi );
				}

				return;
			}
			else if( pi->container()->isChar() )
			{
				// Equipped on another character
				P_CHAR pChar = dynamic_cast< P_CHAR >( pi->container() );

				if( pChar && pChar != pc_currchar )
				{
					if( !pChar->inRange( pc_currchar, 2 ) )
						socket->sysMessage( tr( "You must stand nearer to snoop!" ) );
					else
						Skills->Snooping( pc_currchar, pi );
				}
				else if( pChar == pc_currchar )
					socket->sendContainer( pi );

				return;
			}

			socket->sysMessage( tr( "You can't open this container." ) );
			return;
		}
		return;

	case 16:
		// Check for 'resurrect item type' this is the ONLY type one can use if dead.
		if( pc_currchar->isDead() )
		{
			pc_currchar->resurrect();
			socket->sysMessage( tr( "You have been resurrected." ) );
			return;
		}
		else
		{
			socket->sysMessage( tr( "You are already living!" ) );
			return;
		}

	// Drinks
	case 105:
		pc_currchar->soundEffect( 0x30 + RandomNum( 0, 1 ) );
		pi->reduceAmount( 1 ); // Remove a drink
		pc_currchar->message( "Gulp!" );
		return;

	// 1001: Sword Weapons (Swordsmanship)
	case 1001:
	// 1002: Axe Weapons (Swordsmanship + Lumberjacking)
	case 1002:
	// 1005: Fencing
	case 1005:
	// 1003: Macefighting (Staffs)
	case 1003:
	// 1004: Macefighting (Maces/WarHammer)
	case 1004:
	// 1006: Bows
	case 1006:
	// 1007: Crossbows
	case 1007:
	// 1008: Shields
	case 1008:
		break;

	default:
		break;
	}

	socket->sysMessage( tr( "You can't think of a way to use that item." ) );
}
Пример #17
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();
}
Пример #18
0
void pack_item(NXWCLIENT ps, PKGx08 *pp) // Item is put into container
{
	if (ps == NULL) return;

	char temp[TEMP_STR_SIZE]; //xan -> this overrides the global temp var
	char temp2[TEMP_STR_SIZE]; //xan -> this overrides the global temp var
	int serial/*, serhash*/;
	tile_st tile;
//	bool abort=false;
	NXWSOCKET  s=ps->toInt();

	P_CHAR pc=ps->currChar();
	VALIDATEPC(pc);

	Location charpos= pc->getPosition();

	P_ITEM pack;

	P_ITEM pCont = pointers::findItemBySerial(pp->Tserial);
	VALIDATEPI(pCont);

	P_ITEM pItem = pointers::findItemBySerial(pp->Iserial);
	VALIDATEPI(pItem);

	if (pItem->getId() >= 0x4000)
	{
//		abort=true; // LB crashfix that prevents moving multi objcts in BP's
		ps->sysmsg(TRANSLATE("Hey, putting houses in your pack crashes your back and client!"));
	}

	//ndEndy recurse only a time
	P_ITEM contOutMost = pCont->getOutMostCont();
	P_CHAR contOwner = ( !contOutMost->isInWorld() )? pointers::findCharBySerial( contOutMost->getContSerial() ) : NULL;

	if( ISVALIDPC(contOwner) ) {
		//if ((contOwner->npcaitype==NPCAI_PLAYERVENDOR) && (contOwner->npc) && (contOwner->getOwnerSerial32()!=pc->getSerial32()) )
		if ( contOwner->getSerial32() != pc->getSerial32() && contOwner->getOwnerSerial32() != pc->getSerial32() && !pc->IsGM() ) { // Luxor
			ps->sysmsg(TRANSLATE("This aint your backpack!"));
			Sndbounce5(s);
			if (ps->isDragging()) {
				ps->resetDragging();
				item_bounce3(pItem);
				if (pCont->getId() >= 0x4000)
					senditem(s, pCont);
			}
			return;
		}
	}

	if (pCont->amxevents[EVENT_IONPUTITEM]!=NULL) {
		g_bByPass = false;
		pCont->amxevents[EVENT_IONPUTITEM]->Call( pCont->getSerial32(), pItem->getSerial32(), pc->getSerial32() );
		if (g_bByPass)
		{
			item_bounce6(ps,pItem);
			return;
		}
	}
	/*
	g_bByPass = false;
	pCont->runAmxEvent( EVENT_IONPUTITEM, pCont->getSerial32(), pItem->getSerial32(), pc->getSerial32() );
	if (g_bByPass)
	{	//AntiChrist to preview item disappearing
		item_bounce6(ps,pItem);
		return;
	}
	*/

	if (pCont->layer==0 && pCont->getId() == 0x1E5E &&
		pCont->getContSerial()==pc->getSerial32())
	{
		// Trade window???
		serial=calcserial(pCont->moreb1, pCont->moreb2, pCont->moreb3, pCont->moreb4);
		if(serial==-1) return;

		P_ITEM pi_z = pointers::findItemBySerial(serial);

		if (ISVALIDPI(pi_z))
			if ((pi_z->morez || pCont->morez))
			{
				pi_z->morez=0;
				pCont->morez=0;
				sendtradestatus( pi_z, pCont );
			}
	}

	if(SrvParms->usespecialbank)//only if special bank is activated
	{
		if(pCont->morey==MOREY_GOLDONLYBANK && pCont->morex==MOREX_BANK && pCont->type==ITYPE_CONTAINER)
		{
			if ( pItem->getId() == ITEMID_GOLD )
			{//if they're gold ok
				pc->playSFX( goldsfx(2) );
			} else
			{//if they're not gold..bounce on ground
				ps->sysmsg(TRANSLATE("You can only put golds in this bank box!"));

				pItem->setContSerial(-1);
				pItem->MoveTo( charpos );
				pItem->Refresh();
				pc->playSFX( itemsfx(pItem->getId()) );
				return;
			}
		}
	}

	// Xanathars's Bank Limit Code
	if (ServerScp::g_nBankLimit != 0) {

		if( ISVALIDPI( contOutMost ) && contOutMost->morex==MOREX_BANK ) {

			int n = contOutMost->CountItems( INVALID, INVALID, false);
			n -= contOutMost->CountItems( ITEMID_GOLD, INVALID, false);
			if( pItem->type == ITYPE_CONTAINER )
				n += pItem->CountItems( INVALID, INVALID, false);
			else
				++n;
			if( n > ServerScp::g_nBankLimit ) {
				ps->sysmsg(TRANSLATE("You exceeded the number of maximimum items in bank of %d"), ServerScp::g_nBankLimit);
				item_bounce6(ps,pItem);
				return;
			}

		}
	}


	//ndEndy this not needed because when is dragging cont serial is INVALID
	//testing UOP Blocking Tauriel 1-12-99
	if (!pItem->isInWorld())
	{
		item_bounce6(ps,pItem);
		return;
	}

	data::seekTile(pItem->getId(), tile);
	if (( ( (pItem->magic==2) || ( (tile.weight==255) && (pItem->magic != 1 ) ) ) && !pc->canAllMove()) ||
				( (pItem->magic==3|| pItem->magic==4) && !(pItem->getOwnerSerial32()==pc->getSerial32())))
	{
		Sndbounce5(s);
		if (ps->isDragging())
		{
			ps->resetDragging();
			item_bounce3(pItem);
			if (pCont->getId() >= 0x4000)
				senditem(s, pCont);
		}
		return;
	}
	// - Trash container
	if( pCont->type==ITYPE_TRASH)
	{
		pItem->Delete();
		ps->sysmsg(TRANSLATE("As you let go of the item it disappears."));
		return;
	}
	// - Spell Book
	if (pCont->type==ITYPE_SPELLBOOK)
	{
		if (!pItem->IsSpellScroll72())
		{
			ps->sysmsg(TRANSLATE("You can only place spell scrolls in a spellbook!"));
			Sndbounce5(s);
			if (ps->isDragging())
			{
				ps->resetDragging();
				item_bounce3(pItem);
			}
			if (pCont->getId() >= 0x4000)
				senditem(s, pCont);
			return;
		}
		pack= pc->getBackpack();
		if(ISVALIDPI(pack))
		{
			if ((!(pCont->getContSerial()==pc->getSerial32())) &&
				(!(pCont->getContSerial()==pack->getSerial32())) && (!(pc->CanSnoop())))
			{
				ps->sysmsg(TRANSLATE("You cannot place spells in other peoples spellbooks."));
				item_bounce6(ps,pItem);
				return;
			}

			if( strncmp(pItem->getCurrentNameC(), "#", 1) )
				pItem->getName(temp2);
			else
				strcpy(temp2,pItem->getCurrentNameC());

			NxwItemWrapper sii;
			sii.fillItemsInContainer( pCont, false );
			for( sii.rewind(); !sii.isEmpty(); sii++ ) {

				P_ITEM pi_ci=sii.getItem();

					if (ISVALIDPI(pi_ci))
					{
						if( strncmp(pi_ci->getCurrentNameC(), "#", 1) )

							pi_ci->getName(temp);
						else
							strcpy(temp,pi_ci->getCurrentNameC());

						if(!(strcmp(temp,temp2)) || !(strcmp(temp,"All-Spell Scroll")))
						{
							ps->sysmsg(TRANSLATE("You already have that spell!"));
							item_bounce6(ps,pItem);
							return;
						}
					}
				// Juliunus, to prevent ppl from wasting scrolls.
				if (pItem->amount > 1)
				{
					ps->sysmsg(TRANSLATE("You can't put more than one scroll at a time in your book."));
					item_bounce6(ps,pItem);
					return;
				}
			}
		}
		pCont->AddItem( pItem );
		ps->sendSpellBook(pCont);
		return;
	}

	if (pCont->type == ITYPE_CONTAINER) {

		if ( ISVALIDPC(contOwner) )
		{
			if ( (contOwner->npcaitype==NPCAI_PLAYERVENDOR) && (contOwner->npc) && (contOwner->getOwnerSerial32()==pc->getSerial32()) )
			{
				pc->fx1= DEREF_P_ITEM(pItem);
				pc->fx2=17;
				pc->sysmsg(TRANSLATE("Set a price for this item."));
			}
		}

		short xx=pp->TxLoc;
		short yy=pp->TyLoc;

		pCont->AddItem(pItem,xx,yy);

		pc->playSFX( itemsfx(pItem->getId()) );
		statwindow(pc,pc);
	}
	// end of player run vendors

	else
		// - Unlocked item spawner or unlockable item spawner
		if (pCont->type==ITYPE_UNLOCKED_CONTAINER || pCont->type==ITYPE_NODECAY_ITEM_SPAWNER || pCont->type==ITYPE_DECAYING_ITEM_SPAWNER)
		{
			pCont->AddItem(pItem, pp->TxLoc, pp->TyLoc); //Luxor
			pc->playSFX( itemsfx(pItem->getId()) );

		}
		else  // - Pileable
			if (pCont->pileable && pItem->pileable)
			{
				if ( !pCont->PileItem( pItem ) )
				{
					item_bounce6(ps,pItem);
					return;
				}
			}
			else
			{
				if( pItem->getContSerial( true )==INVALID  ) //current cont serial is invalid because is dragging
				{
					NxwSocketWrapper sw;
					sw.fillOnline( pItem->getPosition() );
					for( sw.rewind(); !sw.isEmpty(); sw++ )
						SendDeleteObjectPkt(sw.getSocket(), pItem->getSerial32() );
					mapRegions->remove(pItem);
				}

				pItem->setPosition( pp->TxLoc, pp->TyLoc, pp->TzLoc);
				pItem->setContSerial( pCont->getContSerial() );

				pItem->Refresh();
			}


}