예제 #1
0
Q_UINT16 DynTile( const Coord& pos )
{
	MapItemsIterator ri = MapObjects::instance()->listItemsInCircle( pos, 18 );
	for ( P_ITEM mapitem = ri.first(); mapitem; mapitem = ri.next() )
	{
		if ( mapitem->isMulti() )
		{
			MultiDefinition* def = MultiCache::instance()->getMulti( mapitem->id() - 0x4000 );
			if ( !def )
				return 0;

			QValueVector<multiItem_st> multi = def->getEntries();
			for ( Q_UINT32 j = 0; j < multi.size(); ++j )
			{
				if ( ( multi[j].visible && ( mapitem->pos().x + multi[j].x == pos.x ) && ( mapitem->pos().y + multi[j].y == pos.y ) && ( abs( mapitem->pos().z + multi[j].z - pos.z ) <= 1 ) ) )
				{
					return multi[j].tile;
				}
			}
		}
		else if ( mapitem->pos() == pos )
		{
			return mapitem->id();
		}
	}
	return ( Q_UINT16 ) - 1;
}
예제 #2
0
Q_UINT16 DynTile( const Coord_cl& pos )
{
	RegionIterator4Items ri( pos );
	for ( ri.Begin(); !ri.atEnd(); ri++ )
	{
		P_ITEM mapitem = ri.GetData();
		if ( mapitem )
		{
			if ( mapitem->isMulti() )
			{
				MultiDefinition* def = MultiCache::instance()->getMulti( mapitem->id() - 0x4000 );
				if ( !def )
					return 0;
				QValueVector<multiItem_st> multi = def->getEntries();
				for ( Q_UINT32 j = 0; j < multi.size(); ++j )
				{
					if ( ( multi[j].visible && ( mapitem->pos().x + multi[j].x == pos.x ) && ( mapitem->pos().y + multi[j].y == pos.y ) && ( abs( mapitem->pos().z + multi[j].z - pos.z ) <= 1 ) ) )
					{
						return multi[j].tile;
					}
				}
			}
			else if ( mapitem->pos() == pos )
				return mapitem->id();
		}
	}
	return ( Q_UINT16 ) - 1;
}
예제 #3
0
void DragAndDrop::dropOnGround( cUOSocket* socket, P_ITEM pItem, const Coord_cl& pos )
{
	P_PLAYER pChar = socket->player();

	// Check if the destination is in line of sight
	if ( !pChar->lineOfSight( pos.losItemPoint(pItem->id()) ) )
	{
		socket->bounceItem( pItem, BR_OUT_OF_SIGHT );
		return;
	}

	if ( !pChar->canPickUp( pItem ) )
	{
		socket->bounceItem( pItem, BR_CANNOT_PICK_THAT_UP );
		return;
	}

	if ( pItem->onDropOnGround( pos ) )
	{
		// We're still dragging something
		if ( socket->dragging() )
			socket->bounceItem( socket->dragging(), BR_NO_REASON );

		return;
	}

	pItem->removeFromCont();
	pItem->moveTo( pos );
	pItem->update();

	// Play Sounds for non gold items
	if (pItem->id() != 0xEED) {
		pItem->soundEffect(0x42);
	}
}
예제 #4
0
// this is a q&d fix for 'sell price higher than buy price' bug (Duke, 30.3.2001)
static bool items_match(P_ITEM pi1, P_ITEM pi2)
{
	if (pi1 && pi2 && pi1->id()==pi2->id() &&
		pi1->type==pi2->type &&
		!(pi1->id()==0x14F0 && (pi1->morex!=pi2->morex)) &&			// house deeds only differ by morex
		!(IsShield(pi1->id()) && pi1->name2 == pi2->name2) &&	// magic shields only differ by name2
		!(IsMetalArmour(pi1->id()) && pi1->color != pi2->color) )	// color checking for armour
		return true;
	return false;
}
예제 #5
0
static bool ItemDroppedOnTrainer(P_CLIENT ps, PKGx08 *pp, P_ITEM pi)
{
	UOXSOCKET s=ps->GetSocket();
	CHARACTER cc=ps->GetCurrChar();
	P_CHAR pc_currchar = MAKE_CHARREF_LRV(cc,true);
	int t=calcCharFromSer(pp->Tserial);

	if( pi->id() ==0x0EED )
	{ // They gave the NPC gold
		char sk=chars[t].trainingplayerin;
		npctalk(s, t, "I thank thee for thy payment. That should give thee a good start on thy way. Farewell!",0);

		int sum = pc_currchar->getSkillSum();
		int delta = chars[t].getTeachingDelta(pc_currchar, sk, sum);

		if(pi->amount>delta) // Paid too much
		{
			pi->amount-=delta;
			Sndbounce5(s);
			if (ps->IsDragging())
			{
				ps->ResetDragging();
				item_bounce5(s,pi);
			}
		}
		else
		{
			if(pi->amount < delta)		// Gave less gold
				delta = pi->amount;		// so adjust skillgain
			Items->DeleItem(pi);
		}
		pc_currchar->baseskill[sk]+=delta;
		Skills->updateSkillLevel(DEREF_P_CHAR(pc_currchar), sk);
		updateskill(s,sk);

		pc_currchar->trainer=-1;
		chars[t].trainingplayerin='\xFF';
		itemsfx(s, pi->id());//AntiChrist - do the gold sound
		return true;
	}
	else // Did not give gold
	{
		npctalk(s, t, "I am sorry, but I can only accept gold.",0);
		Sndbounce5(s);
		if (ps->IsDragging())
		{
			ps->ResetDragging();
			item_bounce5(s,pi);
			return true;
		}
		else
			return true;
	}//if items[i]=gold
	return true;
}
예제 #6
0
Coord Coord::losTargetPoint( cUORxTarget* target, unsigned char map )
{
	SERIAL serial = target->serial();
	P_ITEM pItem = World::instance()->findItem( serial );
	P_CHAR pChar = World::instance()->findChar( serial );

	if ( pItem )
	{
		pItem = pItem->getOutmostItem();

		if ( pItem->container() && pItem->container()->isChar() )
		{
			return pItem->container()->pos().losCharPoint();
		}
		else
		{
			return pItem->pos().losItemPoint( pItem->id() );
		}
	}
	else if ( pChar )
	{
		return pChar->pos().losCharPoint();
	}
	else
	{
		return Coord( target->x(), target->y(), target->z(), map );
	}
}
예제 #7
0
static bool ItemDroppedOnBeggar(P_CLIENT ps, PKGx08 *pp, P_ITEM pi)
{
	UOXSOCKET s=ps->GetSocket();
	CHARACTER cc=ps->GetCurrChar();
	P_CHAR pc_currchar = MAKE_CHARREF_LRV(cc,false);
	int t=calcCharFromSer(pp->Tserial);
	if(pi->id()!=0x0EED)
	{
		sprintf((char*)temp,"Sorry %s i can only use gold",pc_currchar->name);
		npctalk(s,t,(char*)temp,0);
		return false;
	}
	sprintf((char*)temp,"Thank you %s for the %i gold!",pc_currchar->name,pi->amount);
	npctalk(s,t,(char*)temp,0);
	if(pi->amount<=100)
	{
		pc_currchar->karma += 10;
		sysmessage(s,"You have gain a little karma!");
	}
	else
	{
		pc_currchar->karma += 50;
		sysmessage(s,"You have gain some karma!");
	}
		Items->DeleItem(pi);
	    return true;
}
예제 #8
0
void cTrade::clearalltrades()
{
	AllItemsIterator iterItems;
	for (iterItems.Begin(); !iterItems.atEnd(); iterItems++)
	{
		P_ITEM pi = iterItems.GetData();
		if (pi->type==1 && pi->pos.x==26 && pi->pos.y==0 && pi->pos.z==0 &&
			pi->id()==0x1E5E)
		{
			P_CHAR pc = FindCharBySerial(pi->contserial);
			P_ITEM pBackpack = Packitem(pc);
			SERIAL serial = pi->serial;
			unsigned int ci;
			vector<SERIAL> vecContainer = contsp.getData(serial);
			for (ci = 0; ci < vecContainer.size(); ci++)
			{
				P_ITEM pj = FindItemBySerial(vecContainer[ci]);
				if (pj != NULL)
					if ((pj->contserial==serial))
					{
						if(pBackpack != NULL)
						{
							pBackpack->AddItem(pj);
						}
					}
			}
			iterItems--; // Iterator will became invalid when deletting.
			Items->DeleItem(pi);
			clConsole.send("Trade cleared\n");
		}
	}
}
예제 #9
0
void cDragItems::dropOnBanker( P_CLIENT client, P_ITEM pItem, P_CHAR pBanker )
{
	P_CHAR pChar = client->player();

	// No cheque ? >> Put into bank
	if( ( pItem->id() != 0x14F0 ) && ( pItem->type() != 1000 ) )
	{
		P_ITEM bankBox = pChar->getBankBox();

		if( bankBox )
			bankBox->AddItem( pItem );
		else
			bounceItem( client, pItem );

		pBanker->talk( QString( "The %1 is now in thy bank box" ).arg( pItem->getName() ) );
		return;
	}

	// No Value ?!
	if( !pItem->value )
	{
		pBanker->talk( "This cheque does not have any value!" );
		bounceItem( client, pItem );
		return;
	}

	pChar->giveGold( pItem->value, true );
	pBanker->talk( QString( "%1 I have cashed thy cheque and deposited %2 gold." ).arg( pChar->name.c_str() ).arg( pItem->amount() ) );

	pItem->ReduceAmount();
	statwindow( client->socket(), pChar );
}
예제 #10
0
void cWeight::NewCalc(P_CHAR pc)
{
	float totalweight=0.0;

	//get weight for items on players
	unsigned int ci = 0;
	P_ITEM pi;
	vector<SERIAL> vecContainer = contsp.getData(pc->serial);
	for ( ci = 0; ci < vecContainer.size(); ci++)
	{
		pi = FindItemBySerial(vecContainer[ci]);
		if (pi == NULL || (pi != NULL && pi->id() == 0x1E5E))	// trade window ?
			continue;
		if ((pi->layer()!=0x0B) && (pi->layer()!=0x10) && //no weight for hair/beard
			(pi->layer()!=0x1D) && (pi->layer()!=0x19))   //no weight for steed/bank box
		{
			totalweight+=(pi->getWeight()/100.0f);
		}
	}

	// Items in players pack
	P_ITEM pBackpack = Packitem(pc);
	if (pBackpack != NULL) totalweight += RecursePacks(pBackpack); //LB

	pc->weight = (int)totalweight;

	return;
}
예제 #11
0
//////////////////
// name:	RecursePacks
// Purpose:	recurses through the container given by bp to calculate the total weight
// History:	Ison 2-20-99  - rewrote by Tauriel 3/20/99
//			rewritten by Duke 4.11.2k
//
float cWeight::RecursePacks(P_ITEM bp)
{
	float totalweight=0.0;

	if (bp == NULL) return 0.0f;
	
	unsigned int ci = 0;
	vector<SERIAL> vecContainer = contsp.getData(bp->serial);
	for ( ci = 0; ci < vecContainer.size(); ci++)
	{
		P_ITEM pi = FindItemBySerial(vecContainer[ci]);
		int itemsweight=pi->getWeight();
		if (pi->type==1) //item is another container
		{
			totalweight += (itemsweight/100.0f);		// the weight of container itself
			totalweight += RecursePacks(pi);			//find the item's weight within this container
		}
		
		if (pi->id() == 0x0EED)
			totalweight += (pi->amount*SrvParms->goldweight);
		else
			totalweight += (float)((itemsweight*pi->amount)/100.0f);
	}
	return totalweight;
}
예제 #12
0
// Tries to equip an item
// if that fails it tries to put the item in the users backpack
// if *that* fails it puts it at the characters feet
// That works for NPCs as well
void equipItem( P_CHAR wearer, P_ITEM item )
{
	tile_st tile = TileCache::instance()->getTile( item->id() );

	// User cannot wear the item
	if ( tile.layer == 0 )
	{
		if ( wearer->objectType() == enPlayer )
		{
			P_PLAYER pp = dynamic_cast<P_PLAYER>( wearer );
			if ( pp->socket() )
				pp->socket()->sysMessage( tr( "You cannot wear that item." ) );
		}

		item->toBackpack( wearer );
		return;
	}

	cBaseChar::ItemContainer container = wearer->content();
	cBaseChar::ItemContainer::const_iterator it( container.begin() );
	for ( ; it != container.end(); ++it )
	{
		P_ITEM equip = *it;

		// Unequip the item and free the layer that way
		if ( equip && ( equip->layer() == tile.layer ) )
			equip->toBackpack( wearer );
	}

	// *finally* equip the item
	wearer->addItem( static_cast<cBaseChar::enLayer>( item->layer() ), item );
}
예제 #13
0
//////////////////
// name:	RecursePacks
// Purpose:	recurses through the container given by bp to calculate the total weight
// History:	Ison 2-20-99  - rewrote by Tauriel 3/20/99
//			rewritten by Duke 4.11.2k
//
float cWeight::RecursePacks(P_ITEM bp)
{
	float totalweight=0.0;

	if (bp == NULL) return 0.0f;
	
	unsigned int ci = 0;
	vector<SERIAL> vecContainer = contsp.getData(bp->serial);
	for ( ci = 0; ci < vecContainer.size(); ci++)
	{
		P_ITEM pi = FindItemBySerial(vecContainer[ci]);
		if ( pi == NULL ) // Should never happen, but...
		{
			contsp.remove( bp->serial, vecContainer[ci]); // Remove the invalid Entrie.
			continue; // let's pick up next.
		}
		int itemsweight=pi->getWeight();
		if( pi->type() == 1 ) //item is another container
		{
			totalweight += (itemsweight/100.0f);		// the weight of container itself
			totalweight += RecursePacks(pi);			//find the item's weight within this container
		}
		
		if (pi->id() == 0x0EED)
			totalweight += ( pi->amount() * SrvParams->goldWeight() );
		else
			totalweight += (float)((itemsweight * pi->amount())/100.0f);
	}
	return totalweight;
}
예제 #14
0
static bool ItemDroppedOnBanker(P_CLIENT ps, PKGx08 *pp, P_ITEM pi)
{
	UOXSOCKET s=ps->GetSocket();
	CHARACTER cc=ps->GetCurrChar();
	P_CHAR pc_currchar = MAKE_CHARREF_LRV(cc,true);
	int t=calcCharFromSer(pp->Tserial);
	P_ITEM bankbox = pc_currchar->GetBankBox();
	int amt = pi->amount;
	int value = pi->value;
	
	if (pi->id() == 0x14F0 && pi->type == 1000)
	{
		 const P_ITEM pi_n = Items->SpawnItem(DEREF_P_CHAR(pc_currchar), DEREF_P_CHAR(pc_currchar),value,"#",1,0x0E,0xED,0,0,0,0);
	     if(pi_n == NULL) return false;
		 sprintf((char*)temp,"%s I have cashed your check and deposited %i gold.",pc_currchar->name, value);
		 npctalk(s,t,(char*)temp,0);
		 bankbox->AddItem(pi_n);
	     statwindow(s, DEREF_P_CHAR(pc_currchar));
		 return true;
	}
    else
	{	    
	if (pi->id() == 0x0EED)
	{
		sprintf((char*)temp,"%s you have deposited %i gold.",pc_currchar->name, amt);
		npctalk(s,t,(char*)temp,0);
		bankbox->AddItem(pi);
	    statwindow(s, DEREF_P_CHAR(pc_currchar));
		return true;
	}
    else
	{
		  sprintf((char*)temp,"Sorry %s i can only deposit gold",pc_currchar->name);
		  npctalk(s,t,(char*)temp,0);
		  Sndbounce5(s);
		  if (ps->IsDragging())
		  {
			 ps->ResetDragging();
			 item_bounce5(s,pi);
			 return true;
		  }
	}
	return true;
	}
}
예제 #15
0
// Handles house commands from friends of the house.
// msg must already be capitalized
void HouseSpeech( cUOSocket *socket, P_CHAR pPlayer, const QString& msg )
{
	Q_UNUSED(socket);
	// Not inside a multi
	if( pPlayer->multis() == INVALID_SERIAL )
		return; 

	P_ITEM pMulti = FindItemBySerial( pPlayer->multis() );

	if( !pMulti )
	{
		clConsole.send( tr( "Player %1 [0x%2] has bad multi serial [0x%1]" ).arg( pPlayer->name() ).arg( pPlayer->serial(), 8, 16 ).arg( pPlayer->multis() ) );
		pPlayer->setMultis( INVALID_SERIAL );
		return;
	}

	if ( pMulti && IsHouse( pMulti->id() ) )
	{
		cHouse* pHouse = dynamic_cast< cHouse* >( pMulti );

		// Only the owner or a friend of the house can control it
		if( !( pPlayer->Owns( pHouse ) || pHouse->isFriend( pPlayer ) ) )
			return;
	}
	else
		return;

	// >> LEGACY
	/*if(msg.contains("I BAN THEE")) 
	{ // house ban
		addid1[s] = pMulti->serial()>>24;
		addid2[s] = pMulti->serial()>>16;
		addid3[s] = pMulti->serial()>>8;
		addid4[s] = pMulti->serial()%256;
		target(s, 0, 1, 0, 229, "Select person to ban from house.");
	}
	else if(msg.contains("REMOVE THYSELF")) 
	{ // kick out of house
		addid1[s] = pMulti->serial()>>24;
		addid2[s] = pMulti->serial()>>16;
		addid3[s] = pMulti->serial()>>8;
		addid4[s] = pMulti->serial()%256;
		target(s, 0, 1, 0, 228, "Select person to eject from house.");
	}
	else if (msg.contains("I WISH TO LOCK THIS DOWN")) 
	{ // lock down code AB/LB
         target(s, 0, 1, 0, 232, "Select item to lock down");
	}
	else if (msg.contains("I WISH TO RELEASE THIS")) 
	{ // lock down code AB/LB
          target(s, 0, 1, 0, 233, "Select item to release");
	}
	else if (msg.contains("I WISH TO SECURE THIS")) 
	{ // lock down code AB/LB
		target(s, 0, 1, 0, 234, "Select item to secure"); 
	}*/
}
예제 #16
0
void DragAndDrop::dropOnBeggar( cUOSocket* socket, P_ITEM pItem, P_CHAR pBeggar )
{
	int tempint;

	if( ( pBeggar->hunger() < 6 ) && pItem->type() == 14 )
	{
		pBeggar->talk( tr("*cough* Thank thee!") );
		pBeggar->soundEffect( 0x3A + RandomNum( 1, 3 ) );

		// *You see Snowwhite eating some poisoned apples*
		// Color: 0x0026
		pBeggar->emote( tr( "*You see %1 eating %2*" ).arg( pBeggar->name() ).arg( pItem->getName() ) );

		// We try to feed it more than it needs
		if( pBeggar->hunger() + pItem->amount() > 6 )
		{

//			client->player()->karma += ( 6 - pBeggar->hunger() ) * 10;
			tempint = ( 6 - pBeggar->hunger() ) * 10;
			socket->player()->setKarma( socket->player()->karma() + tempint );

			pItem->setAmount( pItem->amount() - ( 6 - pBeggar->hunger() ) );
			pBeggar->setHunger( 6 );

			// Pack the rest into his backpack
			bounceItem( socket, pItem );
			return;
		}

		pBeggar->setHunger( pBeggar->hunger() + pItem->amount() );
//		client->player()->karma += pItem->amount() * 10;
		tempint = pItem->amount() * 10;
		socket->player()->setKarma( socket->player()->karma() + tempint );

		pItem->remove();
		return;
	}

	// No Food? Then it has to be Gold
	if( pItem->id() != 0xEED )
	{
		pBeggar->talk( tr("Sorry, but i can only use gold.") );
		bounceItem( socket, pItem );
		return;
	}

	pBeggar->talk( tr( "Thank you %1 for the %2 gold!" ).arg( socket->player()->name() ).arg( pItem->amount() ) );
	socket->sysMessage( tr("You have gained some karma!") );

	if( pItem->amount() <= 100 )
		socket->player()->setKarma( socket->player()->karma() + 10 );
	else
		socket->player()->setKarma( socket->player()->karma() + 50 );

	pItem->remove();
}
예제 #17
0
void cDragItems::dropItem( cUOSocket *socket, cUORxDropItem *packet )
{
	P_PLAYER pChar = socket->player();

	if( !pChar )
		return;

	// Get the data
	SERIAL contId = packet->cont();

	Coord_cl dropPos = pChar->pos(); // plane
	dropPos.x = packet->x();
	dropPos.y = packet->y();
	dropPos.z = packet->z();

	// Get possible containers
	P_ITEM pItem = FindItemBySerial( packet->serial() );
	
	if( !pItem )
		return;

	P_ITEM iCont = FindItemBySerial( packet->cont() );
	P_CHAR cCont = FindCharBySerial( packet->cont() );

	// >> SEE LORD BINARIES DROPFIX <<

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

	UINT32 weight = pChar->weight();

	// Item dropped on Ground
	if( !iCont && !cCont )
		dropOnGround( socket, pItem, dropPos );

	// Item dropped on another item
	else if( iCont )
		dropOnItem( socket, pItem, iCont, dropPos );

	// Item dropped on char
	else if( cCont )
		dropOnChar( socket, pItem, cCont );

	// Handle the sound-effect
	if( pItem->id() == 0xEED )
		goldsfx( socket, pItem->amount(), true );

	// Update our weight.
	if( weight != pChar->weight() )
		socket->sendStatWindow();
}
예제 #18
0
bool cMovement::canLandMonsterMoveHere( const Coord_cl& pos ) const
{
	if ( pos.x >= ( Maps::instance()->mapTileWidth( pos.map ) * 8 ) || pos.y >= ( Maps::instance()->mapTileHeight( pos.map ) * 8 ) )
		return false;

	const signed char elev = Maps::instance()->mapElevation( pos );
	Coord_cl target = pos;
	target.z = elev;
	if ( ILLEGAL_Z == elev )
		return false;

	// get the tile id of any dynamic tiles at this spot
	Coord_cl mPos = pos;
	mPos.z = elev;
	const Q_INT32 dt = DynTile( mPos );

	// if there is a dynamic tile at this spot, check to see if its a blocker
	// if it does block, might as well Q_INT16-circuit and return right away
	if ( dt >= 0 )
	{
		tile_st tile = TileCache::instance()->getTile( dt );
		if ( tile.isBlocking() || tile.isWet() )
			return false;
	}

	// if there's a static block here in our way, return false
	StaticsIterator msi = Maps::instance()->staticsIterator( pos );
	while ( !msi.atEnd() )
	{
		tile_st tile = TileCache::instance()->getTile( msi->itemid );
		const Q_INT32 elev = msi->zoff + cTileCache::tileHeight( tile );
		if ( ( elev >= pos.z ) && ( msi->zoff <= pos.z ) )
		{
			if ( tile.isBlocking() || tile.isWet() )
				return false;
		}
		msi++;
	}

	RegionIterator4Items items( pos, 0 );
	for ( items.Begin(); !items.atEnd(); items++ )
	{
		P_ITEM item = items.GetData();
		tile_st tile = TileCache::instance()->getTile( item->id() );
		const Q_INT32 elev = item->pos().z + cTileCache::tileHeight( tile );
		if ( ( elev >= pos.z ) && ( item->pos().z <= pos.z ) )
		{
			if ( tile.isBlocking() || tile.isWet() )
				return false;
		}
	}

	return true;
}
예제 #19
0
//AntiChrist - do the sound effect ( only if HITTEN! )
void cCombat::doSoundEffect(P_CHAR pc, int fightskill, P_ITEM pWeapon)
{
	bool heavy=false;
	int a=rand()%4;

	//check if a heavy weapon
	if (pWeapon && IsAxe(pWeapon->id()))
		heavy=true;

	if(heavy)
	{
		if (a==0 || a==1) soundeffect2(pc, 0x0236);
		else soundeffect2(pc, 0x0237);
		return;
	}		

	switch(fightskill)
	{
	case ARCHERY:
		soundeffect2(pc, 0x0234);
		break;
	case FENCING:
	case SWORDSMANSHIP:
		if (a==0 || a==1) 
			soundeffect2(pc, 0x023B);
		else 
			soundeffect2(pc, 0x023C);
		break;
	case MACEFIGHTING:
		if (a==0 || a==1) 
			soundeffect2(pc, 0x0232);
		else if (a==2) 
			soundeffect2(pc, 0x0139);
		else 
			soundeffect2(pc, 0x0233);
		break;
	case WRESTLING:
		if (a==0) soundeffect2(pc, 0x0135);
		else if (a==1) soundeffect2(pc, 0x0137);
		else if (a==2) soundeffect2(pc, 0x013D);
		else soundeffect2(pc, 0x013B);
		break;
	default:
		soundeffect2(pc, 0x013D);
	}
}
예제 #20
0
void cDragItems::dropOnBroker( cUOSocket* socket, P_ITEM pItem, P_CHAR pBroker )
{
	// For House and Boat deeds we should pay back 75% of the value
	if( pItem->id() == 0x14EF )
	{
		if( !pItem->sellprice() )
		{
			pBroker->talk( tr("I can only accept deeds with value!") );
			bounceItem( socket, pItem );
			return;
		}
		
		socket->player()->giveGold( pItem->sellprice(), true );
		pBroker->talk( tr( "Here you have your %1 gold, %2" ).arg( pItem->sellprice() ).arg( socket->player()->name() ) );
		Items->DeleItem( pItem );
		return;
	}

	bounceItem( socket, pItem );
}
예제 #21
0
//	history:	added containersearch Duke, 4.11.2k
float cWeight::LockeddownWeight(P_ITEM pItem, int *total, int *total2 )
{
	float totalweight=0.0;
	if (!pItem) 
	{
		*total=0;
		return 0.0;
	}
	
	unsigned int ci = 0;
	P_ITEM pi;
	vector<SERIAL> vecContainer = contsp.getData(pItem->serial);
	for ( ci = 0; ci < vecContainer.size(); ci++)
	{
		pi = FindItemBySerial(vecContainer[ci]);
		int itemsweight=pi->getWeight();
		total2=total2+pi->amount();
		*total=*total+1;
		if( pi->type() == 1 || pi->type() == 63 || pi->type() == 65 || pi->type() == 87) //item is another container
		{
			totalweight+=(itemsweight/100.0f); //(pi->weight/100);
			totalweight+=LockeddownWeight(pi, total, total2); //find the item's weight within this container
		}
		
		if ( pi->id() == 0x0EED )
			totalweight+=(pi->amount()*SrvParams->goldWeight());
		else
			totalweight+=(float)((itemsweight*pi->amount())/100.0f); //((pi->weight*pi->amount)/100);  // Ison 2-21-99
	}

	if (*total==0) 
	{ 
		*total=pItem->amount();
		*total=*total*-1; // Indicate that not a pack ! on osi servers in that case weigt/items count isnt shown
		                  // thus i set it negative, if you want to show it anyway, add something like if (weight<0) weight*=-1; 
		return ((((float)pItem->getWeight())/100)*pItem->amount()); // if no pack return single item weight*/        		
		
	}
	else
		return totalweight;
}
예제 #22
0
void cDragItems::dropOnBroker( P_CLIENT client, P_ITEM pItem, P_CHAR pBroker )
{
	// For House and Boat deeds we should pay back 75% of the value
	if( pItem->id() == 0x14EF )
	{
		if( !pItem->value )
		{
			pBroker->talk( "I can only accept deeds with value!" );
			bounceItem( client, pItem );
			return;
		}

		Q_UINT32 nValue = static_cast< Q_UINT32 >( 0.75 * pItem->value );
		client->player()->giveGold( nValue, true );
		Items->DeleItem( pItem );
		pBroker->talk( QString( "Here you have your %1 gold, %2" ).arg( nValue ).arg( client->player()->name.c_str() ) );
		return;
	}

	bounceItem( client, pItem );
}
예제 #23
0
///////////////////////////
// Name:	ContainerCountItems
// history:	by Duke, 26.03.2001
// Purpose:	searches the container given by serial AND the subcontainers
//			for items with the given id and (if given) color.
//			Returns the total number of items found
//
int ContainerCountItems(const int serial, short id, short color)
{
	unsigned int ci=0; 
	int total=0;
	P_ITEM pi;
	vector<SERIAL> vecContainer = contsp.getData(serial);
	for ( ci = 0; ci < vecContainer.size(); ci++)
	{
		pi = FindItemBySerial(vecContainer[ci]);
		if (!pi || pi->free)			// just to be sure ;-)
			continue;
		if (pi->type==1)		// a subcontainer ?
		{
			total += ContainerCountItems(pi->serial, id, color);
			continue;
		}
		if (pi->id()==id &&
			(color==-1 || pi->color == color))
			total += pi->amount;
	}
	return total;
}
예제 #24
0
// Tries to equip an item
// if that fails it tries to put the item in the users backpack
// if *that* fails it puts it at the characters feet
// That works for NPCs as well
void equipItem( P_CHAR wearer, P_ITEM item )
{
	tile_st tile;

	Map->SeekTile( item->id(), &tile );

	// User cannot wear the item
	if( tile.layer == 0 )
	{
		if( online( wearer ) )
			sysmessage( calcSocketFromChar( wearer ), "You cannot wear that item." );

		item->toBackpack( wearer );
		return;
	}

	vector< SERIAL > equipment = contsp.getData( wearer->serial );	

	// If n item on the same layer is already equipped, unequip it
	for( UI08 i = 0; i < equipment.size(); i++ )
	{
		P_ITEM equip = FindItemBySerial( equipment[ i ] ); 
		
		// Unequip the item and free the layer that way
		if( equip && ( equip->layer() == tile.layer ) )
			equip->toBackpack( wearer );

		wearer->removeItemBonus( equip );
	}

	// *finally* equip the item
	item->setContSerial( wearer->serial );

	// Add the item bonuses
	wearer->st = (wearer->st + item->st2);
	wearer->chgDex( item->dx2 );
	wearer->in = (wearer->in + item->in2);
}
예제 #25
0
int cCombat::GetBowType(P_CHAR pc)
{
	unsigned int ci=0;
	P_ITEM pi;
	vector<SERIAL> vecContainer = contsp.getData(pc->serial);
	for ( ; ci < vecContainer.size(); ++ci)
	{
		pi = FindItemBySerial(vecContainer[ci]);
		if (pi && ( pi->layer == 1 || pi->layer == 2 ) )
		{
			switch( pi->id() )
			{
			case 0x13B1:
			case 0x13B2:	return 1;	// bows
			case 0x0F4F:
			case 0x0F50:	return 2;	// crossbow
			case 0x13FC:
			case 0x13FD:	return 3;	// heavy xbow
			}
		}
	}
	return 0;
}
예제 #26
0
bool inmulti(Coord_cl pos, P_ITEM pi)//see if they are in the multi at these chords (Z is NOT checked right now)
{
	int j;
	SI32 length;			// signed long int on Intel
	st_multi multi;
	UOXFile *mfile;
	Map->SeekMulti(pi->id()-0x4000, &mfile, &length);
	length=length/sizeof(st_multi);
	if (length == -1 || length>=17000000)//Too big...
	{
		sprintf((char*)temp,"inmulti() - Bad length in multi file. Avoiding stall. (Item Name: %s)\n", pi->name.c_str() );
		LogError( (char*)temp ); // changed by Magius(CHE) (1)
		length = 0;
	}
	for (j=0;j<length;j++)
	{
		mfile->get_st_multi(&multi);
		if ((multi.visible)&&(pi->pos.x+multi.x == pos.x) && (pi->pos.y+multi.y == pos.y))
		{
			return true;
		}
	}
	return false;
}
예제 #27
0
void cDragItems::dropOnTrainer( P_CLIENT client, P_ITEM pItem, P_CHAR pTrainer )
{
	P_CHAR pChar = client->player();

	if( pItem->id() != 0xEED )
	{
		pTrainer->talk( "You need to give me gold if you want me to train you!" );
		bounceItem( client, pItem );
		return;
	}

	pTrainer->talk( "I thank thee for thy payment. That should give thee a good start on thy way. Farewell!" );

	Q_UINT8 skill = pTrainer->trainingplayerin();
	Q_INT32 skillSum = pChar->getSkillSum();
	Q_INT32 skillDelta = pTrainer->getTeachingDelta( pChar, skill, skillSum );

	goldsfx( client->socket(), pItem->amount() );

	if( pItem->amount() > skillDelta )
	{
		pItem->ReduceAmount( skillDelta );
		bounceItem( client, pItem );
	}
	else
	{
		skillDelta = pItem->amount();
		Items->DeleItem( pItem );
	}
	
	pChar->setBaseSkill( skill, pChar->baseSkill( skill ) + skillDelta );
	Skills->updateSkillLevel( pChar, skill );
	updateskill( client->socket(), skill );

	// we will not reset the trainer id here because he may want to give him more money
}
예제 #28
0
static bool ItemDroppedOnSelf(P_CLIENT ps, PKGx08 *pp, P_ITEM pi)
{
	UOXSOCKET s=ps->GetSocket();
	CHARACTER cc=ps->GetCurrChar();
	P_CHAR pc_currchar = MAKE_CHARREF_LRV(cc,true);
	
	if (pi->id1>=0x40) // crashfix , prevents putting multi-objects ni your backback
	{
		sysmessage(s,"Hey, putting houses in your pack crashes your back and client !");
		pi->MoveTo(pc_currchar->pos.x,pc_currchar->pos.y,pc_currchar->pos.z);
		RefreshItem(pi);//AntiChrist
		return true;
	}
	
	if (pi->glow>0) // glowing items
	{
		pc_currchar->addHalo(pi);
		pc_currchar->glowHalo(pi);
	}
	
	P_ITEM pack = Packitem(pc_currchar); // LB ...
	if (pack == NULL) // if player has no pack, put it at its feet
	{ 
		pi->MoveTo(pc_currchar->pos.x,pc_currchar->pos.y,pc_currchar->pos.z);
		RefreshItem(pi);//AntiChrist
	}
	else
	{
		pack->AddItem(pi); // player has a pack, put it in there
		
		Weight->NewCalc(DEREF_P_CHAR(pc_currchar));//AntiChrist bugfixes
		statwindow(s,DEREF_P_CHAR(pc_currchar));
		itemsfx(s, pi->id());
	}
	return true;
}
예제 #29
0
// The highest items will be @ the beginning
// While walking we always will try the highest first.
vector< stBlockItem > getBlockingItems( P_CHAR pChar, const Coord& pos )
{
	vector<stBlockItem> blockList;
	make_heap( blockList.begin(), blockList.end(), compareTiles() );

	// Process the map at that position
	stBlockItem mapBlock;
	mapBlock.maptile = true;
	mapBlock.z = Maps::instance()->mapAverageElevation( pos );
	mapBlock.height = 0;

	// TODO: Calculate the REAL average Z Value of that Map Tile here! Otherwise clients will have minor walking problems.
	map_st mapCell = Maps::instance()->seekMap( pos );
	//mapBlock.z = mapCell.z;
	land_st mapTile = TileCache::instance()->getLand( mapCell.id );

	// If it's not impassable it's automatically walkable
	if ( !( mapTile.flag1 & 0x40 ) )
		mapBlock.walkable = true;
	else
		mapBlock.walkable = checkWalkable( pChar, mapCell.id );

	if ( mapCell.id != 0x02 )
	{
		blockList.push_back( mapBlock );
		push_heap( blockList.begin(), blockList.end(), compareTiles() );
	}

	// Now for the static-items
	StaticsIterator staIter = Maps::instance()->staticsIterator( pos, true );
	for ( ; !staIter.atEnd(); ++staIter )
	{
		tile_st tTile = TileCache::instance()->getTile( staIter->itemid );

		// Here is decided if the tile is needed
		// It's uninteresting if it's NOT blocking
		// And NOT a bridge/surface
		if ( !( ( tTile.flag2 & 0x02 ) || ( tTile.flag1 & 0x40 ) || ( tTile.flag2 & 0x04 ) ) )
			continue;

		stBlockItem staticBlock;
		staticBlock.z = staIter->zoff;

		// If we are a surface we can always walk here, otherwise check if
		// we are special
		if ( ( tTile.flag2 & 0x02 ) && !( tTile.flag1 & 0x40 ) )
			staticBlock.walkable = true;
		else
			staticBlock.walkable = checkWalkable( pChar, staIter->itemid );

		// If we are a stair only the half height counts (round up)
		if ( tTile.flag2 & 0x04 )
			staticBlock.height = ( Q_UINT8 ) ( ( tTile.height ) / 2 );
		else
			staticBlock.height = tTile.height;

		blockList.push_back( staticBlock );
		push_heap( blockList.begin(), blockList.end(), compareTiles() );
	}

	// We are only interested in items at pos
	// todo: we could impliment blocking for items on the adjacent sides
	// during a diagonal move here, but this has yet to be decided.

	MapItemsIterator iIter = MapObjects::instance()->listItemsAtCoord( pos );
	for ( P_ITEM pItem = iIter.first(); pItem; pItem = iIter.next() )
	{
		if ( pChar && pChar->isDead() )
		{
			// Doors can be passed by ghosts
			if ( pItem->hasScript( "door" ) )
			{
				continue;
			}
		}

		tile_st tTile = TileCache::instance()->getTile( pItem->id() );

		// See above for what the flags mean
		if ( !( ( tTile.flag2 & 0x02 ) || ( tTile.flag1 & 0x40 ) || ( tTile.flag2 & 0x04 ) ) )
			continue;

		stBlockItem blockItem;
		blockItem.height = ( tTile.flag2 & 0x04 ) ? ( tTile.height / 2 ) : tTile.height;
		blockItem.z = pItem->pos().z;

		// Once again: see above for a description of this part
		if ( ( tTile.flag2 & 0x02 ) && !( tTile.flag1 & 0x40 ) )
			blockItem.walkable = true;
		else
			blockItem.walkable = checkWalkable( pChar, pItem->id() );

		blockList.push_back( blockItem );
		push_heap( blockList.begin(), blockList.end(), compareTiles() );
	}


	// deal with the multis now, or not.
	// 18 has been tested with castle sides and corners...
	MapMultisIterator iter = MapObjects::instance()->listMultisInCircle( pos, 18 );
	for ( cMulti*pMulti = iter.first(); pMulti; pMulti = iter.next() )
	{
		MultiDefinition* def = MultiCache::instance()->getMulti( pMulti->id() - 0x4000 );
		if ( !def )
			continue;

		QValueVector<multiItem_st> multi = def->getEntries();

		for ( unsigned int j = 0; j < multi.size(); ++j )
		{
			if ( multi[j].visible && ( pMulti->pos().x + multi[j].x == pos.x ) && ( pMulti->pos().y + multi[j].y == pos.y ) )
			{
				tile_st tTile = TileCache::instance()->getTile( multi[j].tile );
				if ( !( ( tTile.flag2 & 0x02 ) || ( tTile.flag1 & 0x40 ) || ( tTile.flag2 & 0x04 ) ) )
					continue;

				stBlockItem blockItem;
				blockItem.height = ( tTile.flag2 & 0x04 ) ? ( tTile.height / 2 ) : tTile.height;
				blockItem.z = pMulti->pos().z + multi[j].z;

				if ( ( tTile.flag2 & 0x02 ) && !( tTile.flag1 & 0x40 ) )
					blockItem.walkable = true;
				else
					blockItem.walkable = checkWalkable( pChar, pMulti->id() );

				blockList.push_back( blockItem );
				push_heap( blockList.begin(), blockList.end(), compareTiles() );
			}
		}
		continue;
	}

	// Now we need to evaluate dynamic items [...] (later)  ??
	sort_heap( blockList.begin(), blockList.end(), compareTiles() );

	return blockList;
};
예제 #30
0
void cDragItems::dropOnBeggar( cUOSocket* socket, P_ITEM pItem, P_CHAR pBeggar )
{
	int tempint;
	
	if( ( pBeggar->hunger() < 6 ) && pItem->type() == 14 )
	{
		pBeggar->talk( tr("*cough* Thank thee!") );
		pBeggar->soundEffect( 0x3A + RandomNum( 1, 3 ) );

		// If you want to poison a pet... Why not
		if( pItem->poisoned() && pBeggar->poisoned() < pItem->poisoned() )
		{
			pBeggar->soundEffect( 0x246 );
			pBeggar->setPoisoned( pItem->poisoned() );
			
			// a lev.1 poison takes effect after 40 secs, a deadly pois.(lev.4) takes 40/4 secs - AntiChrist
			pBeggar->setPoisonTime( uiCurrentTime + ( MY_CLOCKS_PER_SEC * ( 40 / pBeggar->poisoned() ) ) );
			
			//wear off starts after poison takes effect - AntiChrist
			pBeggar->setPoisonWearOffTime( pBeggar->poisonTime() + ( MY_CLOCKS_PER_SEC * SrvParams->poisonTimer() ) );
			
			// Refresh the health-bar of our target
			pBeggar->resend( false );
		}


		// *You see Snowwhite eating some poisoned apples*
		// Color: 0x0026
		pBeggar->emote( tr( "*You see %1 eating %2*" ).arg( pBeggar->name() ).arg( pItem->getName() ) );

		// We try to feed it more than it needs
		if( pBeggar->hunger() + pItem->amount() > 6 )
		{
			
//			client->player()->karma += ( 6 - pBeggar->hunger() ) * 10;
			tempint = ( 6 - pBeggar->hunger() ) * 10;
			socket->player()->setKarma( socket->player()->karma() + tempint );

			pItem->setAmount( pItem->amount() - ( 6 - pBeggar->hunger() ) );
			pBeggar->setHunger( 6 );

			// Pack the rest into his backpack
			bounceItem( socket, pItem );
			return;
		}

		pBeggar->setHunger( pBeggar->hunger() + pItem->amount() );
//		client->player()->karma += pItem->amount() * 10;
		tempint = pItem->amount() * 10;
		socket->player()->setKarma( socket->player()->karma() + tempint );

		Items->DeleItem( pItem );
		return;
	}

	// No Food? Then it has to be Gold
	if( pItem->id() != 0xEED )
	{
		pBeggar->talk( tr("Sorry, but i can only use gold.") );
		bounceItem( socket, pItem );
		return;
	}

	pBeggar->talk( tr( "Thank you %1 for the %2 gold!" ).arg( socket->player()->name() ).arg( pItem->amount() ) );
	socket->sysMessage( tr("You have gained some karma!") );
	
	if( pItem->amount() <= 100 )
		socket->player()->setKarma( socket->player()->karma() + 10 );
	else
		socket->player()->setKarma( socket->player()->karma() + 50 );
	
	Items->DeleItem( pItem );
}