/*!
\brief Add item to container
\author Endymion
\param pItem the item to add
\param xx the x location or INVALID if use rand pos
\param yy the y location or INVALID if use rand pos
*/
LOGICAL cItem::AddItem(P_ITEM pItem, short xx, short yy)
{

	VALIDATEPIR(pItem,false);

	NxwSocketWrapper sw;
	sw.fillOnline( pItem );
	for( sw.rewind(); !sw.isEmpty(); sw++ )
		SendDeleteObjectPkt(sw.getSocket(), pItem->getSerial32() );


	if (xx!=-1)	// use the given position
	{
		pItem->setContSerial( getSerial32() );
		pItem->setPosition(xx, yy, 9);
	}
	else		// no pos given
	{
		if( !ContainerPileItem(pItem) )	{ // try to pile
			pItem->SetRandPosInCont(this);		// not piled, random pos
			pItem->setContSerial( getSerial32() );
		}
		else
			return true; //Luxor: we cannot do a refresh because item was piled
	}
	pItem->Refresh();
	return true;

}
Exemple #2
0
static bool ItemDroppedOnSelf(NXWCLIENT ps, PKGx08 *pp, P_ITEM pi)
{
	if (ps == NULL) return false;
	VALIDATEPIR(pi, false);
//	NXWSOCKET  s=ps->toInt();
//	CHARACTER cc=ps->currCharIdx();
	P_CHAR pc = ps->currChar(); // MAKE_CHAR_REF(cc);
	VALIDATEPCR(pc, false);

	Location charpos = pc->getPosition();

	if (pi->getId() >= 0x4000 ) // crashfix , prevents putting multi-objects ni your backback
	{
		ps->sysmsg(TRANSLATE("Hey, putting houses in your pack crashes your back and client !"));
		pi->MoveTo( charpos );
		pi->Refresh();//AntiChrist
		return true;
	}

//	if (pi->glow>0) // glowing items
//	{
//		pc->addHalo(pi);
//		pc->glowHalo(pi);
//	}

	P_ITEM pack = pc->getBackpack();
	if (pack==NULL) // if player has no pack, put it at its feet
	{
		pi->MoveTo( charpos );
		pi->Refresh();
	}
	else
	{
		pack->AddItem(pi); // player has a pack, put it in there

		weights::NewCalc(pc);//AntiChrist bugfixes
		statwindow(pc,pc);
		pc->playSFX( itemsfx(pi->getId()) );
	}
	return true;
}
/*!
\brief Steal random
\author Unknow, updated by Endymion
\param ps the client
\todo add string because it's locked contanier into translate
*/
void Skills::target_randomSteal( NXWCLIENT ps, P_TARGET t )
{

	P_CHAR thief=ps->currChar();
	VALIDATEPC(thief);
	P_CHAR victim = pointers::findCharBySerial( t->getClicked() );
	VALIDATEPC(victim);
	

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

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

	if (victim->IsGMorCounselor() )
	{
		thief->sysmsg( TRANSLATE("You can't steal from gods."));
		return;
	}

	P_ITEM pack= victim->getBackpack();
	if ( !ISVALIDPI(pack))
	{
		thief->sysmsg(TRANSLATE("bad luck, your victim doesn't have a backpack"));
		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
	sprintf(temp, TRANSLATE("You reach into %s's pack to steal something ..."), victim->getCurrentNameC() );
	thief->sysmsg(temp);

	if ( char_inRange(thief,victim,1) )
	{
		P_ITEM pi = NULL;

		NxwItemWrapper si;
		si.fillItemsInContainer( pack, false );
		if( si.size()>0 ) {
			int ra=rand()%si.size();
			int c=0;
			for( si.rewind(); !si.isEmpty(); si++ ) {
				c++;
				if( c==ra ) {
					pi=si.getItem();
					break;
				}
			}
		}

		if( pi==NULL ) {
			thief->sysmsg(TRANSLATE("... and discover your victim doesn't have any posessions"));
			return;
		}

		
		//Endy can't be not valid after this -^ loop, else error
		VALIDATEPI(pi);

		if( pi->isNewbie() ) 
		{//newbie
			thief->sysmsg(TRANSLATE("... and fail because it is of no value to you."));
			return;
		}

		if(pi->isSecureContainer())
		{
			thief->sysmsg(TRANSLATE("... and fail because it's a locked container."));
			return;
		}

		if ( thief->checkSkill( STEALING,0,999) )
		{
			// 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 ( ((pi->getWeightActual())>cansteal) && !pi->isContainer())//Containers
				thief->sysmsg(TRANSLATE("... and fail because it is too heavy."));
        		else
				if(pi->isContainer() && (weights::RecursePacks(pi)>cansteal))
					thief->sysmsg(TRANSLATE("... and fail because it is too heavy."));
				else
				{
					
					if (victim->amxevents[EVENT_CHR_ONSTOLEN])
					{
						g_bByPass = false;
						victim->amxevents[EVENT_CHR_ONSTOLEN]->Call(victim->getSerial32(), thief->getSerial32());
						if (g_bByPass==true)
							return;
					}
					/*
					victim->runAmxEvent( EVENT_CHR_ONSTOLEN, victim->getSerial32(), s);
					if (g_bByPass==true)
						return;
					*/
					P_ITEM thiefpack = thief->getBackpack();
					VALIDATEPI(thiefpack);
					pi->setContSerial( thiefpack->getSerial32() );
					thief->sysmsg(TRANSLATE("... and you succeed."));
					pi->Refresh();
					//all_items(s);
				}
		}
		else
			thief->sysmsg(TRANSLATE(".. and fail because you're not good enough."));

		if ( thief->skill[STEALING] < rand()%1001 )
		{
			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)//AntiChrist
				setCrimGrey(thief, ServerScp::g_nStealWillCriminal);//Blue and not attacker and not guild

			std::string itmname = "";
			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)
				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)))
						sysmessage(ps_i->toInt(),temp2);
			}
		}
	}
	else 
	{
		thief->sysmsg( TRANSLATE("... and realise you're too far away."));
	}

}
/*!
\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);
}
/*!
\author Luxor
\brief execute decay on the item
\return true if decayed (so deleted), false else
*/
LOGICAL cItem::doDecay()
{
	if ( !canDecay() )
		return false;

	if ( magic == 4/* || magic == 2*/ )
		return false;

	if ( !isInWorld() )
		return false;

	if ( TIMEOUT( decaytime ) )
	{


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

		//Multis
		if ( !isFieldSpellItem() && !corpse )
		{
			if ( getMultiSerial32() == INVALID )
			{
				P_ITEM pi_multi = findmulti(getPosition());
				if ( ISVALIDPI(pi_multi) )
				{
					if ( pi_multi->more4 == 0 )
					{
						setDecayTime();
						SetMultiSerial(pi_multi->getSerial32());
						return false;
					}
				}
			}
			else
			{
				setDecayTime();
				return false;
			}
		}
		//End Multis

		if( type == ITYPE_CONTAINER || ( !SrvParms->lootdecayswithcorpse && corpse ) )
		{
			NxwItemWrapper si;
			si.fillItemsInContainer( this, false );
			for( si.rewind(); !si.isEmpty(); si++ )
			{
				P_ITEM pj = si.getItem();
				if( ISVALIDPI(pj) )
				{
					pj->setContSerial(INVALID);
					pj->MoveTo( getPosition() );
					pj->setDecayTime();
					pj->Refresh();
				}
			}
		}
		Delete();
		return true;
	}
	else
		return false;
}
Exemple #6
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);
	}
}
Exemple #7
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();
			}


}
Exemple #8
0
static bool ItemDroppedOnChar(NXWCLIENT ps, PKGx08 *pp, P_ITEM pi)
{
	if (ps == NULL) return true;
	VALIDATEPIR(pi, false);
	NXWSOCKET  s = ps->toInt();
//	CHARACTER cc=ps->currCharIdx();
	P_CHAR pTC = pointers::findCharBySerial(pp->Tserial);	// the targeted character
	VALIDATEPCR(pTC, false);
	P_CHAR pc_currchar = ps->currChar(); //MAKE_CHAR_REF(cc);
	VALIDATEPCR(pc_currchar, false);
	Location charpos = pc_currchar->getPosition();

	if (!pTC) return true;
	if (pi->amxevents[EVENT_IDROPONCHAR]!=NULL) 
	{
		g_bByPass = false;
		pi->amxevents[EVENT_IDROPONCHAR]->Call( pi->getSerial32(), pc_currchar->getSerial32(), pTC->getSerial32() );
		if (g_bByPass) {
			pi->Refresh();
			return true;
		}
	}

	if (pc_currchar->getSerial32() != pTC->getSerial32() /*DEREF_P_CHAR(pTC)!=cc*/)
	{
		if (pTC->npc)
		{
			if(!pTC->HasHumanBody())
			{
				ItemDroppedOnPet( ps, pp, pi);
			}
			else	// Item dropped on a Human character
			{
				// Item dropped on a Guard (possible bounty quest)
				if( ( pTC->npc == 1 ) && ( pTC->npcaitype == NPCAI_TELEPORTGUARD ) )
				{
					ItemDroppedOnGuard( ps, pp, pi);
				}
				if ( pTC->npcaitype == NPCAI_BEGGAR )
				{
					ItemDroppedOnBeggar( ps, pp, pi);
				}
				//This crazy training stuff done by Anthracks ([email protected])
				if(pc_currchar->isBeingTrained() )
				{
					if ( pc_currchar->trainer != pTC->getSerial32())
					{
						pTC->talk(s, TRANSLATE("Thank thee kindly, but I have done nothing to warrant a gift."),0);
						Sndbounce5(s);
						if (ps->isDragging())
						{
							ps->resetDragging();
							item_bounce5(s,pi);
						}
						return true;
					}
					else // The player is training from this NPC
					{
						ItemDroppedOnTrainer( ps, pp, pi);
					}
				}
				if ( pTC->isHirable() )
				{
					// test if gold is enough
					if ( pi->amount  < pTC->getHireFee() )
					{
						pTC->talk(s, TRANSLATE("I need much more gold if i shall be working for you !"),0);
						Sndbounce5(s);
						if (ps->isDragging())
						{
							ps->resetDragging();
							item_bounce5(s,pi);
						}
						return true;
					}
					else if ( pi->amount >= pTC->getHireFee() )
					{
						if ( pi->amount > pTC->getHireFee() )
						{
							pi->amount=(UI16)(pi->amount - pTC->getHireFee());
							pTC->talk(s, TRANSLATE("Thank thee kindly, but this is more than i need for the day."),0);
							Sndbounce5(s);
							if (ps->isDragging())
							{
								ps->resetDragging();
								item_bounce5(s,pi);
							}
						}
						pTC->setOwner(pc_currchar);
						tempfx::add(pTC, 
							pc_currchar,
							tempfx::NPC_HIRECOST, 
							0, 
							0, 
							0,
							0,
							(UI16)(MY_CLOCKS_PER_SEC*secondsperuominute*60*24 )); // call callback every uo day
						return true;
					}
				}
			}//if human or not
		}
		else // dropped on another player
		{
			// By Polygon: Avoid starting the trade if GM drops item on logged on char (crash fix)
			if ((pc_currchar->IsGM()) && !pTC->IsOnline())
			{
				// Drop the item in the players pack instead
				// Get the pack
				P_ITEM pack = pTC->getBackpack();
				if (pack != NULL)	// Valid pack?
				{
					pack->AddItem(pi);	// Add it
					weights::NewCalc(pTC);
				}
				else	// No pack, give it back to the GM
				{
					pack = pc_currchar->getBackpack();
					if (pack != NULL)	// Valid pack?
					{
						pack->AddItem(pi);	// Add it
						weights::NewCalc(pc_currchar);
					}
					else	// Even GM has no pack?
					{
						// Drop it to it's feet
						pi->MoveTo( charpos );
						pi->Refresh();
					}
				}
			}
			else
			{
                                //<Luxor>: secure trade
                 P_ITEM tradeCont = tradestart(pc_currchar, pTC);
                 if (ISVALIDPI(tradeCont)) {
                    tradeCont->AddItem( pi, 30, 30 );
                 } else {
                    Sndbounce5(s);
                    if (ps->isDragging()) {
                 		ps->resetDragging();
                 		UpdateStatusWindow(s,pi);
                   	}
                 }
                 //</Luxor>
		        }
	        }
	}
	else // dumping stuff to his own backpack !
	{
		ItemDroppedOnSelf( ps, pp, pi);
	}
	return true;
}