コード例 #1
0
void cTrade::trademsg(int s)
{
	P_ITEM cont1, cont2;
	cont1 = cont2 = NULL ;
	switch(buffer[s][3])
	{
	case 0://Start trade - Never happens, sent out by the server only.
		break;
	case 2://Change check marks. Possibly conclude trade
		cont1 = FindItemBySerPtr(&buffer[s][4]);
		if (cont1 != NULL)
			cont2 = FindItemBySerial(calcserial(cont1->moreb1, cont1->moreb2, cont1->moreb3, cont1->moreb4));
		else
			cont2 = NULL;
		if (cont2 != NULL) // lb crashfix
		{
			cont1->morez=buffer[s][11];
			sendtradestatus(cont1, cont2);
			if (cont1->morez && cont2->morez)
			{
				dotrade(cont1, cont2);
				endtrade(calcserial(buffer[s][4], buffer[s][5], buffer[s][6], buffer[s][7]));
			}
		}
		break;
	case 1://Cancel trade. Send each person cancel messages, move items.
		endtrade(calcserial(buffer[s][4], buffer[s][5], buffer[s][6], buffer[s][7]));
		break;
	default:
		clConsole.send("ERROR: Fallout of switch statement without default. wolfpack.cpp, trademsg()\n"); //Morrolan
	}
}
コード例 #2
0
// guildrecruit() Let the guild members recruit some player into the guild.
// Checks the guild database if "to be recruited" player already in any other guild.
// puts a tag with players serial number into the guilds recruit database.
void cGuildStone::Recruit(UOXSOCKET s)
{

	if ( currchar[s]->guildstone() == INVALID_SERIAL ) 
	{
		sysmessage(s,"you are in no guild");
		return;
	}

	if(buffer[s][11]==0xFF && buffer[s][12]==0xFF && buffer[s][13]==0xFF && buffer[s][14]==0xFF) return; // check if user canceled operation - Morrolan
	int serial = calcserial(buffer[s][7],buffer[s][8],buffer[s][9],buffer[s][10]);
	P_CHAR pc = FindCharBySerial( serial );
	if(pc != NULL)
	{
			if (pc->guildstone() != INVALID_SERIAL) 
				sysmessage(s,"This person is already in a guild.");
			else 
			{
				if (pc->isPlayer())
				{
					this->recruit.push_back(pc->serial);
				} 
				else sysmessage(s,"This is not a player.");
			}
			//break;
		//} for
	}
	this->Menu(s,1);
	return;
}
コード例 #3
0
// opens old (readonly) books == old, bugfixed readbook function
void cBooks::openbook_old(UOXSOCKET s, P_ITEM pBook)
{
	unsigned char bookopen[10]="\x93\x40\x01\x02\x03\x00\x00\x00\x02"; //LB 7'th dec 1999, making it client 1.26 complaint
	unsigned char booktitle[61]="\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
	unsigned char bookauthor[31]="\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
	unsigned long loopexit=0;
	
	openscript("misc.scp");
	sprintf((char*)temp, "BOOK %i",	calcserial(pBook->more1, pBook->more2, pBook->more3, pBook->more4));
	if (!i_scripts[misc_script]->find((char*)temp))
	{
		closescript();
		return;
	}
	LongToCharPtr(pBook->serial, &bookopen[1]);
	do
	{
		read2();
	}
	while ( (strcmp((char*)script1, "PAGES")) && (++loopexit < MAXLOOPS) );
	bookopen[8] = (char) str2num(script2); // LB, bugfixing old code

	loopexit=0;
	do
	{
		read2();
	}
	while ( (strcmp((char*)script1, "TITLE")) && (++loopexit < MAXLOOPS) );

	strcpy((char*)(booktitle), script2);

	loopexit=0;
	do
	{
		read2();
	}
	while ( (strcmp((char*)script1, "AUTHOR")) && (++loopexit < MAXLOOPS) );

	strcpy((char*)(bookauthor), script2);
	Xsend(s, bookopen, 9); // LB, bugfixing of old code
	Xsend(s, booktitle, 60);
	Xsend(s, bookauthor, 30);
	closescript();
}
コード例 #4
0
void cCommands::DyeItem(int s) // Rehue an item
{
	int body,c1,c2,b,k;
	int serial=calcserial(buffer[s][1],buffer[s][2],buffer[s][3],buffer[s][4]);
	P_ITEM pi = FindItemBySerial(serial);
	if (pi != NULL)
	{
			c1=buffer[s][7];
			c2=buffer[s][8];
			
               
			   if(!(dyeall[s]))
               {
				 if ((((c1<<8)+c2)<0x0002) ||
				    	(((c1<<8)+c2)>0x03E9))
				 {
					c1=0x03;
					c2=0xE9;
				 }
			   }
		
           	b=((((c1<<8)+c2)&0x4000)>>14)+((((c1<<8)+c2)&0x8000)>>15);	       
			if (!b)
            {
              pi->color1=c1;
			  pi->color2=c2;
			}

			if (((c1<<8)+c2)==17969)
			{
				pi->color1=c1;
				pi->color2=c2;
			}
			RefreshItem(pi);//AntiChrist
			
			soundeffect( s, 0x02, 0x3e ); // plays the dye sound, LB
			return;
	}
コード例 #5
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();
}
コード例 #6
0
void cDragItems::dropOnItem( cUOSocket *socket, P_ITEM pItem, P_ITEM pCont, const Coord_cl &dropPos )
{
	P_PLAYER pChar = socket->player();
	
	if( pItem->isMulti() )
	{
		socket->sysMessage( tr( "You cannot put houses in containers" ) );
		cUOTxBounceItem bounce;
		bounce.setReason( BR_NO_REASON );
		socket->send( &bounce );
		Items->DeleItem( pItem );
		return;
	}
	
	if( pItem->onDropOnItem( pCont ) )
	{
		if( socket->dragging() )
			socket->bounceItem( socket->dragging(), BR_NO_REASON );

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

		return;
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/*	// This needs to be checked
	// It annoyingly shows the spellbook
	// whenever you add a scroll
	// << could it be that addItemToContainer is enough?? >>
	if( pCont->type() == 9 )
		Magic->openSpellBook( pChar, pCont );*/
}
コード例 #7
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));
}
コード例 #8
0
void cTrade::buyaction(int s)
{
	char clearmsg[8];
	int clear, i, j;
	P_ITEM buyit[256];
	int amount[512];
	int layer[512];
	int playergoldtotal;
	int goldtotal;
	int itemtotal;
	int soldout;
	int tmpvalue=0; // Fixed for adv trade system -- Magius(CHE) §
//	CHARACTER cc=currchar[s];
	P_CHAR pc_currchar = currchar[s];
	P_ITEM pi_pack = Packitem(pc_currchar);
	if (pi_pack == NULL)
		return; //LB no player-pack - no buy action possible - and no crash too ;-)
	P_CHAR npc = FindCharBySerial(calcserial(buffer[s][3], buffer[s][4], buffer[s][5], buffer[s][6]));

	if (npc <= 0) return;

	clear=0;
	goldtotal=0;
	soldout=0;
	itemtotal=(((256*(buffer[s][1]))+buffer[s][2])-8)/7;
	if (itemtotal>256) return; //LB

	for(i = 0; i < itemtotal; i++)
	{
		layer[i]=buffer[s][8+(7*i)];
		buyit[i] = FindItemBySerial(calcserial(buffer[s][8+(7*i)+1], buffer[s][8+(7*i)+2], buffer[s][8+(7*i)+3], buffer[s][8+(7*i)+4]));
		amount[i]=(256*(buffer[s][8+(7*i)+5]))+buffer[s][8+(7*i)+6];

		if (buyit[i] != NULL)
		{
			buyit[i]->rank=10;
			// Fixed for adv trade system -- Magius(CHE) §
			tmpvalue = buyit[i]->value;
			tmpvalue = calcValue(buyit[i], tmpvalue);
			if (SrvParams->trade_system()==1)
				tmpvalue = calcGoodValue(pc_currchar, buyit[i], tmpvalue,0);
			goldtotal += (amount[i]*tmpvalue);
			// End Fix for adv trade system -- Magius(CHE) §
		}
	}

	bool useBank;
	useBank = (goldtotal >= SrvParams->checkBank() );

	if( useBank )
		playergoldtotal = GetBankCount( pc_currchar, 0x0EED );
	else
		playergoldtotal = pc_currchar->CountGold();

	if ((playergoldtotal>=goldtotal)||(pc_currchar->isGM()))
	{
		for (i = 0; i < itemtotal; i++)
		{
			if (buyit[i] != NULL)
			{
				if (buyit[i]->amount < amount[i])
				{
					soldout = 1;
				}
			}
		}
		if (soldout)
		{
			npctalk(s, npc, "Alas, I no longer have all those goods in stock. Let me know if there is something else thou wouldst buy.",0);
			clear = 1;
		}
		else
		{
			if (pc_currchar->isGM())
			{
				sprintf((char*)temp, "Here you are, %s. Someone as special as thee will receive my wares for free of course.", pc_currchar->name.c_str());
			}
			else
			{
				if(useBank)
				{
					sprintf((char*)temp, "Here you are, %s. %d gold coin%s will be deducted from your bank account.  I thank thee for thy business.",
					pc_currchar->name.c_str(), goldtotal, (goldtotal==1) ? "" : "s");
				    goldsfx(s, goldtotal);
				}
			    else
				{
				    sprintf((char*)temp, "Here you are, %s.  That will be %d gold coin%s.  I thank thee for thy business.",
					pc_currchar->name.c_str(), goldtotal, (goldtotal==1) ? "" : "s");
				    goldsfx(s, goldtotal);	// Dupois, SFX for gold movement. Added Oct 08, 1998
				}
			}
			npctalkall(npc, (char*)temp, 0);
			npcaction(npc, 0x20);		// bow (Duke, 17.3.2001)

			clear = 1;
			if( !(pc_currchar->isGM() ) )
			{
				if( useBank )
					DeleBankItem( pc_currchar, 0x0EED, 0, goldtotal );
				else
					delequan( pc_currchar, 0x0EED, goldtotal, NULL );
			}
			for (i=0;i<itemtotal;i++)
			{
				P_ITEM pi = buyit[i];
				if (pi != NULL)
				{
					if (pi->amount>amount[i])
					{
						if (pi->pileable)
						{
							Commands->DupeItem(s, buyit[i], amount[i]);
						}
						else
						{
							for (j=0;j<amount[i];j++)
							{
								Commands->DupeItem(s, buyit[i], 1);
							}
						}
						pi->amount-=amount[i];
						pi->restock+=amount[i];
					}
					else
					{
						switch(layer[i])
						{
						case 0x1A:
							if (pi->pileable)
							{
								Commands->DupeItem(s, buyit[i], amount[i]);
							}
							else
							{
								for (j=0;j<amount[i];j++)
								{
									Commands->DupeItem(s, buyit[i], 1);
								}
							}
							pi->amount=pi->amount-amount[i];
							pi->restock=pi->restock+amount[i];
							break;
						case 0x1B:
							if (pi->pileable)
							{
								pi->SetContSerial(pi_pack->serial);
								RefreshItem(buyit[i]);//AntiChrist
							}
							else
							{
								for (j=0;j<amount[i]-1;j++)
								{
									Commands->DupeItem(s, buyit[i], 1);
								}
								pi->SetContSerial(pi_pack->serial);
								pi->amount = 1;
								RefreshItem(buyit[i]);//AntiChrist
							}
							break;
						default:
							clConsole.send("ERROR: Fallout of switch statement without default. wolfpack.cpp, buyaction()\n"); //Morrolan
						}
					}
				}
			}
		}
	}
	else
	{
		npctalkall(npc, "Alas, thou dost not possess sufficient gold for this purchase!",0);
	}

	if (clear)
	{
		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);
	}
	Weight->NewCalc(pc_currchar);	// Ison 2-20-99
	statwindow(s, pc_currchar);
}
コード例 #9
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);
}
コード例 #10
0
ファイル: dragdrop.cpp プロジェクト: nox-wizard/noxwizard
/*!
\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
bool cBoat::Block(P_ITEM pBoat, short int xmove, short int ymove, int dir)//Check to see if the boat is blocked in front of, behind, or next to it (Depending on direction)
// PARAM WARNING: xmove and ymove is unreferenced
{
	int ser, sz, zt, loopexit=0;
	short x = 0, y = 0, c;
	bool blocked = false;
	char type, size = 0, typ = 0;
	
	map_st map;
	land_st land;
	tile_st tile;

    ser = calcserial(pBoat->moreb1, pBoat->moreb2, pBoat->moreb3, pBoat->moreb4);
	P_ITEM t	= FindItemBySerial( ser );
	P_ITEM p1	= FindItemBySerial( pBoat->morex );
	P_ITEM p2	= FindItemBySerial( pBoat->morey );
	P_ITEM h	= FindItemBySerial( pBoat->morez );

	switch(dir)
	{
	case 6: // L
	case 7: // U & L
	case 0: // U
	case 1: // U & R
		x = min( t->pos.x, min( h->pos.x, min( p1->pos.x, p2->pos.x ) ) );
		y = min( t->pos.y, min( h->pos.y, min( p1->pos.y, p2->pos.y ) ) );
		if ( dir != 6 )
			type = 1;
		else if ( dir == 0 )
			type = 2;
		else 
			type = 3;
		break;

	case 2: // R
	case 3: // D & R
	case 4: // D
	case 5: // D & L
		x = max( t->pos.x, max( h->pos.x, max( p1->pos.x, p2->pos.x ) ) );
		y = min( t->pos.y, min( h->pos.y, min( p1->pos.y, p2->pos.y ) ) );
		if ( dir != 2 )
			type = 1;
		else if ( dir == 4 )
			type = 2;
		else 
			type = 3;
		break;
	}
	//small = 10x5, med = 11x5 large = 12x5
	switch(pBoat->more1)//Now set what size boat it is and move the specail items
	{
	case 0x00:
	case 0x04:
		if ( type == 1 )
			size = 10;
		else if ( type == 2 )
			size = 5;
		else
			size = 7;
	case 0x08:
	case 0x0C:
		if ( type == 1 )
			size = 11;
		else if ( type == 2 )
			size = 5;
		else
			size = 7;
	case 0x10:
	case 0x14:
		if ( type == 1 )
			size = 12;
		else if ( type == 2 )
			size = 5;
		else
			size = 7;
		break;
	}

	if ( type == 1)
		y -= (size/2)-1;
	else
		x -= (size/2)-1;

	for ( c=0 ; c<size ; c++ )
	{
		if ( type == 1 )
			y++;
		else if ( type == 2 )
			x++;
		else // type == 3
		{
			x++;
			y++;
		}

		sz = Map->StaticTop(Coord_cl(x,y, pBoat->pos.z, pBoat->pos.map ) );

		if (sz==illegal_z) 
			typ=0; //0: map-tile 
		else 
			typ=1; //1: static-tile
		
		if (typ==0)
		{
			map=Map->SeekMap( Coord_cl( x, y, 0, pBoat->pos.map ) );
			Map->SeekLand(map.id, &land);
			//clConsole.send("map type, water bit: %i\n",land.flag1&0x80);
			if (!(land.flag1&0x80)) 
				blocked = true;
		} else { // go through all statics of a given x,y...
			MapStaticIterator msi(Coord_cl( x, y, 0, pBoat->pos.map ));
			staticrecord *stat;

			while ( (stat = msi.Next()) && (++loopexit < MAXLOOPS) )
			{
				msi.GetTile(&tile);
				zt=stat->zoff+tile.height;
					
				//for this part...: Bridges can be shown not valid,
				//so we will keep setting false until we hit a valid point,
				//when we hit a valid place, we'll stop, leave block as it was, 
				//if all points are invalid, block is true and we exit as normal.
				if (!(tile.flag1&0x80) && zt<=70) blocked = true;
				else if (strcmp((char*)tile.name, "water")) blocked = true;
				//if (zt>70) water = 1; // every static til with z>70 (mast height?) doesnt block, no matter what water-bit is has
			}
		}//if type....
		if ( blocked )
			return true;
	}//for c=soze
	return false;
}
コード例 #12
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);
				}		   
				
			}	
}
コード例 #13
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));
}
コード例 #14
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 );
	}
}
コード例 #15
0
void cDragItems::dropOnItem( P_CLIENT client, P_ITEM pItem, P_ITEM pCont, const Coord_cl &dropPos )
{
	P_CHAR pChar = client->player();
	
	if( pItem->isMulti() )
	{
		client->sysMessage( "You cannot put houses in containers" );
		bounceItem( client, pItem );
		return;
	}
	
	// If the target belongs to another character 
	// It needs to be our vendor or else it's denied
	P_CHAR packOwner = GetPackOwner( pCont );

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Glowing Objects moved between chars
	if( pItem->glow != INVALID_SERIAL )
	{
		pChar->removeHalo( pItem );
				
		if( packOwner != NULL )
		{
			packOwner->addHalo(pItem);
			packOwner->glowHalo(pItem);
		}
	}
}
コード例 #16
0
void cDragItems::dropOnChar( P_CLIENT client, P_ITEM pItem, P_CHAR pOtherChar )
{
	// Three possibilities:
	// If we're dropping it on ourself: packintobackpack
	// If we're dropping it on some other player: trade-window
	// If we're dropping it on some NPC: checkBehaviours
	// If not handeled: Equip the item if the NPC is owned by us
	
	P_CHAR pChar = client->player();

	// Dropped on ourself
	if( pChar == pOtherChar )
	{
		pItem->setLayer( 0 );
		pItem->setContSerial( INVALID_SERIAL );
		pItem->toBackpack( pChar );
		return;
	}

	// Are we in range of our target
	if( !inrange1p( pChar, pOtherChar ) )
	{
		client->sysMessage( "You are too far away from that character." );
		bounceItem( client, pItem );
		return;
	}

	// Can wee see our target
	if( !line_of_sight( client->socket(), pChar->pos, pOtherChar->pos, TREES_BUSHES|WALLS_CHIMNEYS|DOORS|ROOFING_SLANTED|FLOORS_FLAT_ROOFING|LAVA_WATER ) )
	{
		client->sysMessage( "You can't see this character" );
		bounceItem( client, pItem );
		return;
	}

	// Open a secure trading window
	if( !pOtherChar->isNpc() && online( pOtherChar ) )
	{
		// Check if we're already trading, 
		// if not create a new window
		vector< SERIAL > equipment = contsp.getData( pChar->serial );
		P_ITEM tradeWindow = NULL;

		for( UI16 i = 0; i < equipment.size(); i++ )
		{
			P_ITEM pEquip = FindItemBySerial( equipment[ i ] );
			
			// Is it a trade-window ?
			if( ( pEquip->layer() == 0 ) && ( pEquip->id() == 0x1E5E ) )
			{
				P_ITEM tradeWindow = FindItemBySerial( calcserial( pEquip->moreb1(), pEquip->moreb2(), pEquip->moreb3(), pEquip->moreb4() ) );
				if( tradeWindow && ( tradeWindow->contserial == pOtherChar->serial ) )
				{
					tradeWindow = pEquip;
					break;
				}
			}
		}

		if( !tradeWindow )
			tradeWindow = Trade->tradestart( client->socket(), pOtherChar );

		pItem->setContSerial( tradeWindow->serial);
		pItem->pos.x = rand() % 60;
		pItem->pos.y = rand() % 60;
		pItem->pos.z = 9;
		pItem->setLayer( 0 );
		SndRemoveitem( pItem->serial );
		RefreshItem( pItem );
		return;
	}

	// For our hirelings we have a special function
	if( pChar->Owns( pOtherChar ) )
	{
		dropOnPet( client, pItem, pOtherChar );
		return;
	}

	// Dropping based on AI Type
	switch( pOtherChar->npcaitype() )
	{
	case 4:
		dropOnGuard( client, pItem, pOtherChar );
		break;
	case 5:
		dropOnBeggar( client, pItem, pOtherChar );
		break;
	case 8:
		dropOnBanker( client, pItem, pOtherChar );
		break;
	case 19:
		dropOnBroker( client, pItem, pOtherChar );
		break;
	};

	// Try to train - works for any NPC
	if( pOtherChar->cantrain() )
		if( pChar->trainer() == pOtherChar->serial )
			dropOnTrainer( client, pItem, pOtherChar );
		else
			pOtherChar->talk( "You need to tell me what you want to learn first" );

	bounceItem( client, pItem );
	return;
}
コード例 #17
0
// old readbook function
void cBooks::readbook_readonly_old(UOXSOCKET s, P_ITEM pBook, int p)
{
	int x, y, pos, j;
	unsigned char bookpage[14]="\x66\x01\x02\x40\x01\x02\x03\x00\x01\x00\x01\x00\x01";
	unsigned long loopexit=0,loopexit2=0;
	
	openscript("misc.scp");
	sprintf((char*)temp, "BOOK %i", calcserial(pBook->more1, pBook->more2, pBook->more3, pBook->more4));
	if (!i_scripts[misc_script]->find((char*)temp))
	{
		closescript();
		return;
	}
	x=p;

	do
	{
		loopexit=0;
		do
		{
			read2();
		}
		while ( (strcmp((char*)script1, "PAGE")) && (++loopexit < MAXLOOPS) );
		x--;
	}
	while ( (x>0) && (++loopexit2 < 6666 ));

	closescript();
	openscript("misc.scp");
	sprintf((char*)temp, "PAGE %s", script2);
	if (!i_scripts[misc_script]->find((char*)temp))
	{
		closescript();
		return;
	}
	pos=ftell(scpfile);
	x=-1;
	y=-2;
	loopexit=0;
	do
	{
		read1();
		x++;
		y+=strlen((char*)script1)+1;
	}
	while ( (strcmp((char*)script1, "}")) && (++loopexit < MAXLOOPS) );
	y+=13;
	fseek(scpfile, pos, SEEK_SET);
	bookpage[1]=y>>8;
	bookpage[2]=y%256;
	LongToCharPtr(pBook->serial, &bookpage[3]);
	bookpage[9]=p>>8;
	bookpage[10]=p%256;
	bookpage[11]=x>>8;
	bookpage[12]=x%256;
	Xsend(s, bookpage, 13);
	for (j=0;j<x;j++)
	{
		read1();
		Xsend(s, script1, strlen((char*)script1)+1);
	}
	closescript();
}
コード例 #18
0
void cBoat::Turn(P_ITEM pBoat, int turn)//Turn the boat item, and send all the people/items on the boat to turnboatstuff()
{
	if (pBoat == NULL) return; 
	
	int id2 = pBoat->id2 ,olddir = pBoat->dir;
	unsigned short int Send[MAXCLIENT];
	SERIAL serial;
	int a,dir, d=0;
	
	
	for (a = 0; a < now; ++a)
	{
		if (iteminrange(a, pBoat, BUILDRANGE) && perm[a])
		{
			Send[d]=a;
			Xsend(a,wppause,2);
			d++; 
		} 
		
	}
	
	//Of course we need the boat items!
	serial = calcserial(pBoat->moreb1,pBoat->moreb2,pBoat->moreb3,pBoat->moreb4);
	if(serial == INVALID_SERIAL) return;
	P_ITEM pTiller = FindItemBySerial( serial );
	if(pTiller == NULL) return;
	P_ITEM pi_p1 = FindItemBySerial( pBoat->morex );
	if(pi_p1 == NULL) return;
	P_ITEM pi_p2 = FindItemBySerial( pBoat->morey );
	if(pi_p2 == NULL) return;
	P_ITEM pi_hold = FindItemBySerial( pBoat->morez );
	if(pi_hold == NULL) return;
	
	if(turn)//Right
	{
		pBoat->dir+=2;
		id2++;
	} else {//Left
		pBoat->dir-=2;
		id2--;
	}
	if(pBoat->dir>7) pBoat->dir-=4;//Make sure we dont have any DIR errors
	//if(pBoat->dir<0) pBoat->dir+=4;
	if(id2<pBoat->more1) id2+=4;//make sure we don't have any id errors either
	if(id2>pBoat->more2) id2-=4;//Now you know what the min/max id is for :-)
	
	pBoat->id2=id2;//set the id
	
	if(pBoat->id2==pBoat->more1) pBoat->dir=0;//extra DIR error checking
	if(pBoat->id2==pBoat->more2) pBoat->dir=6;
	
	
	if( Block( pBoat, 0, 0, pBoat->dir ) )
	{
		pBoat->dir = olddir;
		for( a = 0; a < d; a++ )
		{
			Xsend( Send[a], restart, 2 );
			itemtalk( Send[a], pTiller, "Arr, something's in the way!" );
		}
		return;
	}
	pBoat->id2=id2;//set the id
	
	if(pBoat->id2==pBoat->more1) pBoat->dir=0;//extra DIR error checking
	if(pBoat->id2==pBoat->more2) pBoat->dir=6;    
	
	
	
	
    serial=pBoat->serial; // lb !!!

	unsigned int ci;	
	vector<SERIAL> vecEntries = imultisp.getData(serial);
    for (ci = 0; ci < vecEntries.size(); ci++)
	{
		P_ITEM pi = FindItemBySerial(vecEntries[ci]);
		if (pi != NULL)
			TurnStuff(pBoat, pi, turn);
	}
	
	vecEntries.clear();
	vecEntries = cmultisp.getData(serial);
	for (ci = 0; ci < vecEntries.size(); ci++)
	{
		P_CHAR pc = FindCharBySerial(vecEntries[ci]);
		if (pc != NULL)
			TurnStuff(pBoat, pc, turn);
	}
	
	//Set the DIR for use in the Offsets/IDs array
	dir = (pBoat->dir&0x0F)/2;
	
	//set it's Z to 0,0 inside the boat
	
	pi_p1->MoveTo(pBoat->pos.x,pBoat->pos.y,pi_p1->pos.z);
	pi_p1->id2 = cShipItems[dir][PORT_P_C];//change the ID
	
	pi_p2->MoveTo(pBoat->pos.x,pBoat->pos.y,pi_p2->pos.z);
	pi_p2->id2=cShipItems[dir][STAR_P_C];
	
	pTiller->MoveTo(pBoat->pos.x,pBoat->pos.y, pTiller->pos.z);
	pTiller->id2=cShipItems[dir][TILLERID];
	
	pi_hold->MoveTo(pBoat->pos.x,pBoat->pos.y, pi_hold->pos.z);
	pi_hold->id2=cShipItems[dir][HOLDID];
	
	switch(pBoat->more1)//Now set what size boat it is and move the specail items
	{
	case 0x00:
	case 0x04:
		pi_p1->moveTo(pi_p1->pos + Coord_cl(iSmallShipOffsets[dir][PORT_PLANK][X], iSmallShipOffsets[dir][PORT_PLANK][Y], 0));
		pi_p2->moveTo(pi_p2->pos + Coord_cl(iSmallShipOffsets[dir][STARB_PLANK][X], iSmallShipOffsets[dir][STARB_PLANK][Y], 0));
		pTiller->moveTo(pTiller->pos + Coord_cl(iSmallShipOffsets[dir][TILLER][X], iSmallShipOffsets[dir][TILLER][Y], 0));
		pi_hold->moveTo(pi_hold->pos + Coord_cl(iSmallShipOffsets[dir][HOLD][X], iSmallShipOffsets[dir][HOLD][Y], 0));
		break;
	case 0x08:
	case 0x0C:
		pi_p1->moveTo(pi_p1->pos + Coord_cl(iMediumShipOffsets[dir][PORT_PLANK][X], iMediumShipOffsets[dir][PORT_PLANK][Y], 0) );
		pi_p2->moveTo(pi_p2->pos + Coord_cl(iMediumShipOffsets[dir][STARB_PLANK][X], iMediumShipOffsets[dir][STARB_PLANK][Y], 0) );
		pTiller->moveTo(pTiller->pos + Coord_cl(iMediumShipOffsets[dir][TILLER][X], iMediumShipOffsets[dir][TILLER][Y], 0) );
		pi_hold->moveTo(pi_hold->pos + Coord_cl(iMediumShipOffsets[dir][HOLD][X], iMediumShipOffsets[dir][HOLD][Y], 0) );
		
		break;
	case 0x10:
	case 0x14:
		pi_p1->moveTo(pi_p1->pos + Coord_cl(iLargeShipOffsets[dir][PORT_PLANK][X], iLargeShipOffsets[dir][PORT_PLANK][Y], 0) );
        pi_p2->moveTo(pi_p2->pos + Coord_cl(iLargeShipOffsets[dir][STARB_PLANK][X], iLargeShipOffsets[dir][STARB_PLANK][Y], 0 ) );
		pTiller->moveTo(pTiller->pos + Coord_cl(iLargeShipOffsets[dir][TILLER][X], iLargeShipOffsets[dir][TILLER][Y], 0 ) );
		pi_hold->moveTo(pi_hold->pos + Coord_cl(iLargeShipOffsets[dir][HOLD][X], iLargeShipOffsets[dir][HOLD][Y], 0 ) );
		
		break;
		
	default: 
		{ 
			sprintf((char*)temp,"Turnboatstuff() more1 error! more1 = %c not found!\n",pBoat->more1); 
			LogWarning((char*)temp);
		}  
	}
	
	sendinrange(pi_p1);
	sendinrange(pi_p2);
	sendinrange(pi_hold);
	sendinrange(pTiller);
	
	for (a = 0; a < d; ++a) 
	{ 
		Xsend(Send[a],restart,2);
	}
}
コード例 #19
0
void cDragdrop::wear_item(P_CLIENT ps) // Item is dropped on paperdoll
{
	int j, k;
	tile_st tile;
	int serial, serhash, ci, letsbounce=0; // AntiChrist (5) - new ITEMHAND system
	UOXSOCKET s=ps->GetSocket();
	int cc=ps->GetCurrChar();
	P_CHAR pc_currchar = MAKE_CHARREF_LR(cc);

	int cserial=calcserial(buffer[s][6],buffer[s][7],buffer[s][8],buffer[s][9]);
	if(cserial==-1) return;
	k=calcCharFromSer( cserial );
	
	if( chars[k].dead )  //Exploit fix: Dead ppl can't equip anything.
		return;
	
	P_ITEM pi=FindItemBySerPtr(buffer[s]+1);
	if (!pi) return;
	pi->flags.isBeeingDragged=false;

//	if (clientDimension[s]==3)
//	{
	Map->SeekTile(pi->id(), &tile);
		
	// sprintf(temp, "Tiledata: name: %s flag1: %i flag2: %i flag3: %i flag4: %i layer: %i\n", tile.name, tile.flag1, tile.flag2, tile.flag3, tile.flag4, tile.layer);
	// clConsole.send(temp);
		
	if (tile.layer==0)
	{
		sysmessage(s,"You can't wear that");
		Sndbounce5(s);
		if (ps->IsDragging())
		{
			ps->ResetDragging();
			item_bounce4(s,pi);
			UpdateStatusWindow(s,pi);
		}
		return;
	}
//	}

	if (pi->id1>=0x40) return; // LB, client crashfix if multi-objects are moved to PD

	if (k==DEREF_P_CHAR(pc_currchar) || pc_currchar->isGM()) 
	{
		if (k!=-1) //lb
			if (k==DEREF_P_CHAR(pc_currchar) && pi->st>chars[k].st)
			{
				sysmessage(s,"You are not strong enough to use that.");
				Sndbounce5(s);
				if (ps->IsDragging())
				{
					ps->ResetDragging();
					item_bounce4(s,pi);
					UpdateStatusWindow(s,pi);
				}
				return;
			}
			
			if (pc_currchar->id1==0x01 && pc_currchar->id2==0x90) // Ripper...so males cant wear female armor
			if (pi->id1==0x1c && ( pi->id2==0x00 || pi->id2==0x02 || pi->id2==0x04 ||
                pi->id2==0x06 || pi->id2==0x08 || pi->id2==0x0a || pi->id2==0x0c))
			{
				sysmessage(s,"You cant wear female armor!");
				Sndbounce5(s);
				if (ps->IsDragging())
                {
					ps->ResetDragging();
					item_bounce4(s,pi);				  
					UpdateStatusWindow(s,pi);
				}
				return;
			}

//			if (clientDimension[s]==2) Map->SeekTile(pi->id(), &tile);
			if ((((pi->magic==2)||((tile.weight==255)&&(pi->magic!=1)))&&((pc_currchar->priv2&1)==0)) ||
				( (pi->magic==3|| pi->magic==4) && !pc_currchar->Owns(pi)))
			{
				item_bounce6(ps,pi);
				return;
			}
		

		// - AntiChrist (4) - checks for new ITEMHAND system
		// - now you can't equip 2 hnd weapons with 1hnd weapons nor shields!!
		serial=pc_currchar->serial;
		vector<SERIAL> vecContainer = contsp.getData(serial);
		for (ci=0;ci<vecContainer.size();ci++)
		{
			P_ITEM pi2 = FindItemBySerial(vecContainer[ci]);
			if (pi2 != NULL && pi2->contserial == serial)
			{
				if (pi2->itmhand==1 && pi->itmhand==1)
				{
					sysmessage(s,"You already have a weapon equipped!");
					letsbounce=1;
				}
				else if (pi2->itmhand==2 && pi->itmhand==1)
				{
					sysmessage(s,"Your hands are both occupied!");
					letsbounce=1;
				}
				else if (pi2->itmhand==1 && pi->itmhand==2)
				{
					sysmessage(s,"You cannot equip a two handed weapon with a weapon equipped!");
					letsbounce=1;
				}
				else if (pi2->itmhand==2 && pi->itmhand==2)
				{
					sysmessage(s,"You cannot equip a two handed weapon with a two handed weapon equipped!");
					letsbounce=1;
				}
				else if (pi2->itmhand==2 && pi->itmhand==3)
				{
					sysmessage(s,"You cannot equip a shield with a two handed weapon equipped!");
					letsbounce=1;
				}
				else if (pi2->itmhand==3 && pi->itmhand==2)
				{
					sysmessage(s,"You cannot equip a two handed weapon with a shield equipped!");
					letsbounce=1;
				}
				else if (pi2->layer == tile.layer) 
				{
 					sysmessage(s, "You already have an armor equipped!");
					letsbounce = 1;
				}
			}
			if(letsbounce)//Let's bounce the item
			{
				Sndbounce5(s);
				if (ps->IsDragging())
				{
					ps->ResetDragging();
					item_bounce4(s,pi);
					UpdateStatusWindow(s,pi);
					itemsfx(s, pi->id());		// antichrist
				}
				return;
			} 
		}
		if (!(pc_currchar->isGM())) //Ripper..players cant equip items on other players or npc`s paperdolls.
		{
			if ((k != DEREF_P_CHAR(pc_currchar)) && (!chars[k].isNpc()))
			{
				sysmessage(s, "You cant put items on other players!");
				item_bounce6(ps,pi);
				return;
			}
		}
		pi->SetContSerial(LongFromCharPtr(buffer[s]+6));
		pi->layer=buffer[s][5];
		// AntiChrist - now the STAT BONUS works -
		pc_currchar->st = (pc_currchar->st + pi->st2);
		pc_currchar->chgDex(pi->dx2);
		pc_currchar->in = (pc_currchar->in + pi->in2);
		if (pi->trigtype==2) // -Frazurbluu- Trigger Type 2 is my new trigger type *-
		{
			Trig->triggerwitem(s, pi, 1); // trigger is fired
		}	
		// AntiChrist -- for poisoned items
		if (showlayer)	clConsole.send("Item equipped on layer %i.\n",pi->layer);
		
		SndRemoveitem(pi->serial);
		
		LongToCharPtr(pi->serial,wearitem+1);
		ShortToCharPtr(pi->id(),wearitem+5);
		wearitem[8]=pi->layer;
		LongToCharPtr(pi->contserial,wearitem+9);
		wearitem[13]=pi->color1;
		wearitem[14]=pi->color2;
		Xsend(s, wearitem, 15);
		wornitems(s, k);//send update to current socket
		// -Frazurbluu- Worn item triggers will need code here
		// Trigger cod ewill also need the adjustments made for skill adding
		// An apply/unapply type of variable must be added for skill gains
		// Spell Item will have to be considered, like a necklace of reflection

		for (j=0;j<now;j++)
		{
			if (perm[j] && inrange1p(k, currchar[j]) && (j!=s))//and to all inrange sockets (without re-sending to current socket)//AntiChrist
				wornitems(j, k);
		}
		
		itemsfx(s, pi->id());	// Dupois - see itemsfx() for details	// Added Oct 09, 1998
		Weight->NewCalc(DEREF_P_CHAR(pc_currchar));	// Ison 2-20-99
		statwindow(s,DEREF_P_CHAR(pc_currchar));
		
		if (pi->glow>0)
		{
			pc_currchar->removeHalo(pi); // if gm equips on differnt player it needs to be deleted out of the hashteble
			chars[k].addHalo(pi);
			chars[k].glowHalo(pi);
		}
    }
}
コード例 #20
0
              pi->color1=c1;
			  pi->color2=c2;
			}

			if (((c1<<8)+c2)==17969)
			{
				pi->color1=c1;
				pi->color2=c2;
			}
			RefreshItem(pi);//AntiChrist
			
			soundeffect( s, 0x02, 0x3e ); // plays the dye sound, LB
			return;
	}

	serial=calcserial(buffer[s][7],buffer[s][8],buffer[s][9],buffer[s][10]);
	P_CHAR pc = FindCharBySerial(serial);
	if (pc != NULL)
	{
		P_CHAR pc_currchar = MAKE_CHARREF_LR(currchar[s]);
		if( !(pc_currchar->isGM() ) ) return; // Only gms dye characters
		k=(buffer[s][7]<<8)+buffer[s][8];


		 body=(pc->id1<<8)+pc->id2;
         b=k&0x4000; 

		 if( ( ( k>>8 ) < 0x80 ) && body >= 0x0190 && body <= 0x0193 ) k+= 0x8000;

		 if (b==16384 && (body >=0x0190 && body<=0x03e1)) k=0xf000; // but assigning the only "transparent" value that works, namly semi-trasnparency.
コード例 #21
0
void cBoat::Move(UOXSOCKET s, int dir, P_ITEM pBoat)
{//Move the boat and all it's items 1 square
	int tx=0,ty=0;
	int serial;
     
	if (pBoat == NULL)
		return;

	serial = calcserial(pBoat->moreb1, pBoat->moreb2, pBoat->moreb3, pBoat->moreb4);
	if (serial == INVALID_SERIAL) return;
	P_ITEM pTiller = FindItemBySerial( serial );
	if(pTiller == NULL)
		return;
	
	P_ITEM pi_p1 = FindItemBySerial( pBoat->morex );
	if(pi_p1 == NULL) 
		return;

	P_ITEM pi_p2 = FindItemBySerial( pBoat->morey );
	if(pi_p2 == NULL) 
		return;

	P_ITEM pHold = FindItemBySerial( pBoat->morez );
	if(pHold == NULL) 
		return;

	Xsend(s,wppause,2);

	switch(dir&0x0F)//Which DIR is it going in?
	{
	case '\x00' : 
		ty--;
		break;
	case '\x01' : 
		tx++; 
		ty--;
		break;
	case '\x02' :
		tx++;
		break;
	case '\x03' :
		tx++;
		ty++;
		break;
	case '\x04' : 
		ty++;
		break;
	case '\x05' :
		tx--;
		ty++;
		break;
	case '\x06' : 
		tx--;
		break;
	case '\x07' : 
		tx--; 
		ty--;
		break;
	default:
		{
		  sprintf((char*)temp,"warning: Boat direction error: %i int boat %i\n",pBoat->dir&0x0F,pBoat->serial);
		  LogWarning((char*)temp);
		  break;
		}
	}

	if((pBoat->pos.x+tx<=200 || pBoat->pos.x+tx>=6000) && (pBoat->pos.y+ty<=200 || pBoat->pos.y+ty>=4900)) //bugfix LB
	{
		pBoat->type2=0;
		itemtalk(s, pTiller, "Arr, Sir, we've hit rough waters!");
		Xsend(s,restart,2);
		return;
	}
	if(Block(pBoat,tx,ty,dir))
	{
		pBoat->type2=0;
		itemtalk(s, pTiller, "Arr, somethings in the way!");
		Xsend(s,restart,2);
		return;
	}

	//Move all the special items
	Coord_cl desloc(tx, ty, 0);
	pBoat->moveTo(pBoat->pos + desloc);
	pTiller->moveTo(pTiller->pos + desloc);
	pi_p1->moveTo(pi_p1->pos + desloc);
	pi_p2->moveTo(pi_p2->pos + desloc);
	pHold->moveTo(pHold->pos + desloc);

    serial = pBoat->serial;
	
	unsigned int a;
	vector<SERIAL> vecEntries = imultisp.getData(pBoat->serial);
	for (a = 0; a < vecEntries.size(); a++)
	{
		P_ITEM pi = FindItemBySerial(vecEntries[a]);
		if(pi != NULL)
		{
			pi->MoveTo(pi->pos.x+=tx, pi->pos.y+=ty, pi->pos.z);
			sendinrange(pi);
		}
	}

	vecEntries.clear();
	vecEntries = cmultisp.getData(pBoat->serial);
	for (a = 0; a < vecEntries.size(); a++)
	{
		P_CHAR pc_c = FindCharBySerial(vecEntries[a]);
		if (pc_c != NULL)
		{
			pc_c->moveTo(pc_c->pos + desloc);
			teleport((pc_c));
		}
	}
	Xsend(s,restart,2);
}
コード例 #22
0
void RcvAttack(P_CLIENT ps)
{
	UOXSOCKET s = ps->GetSocket();
	P_CHAR pc_currchar = ps->getPlayer();
	int j;

	SERIAL serial=calcserial(buffer[s][1],buffer[s][2],buffer[s][3],buffer[s][4]);
	if(serial == INVALID_SERIAL) return;
	P_CHAR pc_i = FindCharBySerPtr(&buffer[s][1]);
	if(pc_i == NULL) return;	//to avoid problems
	
	if(pc_currchar->dead)//AntiChrist stuff
	{
		if(SrvParams->persecute())
		{//start persecute stuff - AntiChrist
			pc_currchar->targ = pc_i->serial;
			if(pc_currchar->targ==INVALID_SERIAL) return;
			else Skills->Persecute(s);
			return;
		} else
		{
			sysmessage(s,"You are dead and cannot do that.");
			return;
		}
	}
	if(pc_currchar->cell>0)
	{
		sysmessage(s,"There is no fighting in the jail cells!");
		return;
	}

	if(!pc_currchar->dead)
	{
		pc_currchar->targ = serial;
		pc_currchar->unhide();
		pc_currchar->disturbMed(s);

		
		if(pc_i->dead || pc_i->hp<=0)//AntiChrist
		{
			sysmessage(s,"That person is already dead!");
			return;
		}
		
		if (pc_i->npcaitype==17)//PlayerVendors
		{
			sprintf((char*)temp, "%s cannot be harmed.",pc_i->name.c_str());
			sysmessage(s, (char*)temp);
			return;
		}
		
		SndAttackOK(s, pc_i->serial);	//keep the target highlighted       
		if (!(pc_i->targ == INVALID_SERIAL))
		{
			pc_i->attacker = pc_currchar->serial;
			pc_i->resetAttackFirst();
		}
		pc_currchar->setAttackFirst();
		pc_currchar->attacker = pc_i->serial;
 
		pc_currchar->dir = chardir(pc_currchar, pc_i);	// turn to attacker, LB (& Duke)

		updatechar(pc_currchar);

		if( pc_i->guarded )
		{
			AllCharsIterator iter_char;
			for (iter_char.Begin(); !iter_char.atEnd(); iter_char++)
			{
				P_CHAR toCheck = iter_char.GetData();
				if (pc_i->Owns(toCheck) && toCheck->npcaitype == 32 && chardist( pc_currchar, toCheck )<= 10 )
				{
					npcattacktarget( pc_currchar, toCheck );
				}
			}
		}

		if (pc_i->inGuardedArea() && SrvParams->guardsActive())
		{
			if (pc_i->isPlayer() && pc_i->isInnocent() && GuildCompare( pc_currchar, pc_i )==0) //REPSYS
			{
				criminal( pc_currchar );
				Combat->SpawnGuard(pc_currchar, pc_i ,pc_currchar->pos.x,pc_currchar->pos.y,pc_currchar->pos.z);
			}
			else if( pc_i->isNpc() && pc_i->isInnocent() && !pc_i->isHuman() && pc_i->npcaitype!=4 )
			{
				criminal( pc_currchar );
				Combat->SpawnGuard(pc_currchar, pc_i, pc_currchar->pos.x,pc_currchar->pos.y,pc_currchar->pos.z);
			}
			else if( pc_i->isNpc() && pc_i->isInnocent() && pc_i->isHuman() && pc_i->npcaitype!=4 )
			{
				npctalkall(pc_i, "Help! Guards! I've been attacked!", 1);
				criminal( pc_currchar );
				callguards(pc_i);
			}
			else if( pc_i->isNpc() && pc_i->npcaitype==4)
			{
				criminal( pc_currchar );
				npcattacktarget(pc_i, pc_currchar);
			}
			else if ((pc_i->isNpc() || pc_i->tamed) && !pc_i->war && pc_i->npcaitype!=4) // changed from 0x40 to 4, cauz 0x40 was removed LB
			{
				npcToggleCombat(pc_i);
				pc_i->setNextMoveTime();
			}
			else
			{
				pc_i->setNextMoveTime();
			}
			
			sprintf((char*)temp, "You see %s attacking %s!", pc_currchar->name.c_str(), pc_i->name.c_str());
			
			for (j=0;j<now;j++)
			{
				if((inrange1(s, j) && perm[j]) && (s!=j))
				{
					pc_i->emotecolor = 0x0026;
					npcemote(j, pc_currchar, (char*)temp,1);
				}
			}
		}
		else	// not a guarded area
		{
			if (pc_i->isInnocent())
			{
				if (pc_i->isPlayer() && GuildCompare( pc_currchar, pc_i )==0)
				{
					criminal( pc_currchar );
				}
				else if (pc_i->isNpc() && pc_i->tamed)
				{
					criminal( pc_currchar );
					npcattacktarget(pc_i, pc_currchar);
				}
				else if (pc_i->isNpc())
				{
					criminal( pc_currchar );
					npcattacktarget(pc_i, pc_currchar);
					if (pc_i->isHuman() )
					{
						npctalkall(pc_i, "Help! Guards! Tis a murder being commited!", 1);
					}
				}
			}
		}
	}
}
コード例 #23
0
char cBoat::Speech(UOXSOCKET s, const QString& msg)//See if they said a command. msg must already be capitalized
{
	P_CHAR pc_currchar = currchar[s];
	P_ITEM boat = GetBoat(pc_currchar);
	if(boat == NULL) 
		return 0;
	int dir = boat->dir&0x0F;
	int serial;
	char msg2[512];

	if (s == INVALID_UOXSOCKET) 
		return 0;

	//get the tiller man's item #
	serial=calcserial(boat->moreb1, boat->moreb2, boat->moreb3, boat->moreb4);
	if ( serial == INVALID_SERIAL ) 
		return 0;
	P_ITEM tiller = FindItemBySerial(serial);
	if ( tiller == NULL ) 
		return 0;

	if((msg.find("FORWARD")!= string::npos) || (msg.find("UNFURL SAIL")!=string::npos))
	{
		boat->type2=1;//Moving
		Move(s,dir, boat);
		itemtalk(s, tiller, "Aye, sir.");
		return 1;
	} else if(msg.find("BACKWARD")!= string::npos)
	{
		boat->type2=2;//Moving backward
		if(dir >= 4) dir-=4; 
		else dir+=4;
		Move(s,dir, boat);		
		itemtalk(s, tiller, "Aye, sir.");
		return 1;
	}  else if((msg.find("ONE")!= string::npos) || (msg.find("DRIFT")!=string::npos))
	{
		if(msg.find("LEFT")!=string::npos)
		{
			dir-=2;
			if(dir<0) dir+=8;			
			Move(s, dir, boat);
			itemtalk(s, tiller, "Aye, sir.");
			return 1;

		} else if(msg.find("RIGHT")!=string::npos)
		{
			dir+=2;
			if(dir>=8) dir-=8; 			
			Move(s,dir,boat);
		
			itemtalk(s, tiller, "Aye, sir.");
			return 1;
		}
	} 
	else if((msg.find("STOP")!=string::npos) || (msg.find("FURL SAIL")!=string::npos))
	{ 
		boat->type2=0; itemtalk(s, tiller, "Aye, sir."); 
	}//Moving is type2 1 and 2, so stop is 0 :-)
	
	else if(((msg.find("TURN")!=string::npos) && ((msg.find("AROUND")!=string::npos) || (msg.find("LEFT")!=string::npos) || (msg.find("RIGHT")!=string::npos)))
		|| (msg.find("PORT")!=string::npos) || (msg.find("STARBOARD")!=string::npos) || (msg.find("COME ABOUT")!=string::npos))
	{
		if((msg.find("RIGHT")!=string::npos) || (msg.find("STARBOARD")!=string::npos)) 
		{
			dir-=2; if(dir<0) dir+=8;
			int tx=0,ty=0;

	        switch(dir&0x0F) // little reminder for myself: move this swtich to a function to have less code ... LB
			{
	           case '\x00' : 
		       ty--;
		       break;
	           case '\x01' : 
		       tx++; 
		       ty--;
		       break;
	           case '\x02' :
		       tx++;
		       break;
	           case '\x03' :
		       tx++;
		       ty++;
		       break;
	           case '\x04' : 
		       ty++;
		       break;
	           case '\x05' :
		       tx--;
		       ty++;
		       break;
	           case '\x06' : 
		       tx--;
		       break;
	           case '\x07' : 
		       tx--; 
		       ty--;
		       break;
			}


			if (!Block(boat,tx,ty,dir))
			{
			  Turn(boat,1);
			  itemtalk(s, tiller, "Aye, sir.");
			  return 1;
			} else { 
				boat->type2 = 0;
			    itemtalk(s, tiller, "Arr,somethings in the way"); 
				return 1;
			}
		}
		else if((msg.find("LEFT")!=string::npos) || (msg.find("PORT")!=string::npos)) 
		{
			dir+=2; if(dir>7) dir-=8;
			int tx=0,ty=0;

	        switch(dir&0x0F)
			{
	           case '\x00' : 
		       ty--;
		       break;
	           case '\x01' : 
		       tx++; 
		       ty--;
		       break;
	           case '\x02' :
		       tx++;
		       break;
	           case '\x03' :
		       tx++;
		       ty++;
		       break;
	           case '\x04' : 
		       ty++;
		       break;
	           case '\x05' :
		       tx--;
		       ty++;
		       break;
	           case '\x06' : 
		       tx--;
		       break;
	           case '\x07' : 
		       tx--; 
		       ty--;
		       break;
			}


			if (!Block(boat,tx,ty,dir))
			{
			  Turn(boat,0);			
			  itemtalk(s, tiller, "Aye, sir.");
			  return 1;
			} else 
			{ 
				boat->type2 = 0;
				itemtalk(s, tiller, "Arr,somethings in the way"); 
				return 1;
			}
		}
		else if((msg.find("COME ABOUT")!=string::npos) || (msg.find("AROUND")!=string::npos))
		{
			Turn(boat, 1);
			Turn(boat, 1);
			itemtalk(s, tiller, "Aye, sir.");
			return 1;
		}
	}
	else if(msg.find("SET NAME")!=string::npos)
	{
		tiller->name = "a ship named ";
		tiller->name += msg2+8;
		return 1;
	}

	return 0;
}
コード例 #24
0
ファイル: dragdrop.cpp プロジェクト: nox-wizard/noxwizard
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();
			}


}