Пример #1
0
	/*!
	\brief returns the *index element of the vector of a container (identified by serial)
	\author Luxor
	\param serial the serial of the container
	\index the pointer to the integer which we're using for the search
	\note *index should be 0 at the beginning of the search
	\return P_ITEM of the item found
	*/
	P_ITEM containerSearch(int serial, int *index)
	{
		if (serial < 0 || (*index) < 0)
			return 0;

		P_ITEM pi = 0;

		vector<P_ITEM> &pcm = pContMap[serial];

		for (pi = 0; pi == 0; (*index)++)
		{
			if ( pcm.empty())
				return 0;

			if ((UI32)(*index) >= pcm.size())
				return 0;

			pi = pcm[*index];

			if (!(ISVALIDPI(pi)))
			{
				if ((UI32)(*index)+1 < pcm.size() && !pcm.empty())
					pcm[*index] = pcm[pcm.size()-1];
			}
			pi = 0;
			pcm.pop_back();
		}

		if ( !ISVALIDPI(pi) )
			return 0;

		return pi;
	}
Пример #2
0
static LOGICAL canMine( P_CHAR pc, P_ITEM weapon )
{

	VALIDATEPCR(pc,false);
	
	if( !ISVALIDPI(weapon) && ( pc->CountItemsByType(ITYPE_MINING) <= 0 ) )
			pc->sysmsg( TRANSLATE("You must have a pickaxe or shovel in hand in order to mine."));
	else
	{
		if ( (ISVALIDPI(weapon) && ( weapon->getType() == ITYPE_MINING )) || (pc->CountItemsByType(ITYPE_MINING) > 0 ))
		// Let's see if he has a shovel in his pack
		{
			if (pc->isMounting())
				pc->sysmsg( TRANSLATE("You cant mine while on a horse!"));
			else
				if( !pc->IsGM() && (ores.stamina<0) && (abs( ores.stamina )>pc->stm) )
					pc->sysmsg( TRANSLATE("You are too tired to mine."));
				else
					return true;
					
		}
	}

	return false;
}
Пример #3
0
void Skills::MakeMenu( P_CHAR pc, int m, int skill, P_ITEM first, P_ITEM second )
{

	Skills::MakeMenu( 
		pc, m, skill, ISVALIDPI(first)? (unsigned short)first->getId() : (unsigned short)0, ISVALIDPI(first)? (unsigned short)first->getColor() : (unsigned short)0,
		ISVALIDPI(second)? (unsigned short)second->getId() : (unsigned short)0, ISVALIDPI(second)? (unsigned short)second->getColor() : (unsigned short)0 
	);
	
}
Пример #4
0
void Skills::MakeMenu( P_CHAR pc, int m, int skill, P_ITEM first, P_ITEM second )
{

	Skills::MakeMenu( 
		pc, m, skill, ISVALIDPI(first)? first->getId() : 0, ISVALIDPI(first)? first->getColor() : 0,
		ISVALIDPI(second)? second->getId() : 0, ISVALIDPI(second)? second->getColor() : 0 
	);
	
}
Пример #5
0
/*!
\brief Search player's paperdoll and then backpacks for items with weight then set the weight of the current player
\author Ison (02/20/99), rewrote by Tauriel (03/20/99)
\param pc the character
\note  The called character's weight is first set to zero then re-calculated during the function.
*/
void weights::NewCalc(P_CHAR pc)
{
	VALIDATEPC(pc);
	double totalweight=0.0;
	//get weight for items on players
	
	NxwItemWrapper si;
	si.fillItemWeared( pc, false, false, true );
	for( si.rewind(); !si.isEmpty(); si++ )
	{
		P_ITEM pi=si.getItem();
		// Wintermute: Exclude mounted layer (counts as worn item)
		if (ISVALIDPI(pi) && pi->layer != LAYER_MOUNT)
		{
			totalweight+=(pi->getWeightActual()/100.0);
		}
	}

	// Items in players pack
	P_ITEM bp= pc->getBackpack();
	if (bp!=NULL) totalweight+=RecursePacks(bp); //LB

	pc->weight=(int)totalweight;

	return;

}
Пример #6
0
	void showItemLocationMap()
	{
		PITEMLOCATIONMAPIT it( pItemLocationMap.begin() ), end( pItemLocationMap.end() );

		ConOut( "--------------------------------\n" );
		ConOut( "|      ITEM LOCATION MAP       |\n" );
		ConOut( "--------------------------------\n" );
		ConOut( "|   Key   | X  | Y  |  SERIAL  |\n" );
		ConOut( "--------------------------------\n" );

		UI32 	invalidCount	=  0;
		SI32 	x	  	=  0;
		SI32 	y		=  0;
		SERIAL	serial		= INVALID;
		for( ; it != end; ++it )
		{
			x = it->first >> 16;
			y = it->first & 0x0000FFFF;
			if( ISVALIDPI( it->second ) )
				serial = it->second->getSerial32();
			else
			{
				++invalidCount;
				serial = INVALID;
			}
			ConOut( "|%10i|%4i|%4i|%10i|\n", it->first, x, y, serial );
		}
		ConOut( "--------------------------------\n" );
		ConOut( "| entries in map : %10i  |\n", pItemLocationMap.size());
		ConOut( "| invalid entries: %10i  |\n", invalidCount );
		ConOut( "--------------------------------\n" );
	}
