Пример #1
0
void cDragItems::dropItem( P_CLIENT client )
{
	P_CHAR pChar = client->player();

	// Get the data
	SERIAL itemId = LongFromCharPtr( &buffer[ client->socket() ][ 1 ] );
	SERIAL contId = LongFromCharPtr( &buffer[ client->socket() ][ 10 ] );

	Coord_cl dropPos = pChar->pos; // plane+map
	dropPos.x = ShortFromCharPtr( &buffer[ client->socket() ][ 5 ] );
	dropPos.y = ShortFromCharPtr( &buffer[ client->socket() ][ 7 ] );
	dropPos.z = buffer[ client->socket() ][ 9 ];

	// Get possible containers
	P_ITEM pItem = FindItemBySerial( itemId );
	
	if( !pItem )
		return;

	P_ITEM iCont = FindItemBySerial( contId );
	P_CHAR cCont = FindCharBySerial( contId );

	/* >> SEE LORD BINARIES DROPFIXBUGFIXBUG << */

	// A completely invalid Drop packet
	if( !iCont && !cCont && ( dropPos.x == 0xFFFF ) && ( dropPos.y == 0xFFFF ) && ( dropPos.z == 0xFF ) )
	{
		bounceItem( client, pItem );
		return;
	}

	// Item dropped on Ground
	if( !iCont && !cCont )
		dropOnGround( client, pItem, dropPos );
	// Item dropped on another item
	else if( iCont )
		dropOnItem( client, pItem, iCont, dropPos );
	// Item dropped on char
	else if( cCont )
		dropOnChar( client, pItem, cCont );
}
Пример #2
0
void cFishing::FishTarget(P_CLIENT ps)
{
	// fixes an exploit with fishing, LB
	int px,py,cx,cy;
	UOXSOCKET s=ps->GetSocket();
	P_CHAR pPlayer=ps->getPlayer();
	if (!pPlayer) return;

	px=((buffer[s][0x0b]<<8)+(buffer[s][0x0c]%256));
	py=((buffer[s][0x0d]<<8)+(buffer[s][0x0e]%256));
	cx=abs(pPlayer->pos.x-px);
	cy=abs(pPlayer->pos.y-py);
//	int cz=abs(pPlayer->z-buffer[s][0x10]);

	if(!(cx<=6 && cy<=6))
	{
		ps->SysMsg("You are too far away to reach that");
		return;
	}
	// end exploit fix

	bool ok=false;
	if (IsFishWater(ShortFromCharPtr(buffer[s]+0x11)))
		ok = true;
	else
	{	// it might be offshore fishing (client returns id=0 for deep sea ) Duke, Thx for the hint goes to Avanoon guys
		map_st map = Map->SeekMap0(px, py);	// search the ground tile where they casted
		if ( map.id == 0x00A8 || map.id == 0x00A9 || map.id == 0x00AA || map.id == 0x00AB )
			ok = true;
	}
	if (ok)
	{
		action(s,0x0b);
		if ((buffer[s][1]==1 || buffer[s][1]==0)&&(buffer[s][2]==0)&&(buffer[s][3]==1)&&(buffer[s][4]==0))
		{
			if (fishing_data.randomtime!=0)
				pPlayer->fishingtimer=rand()%fishing_data.randomtime+fishing_data.basetime;
			else
				pPlayer->fishingtimer=fishing_data.basetime;
		}
		soundeffect(s, 0x02, 0x3F);
		pPlayer->unhide();
		Fish(DEREF_P_CHAR(pPlayer));
	}
	else
		ps->SysMsg("You need to be closer to the water to fish!");
}
Пример #3
0
void cFishing::FishTarget(P_CLIENT ps)
{
	// fixes an exploit with fishing, LB
	int px,py,cx,cy;
	UOXSOCKET s=ps->socket();
	P_CHAR pPlayer=ps->player();
	if (!pPlayer) return;

	px=((buffer[s][0x0b]<<8)+(buffer[s][0x0c]%256));
	py=((buffer[s][0x0d]<<8)+(buffer[s][0x0e]%256));
	cx=abs(pPlayer->pos.x-px);
	cy=abs(pPlayer->pos.y-py);
//	int cz=abs(pPlayer->z-buffer[s][0x10]);

	if(!(cx<=6 && cy<=6))
	{
		sysmessage(s, "You are too far away to reach that");
		return;
	}
	// end exploit fix

	bool ok=false;
	if (IsFishWater(ShortFromCharPtr(buffer[s]+0x11)))
		ok = true;
	else
	{	// it might be offshore fishing (client returns id=0 for deep sea ) Duke, Thx for the hint goes to Avanoon guys
		map_st map = Map->SeekMap(Coord_cl(px, py, pPlayer->pos.map));	// search the ground tile where they casted
		if ( map.id == 0x00A8 || map.id == 0x00A9 || map.id == 0x00AA || map.id == 0x00AB )
			ok = true;
	}
	if (ok)
	{
		action(s,0x0b);
		if (SrvParams->randomtime()!=0) pPlayer->setFishingtimer(rand()%SrvParams->randomtime()+SrvParams->basetime());
		else
		pPlayer->setFishingtimer(SrvParams->basetime());
		
		soundeffect(s, 0x02, 0x3F);
		pPlayer->unhide();
		Fish(pPlayer);
	}
	else
		sysmessage(s, "You need to be closer to the water to fish!");
}
Пример #4
0
void cSpeech::talking(int s, QString speech) // PC speech
{
/*
	Unicode speech format
	byte = char, short = char[2], int = char[4], wchar = char[2] = unicode character

	Message Sent By Client:
	0xAD - Unicode Speech Request
	BYTE cmd(0xAD)
	short msgsize 1, 2
	byte type(0 = say, 2 = emote, 8 = whisper, 9 = yell) 3
	short color 4, 5
	short font 6, 7
	BYTE[4] lang(null terminated, "enu " for US english.) 8, 9, 10, 11
	wchar[?] text(null terminated, ?=(msgsize - 12)/2) 13
  
	Message Sent By Server:
	0xAE - Unicode Speech Message
	BYTE cmd(0xAE) 0
	short msgsize 1, 2
	BYTE[4] ser(ser of speaker, all 0xFF if none) 3, 4, 5, 6
	BYTE[2] model(id of speaker, all 0xFF if none)7, 8
	BYTE type 9
	short color 10, 11
	short font 12, 13
	BYTE[4] language(same as before) 14, 15, 16, 17
	BYTE[30] speaker's name(normal chars, not wchars) 18 - 48
	WCHAR[?] text(null terminated, ?=(msgsize - 48)/2

    Importnat note regarding 0xAD: since 2.0.7 clients send between lang and text 0...10 bytes. (we can ignore them safely)
	Those bytes get cut out in network.cpp correctly, so the buffer THIS functions sees is actualy what is written above.
    The actual data the client sends is differently though.
	Just noted this to prevent from debugging if somebody finds out client data doesn't fit to this description (LB) 

*/
	
	//char nonuni[512];
	unsigned char talk2[19];
	QByteArray unicodetext;
	char lang[4];
	char name[50] = {0,};	// it **IS** important to 0 out the remaining gaps
	
	P_CHAR pc_currchar = currchar[s];	
//	strcpy(nonuni, speech.latin1());

	// len+font+color+type = same postion for non unicode and unicode speech packets
	// but 8 ... x DIFFER a lot for unicode and non unicode packets !!!

	strncpy(name, pc_currchar->name.c_str(), 50);

	char speech_type       = buffer[s][3]; 
	UI16 speech_color	   = ShortFromCharPtr(&buffer[s][4]);
	char speech_fontbyte1  = buffer[s][6];
	char speech_fontbyte2  = buffer[s][7];

	int ucl = ( speech.length() * 2 ) + 2;
	int tl = ucl + 48 ;

	if (pc_currchar->unicode)
	{
		lang[0]=buffer[s][8];
		lang[1]=buffer[s][9];
		lang[2]=buffer[s][10];
		lang[3]=buffer[s][11];
		
		unicodetext.duplicate( (char*)&buffer[s][12], ucl );
	}
	else
	{
		lang[0]='E';
		lang[1]='N';
		lang[2]='U';
		lang[3]=0;
		
		char2wchar(speech.latin1());		// we are sending unicode response no matter if the speech request was non unicode or not
											// so convert to uni-text in case of non unicode
		unicodetext.duplicate( (char*)&temp, ucl );
	}

	/*
	clConsole.send("speech: %s\n",nonuni);
	clConsole.send("unicode speech:\n");
	for ( a=0; a < tl-48; a++) clConsole.send("%02i ",unicodetext[a]);
	clConsole.send("\n");*/




	//// Very important: do not use buffer[s][] anymore in this function !!!!
	//// unicode text that gets send is in unicodetext, nonunicode text for normal string processing in non uni code
//	string punt(nonuni);
	if (InputSpeech(speech, pc_currchar, s))	// handle things like renaming or describing an item
		return;

	if (pc_currchar->squelched)					// not allowed to talk
	{
		sysmessage(s, "You have been squelched.");
		return;
	}
			
	// AntiChrist
	pc_currchar->unhide();
		
	if (speech[0] == (char)SrvParams->commandPrefix() )
	{
		Commands->Command(s, speech.latin1());
		return;
	}

	if ( speech_type == '\x09' && pc_currchar->canBroadcast() )
	{
		broadcast(s);
		return;
	}
	
	talk2[0] = 0xAE;
	ShortToCharPtr(tl, &talk2[1]);
	LongToCharPtr(pc_currchar->serial, &talk2[3]);
	ShortToCharPtr(pc_currchar->id(), &talk2[7]);
	talk2[9] =  speech_type;
	ShortToCharPtr(speech_color, &talk2[10]);
	talk2[12] = speech_fontbyte1;
	talk2[13] = speech_fontbyte2;
	
	talk2[14] = lang[0];
	talk2[15] = lang[1];
	talk2[16] = lang[2];
	talk2[17] = lang[3];
	
	Xsend(s, talk2, 18);
	Xsend(s, name, 30);   
	Xsend(s, unicodetext.data(), unicodetext.size());   
	
	if (speech_type == 0 || speech_type == 2)
	{
		pc_currchar->saycolor = speech_color;
	}
	if (SrvParams->speechLog()) // Logging bugfixed by LB
	{
		char temp2[512];
		sprintf(temp2, "%s.speech_log", pc_currchar->name.c_str());
		sprintf((char*)temp, "%s [%x] [%i] said:\n%s\n", pc_currchar->name.c_str(), pc_currchar->serial, pc_currchar->account, speech.latin1());
		savelog((char*)temp, (char*)temp2);
	}
	
	//char SpeechUpr[512];
	//strcpy(SpeechUpr, nonuni);
	//strupr(SpeechUpr);
	QString SpeechUpr = speech.upper();
	//transform(SpeechUpr.begin(), SpeechUpr.end(), SpeechUpr.begin(), ::toupper);
	//if (!strcmp(SpeechUpr, "I RESIGN FROM MY GUILD"))
	if (SpeechUpr == "I RESIGN FROM MY GUILD")
	{
		GuildResign(s);
	}
	
	if (response(s,pc_currchar, SpeechUpr))
		return;  // Vendor responded already
	
	//if (strstr(SpeechUpr, "GUARDS"))
	if (SpeechUpr.contains("GUARDS"))
		callguards(currchar[s]);
	
	if (Boats->Speech(s, SpeechUpr))
		return;
	
	house_speech(s, SpeechUpr); // houses crackerjack 8/12/99			
	
	int i, j;
	for (i = 0; i < now; i++)
	{
		// AntiChrist - don't check line of sight for talking!!!
		if (inrange1(i, s) && perm[i] && i!=s)//&&line_of_sight(s, pc_currchar->pos.x, pc_currchar->pos.y, pc_currchar->pos.z, chars[currchar[i]].x, chars[currchar[i]].y, chars[currchar[i]].z, WALLS_CHIMNEYS + DOORS + FLOORS_FLAT_ROOFING))
		{
			Xsend(i, talk2, 18);
			Xsend(i, name, 30);
			if (pc_currchar->dead				// a ghost is talking
				&& !currchar[i]->dead		// Ghost can talk normally to other ghosts
				&& !currchar[i]->isGMorCounselor()// GM/Counselors can see ghosts talking always  Seers?
				&& currchar[i]->spiritspeaktimer == 0)
			{
				unsigned char ghostspeech[512];
				memcpy(&ghostspeech, unicodetext.data(), unicodetext.size());
				for (j = 1; j < ucl-2 ; j += 2)	// -2: dont override /0 /0 terminator !
				{
					if (ghostspeech[j] != 32)	// keep the blanks
						ghostspeech[j] = (ghostspeech[j]%2) ? 'O' : 'o';
				}
				Xsend(i, ghostspeech, ucl);		// send 'ghostified' speech "OOoooOo  Ooo"
			}
			else
				Xsend(i, unicodetext.data(), unicodetext.size());   
		}
	}
	
	if (pc_currchar->dead) return; // this makes it so npcs do not respond to dead people
	
	cChar* pc=NULL;
	cChar* pNpc=NULL;
	cRegion::RegionIterator4Chars ri(pc_currchar->pos);
	for (ri.Begin(); !ri.atEnd(); ri++)
	{	
		pc = ri.GetData();
		if (!pc->isSameAs(pc_currchar) 
			&& pc->isNpc()
			&& pc->dist(pc_currchar) <= 2)
		{
			pNpc=pc;
			break;
		}
	}
	if (pNpc && pNpc->speech)
	{
		Script *pScp=i_scripts[speech_script];
		if (!pScp->Open())
			return;
		char sect[512];
		sprintf(sect, "SPEECH %i", pNpc->speech);
		if (!pScp->find(sect)) 
		{
			pScp->Close();
			return;
		}
		int match = 0;
		strcpy(sect, "NO DEFAULT TEXT DEFINED");
		unsigned long loopexit = 0;
		do
		{
			pScp->NextLineSplitted();
			if (script1[0] != '}')
			{
				if (!(strcmp("DEFAULT", (char*)script1)))
				{
					strcpy(sect, (char*)script2);
				}
				if (!(strcmp("ON", (char*)script1)))
				{
					char scpUpr[500];
					strcpy(scpUpr,script2);
					strupr(scpUpr);
					if (SpeechUpr.find(scpUpr)!= string::npos)
						match=1;
				}
				if (!(strcmp("SAY", (char*)script1)))
				{
					if (match == 1)
					{
						npctalk(s, pNpc, (char*)script2, 0);
						match = 2;
					}
				}
				
				if (!(strcmp("TRG", (char*)script1))) // Added by Magius(CHE) §
				{							  
					if (match == 1)
					{
						pNpc->trigger = str2num(script2);
						scpMark m=pScp->Suspend();
						
						Trig->triggernpc(s, pNpc, 1);
						
						pScp->Resume(m);
						strcpy((char*)script1, "DUMMY");
						
						match = 2;
					}
				}
			}
		}
		while (script1[0] != '}'  && (++loopexit < MAXLOOPS));
		if (match == 0)
		{
			npctalk(s, pNpc, sect, 0);
		}
		pScp->Close();
	}
}
Пример #5
0
void cTrade::sellaction(int s)
{
	int i, amt, value=0, totgold=0;

	P_ITEM pRestock = NULL;
	P_ITEM pNoRestock = NULL;
	P_ITEM pSellCont = NULL;

	if (buffer[s][8]!=0)
	{
		P_CHAR pc_n = FindCharBySerial(calcserial(buffer[s][3], buffer[s][4], buffer[s][5], buffer[s][6]));
		if (pc_n == NULL) return;

		P_ITEM pi;
		unsigned int ci;
		vector<SERIAL> vecContainer = contsp.getData(pc_n->serial);
		for ( ci = 0; ci < vecContainer.size(); ci++)
		{
			pi = FindItemBySerial(vecContainer[ci]);
			if (pi->layer==0x1A) pRestock = pi;				// Buy Restock container
			else if (pi->layer==0x1B) pNoRestock = pi;		// Buy no restock container
			else if (pi->layer==0x1C) pSellCont = pi;		// Sell container
		}

		// Pre Calculate Total Amount of selling items to STOPS if the items if greater than SELLMAXITEM - Magius(CHE)
		int maxsell=0;
		i=buffer[s][8];
		if (i>256) return;
		for (i=0;i<buffer[s][8];i++)
		{
			amt=ShortFromCharPtr(buffer[s]+9+(6*i)+4);
			maxsell+=amt;
		}
		if (maxsell>SrvParams->sellmaxitem())
		{
			char tmpmsg[256];
			sprintf(tmpmsg,"Sorry %s but i can buy only %i items at time!",currchar[s]->name.c_str(),SrvParams->sellmaxitem());
			npctalkall(pc_n, tmpmsg,0);
			return;
		}

		for (i=0;i<buffer[s][8];i++)
		{
			P_ITEM pSell=FindItemBySerPtr(buffer[s]+9+(6*i));	// the item to sell
			if (!pSell) continue;
			amt=ShortFromCharPtr(buffer[s]+9+(6*i)+4);
			
			// player may have taken items out of his bp while the sell menu was up ;-)
			if (pSell->amount<amt)
			{
				npctalkall(pc_n, "Cheating scum! Leave now, before I call the guards!",0);
				return;
			}

			// Search the buy restock Container
			P_ITEM join = NULL;
			ci=0;
			P_ITEM pi;
			vector<SERIAL> vecContainer = contsp.getData(pRestock->serial);
			for ( ci = 0; ci < vecContainer.size(); ci++)
			{
				pi = FindItemBySerial(vecContainer[ci]);
				if (items_match(pi,pSell))
					join = pi;
			}

			// Search the sell Container to determine the price
			ci=0;
			vecContainer.clear();
			vecContainer = contsp.getData(pSellCont->serial);
			for ( ci = 0; ci < vecContainer.size(); ci++)
			{
				pi = FindItemBySerial(vecContainer[ci]);
				if (items_match(pi,pSell))
				{
					value=pi->value;
					value=calcValue(pSell, value);
					if (SrvParams->trade_system()==1)
						value=calcGoodValue(currchar[s], pSell, value, 1); // Fixed for adv trade --- by Magius(CHE) §
					break;	// let's take the first match
				}
			}
			totgold+=(amt*value);	// add to the bill

			if (join != NULL)	// The item goes to the container with restockable items
			{
				join->amount+=amt;
				join->restock-=amt;
				pSell->ReduceAmount(amt);
			}
			else
			{
				pSell->SetContSerial(pNoRestock->serial);
				SndRemoveitem(pSell->serial);
				if (pSell->amount!=amt)
					Commands->DupeItem(s, pSell, pSell->amount-amt);
			}
		}
		addgold(s, totgold);
		goldsfx(s, totgold);	// Dupois, SFX for gold movement	// Added Oct 08, 1998
	}

	char clearmsg[9];
	clearmsg[0]=0x3B;
	clearmsg[1]=0x00;
	clearmsg[2]=0x08;
	clearmsg[3]=buffer[s][3];
	clearmsg[4]=buffer[s][4];
	clearmsg[5]=buffer[s][5];
	clearmsg[6]=buffer[s][6];
	clearmsg[7]=0x00;
	Xsend(s, clearmsg, 8);
}
Пример #6
0
/*!
\author Zippy
\brief Build an house

Triggered by double clicking a deed-> the deed's morex is read
for the house section in house.cpp. Extra items can be added
using HOUSE ITEM, (this includes all doors!) and locked "LOCK"
Space around the house with SPACEX/Y and CHAR offset CHARX/Y/Z

\todo Remove temp variable
*/
void buildhouse( pClient client, pTarget t )
{
	int i = t->buffer[2];
	char temp[TEMP_STR_SIZE]; //xan -> this overrides the global temp var
	int loopexit=0;//where they click, and the house/key items
	uint32_t k, sx = 0, sy = 0, icount=0;
	uint16_t x, y, id_tile;
	int16_t z;
	int hitem[100];//extra "house items" (up to 100)
	char sect[512];                         //file reading
	char itemsdecay = 0;            // set to 1 to make stuff decay in houses
	static int looptimes=0;         //for targeting
	int cx=0,cy=0,cz=8;             //where the char is moved to when they place the house (Inside, on the steps.. etc...)(Offset)
	int boat=0;//Boats
	int hdeed=0;//deed id #
	int norealmulti=0,nokey=0,othername=0;
	char name[512];

	pChar pc = client->currChar();
	if ( ! pc ) return;

	sLocation charpos= pc->getPosition();

	int16_t id = INVALID; //house ID



	hitem[0]=0;//avoid problems if there are no HOUSE_ITEMs by initializing the first one as 0
	if (i)
	{
		cScpIterator* iter = NULL;
		char script1[1024];
		char script2[1024];
		sprintf(sect, "SECTION HOUSE %d", i);//and BTW, .find() adds SECTION on there for you....

		iter = Scripts::House->getNewIterator(sect);
		if (iter==NULL) return;

		do
		{
			iter->parseLine(script1, script2);
			if ((script1[0]!='}')&&(script1[0]!='{'))
			{
				if (!(strcmp(script1,"ID")))
				{
					id = hex2num(script2);
				}
				else if (!(strcmp(script1,"SPACEX")))
				{
					sx=str2num(script2)+1;
				}
				else if (!(strcmp(script1,"SPACEY")))
				{
					sy=str2num(script2)+1;
				}
				else if (!(strcmp(script1,"CHARX")))
				{
					cx=str2num(script2);
				}
				else if (!(strcmp(script1,"CHARY")))
				{
					cy=str2num(script2);
				}
				else if (!(strcmp(script1,"CHARZ")))
				{
					cz=str2num(script2);
				}
				else if( !(strcmp(script1, "ITEMSDECAY" )))
				{
					itemsdecay = str2num( script2 );
				}
				else if (!(strcmp(script1,"HOUSE_ITEM")))
				{
					hitem[icount]=str2num(script2);
					icount++;
				}
				else if (!(strcmp(script1, "HOUSE_DEED")))
				{
					hdeed=str2num(script2);
				}
				else if (!(strcmp(script1, "BOAT"))) boat=1;//Boats

				else if (!(strcmp(script1, "NOREALMULTI"))) norealmulti=1; // LB bugfix for pentas crashing client
				else if (!(strcmp(script1, "NOKEY"))) nokey=1;
				else if (!(strcmp(script1, "NAME")))
				{
					strcpy(name,script2);
					othername=1;
				}
			}
		}
		while ( (strcmp(script1,"}")) && (++loopexit < MAXLOOPS) );
		safedelete(iter);

		if (!id)
		{
			ErrOut("Bad house script # %i!\n",i);
			return;
		}
	}

	if(!looptimes)
	{
		if (i)
		{


			if (norealmulti) {
				pTarget targ = clientInfo[s]->newTarget( new cLocationTarget() );
				targ->code_callback=buildhouse;
				ShortToCharPtr(0x4064, t->buffer);
				targ->send( ps );
				ps->sysmsg( "Select a place for your structure: ");
			}
			else
				client->sysmessage("Select location for building.");
				nPackets::Sent::TargetMulti pk(0x00010000/*serial*/, id -0x4000/*model*/);
				client->sendPacket(&pk);
		}
		else
		{
			client->sysmessage("Select location for building.");
			nPackets::Sent::TargetMulti pk(0x00010000/*serial*/, ShortFromCharPtr(t->buffer) -0x4000/*model*/);
			client->sendPacket(&pk);
		}
		looptimes++;//for when we come back after they target something
		return;
	}
	if(looptimes)
	{
		looptimes=0;
		if(!pc->IsGM() && SrvParms->houseintown==0)
		{
			if ((region[pc->region].priv & rgnFlagGuarded) && itemById::IsHouse(id) ) // popy
			{
			    client->sysmessage(" You cannot build houses in town!");
			    return;
			}
		}
		x = ShortFromCharPtr(buffer[s] +11); //where they targeted	
		y = ShortFromCharPtr(buffer[s] +13);
		z = ShortFromCharPtr(buffer[s] +15);
		id_tile = ShortFromCharPtr(buffer[s] +17);
		z += tileHeight(id_tile);

		//XAN : House placing fix :)
		if ( (( x<XBORDER || y <YBORDER ) || ( x>(uint32_t)((map_width*8)-XBORDER) || y >(uint32_t)((map_height*8)-YBORDER) ))  )
		{
			client->sysmessage("You cannot build your structure there!");
			return;
		}


		/*
		if (ishouse(id1, id2)) // strict checking only for houses ! LB
		{
			if(!(CheckBuildSite(x,y,z,sx,sy)))
			{
				client->sysmessage("Can not build a house at that location (CBS)!");
				return;
			}
		}*/


		for (k=0;k<sx;k++)//check the SPACEX and SPACEY to make sure they are valid locations....
		{
			for (uint32_t l=0;l<sy;l++)
			{

				sLocation loc;

				loc.x=x+k;

				loc.y=y+l;

				loc.z=z;
				sLocation newpos = sLocation( x+k, y+l, z );
				if ( (isWalkable( newpos ) == illegal_z ) &&
					((charpos.x != x+k)&&(charpos.y != y+l)) )
					/*This will take the char making the house out of the space check, be careful
					you don't build a house on top of your self..... this had to be done So you
					could extra space around houses, (12+) and they would still be buildable.*/
				{
					client->sysmessage("You cannot build your stucture there.");
					return;
					//ConOut("Invalid %i,%i [%i,%i]\n",k,l,x+k,y+l);
				} //else ConOut("DEBUG: Valid at %i,%i [%i,%i]\n",k,l,x+k,y+l);

				if ( !norealmulti && cMulti::getAt(loc) )
				{
					client->sysmessage("You cant build structures inside structures");
					return;
				}
			}
		}

		if((id % 256)>=18)
			sprintf(temp,"%s's house",pc->getCurrentName().c_str());//This will make the little deed item you see when you have showhs on say the person's name, thought it might be helpful for GMs.
		else
			strcpy(temp, "a mast");
		if(norealmulti)
			strcpy(temp, name);
		//--^

		if (othername)
			strcpy(temp,name);

		if (id == INVALID)
			return;

		pItem pHouse = item::CreateFromScript( "$item_hardcoded" );
		if ( !pHouse ) return;
		pHouse->setId( id );
		pHouse->setCurrentName( temp );

		pc->making=0;

		pHouse->setPosition(x, y, z);
		pHouse->setDecay( false );
		pHouse->setNewbie( false );
		pHouse->setDispellable( false );
		pHouse->more4 = itemsdecay; // set to 1 to make items in houses decay
		pHouse->morex=hdeed; // crackerjack 8/9/99 - for converting back *into* deeds
		pHouse->setOwner(pc);
		if (pHouse->isInWorld())
		{
			mapRegions->add(pHouse);
		}
		if (!hitem[0] && !boat)
		{
			pc->teleport();
			return;//If there's no extra items, we don't really need a key, or anything else do we? ;-)
		}

		if(boat)
		{
			if(!Build(s,pHouse, id%256/*id2*/))
			{
				pHouse->Delete();
				return;
			}
		}

		if (i)
		{
			pItem pFx1 = MAKE_ITEM_REF( pc->fx1 );
			if ( pFx1 != 0 )
				pFx1->Delete(); // this will del the deed no matter where it is
		}

		pc->fx1=-1; //reset fx1 so it does not interfere
		// bugfix LB ... was too early reseted

		pItem pKey=NULL;
		pItem pKey2=NULL;

		pItem pBackPack = pc->getBackpack();

		//Key...
		//Altered key naming to include pc's name. Integrated backpack and bankbox handling (Sparhawk)
		if ((id%256 >=0x70) && (id%256 <=0x73))
		{
			sprintf(temp,"%s's tent key",pc->getCurrentName().c_str());
			pKey = item::CreateFromScript( "$item_iron_key", pBackPack ); //iron key for tents
			pKey2= item::CreateFromScript( "$item_iron_key", pBackPack );
		}
		else if(id%256 <=0x18)
		{
			sprintf(temp,"%s's ship key",pc->getCurrentName().c_str());
			pKey= item::CreateFromScript( "$item_bronze_key", pBackPack ); //Boats -Rusty Iron Key
			pKey2= item::CreateFromScript( "$item_bronze_key", pBackPack );
		}
		else
		{
			sprintf(temp,"%s's house key",pc->getCurrentName().c_str());
			pKey= item::CreateFromScript( "$item_gold_key", pBackPack ); //gold key for everything else;
			pKey2= item::CreateFromScript( "$item_gold_key", pBackPack );
		}

		if ( ! pKey || ! pKey2 ) return;

		pKey->Refresh();
		pKey2->Refresh();

		pHouse->st = pKey->getSerial();		// Create link from house to housekeys to allow easy renaming of
		pHouse->st2= pKey2->getSerial();	// house, housesign and housekeys without having to loop trough
														// all world items (Sparhawk)


		pKey->more = pHouse->getSerial();	//use the house's serial for the more on the key to keep it unique
		pKey->type=ITYPE_KEY;
		pKey->setNewbie();

		pKey2->more = pHouse->getSerial();	//use the house's serial for the more on the key to keep it unique
		pKey2->type=ITYPE_KEY;
		pKey2->setNewbie();

		pItem bankbox = pc->GetBankBox();
		if(bankbox!=NULL) // we sould add a key in bankbox only if the player has a bankbox =)
		{
			pItem p_key3=item::CreateFromScript( "$item_gold_key" );
			if ( ! p_key3 ) return;
			p_key3->setCurrentName( "a house key" );
			p_key3->more = pHouse->getSerial();
			p_key3->type=ITYPE_KEY;
			p_key3->setNewbie();
			bankbox->AddItem(p_key3);
		}
		if(nokey)
		{
			pKey->Delete(); // No key for .. nokey items
			pKey2->Delete(); // No key for .. nokey items
		}

		for (k=0;k<icount;k++)//Loop through the HOUSE_ITEMs
		{
			cScpIterator* iter = NULL;
			char script1[1024];
			char script2[1024];
			sprintf(sect,"SECTION HOUSE ITEM %i",hitem[k]);
			iter = Scripts::House->getNewIterator(sect);

			if (iter!=NULL)
			{
				pItem pi_l=NULL;
				loopexit=0;
				do
				{
					iter->parseLine(script1, script2);
					if (script1[0]!='}')
					{
						if (!(strcmp(script1,"ITEM")))
						{
							pi_l=item::CreateScriptItem(s,str2num(script2),0);//This opens the item script... so we gotta keep track of where we are with the other script.

							if(pi_l)
							{


							pi_l->magic=2;//Non-Movebale by default
							pi_l->setDecay( false ); //since even things in houses decay, no-decay by default
							pi_l->setNewbie( false );
							pi_l->setDispellable( false );
							pi_l->setPosition(x, y, z);
							pi_l->setOwner(pc);
							// SPARHAWK 2001-01-28 Added House sign naming
							if (pi_l->IsSign())
								if ((id%256 >=0x70) && (id%256<=0x73))
									pi_l->setCurrentName("%s's tent",pc->getCurrentName().c_str());
								else if (id%256<=0x18)
									pi_l->setCurrentName("%s's ship",pc->getCurrentName().c_str());
								else
									pi_l->setCurrentName("%s's house",pc->getCurrentName().c_str());

							}
						}
						if (!(strcmp(script1,"DECAY")))
						{
							if (pi_l) pi_l->setDecay();
						}
						if (!(strcmp(script1,"NODECAY")))
						{
							if (pi_l) pi_l->setDecay( false );
						}
						if (!(strcmp(script1,"PACK")))//put the item in the Builder's Backpack
						{
							if (pi_l) pi_l->setContainer(pc->getBackpack());
							if (pi_l) pi_l->setPosition("x", rand()%90+31);
							if (pi_l) pi_l->setPosition("y", rand()%90+31);
							if (pi_l) pi_l->setPosition("z", 9);
						}
						if (!(strcmp(script1,"MOVEABLE")))
						{
							if (pi_l) pi_l->magic=1;
						}
						if (!(strcmp(script1,"LOCK")))//lock it with the house key
						{
							if (pi_l) pi_l->more = pHouse->getSerial();
						}
						if (!(strcmp(script1,"X")))//offset + or - from the center of the house:
						{
							if (pi_l) pi_l->setPosition("x", x+str2num(script2));
						}
						if (!(strcmp(script1,"Y")))
						{
							if (pi_l) pi_l->setPosition("y", y+str2num(script2));
						}
						if (!(strcmp(script1,"Z")))
						{
							if (pi_l) pi_l->setPosition("z", z+str2num(script2));
						}
					}
				}
				while ( (strcmp(script1,"}")) && (++loopexit < MAXLOOPS) );

				if (pi_l)
					if (pi_l->isInWorld())
					{
						mapRegions->add(pi_l);
					}
				safedelete(iter);
			}
		}

        NxwSocketWrapper sw;
		sw.fillOnline( pc, false );
        for( sw.rewind(); !sw.isEmpty(); sw++ ) {
			pClient ps_i = sw.getClient();
			if(ps_i==NULL)
				continue;
			pChar pc_i=ps_i->currChar();
			if(pc_i)
				pc_i->teleport();
		}
                //</Luxor>
		if (!(norealmulti))
		{
			charpos.x= x+cx; //move char inside house
			charpos.y= y+cy;
			charpos.dispz= charpos.z= z+cz;

			pc->setPosition( charpos );
			//ConOut("Z: %i Offset: %i Char: %i Total: %i\n",z,cz,chars[currchar[s]].z,z+cz);
			pc->teleport();
		}
	}
}
Пример #7
0
void cDragdrop::drop_item(P_CLIENT ps) // Item is dropped
{
	UOXSOCKET s=ps->GetSocket();
//	CHARACTER cc=ps->GetCurrChar();

	PKGx08 pkgbuf, *pp=&pkgbuf;

	pp->Iserial=LongFromCharPtr(buffer[s]+1);
	pp->TxLoc=ShortFromCharPtr(buffer[s]+5);
	pp->TyLoc=ShortFromCharPtr(buffer[s]+7);
	pp->TzLoc=buffer[s][9];
	pp->Tserial=LongFromCharPtr(buffer[s]+10);

    //#define debug_dragg
	
	if (clientDimension[s]==3)
	{
	  // UO:3D clients send SOMETIMES two dragg packets for a single dragg action. 
	  // sometimes we HAVE to swallow it, sometimes it has to be interpreted
	  // if UO:3D specific item loss problems are reported, this is probably the code to blame :)
	  // LB
	  P_ITEM pi = FindItemBySerial(pp->Iserial);

	  #ifdef debug_dragg 
	    if (i!=-1) { sprintf(temp, "%04x %02x %02x %01x %04x i-name: %s EVILDRAG-old: %i\n",pp->Iserial, pp->TxLoc, pp->TyLoc, pp->TzLoc, pp->Tserial, items[i].name, EVILDRAGG[s]); clConsole.send(temp); }
		else { sprintf(temp, "blocked: %04x %02x %02x %01x %04x i-name: invalid item EVILDRAG-old: %i\n",pp->Iserial, pp->TxLoc, pp->TyLoc, pp->TzLoc, pp->Tserial, EVILDRAGG[s]); clConsole.send(temp); }
      #endif

	  if  ( (pp->TxLoc==-1) && (pp->TyLoc==-1) && (pp->Tserial==0)  && (EVILDRAGG[s]==1) ) 
	  { 
		  EVILDRAGG[s]=0; 
          #ifdef debug_dragg
		    clConsole.send("Swallow only\n"); 
          #endif
		  return; 
	  }	 // swallow! note: previous evildrag !
	  else if ( (pp->TxLoc==-1) && (pp->TyLoc==-1) && (pp->Tserial==0)  && (EVILDRAGG[s]==0) ) 
	  {
          #ifdef debug_dragg
		    clConsole.send("Bounce & Swallow\n"); 
          #endif

		  item_bounce6(ps, pi); 
		  return; 
	  }
	  else if ( ( (pp->TxLoc!=-1) && (pp->TyLoc!=-1) && ( pp->Tserial!=-1)) || ( (isItemSerial(pp->Iserial)) && (isItemSerial(pp->Tserial)) ) ) EVILDRAGG[s]=1; // calc new evildrag value
	  else EVILDRAGG[s]=0;
	} 

	#ifdef debug_dragg 
	  else
	  {
		 ITEM i = calcItemFromSer( pp->Iserial );
	     if (i!=-1) { sprintf(temp, "blocked: %04x %02x %02x %01x %04x i-name: %s EVILDRAG-old: %i\n",pp->Iserial, pp->TxLoc, pp->TyLoc, pp->TzLoc, pp->Tserial, items[i].name, EVILDRAGG[s]); clConsole.send(temp); }
	  }
    #endif

	if ( (buffer[s][10]>=0x40) && (buffer[s][10]!=0xff) )
		pack_item(ps,pp);
	else 
		dump_item(ps,pp);
}
Пример #8
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 );
	}
}
Пример #9
0
void drop_item(NXWCLIENT ps) // Item is dropped
{

	if (ps == NULL) return;

	NXWSOCKET  s=ps->toInt();
//	CHARACTER cc=ps->currCharIdx();

	PKGx08 pkgbuf, *pp=&pkgbuf;

	pp->Iserial=LongFromCharPtr(buffer[s]+1);
	pp->TxLoc=ShortFromCharPtr(buffer[s]+5);
	pp->TyLoc=ShortFromCharPtr(buffer[s]+7);
	pp->TzLoc=buffer[s][9];
	pp->Tserial=LongFromCharPtr(buffer[s]+10);

    //#define debug_dragg

	if (clientDimension[s]==3)
	{
	  // UO:3D clients send SOMETIMES two dragg packets for a single dragg action.
	  // sometimes we HAVE to swallow it, sometimes it has to be interpreted
	  // if UO:3D specific item loss problems are reported, this is probably the code to blame :)
	  // LB

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

	  #ifdef debug_dragg
	    if (ISVALIDPI(pi)) { sprintf(temp, "%04x %02x %02x %01x %04x i-name: %s EVILDRAG-old: %i\n",pp->Iserial, pp->TxLoc, pp->TyLoc, pp->TzLoc, pp->Tserial, pi->name, clientInfo[s]->evilDrag); ConOut(temp); }
		else { sprintf(temp, "blocked: %04x %02x %02x %01x %04x i-name: invalid item EVILDRAG-old: %i\n",pp->Iserial, pp->TxLoc, pp->TyLoc, pp->TzLoc, pp->Tserial, clientInfo[s]->evilDrag); ConOut(temp); }
	  #endif

	  if  ( (pp->TxLoc==-1) && (pp->TyLoc==-1) && (pp->Tserial==0)  && (clientInfo[s]->evilDrag) )
	  {
		  clientInfo[s]->evilDrag=false;
          #ifdef debug_dragg
		    ConOut("Swallow only\n");
          #endif
		  return;
	  }	 // swallow! note: previous evildrag !

	  else if ( (pp->TxLoc==-1) && (pp->TyLoc==-1) && (pp->Tserial==0)  && (!clientInfo[s]->evilDrag) )
	  {
          #ifdef debug_dragg
		    ConOut("Bounce & Swallow\n");
          #endif

		  item_bounce6(ps, pi);
		  return;
	  }
	  else if ( ( (pp->TxLoc!=-1) && (pp->TyLoc!=-1) && ( pp->Tserial!=-1)) || ( (pp->Iserial>=0x40000000) && (pp->Tserial>=0x40000000) ) )
		  clientInfo[s]->evilDrag=true; // calc new evildrag value
	  else clientInfo[s]->evilDrag=false;
	}

	#ifdef debug_dragg
	  else
	  {
		P_ITEM pi = pointers::findItemBySerial(pp->Iserial);

	     if (ISVALIDPI(pi)) { sprintf(temp, "blocked: %04x %02x %02x %01x %04x i-name: %s EVILDRAG-old: %i\n",pp->Iserial, pp->TxLoc, pp->TyLoc, pp->TzLoc, pp->Tserial, pi->name, clientInfo[s]->evilDrag); ConOut(temp); }
	  }
	#endif


//	if ( (buffer[s][10]>=0x40) && (buffer[s][10]!=0xff) )
	if ( isItemSerial(pp->Tserial) && (pp->Tserial != INVALID)  ) // Invalid target => invalid container => put inWorld !!!
		pack_item(ps,pp);
	else
		dump_item(ps,pp);
}
Пример #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);
	}
}