Пример #7
0
void cItem::explode(NXWSOCKET  s)
{
	if (s < 0 || s > now) return;	//Luxor

	unsigned int dmg=0,len=0;

	P_CHAR pc_current=MAKE_CHAR_REF(currchar[s]);
	VALIDATEPC(pc_current);

	if(!isInWorld())
		return;

	type=0; //needed for recursive explosion

	//Luxor - recursive explosions!! :DD
	NxwItemWrapper si;
	si.fillItemsNearXYZ( getPosition(), 5, true );
    for( si.rewind(); !si.isEmpty(); si++ ) {
		P_ITEM p_nearbie=si.getItem();
		if(ISVALIDPI(p_nearbie) && p_nearbie->type == ITYPE_POTION && p_nearbie->morey == 3) { //It's an explosion potion!
			p_nearbie->explode(s);
    	}
    }
	//End Luxor recursive explosions

	staticeffect2(this, 0x36, 0xB0, 0x10, 0x80, 0x00);
	soundeffect3(this, 0x0207);

	len=morex/250; //4 square max damage at 100 alchemy
	switch (morez)
	{
		case 1:dmg=RandomNum( 5,10) ;break;
		case 2:dmg=RandomNum(10,20) ;break;
		case 3:dmg=RandomNum(20,40) ;break;
		default:
			ErrOut("Switch fallout. NoX-Wizard.cpp, explodeitem()\n"); //Morrolan
			dmg=RandomNum(5,10);
	}

	if (dmg<5) dmg=RandomNum(5,10);	// 5 points minimum damage
	if (len<2) len=2;	// 2 square min damage range

	NxwCharWrapper sc;
	sc.fillCharsNearXYZ( getPosition(), len, true );
	for( sc.rewind(); !sc.isEmpty(); sc++ ) {

		P_CHAR pc=sc.getChar();
		if( ISVALIDPC(pc) ) {
			pc->damage( dmg+(2-pc->distFrom(this)), DAMAGE_FIRE );
		}
	}

	Delete();

}
Пример #8
0
	/*!
	\author Luxor
	\brief returns the *index element with the given id and color of the vector of a container(identified by serial)
	\param serial the serial of the container
	\param index the pointer to the integer which we're using for the search
	\param id the id which we're searching for
	\param color the color which we're searching for
	\return the item we're searching for
	\note *index should be 0 at the beginning of the search
	*/
	P_ITEM containerSearchFor(const int serial, int *index, short id, short color)
	{
		P_ITEM pi;
		int loopexit=0;
		while ( ((pi = containerSearch(serial,index)) != 0) && (++loopexit < MAXLOOPS) )
		{
			if (pi->getId()==id  &&
				(color==-1 || pi->getColor()==color) && ISVALIDPI(pi))
			return pi;
		}
		return 0;
	}
Пример #9
0
/*!
\brief gets world coordinates from a serial
\author Xanathar
\param sr serial
\param px x coordinate
\param py y coordinate
\param pz z coordinate
\param ch eventual index to char
\param it eventual index to item
*/
void getWorldCoordsFromSerial (int sr, UI16& px, UI16& py, SI08& pz, int& ch, int& it)
{
    int serial = sr;
    int loop = 0;
    it = ch = INVALID;

	P_CHAR pc=0;
	P_ITEM pi=0;

    while ((++loop) < 500)
    {

		pc=pointers::findCharBySerial(serial);
		ch = DEREF_P_CHAR(pc);
		pi=pointers::findItemBySerial(serial);
        it = DEREF_P_ITEM(pi);
        if (ISVALIDPI(pi)) {
            if (pi->getContSerial()!=INVALID) {
                serial = pi->getContSerial();
                continue;
            }
        }
        break;
    }

    if (ISVALIDPC(pc)) {
		Location charpos= pc->getPosition();
        px = charpos.x;
        py = charpos.y;
        pz = charpos.z;
    } else if ( ISVALIDPI(pi) && (pi->getContSerial()==INVALID)) {
        px = pi->getPosition("x");
        py = pi->getPosition("y");
        pz = pi->getPosition("z");
    } else {
        px = 0;
        py = 0;
        pz = 0;
    }
}
Пример #10
0
/*!
\brief Get the player weight
\author Unknow, update by Duke (04/11/00)
\return actual weight
\param pItem the container
\param total the total number of item in container and subcontainer
\note total < 0 indicate that not a pack ! on osi servers in that case weigt/items count isnt show
 thus i set it negative, if you want to show it anyway, add something like if (weight<0) weight*=-1; 
*/
float weights::LockeddownWeight(P_ITEM pItem, int *total )
{
	double totalweight=0.0;
	if (!ISVALIDPI(pItem)) 
	{
		*total=0;
		return 0.0;
	}
	
	NxwItemWrapper si;
	si.fillItemsInContainer( pItem, false );
	for( si.rewind(); !si.isEmpty(); si++ )
	{
		P_ITEM pi= si.getItem();
		if(!ISVALIDPI(pi)) continue;

		R32 itemsweight=pi->getWeightActual();
		*total=*total+1;
		if (pi->isContainer()) //item is another container
		{
			totalweight+=(itemsweight/100.0); //(pi->weight/100);
			totalweight+=LockeddownWeight(pi, total); //find the item's weight within this container
		}
		
		totalweight+=((itemsweight)/100.00); //((pi->weight*pi->amount)/100);  // Ison 2-21-99
	}

	if (*total==0) 
	{ 
		*total=pItem->amount;
		*total=*total*-1; 
		return static_cast<float>(pItem->getWeightActual()/100.0); // if no pack return single item weight*/			
		
	}
	else
		return static_cast<float>(totalweight);
}
Пример #11
0
/*!
\brief recurses through the container given to calculate the total weight
\author Ison (02/20/99), rewritten by Tauriel (03/20/99), rewritten by Duke (04/11/00)
\return the weight
\param bp the item
*/
float weights::RecursePacks(P_ITEM bp)
{
	double totalweight=0.0;

	if (!ISVALIDPI(bp)) return 0.0;
	
	NxwItemWrapper si;
	si.fillItemsInContainer( bp, false );
	for( si.rewind(); !si.isEmpty(); si++ )
	{
		P_ITEM pi=si.getItem();
		if( !ISVALIDPI(pi)) continue;

		R32 itemsweight=pi->getWeightActual();
		if (pi->isContainer()) //item is another container
		{
			totalweight+=(itemsweight/100.0);		// the weight of container itself
			totalweight+=RecursePacks(pi); //find the item's weight within this container
		}
		
		totalweight+=((itemsweight)/100.0);
	}
	return static_cast<float>(totalweight);
}
Пример #12
0
void pack_item(NXWCLIENT ps, PKGx08 *pp) // Item is put into container
{
	if (ps == NULL) return;

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

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

	Location charpos= pc->getPosition();

	P_ITEM pack;

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

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

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

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

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

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

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

		P_ITEM pi_z = pointers::findItemBySerial(serial);

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

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

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

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

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

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

		}
	}


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

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

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

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

				P_ITEM pi_ci=sii.getItem();

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

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

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

	if (pCont->type == ITYPE_CONTAINER) {

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

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

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

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

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

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

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

				pItem->Refresh();
			}


}
/*!
\brief Double click
\author Ripper, rewrite by Endymion
\param ps client of player dbclick
\note Completely redone by Morrolan 20-07-99
\warning I use a define CASE for make more readable the code, if you change name of P_ITEM pi chage also the macro
\todo los
*/
void doubleclick(NXWCLIENT ps)
{

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

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

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

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

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

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

	Location charpos= pc->getPosition();

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

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

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


//<Anthalir> VARIAIBLI

	tile_st item;

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


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

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

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

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

						{

							P_ITEM p_drop=MAKE_ITEM_REF(drop[i]);

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

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


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

	pCont = pi->getOutMostCont();

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

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

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

	P_CHAR itmowner = pi->getPackOwner();

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

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

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

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

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


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

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

	int los = 0;


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


	P_TARGET targ = NULL;

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

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

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

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

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

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

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

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

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

			}

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

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

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

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

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

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

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

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

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

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

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

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

	P_ITEM pack= victim->getBackpack();
	if ( !ISVALIDPI(pack))
	{
		thief->sysmsg(TRANSLATE("bad luck, your victim doesn't have a backpack"));
		return;
	}

	char temp[TEMP_STR_SIZE]; //xan -> this overrides the global temp var
	char temp2[TEMP_STR_SIZE]; //xan -> this overrides the global temp var
	sprintf(temp, TRANSLATE("You reach into %s's pack to steal something ..."), victim->getCurrentNameC() );
	thief->sysmsg(temp);

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

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

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

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

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

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

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

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

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

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

			std::string itmname = "";
			if ( pi->getCurrentName() != "#" )
				itmname = pi->getCurrentName();
			else 
			{
				pi->getName( temp );
				itmname = temp;
			}

			sprintf(temp,TRANSLATE("You notice %s trying to steal %s from you!"), thief->getCurrentNameC(), itmname.c_str());
			sprintf(temp2,TRANSLATE("You notice %s trying to steal %s from %s!"), thief->getCurrentNameC(), itmname.c_str(), victim->getCurrentNameC());

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

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

				P_CHAR pc_i=ps_i->currChar();
				if ( ISVALIDPC(pc_i) )
					if( (rand()%10+10==17) || ( (rand()%2==1) && (pc_i->in>=thief->in)))
						sysmessage(ps_i->toInt(),temp2);
			}
		}
	}
	else 
	{
		thief->sysmsg( TRANSLATE("... and realise you're too far away."));
	}

}
Пример #15
0
void newbieitems(P_CHAR pc)
{

	VALIDATEPC(pc);
	
	NXWCLIENT ps=pc->getClient();
	if(ps==NULL)
		return;

	int first, second, third, storeval, itemaddperskill, loopexit = 0;
	char sect[512];
	char whichsect[105];
	cScpIterator* iter = NULL;

	first = bestskill(pc);
	second = nextbestskill(pc, first);
	third = nextbestskill(pc, second);
	if (pc->baseskill[third] < 190)
		third = 46;

	for (itemaddperskill = 1; itemaddperskill <= 5; itemaddperskill++)
	{
		switch (itemaddperskill)
		{
			// first of all the general section with the backpack, else where we put items?
			case 1: strcpy(whichsect, "SECTION ALLNEWBIES");		break;
			case 2:
				if ( (pc->getId() == BODY_MALE) && (pc->getOldId() == BODY_MALE) )
					strcpy(whichsect, "SECTION MALENEWBIES");
				else
					strcpy(whichsect, "SECTION FEMALENEWBIES");
				break;
			case 3: sprintf(whichsect, "SECTION BESTSKILL %i", first);	break;
			case 4: sprintf(whichsect, "SECTION BESTSKILL %i", second);	break;
			case 5: sprintf(whichsect, "SECTION BESTSKILL %i", third);	break;
			default:
				ErrOut("Switch fallout. newbie.cpp, newbieitems()/n"); // Morrolan
		}

		sprintf(sect, whichsect);
		char script1[1000], script2[1000];
		safedelete(iter);
		iter = Scripts::Newbie->getNewIterator(sect);
		if (iter==NULL) return;

		do
		{
			iter->parseLine(script1,script2);

			if (script1[0] == '@') pc->loadEventFromScript(script1, script2); 	// Sparhawk: Huh loading character events 
												// from newbie item scripts????

			if (script1[0] != '}')
			{
				if (!(strcmp("PACKITEM", script1)))
				{
					std::string itemnum, amount;
					splitLine( script2, itemnum, amount );
					int amt = ( amount != "" )? str2num( amount ) : INVALID; //ndEndy defined amount
					P_ITEM pi_n = item::CreateFromScript( str2num( itemnum ), pc->getBackpack(), amt );
					if (ISVALIDPI(pi_n)) {
						pi_n->priv |= 0x02; // Mark as a newbie item
					}
					strcpy(script1, "DUMMY");
				}
				else if (!strcmp("BANKITEM", script1))
				{
					std::string itemnum, amount;
					splitLine( script2, itemnum, amount );
					int amt= (amount!="")? str2num( amount ) : INVALID;
					P_ITEM pi = item::CreateFromScript( str2num( itemnum ), pc->GetBankBox(), amt );
					if (ISVALIDPI(pi)) {
						pi->priv |= 0x02; // Mark as a newbie item
					}
					strcpy(script1, "DUMMY");
				}
				else if (!strcmp("EQUIPITEM", script1))
				{
					P_ITEM pi = item::CreateFromScript( script2 );
					if (ISVALIDPI(pi))
					{
						pi->priv |= 0x02; // Mark as a newbie item
						pi->setCont(pc);
						storeval = pi->getScriptID();
					}
					strcpy(script1, "DUMMY");
				}
			}
		}
		while ((script1[0] != '}') &&(++loopexit < MAXLOOPS));
	
		safedelete(iter);
	}
	
	// Give the character some gold
	if ( goldamount > 0 )
	{
		item::CreateFromScript( "$item_gold_coin", pc->getBackpack(), goldamount );
	}


}
Пример #16
0
void drop_item(NXWCLIENT ps) // Item is dropped
{

	if (ps == NULL) return;

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

	PKGx08 pkgbuf, *pp=&pkgbuf;

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

    //#define debug_dragg

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

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

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

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

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

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

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

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


//	if ( (buffer[s][10]>=0x40) && (buffer[s][10]!=0xff) )
	if ( isItemSerial(pp->Tserial) && (pp->Tserial != INVALID)  ) // Invalid target => invalid container => put inWorld !!!
		pack_item(ps,pp);
	else
		dump_item(ps,pp);
}
Пример #17
0
void checkFieldEffects( UI32 currenttime, P_CHAR pc, char timecheck )
{

	VALIDATEPC(pc);

	if ( (timecheck && !(nextfieldeffecttime<=currenttime)) ) //changed by Luxor
		return;
#ifdef SPAR_NEW_WR_SYSTEM
	pItemVectorIt itemIt( pc->nearbyItems->begin() ), itemEnd( pc->nearbyItems->end() );

	for( ; itemIt != itemEnd; ++itemIt ) {

		P_ITEM pi= (*itemIt);
#else
	NxwItemWrapper si;
	si.fillItemsNearXYZ( pc->getPosition(), 2, false );
	for( si.rewind(); !si.isEmpty(); si++ )
	{
		P_ITEM pi=si.getItem();
#endif
		if(ISVALIDPI(pi) ) {

			if ( pi->getPosition().x == pc->getPosition().x && pi->getPosition().y == pc->getPosition().y )

				//Luxor: added new field damage handling
				switch( pi->getId() )
				{
					case 0x3996:
					case 0x398C: //Fire Field
						if (!pc->resistsFire())
							tempfx::add(pc, pc, tempfx::FIELD_DAMAGE, (UI08)(pi->morex/100.0), DAMAGE_FIRE, 0, 0,1);
						return;
					case 0x3915:
					case 0x3920: //Poison Field
						if ((pi->morex<997)) {
							tempfx::add(pc, pc, tempfx::FIELD_DAMAGE, 2, DAMAGE_POISON, 0, 0,2);
							pc->applyPoison(POISON_WEAK);
						} else {
							tempfx::add(pc, pc, tempfx::FIELD_DAMAGE, 3, DAMAGE_POISON, 0, 0,2); // gm mages can cast greater poison field, LB
							pc->applyPoison(POISON_NORMAL);
						}
						return;
					case 0x3979:
					case 0x3967: //Para Field
						if (chance(50)) {
							tempfx::add(pc, pc, tempfx::SPELL_PARALYZE, 0, 0, 0, 0,3);
							pc->playSFX( 0x0204 );
						}
						return;
				}
		}
	}
}

void checktimers() // Check shutdown timers
{

	overflow = (lclock > uiCurrentTime);
	if (endtime)
	{
		if ( endtime <= uiCurrentTime ) keeprun=false;
	}
	lclock = uiCurrentTime;

}
Пример #18
0
void checkauto() // Check automatic/timer controlled stuff (Like fighting and regeneration)
{
//	static TIMERVAL checkspawnregions=0;
       	static TIMERVAL checktempfx=0;
	static TIMERVAL checknpcs=0;
	static TIMERVAL checktamednpcs=0;
	static TIMERVAL checknpcfollow=0;
	static TIMERVAL checkitemstime=0;
	static TIMERVAL lighttime=0;
	static TIMERVAL htmltime=0;
	static TIMERVAL housedecaytimer=0;

	LOGICAL lightChanged = false;

	//
	// Accounts
	//
	if (SrvParms->auto_a_reload > 0 && TIMEOUT( Accounts->lasttimecheck + (SrvParms->auto_a_reload*60*MY_CLOCKS_PER_SEC) ) )
		Accounts->CheckAccountFile();
	//
	// Weather (change is handled by crontab)
	//
	// Calendar
	//
	if ( TIMEOUT( uotickcount ) )
	{
		if (Calendar::advanceMinute())
			day++;
		uotickcount=uiCurrentTime+secondsperuominute*MY_CLOCKS_PER_SEC;
		if (Calendar::g_nMinute%8==0)
			moon1=(UI08)((moon1+1)%8);
		if (Calendar::g_nMinute%3==0)
			moon2=(UI08)((moon2+1)%8);
	}
	//
	// Light
	//
	if( TIMEOUT( lighttime ) )
	{
		UI08 lightLevel = worldcurlevel;

		SI32 timenow = (Calendar::g_nHour * 60) + Calendar::g_nMinute;
		SI32 dawntime = (Calendar::g_nCurDawnHour * 60) + Calendar::g_nCurDawnMin;
		SI32 sunsettime = (Calendar::g_nCurSunsetHour * 60) + Calendar::g_nCurSunsetMin;
		SI32 nighttime = qmin((sunsettime+120), (1439));
		SI32 morntime = qmax((dawntime-120), (0));
		SI32 const middaytime = 750;
//		SI32 const midnighttime = 0; // unused variable
		UI08 dawnlight = (UI08)((((worlddarklevel - worldbrightlevel))/3) + worldbrightlevel);
		//
		// default lights at dawn and sunset
		//
		if ( timenow == dawntime || timenow==sunsettime )
			lightLevel = dawnlight;
		//
		// highest light at midday
		//
		else if( timenow == middaytime )
			lightLevel = (UI08) qmax(worldbrightlevel-1, 0);
		//
		// darkest light during night
		//
		else if( timenow >= nighttime )
			lightLevel = worlddarklevel;
		//
		else if( timenow <= morntime )
			lightLevel = worlddarklevel;
		//
		// fading light slight before dawn
		//
		else if( timenow > morntime && timenow < dawntime )
			lightLevel = (UI08)linInterpolation(morntime, worlddarklevel, dawntime, dawnlight, timenow);
		//
		// fading light slight from dawn to midday
		else if( timenow > dawntime &&  timenow < middaytime )
			lightLevel = (UI08)linInterpolation(dawntime, dawnlight, middaytime, worldbrightlevel, timenow);
		//
		// fading light slight from midday to sunset
		//
		else if( timenow > middaytime && timenow < sunsettime )
			lightLevel = (UI08)linInterpolation(middaytime, worldbrightlevel, sunsettime, dawnlight, timenow);
		//
		// fading light slight from sunset to night
		//
		else if( timenow > sunsettime && timenow < nighttime )
			lightLevel = (UI08)linInterpolation(sunsettime, dawnlight, nighttime, worlddarklevel, timenow);

		if (wtype)
			lightLevel += 2;
		if (moon1+moon2<4)
			++lightLevel;
		if (moon1+moon2<10)
			++lightLevel;

		if (lightLevel != worldcurlevel)
		{
			worldcurlevel = lightLevel;
			lightChanged  = true;
		}
		lighttime=uiCurrentTime+secondsperuominute*5*MY_CLOCKS_PER_SEC;
	}

	//
	//	Housedecay and stabling
	//
	if ( TIMEOUT( housedecaytimer ) )
	{
		//////////////////////
		///// check_houses
		/////////////////////
		if( SrvParms->housedecay_secs != UINVALID )
			cHouses::check_house_decay();
		housedecaytimer = uiCurrentTime+MY_CLOCKS_PER_SEC*60*60; // check only each hour
	}
	//
	// Spawns
	//
	if( TIMEOUT( Spawns->check ) )
	{
		Spawns->doSpawn();
	}

	//
	// Shoprestock
	//
	Restocks->doRestock();

	//
	// Prison release
	//
	prison::checkForFree();

	//
	// Temporary effects
	//
	if( TIMEOUT( checktempfx ) )
		tempfx::checktempeffects();

	//
	// Characters & items
	//
	NxwSocketWrapper sw;
	sw.fillOnline();

	for( sw.rewind(); !sw.isEmpty(); sw++ )
	{
		NXWCLIENT ps = sw.getClient();
		if( ps == NULL )
			continue;

		P_CHAR pc=ps->currChar();
		if( !ISVALIDPC( pc ) )
			continue;

		if( lightChanged )
			dolight(ps->toInt(),worldcurlevel);

		pc->heartbeat();

		if( TIMEOUT( checknpcs ) || TIMEOUT( checktamednpcs ) || TIMEOUT( checknpcfollow ) )
		{
#ifdef SPAR_C_LOCATION_MAP
			PCHAR_VECTOR *pCV = pointers::getNearbyChars( pc, VISRANGE, pointers::NPC );
			PCHAR_VECTOR it( pCV->begin() ), end( pCV->end() );
			P_CHAR pNpc = 0;
			while( it != end )
			{
				pNpc = (*it);
				if( pNpc->lastNpcCheck != uiCurrentTime &&
				    (TIMEOUT( checknpcs ) ||
				    (TIMEOUT( checktamednpcs ) && pNpc->tamed) ||
				    (TIMEOUT( checknpcfollow ) && pNpc->npcWander == WANDER_FOLLOW ) ) )
				{
					pNpc->heartbeat();
					pNpc->lastNpcCheck = uiCurrentTime;
				}
				++it;
			}
#else
			NxwCharWrapper sc;
			sc.fillCharsNearXYZ( pc->getPosition(), VISRANGE, true, false );
			for( sc.rewind(); !sc.isEmpty(); sc++ )
			{
				P_CHAR npc=sc.getChar();

				if(!ISVALIDPC(npc) || !npc->npc )
					continue;

				if( npc->lastNpcCheck != uiCurrentTime &&
				    (TIMEOUT( checknpcs ) ||
				    (TIMEOUT( checktamednpcs ) && npc->tamed) ||
				    (TIMEOUT( checknpcfollow ) && npc->npcWander == WANDER_FOLLOW ) ) )
				{
					npc->heartbeat();
					npc->lastNpcCheck = uiCurrentTime;
				}
			}
#endif
		}

		if( TIMEOUT( checkitemstime ) )
		{
			NxwItemWrapper si;
			si.fillItemsNearXYZ( pc->getPosition(), 2*VISRANGE, false );
			for( si.rewind(); !si.isEmpty(); si++ )
			{
				P_ITEM pi=si.getItem();

				if( !ISVALIDPI( pi ) )
					continue;

				pi->doDecay();

				switch( pi->type )
				{
					case  51	:
					case  52	:
						//if( TIMEOUT( pi->gatetime ) )
							//for (int k=0;k<2;++k)	Sparhawk what's this???? Let's comment it out for now
							//	pi->deleteItem(); // bugfix for items disappearing
							//pi->deleteItem();
						break;
					case  61    :
					case  62	:
					case  63	:
					case  64	:
					case  65	:
					case  69	:
					case 125	:
						break; //SPAWNERS may not decay!!! --> Sparhawk then don't use the decay tag in the script
					case  88	:
						if( pi->morey >= 0 && pi->morey < 25 )
							if (pc->distFrom(pi)<=pi->morey)
								if( (UI32)RandomNum(1,100) <= pi->morez )
									soundeffect4(ps->toInt(), pi, (UI16)pi->morex);
						break;
				}
			}
		}
		// Check boats extra, or else they will only be updated every CHECK_ITEMS time
		std::map<int,P_BOAT>::iterator iter_boat;
		for ( iter_boat= s_boat.begin();iter_boat != s_boat.end();iter_boat++)
		{
			P_BOAT boat=iter_boat->second;
			P_ITEM pi=boat->getShipLink();
			if( pi->type2 == 1 || pi->type2 == 2 )
				if( TIMEOUT( pi->gatetime ) )
				{
					if (pi->type2==1)
						Boats->Move(ps->toInt(),pi->dir,pi);
					else
					{
						int dir=pi->dir+4;
						dir%=8;
						Boats->Move(ps->toInt(),dir,pi);
					}
					pi->gatetime=(TIMERVAL)(uiCurrentTime + (R64)(SrvParms->boatspeed*MY_CLOCKS_PER_SEC));

				}
		}
	}//for i<now


	if( TIMEOUT( checkitemstime ) )
		checkitemstime = (TIMERVAL)((R64) uiCurrentTime+(speed.itemtime*MY_CLOCKS_PER_SEC));
	if( TIMEOUT( checknpcs ) )
		checknpcs = (TIMERVAL)((R64) uiCurrentTime+(speed.npctime*MY_CLOCKS_PER_SEC));
	if( TIMEOUT( checktamednpcs ) )
		checktamednpcs=(TIMERVAL)((R64) uiCurrentTime+(speed.tamednpctime*MY_CLOCKS_PER_SEC));
	if( TIMEOUT( checknpcfollow ) )
		checknpcfollow=(TIMERVAL)((R64) uiCurrentTime+(speed.npcfollowtime*MY_CLOCKS_PER_SEC));
	//
	// Html
	//
	if(SrvParms->html>0 && (htmltime<=uiCurrentTime ))
	{
		updatehtml();
		htmltime=uiCurrentTime+(SrvParms->html*MY_CLOCKS_PER_SEC);
	}
	//
	// Finish
	//
	if ( TIMEOUT( nextfieldeffecttime ) )
		nextfieldeffecttime = (TIMERVAL)((R64) uiCurrentTime + (0.5*MY_CLOCKS_PER_SEC));
	if ( TIMEOUT( nextdecaytime ) )
		nextdecaytime = uiCurrentTime + (15*MY_CLOCKS_PER_SEC);
        if( TIMEOUT( checktempfx ) )
		checktempfx = (TIMERVAL)((R64) uiCurrentTime+(0.5*MY_CLOCKS_PER_SEC));
}
Пример #19
0
/*!
\brief Get an item
\author Unknow, revamped by Endymion
\param client the client
*/
void get_item( NXWCLIENT client ) // Client grabs an item
{
	if ( client == NULL)
		return;

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

	NXWSOCKET s = client->toInt();

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

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

	pc_currchar->disturbMed(); // Meditation

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

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


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

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

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

	if ( ISVALIDPI( container ) )
	{

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

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


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

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

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

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

			container->SetMultiSerial(INVALID);

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

		} // end cont valid
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

				pi->amount = amount;

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

	int amt = 0, wgt;
	if ( container == NULL )
	{
		wgt = (int)weights::LockeddownWeight( pi, &amt);
		pc_currchar->weight += wgt;
		statwindow(pc_currchar, pc_currchar);
	}
}
Пример #20
0
void dump_item(NXWCLIENT ps, PKGx08 *pp) // Item is dropped on ground or a character
{
	if (ps == NULL) return;

	tile_st tile;
	NXWSOCKET  s=ps->toInt();

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

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


	if (!ISVALIDPI(pi))
	{
		LogError("client sent bad itemserial %d",pp->Iserial);
		return;
	}

	if ( isCharSerial(pi->getContSerial()) && pi->getContSerial() != pc->getSerial32() ) {
		P_CHAR pc_i = pointers::findCharBySerial(pi->getContSerial());
		if (ISVALIDPC(pc_i))
			pc_i->sysmsg("Warning, backpack disappearing bug located!");

		if (ps->isDragging()) {
                        ps->resetDragging();
                        UpdateStatusWindow(s,pi);
                }
		pi->setContSerial( pi->getContSerial(true) );
                pi->setPosition( pi->getOldPosition() );
                pi->layer = pi->oldlayer;
                pi->Refresh();
	}

	if (pi->magic == 2) { //Luxor -- not movable objects
		if (ps->isDragging()) {
                        ps->resetDragging();
                        UpdateStatusWindow(s,pi);
                }
		pi->setContSerial( pi->getContSerial(true) );
		pi->MoveTo( pi->getOldPosition() );
		pi->layer = pi->oldlayer;
		pi->Refresh();
		return;
	}




    if(pi!=NULL)
	{
		weights::NewCalc(pc);
		statwindow(pc,pc);
	}


	//Ripper...so order/chaos shields disappear when on ground.
	if( pi->getId()==0x1BC3 || pi->getId()==0x1BC4 )
	{
		pc->playSFX( 0x01FE);
		staticeffect(DEREF_P_CHAR(pc), 0x37, 0x2A, 0x09, 0x06);
		pi->Delete();
		return;
	}


	//test UOP blocking Tauriel 1-12-99
	if (!pi->isInWorld())
	{
		item_bounce6(ps,pi);
		return;
	}




	data::seekTile(pi->getId(), tile);
	if (!pc->IsGM() && ((pi->magic==2 || (tile.weight==255 && pi->magic!=1))&&!pc->canAllMove()) ||
		( (pi->magic==3 || pi->magic==4) && !(pi->getOwnerSerial32()==pc->getSerial32())))
	{
		item_bounce6(ps,pi);
		return;
	}

	if (buffer[s][5]!=(unsigned char)'\xFF')
	{


		if (pi->amxevents[EVENT_IDROPINLAND]!=NULL) 
		{
			g_bByPass = false;
			pi->MoveTo(pp->TxLoc,pp->TyLoc,pp->TzLoc);
			pi->amxevents[EVENT_IDROPINLAND]->Call( pi->getSerial32(), pc->getSerial32() );
			if (g_bByPass) {
				pi->Refresh();
				return;
			}
		}

		/*
		//<Luxor>
		g_bByPass = false;
		pi->runAmxEvent( EVENT_IDROPINLAND, pi->getSerial32(), pc->getSerial32() );
	        if (g_bByPass) {
			pi->Refresh();
			return;
		}
        //</Luxor>
		*/
		NxwSocketWrapper sw;
		sw.fillOnline( pi );
		for( sw.rewind(); !sw.isEmpty(); sw++ )
		{
			SendDeleteObjectPkt( sw.getSocket(), pi->getSerial32() );
		}

		pi->MoveTo(pp->TxLoc,pp->TyLoc,pp->TzLoc);
		pi->setContSerial(-1);

		P_ITEM p_boat = Boats->GetBoat(pi->getPosition());

		if(ISVALIDPI(p_boat))
		{
			pi->SetMultiSerial(p_boat->getSerial32());
		}


		pi->Refresh();
	}
	else
	{
		if ( !ItemDroppedOnChar(ps, pp, pi) ) {
			//<Luxor>: Line of sight check
			//This part avoids the circle of transparency walls bug

			//-----
			if ( !lineOfSight( pc->getPosition(), Loc( pp->TxLoc, pp->TyLoc, pp->TzLoc ) ) ) {
		                ps->sysmsg(TRANSLATE("You cannot place an item there!"));

        	        	Sndbounce5(s);
	                	if (ps->isDragging()) {
	                        	ps->resetDragging();
                        		UpdateStatusWindow(s,pi);
                		}
                		pi->setContSerial( pi->getContSerial(true) );
                		pi->setPosition( pi->getOldPosition() );
                		pi->layer = pi->oldlayer;
                		pi->Refresh();
                		return;
        		}
        		//</Luxor>

	        	//<Luxor> Items count check
	        	if (!pc->IsGM()) {
				NxwItemWrapper si;
				si.fillItemsAtXY( pp->TxLoc, pp->TyLoc );
				if (si.size() >= 2) { //Only 2 items permitted
					ps->sysmsg(TRANSLATE("There is not enough space there!"));
					Sndbounce5(s);
					if (ps->isDragging()) {
						ps->resetDragging();
						UpdateStatusWindow(s,pi);
					}
					if (ISVALIDPI(pc->getBackpack())) {
						pi->setCont(pc->getBackpack());
						pi->SetRandPosInCont(pc->getBackpack());
					} else {
						pi->setContSerial( pi->getContSerial(true) );
						pi->setPosition( pi->getOldPosition() );
					}
					pi->layer = pi->oldlayer;
					pi->Refresh();
					return;
				}
			}
        		//</Luxor>
		}

		weights::NewCalc(pc);  // Ison 2-20-99
		statwindow(pc,pc);
		pc->playSFX( itemsfx(pi->getId()) );

		//Boats !
		if (pc->getMultiSerial32() > 0) //How can they put an item in a multi if they aren't in one themselves Cut lag by not checking everytime something is put down
		{
			P_ITEM multi = pointers::findItemBySerial( pc->getMultiSerial32() );
			if (ISVALIDPI(multi))
			{
					//setserial(DEREF_P_ITEM(pi),DEREF_P_ITEM(multi),7);
					pi->SetMultiSerial(multi->getSerial32());
			}
		}
		//End Boats
	}
}
Пример #21
0
static bool ItemDroppedOnChar(NXWCLIENT ps, PKGx08 *pp, P_ITEM pi)
{
	if (ps == NULL) return true;
	VALIDATEPIR(pi, false);
	NXWSOCKET  s = ps->toInt();
//	CHARACTER cc=ps->currCharIdx();
	P_CHAR pTC = pointers::findCharBySerial(pp->Tserial);	// the targeted character
	VALIDATEPCR(pTC, false);
	P_CHAR pc_currchar = ps->currChar(); //MAKE_CHAR_REF(cc);
	VALIDATEPCR(pc_currchar, false);
	Location charpos = pc_currchar->getPosition();

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

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

	bool resetDragging = false;

	if( (pi->getId()>>8) >= 0x40)  // LB, client crashfix if multi-objects are moved to PD
		resetDragging = true;

	tile_st tile;
	int serial/*, letsbounce=0*/; // AntiChrist (5) - new ITEMHAND system

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

	if( ( clientDimension[s]==3 ) &&  (tile.quality==0) )
	{
		ps->sysmsg(TRANSLATE("You can't wear that"));
		resetDragging = true;
	}
	else {
		P_ITEM outmost = pi->getOutMostCont();
		P_CHAR vendor = pointers::findCharBySerial( outmost->getContSerial() );
		if( ISVALIDPC( vendor ) && ( vendor->getOwnerSerial32() != pc->getSerial32() ) )
		{
			resetDragging = true;
		}

	}

	if( resetDragging ) {
		Sndbounce5(s);
		if (ps->isDragging())
		{
			ps->resetDragging();
			item_bounce4(s,pi);
			UpdateStatusWindow(s,pi);
		}
		return;
	}

	if ( pck->getSerial32() == pc->getSerial32() || pc->IsGM() )
	{

		if ( !pc->IsGM() && pi->st > pck->getStrength() && !pi->isNewbie() ) // now you can equip anything if it's newbie
		{
			ps->sysmsg(TRANSLATE("You are not strong enough to use that."));
			resetDragging = true;
		}
		else if ( !pc->IsGM() && !checkItemUsability(pc, pi, ITEM_USE_WEAR) )
		{
			resetDragging = true;
		}
		else if ( (pc->getId() == BODY_MALE) && ( pi->getId()==0x1c00 || pi->getId()==0x1c02 || pi->getId()==0x1c04 || pi->getId()==0x1c06 || pi->getId()==0x1c08 || pi->getId()==0x1c0a || pi->getId()==0x1c0c ) ) // Ripper...so males cant wear female armor
		{
			ps->sysmsg(TRANSLATE("You cant wear female armor!"));
			resetDragging = true;
		}
		else if ((((pi->magic==2)||((tile.weight==255)&&(pi->magic!=1))) && !pc->canAllMove()) ||
				( (pi->magic==3|| pi->magic==4) && !(pi->getOwnerSerial32()==pc->getSerial32())))
		{
			resetDragging = true;
		}

		if( resetDragging ) {
			Sndbounce5(s);
			if (ps->isDragging())
			{
				ps->resetDragging();
				item_bounce4(s,pi);
				UpdateStatusWindow(s,pi);
			}
			return;
		}



		// - AntiChrist (4) - checks for new ITEMHAND system
		// - now you can't equip 2 hnd weapons with 1hnd weapons nor shields!!
		serial= pck->getSerial32(); //xan -> k not cc :)

		P_ITEM pj = NULL;
 		P_CHAR pc_currchar= pck;
// 		P_ITEM pack= pc_currchar->getBackpack();
                //<Luxor>

		P_ITEM pW = pc_currchar->getWeapon();
		if (tile.quality == 1 || tile.quality == 2)
		{ //weapons layers
			if ( (pi->layer == LAYER_2HANDWEAPON && ISVALIDPI(pc_currchar->getShield())) )
			{
				ps->sysmsg(TRANSLATE("You cannot wear two weapons."));
				Sndbounce5(s);
				if (ps->isDragging())
				{
        			ps->resetDragging();
					UpdateStatusWindow(s,pi);
	        	}
				pi->setContSerial( pi->getContSerial(true) );
				pi->setPosition( pi->getOldPosition() );
				pi->layer = pi->oldlayer;
				pi->Refresh();
				return;
			}
			if (ISVALIDPI(pW))
			{
				if (pi->itmhand != 3 && pi->lodamage != 0 && pi->itmhand == pW->itmhand)
				{
					ps->sysmsg(TRANSLATE("You cannot wear two weapons."));
					Sndbounce5(s);
					if (ps->isDragging())
					{
						ps->resetDragging();
						UpdateStatusWindow(s,pi);
					}
					pi->setContSerial( pi->getContSerial(true) );
					pi->setPosition( pi->getOldPosition() );
					pi->layer = pi->oldlayer;
					pi->Refresh();
					return;
				}
			}
		}
		//</Luxor>

		int drop[2]= {-1, -1};	// list of items to drop
								// there no reason for it to be larger
		int curindex= 0;

		NxwItemWrapper si;
		si.fillItemWeared( pc_currchar, false, true, true );
		for( si.rewind(); !si.isEmpty(); si++ )
		{
			// we CANNOT directly bounce the item, or the containersearch() function will not work
			// so we store the item ID in letsbounce, and at the end we bounce the item

			pj=si.getItem();
			if(!ISVALIDPI(pj))
				continue;

			if ((tile.quality == 1) || (tile.quality == 2))// weapons
			{
				if (pi->itmhand == 2) // two handed weapons or shield
				{
					if (pj->itmhand == 2)
						drop[curindex++]= DEREF_P_ITEM(pj);

					if ( (pj->itmhand == 1) || (pj->itmhand == 3) )
						drop[curindex++]= DEREF_P_ITEM(pj);
				}

				if (pi->itmhand == 3)
				{
					if ((pj->itmhand == 2) || pj->itmhand == 3)
						drop[curindex++]= DEREF_P_ITEM(pj);
				}

				if ((pi->itmhand == 1) && ((pj->itmhand == 2) || (pj->itmhand == 1)))
					drop[curindex++]= DEREF_P_ITEM(pj);
			}
			else	// not a weapon
			{
				if (pj->layer == tile.quality)
					drop[curindex++]= DEREF_P_ITEM(pj);
			}
		}

		if (ServerScp::g_nUnequipOnReequip)
		{
			if (drop[0] > -1)	// there is at least one item to drop
			{
				for (int i= 0; i< 2; i++)
				{
					if (drop[i] > -1)
					{
						P_ITEM p_drop=MAKE_ITEM_REF(drop[i]);
						if(ISVALIDPI(p_drop))
							pc_currchar->UnEquip( p_drop, 0);
					}
				}
			}
			pc->playSFX( itemsfx(pi->getId()) );
			// pc_currchar->Equip(pi, 1); // Item is equipped twice ????
		}
		else
		{
			if (drop[0] == -1)
			{
				pc->playSFX( itemsfx(pi->getId()) );
				// pc_currchar->Equip(pi, 1);// Item is equipped twice ????
			}
			else
			{
				ps->sysmsg("You cannot wear two weapons.");
				Sndbounce5(s);
				if (ps->isDragging())
				{
					ps->resetDragging();
					UpdateStatusWindow(s,pi);
				}
				pi->setContSerial( pi->getContSerial(true) );
				pi->setPosition( pi->getOldPosition() );
				pi->layer = pi->oldlayer;
				pi->Refresh();
				return;
			}
		}

		if (!(pc->IsGM())) //Ripper..players cant equip items on other players or npc`s paperdolls.
		{
			if ((pck->getSerial32() != pc->getSerial32())/*&&(chars[s].npc!=k)*/) //-> really don't understand this! :|, xan
			{
				ps->sysmsg(TRANSLATE("You can't put items on other people!"));
				item_bounce6(ps,pi);
				return;
			}
		}

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

		pi->layer=buffer[s][5];
		pi->setContSerial(LongFromCharPtr(buffer[s] +6));

		if (g_nShowLayers) InfoOut("Item equipped on layer %i.\n",pi->layer);

		wearIt(s,pi);

		NxwSocketWrapper sw;
		sw.fillOnline( pck, false );
		for( sw.rewind(); !sw.isEmpty(); sw++ )
		{
			NXWSOCKET j=sw.getSocket();
			if( j!=INVALID )
				wornitems(j, pck );
		}

		pc->playSFX( itemsfx(pi->getId()) );
		weights::NewCalc(pc);	// Ison 2-20-99
		statwindow(pc_currchar,pc_currchar);

//		if (pi->glow>0)
//		{
//			pc->removeHalo(pi); // if gm equips on differnt player it needs to be deleted out of the hashteble
//			pck->addHalo(pi);
//			pck->glowHalo(pi);
//		}

		if ( pck->Equip(pi, 1) == 2)	// bypass called
		{
			P_ITEM pack = pck->getBackpack();
			pc->playSFX( itemsfx(pi->getId()) );
			pi->layer= 0;
			pi->setContSerial( pack->getSerial32() );
			sendbpitem(s, pi);
			return;
		}

	}
}
Пример #23
0
/*!
\author Luxor
\brief execute decay on the item
\return true if decayed (so deleted), false else
*/
LOGICAL cItem::doDecay()
{
	if ( !canDecay() )
		return false;

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

	if ( !isInWorld() )
		return false;

	if ( TIMEOUT( decaytime ) )
	{


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

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

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