コード例 #1
0
ファイル: pointer.cpp プロジェクト: nox-wizard/noxwizard
/*!
\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;
    }
}
コード例 #2
0
/*!
\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?"));
	}
コード例 #3
0
void wear_item(P_CLIENT ps) // Item is dropped on paperdoll
{
	int j, k;
	tile_st tile;
	int serial, serhash, ci, i2, letsbounce=0; // AntiChrist (5) - new ITEMHAND system
	UOXSOCKET s=ps->GetSocket();
	int cc=ps->GetCurrChar();
	P_CHAR pc_currchar = MAKE_CHARREF_LR(cc);

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

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

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

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

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

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

		for (j=0;j<now;j++)
		{
			if (perm[j] && inrange1p(k, currchar[j]) && (j!=s))//and to all inrange sockets (without re-sending to current socket)//AntiChrist
				wornitems(j, k);
		}
		
		itemsfx(s, pi->id());	// Dupois - see itemsfx() for details	// Added Oct 09, 1998
		Weight->NewCalc(cc);	// Ison 2-20-99
		statwindow(s,cc);
		
		if (pi->glow>0)
		{
			pc_currchar->removeHalo(pi); // if gm equips on differnt player it needs to be deleted out of the hashteble
			chars[k].addHalo(pi);
			chars[k].glowHalo(pi);
		}
    }
}
コード例 #4
0
void get_item(P_CLIENT ps) // Client grabs an item
{
	int x,  npc=-1, c, amount, update = 0, serial;
//	tile_st tile;
	int z;// antichrist for trade fix
	UOXSOCKET s = ps->GetSocket();
	int cc = ps->GetCurrChar();
	P_CHAR pc_currchar = MAKE_CHARREF_LR(cc);
	
	
	serial = calcserial(buffer[s][1], buffer[s][2], buffer[s][3], buffer[s][4]);
	if (serial == INVALID_SERIAL || buffer[s][1] < 0x40)
		return;	// landscape or a character
	P_ITEM pi = FindItemBySerial(serial);
	if (pi == NULL)
		return;
	
	pc_currchar->disturbMed(s); // Meditation
	
	// Zippy's stealing changes  
	x = DEREF_P_ITEM(pi);
	if (!items[x].isInWorld())  // Find character owning item
	{
		int loopexit = 0;
		do  // Find character owning item
		{
			if (isCharSerial(items[x].contserial))
			{
				npc = calcCharFromSer(items[x].contserial);
			}
			else  // its an item
			{
				if (items[x].isInWorld())
				{
					npc=-1;
					break;
				}
				x = calcItemFromSer(items[x].contserial);
				// ANTICHRIST -- SECURE TRADE FIX
				if (x!=-1) // LB overwriting x is essential here, dont change it!!!
				{
					if (items[x].layer == 0 && items[x].id() == 0x1E5E)
					{
						// Trade window???
						serial = calcserial(items[x].moreb1, items[x].moreb2, items[x].moreb3, items[x].moreb4);
						if (serial == INVALID_SERIAL)
							return;
						z = calcItemFromSer(serial);
						if (z!=-1)
							if ((items[z].morez || items[x].morez))
							{
								items[z].morez = 0;
								items[x].morez = 0;
								sendtradestatus(z, x);
							}
					}
					// Blackwinds Looting is crime implementation
					// changed slightly by Ripper
					if (items[x].corpse != 0 && !pc_currchar->Owns(&items[x])) 
					{ 
						P_CHAR co = FindCharBySerial(items[x].ownserial);
						if (items[x].more2 == 1 && Guilds->Compare(cc, DEREF_P_CHAR(co)) == 0) 
						{ 
							pc_currchar->karma -= 5; 
							criminal(cc);
							sysmessage(s, "You lost some karma!"); 
						} 
						npc = 0;
					} // Criminal stuff
					if (items[x].corpse != 0)
						npc = 0;
				} // end if x!=-1
				
				if (x==-1)
					npc = 0; 
			}
		} while ((npc==-1) &&(++loopexit < MAXLOOPS));
	}
	
	if (npc>0) // 0=corpse, hence >0 ..
	{
		if (!(pc_currchar->isGM()) && npc != cc && ! pc_currchar->Owns(&chars[npc]))
		{// Own serial stuff by Zippy -^ Pack aniamls and vendors.
			bounce[1] = 0;
			Xsend(s, bounce, 2);
			if (ps->IsDragging())
			{
				ps->ResetDragging();
				item_bounce3(pi);
				pi->magic = 3;
			} 
			return;
		}
	}
	// End Zippy's change
	
	// Boats->
	if (x!=-1 && npc!=-1)
	{
		if (items[x].multis>0)
			imultisp.remove(items[x].multis, items[x].serial);
		items[x].startDecay();
		// End Boats Change
		
		// AntiChrist -- for poisoned items
		if (items[x].layer>0)
		{
			chars[npc].removeItemBonus(&items[x]);	// remove BONUS STATS given by equipped special items
		}
		if ((items[x].trigon==1) && (items[x].layer != 0) && (items[x].layer != 15) && (items[x].layer < 19))// -Frazurbluu- Trigger Type 2 is my new trigger type *-
		{
			triggerwitem(s, DEREF_P_ITEM(pi), 1); // trigger is fired
		}	
			// AntiChrist -- for poisoned items
		if (items[x].poisoned)
		{
			chars[npc].poison -= items[x].poisoned;
			if (chars[npc].poison < 0)
				chars[npc].poison = 0;
		}
	}
	if (pi != NULL)
	{
		if (pi->corpse != 1)
		{
			UpdateStatusWindow(s, pi);
			if (!pc_currchar->canPickUp(pi))
			{
				bounce[1] = 0;
				Xsend(s, bounce, 2);
				if (ps->IsDragging()) // only restore item if it got draggged before !!!
				{
					ps->ResetDragging();
					item_bounce4(s, pi);
				}
			}
			else
			{
				// AntiChrist bugfix for the bad bouncing bug ( disappearing items when bouncing )
				DRAGGED[s] = 1;
				
				pi->oldx = pi->pos.x;	// first let's save the position
				pi->oldy = pi->pos.y;
				pi->oldz = pi->pos.z;
				pi->oldcontserial = pi->contserial;	// then let's save the container
				pi->oldlayer = pi->layer;	// then the layer
				
				pi->layer = 0;
				if (!pi->isInWorld())
					soundeffect(s, 0x00, 0x57);
				if (pi->amount>1)
				{
					amount = (buffer[s][5] << 8) + buffer[s][6];
					if (amount>pi->amount)
						amount = pi->amount;
					if (amount < pi->amount)
					{
						c=Items->MemItemFree();
						items[c].Init(0);
						memcpy(&items[c], pi, sizeof(cItem));  // Tauriel reduce code faster too
						items[c].SetSerial(itemcount2);
						itemcount2++;

						items[c].amount = pi->amount - amount;
						// Tauriel sorry, there is no way to make this call the item creation stuff
// Why doing it twice?
//						setptr(&itemsp[itemcount2%HASHMAX], c);
//						itemcount2++; // important bugfix for items disappearing, lb
						if (!items[c].isInWorld())
							contsp.insert(items[c].contserial, items[c].serial);
						if (items[c].ownserial!=-1)
							setptr(&ownsp[items[c].ownserial%HASHMAX], c);
						if (items[c].spawnserial!=-1)
							setptr(&spawnsp[items[c].spawnserial%HASHMAX], c);
						
						statwindow(s,cc);
						RefreshItem(c);//AntiChrist
					}
					
					if (pi->id() == 0x0EED) // gold coin
					{
						int packnum = packitem(currchar[s]);
						if (packnum!=-1) // lb
							if (pi->contserial == items[packnum].serial)
								update = 1;
					}
					
					pi->amount = amount;
				}
				
				// Tauriel remove item from world mapcells
				mapRegions->Remove(pi); // remove this item from a map cell
				pi->pos.x = 0;
				pi->pos.y = 0;
				pi->pos.z = 0;
				
				pi->flags.isBeeingDragged=true;
				pi->SetContSerial(-1);
				if (pi != NULL) // Ripper...adds weight to the players cursor when carrying a item.
				{
					int amt = 0, wgt;
					wgt = (int)Weight->LockeddownWeight(pi, &amt, 0);
					pc_currchar->weight += wgt;
					update = 1;
				}
			}
		}
	} // end of if i!=-1
	if (update)
		statwindow(s, DEREF_P_CHAR(pc_currchar));
}
コード例 #5
0
ファイル: dragdrop.cpp プロジェクト: nox-wizard/noxwizard
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;
		}

	}
}
コード例 #6
0
ファイル: dragdrop.cpp プロジェクト: nox-wizard/noxwizard
void pack_item(NXWCLIENT ps, PKGx08 *pp) // Item is put into container
{
	if (ps == NULL) return;

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

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

	Location charpos= pc->getPosition();

	P_ITEM pack;

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

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

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

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

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

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

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

		P_ITEM pi_z = pointers::findItemBySerial(serial);

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

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

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

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

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

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

		}
	}


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

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

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

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

				P_ITEM pi_ci=sii.getItem();

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

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

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

	if (pCont->type == ITYPE_CONTAINER) {

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

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

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

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

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

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

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

				pItem->Refresh();
			}


}
コード例 #7
0
void cTmpEff::Expire()
{
	int mortar,k,ccc;

	int s=calcCharFromSer(getDest());
	if (   num != 9		// grinding
		&& num != 10	// create potion
		&& num != 13	// door close
		&& num != 14	// training dummy
		&& num != 17)	// explosion
	{
		//Added by TANiS to fix errors, memory corruption and door auto-close 10-6-98
		// Check to see if it's a dead char and delete the wrong effect, or if it's just
		// a door auto-close effect and process it the right way.
		if ( s < 0 || s >= cmem )
		{
			return;		// just remove this effect
		} //End of TANiS' change
	}
//	P_CHAR pc_s = MAKE_CHARREF_LR(s);	// enabling this reveals a nasty bug I have not found yet: some effects will not work (Duke,13.8.01)
	P_CHAR pc_s = MAKE_CHAR_REF(s);
	switch(num)
	{
	case 1:
		if (pc_s->priv2&0x02)
		{
			pc_s->priv2 &= 0xFD;
			int sk=calcSocketFromChar(s);
			if (sk!=-1) sysmessage(sk, "You are no longer frozen.");
			Magic->afterParticles(38, s); 			
		}
		break;
	case 2:
		pc_s->fixedlight='\xFF';
		dolight(calcSocketFromChar(s), worldbrightlevel);
		break;
	case 3:
		pc_s->chgDex(more1);
		statwindow(calcSocketFromChar(s), s);
		break;
	case 4:
		pc_s->in+=more1;
		statwindow(calcSocketFromChar(s), s);
		break;
	case 5:
		pc_s->st+=more1;
		statwindow(calcSocketFromChar(s), s);
		break;
	case 6:
		pc_s->chgDex(-1 * more1);
		pc_s->stm=min(pc_s->stm, (int)pc_s->effDex());
		statwindow(calcSocketFromChar(s), s);
		break;
	case 7:
		pc_s->in-=more1;
		pc_s->mn=min(pc_s->mn, pc_s->in);
		statwindow(calcSocketFromChar(s), s);
		break;
	case 8:
		pc_s->st-=more1;
		pc_s->hp=min(pc_s->hp, pc_s->st);
		statwindow(calcSocketFromChar(s), s);
		break;
	case 9:
		if (more1 == 0)
		{
			if (more2!=0)
			{
				sprintf((char*)temp, "*%s continues grinding.*", pc_s->name);
				npcemoteall(s, (char*)temp,1);
			}
			soundeffect2(s, 0x02, 0x42);
		}
		break;
	case 10:
		s=calcCharFromSer(getSour());
		mortar=calcItemFromSer(getDest());
		if(mortar>-1) //AntiChrist - to prevent crashes
			Skills->CreatePotion(s, more1, more2, mortar);
		break;
	case 11:
		pc_s->st-=more1;
		pc_s->hp=min(pc_s->hp, pc_s->st);
		pc_s->chgDex(-1 * more2);
		pc_s->stm=min(pc_s->stm, (int)pc_s->effDex());
		pc_s->in-=more3;
		pc_s->mn=min(pc_s->mn, pc_s->in);
		statwindow(calcSocketFromChar(s), s);
		break;
	case 12:
		pc_s->st+=more1;
		pc_s->chgDex(more2);
		pc_s->in+=more3;
		statwindow(calcSocketFromChar(s), s);
		break;
	case 13:
		{
			P_ITEM pDoor = FindItemBySerial(getDest());// door
			if (pDoor)
			{
				if (pDoor->dooropen==0)
					break;
				pDoor->dooropen=0;
				dooruse(calcSocketFromChar(s), DEREF_P_ITEM(pDoor));
			}
			break;
		}
	case 14: //- training dummies Tauriel check to see if item moved or not before searching for it
		{
			P_ITEM pTrainDummy = FindItemBySerial(getDest());
			if (pTrainDummy)
			{
				if (pTrainDummy->id()==0x1071)
				{
					pTrainDummy->setId(0x1070);
					pTrainDummy->gatetime=0;
					RefreshItem(pTrainDummy);//AntiChrist
				}
				else if (pTrainDummy->id()==0x1075)
				{
					pTrainDummy->setId(0x1074);
					pTrainDummy->gatetime=0;
					RefreshItem(pTrainDummy);//AntiChrist
				}
			}
		}
		break;
	case 15: //reactive armor
		pc_s->ra=0;
		break;
	case 16: //Explosion potion messages	Tauriel
		sprintf((char*)temp, "%i", more3);
		sysmessage(calcSocketFromChar(s), (char*)temp); // crashfix, LB
		break;
	case 17: //Explosion potion explosion	Tauriel			
		s=calcCharFromSer(getSour());
		explodeitem(calcSocketFromChar(s), calcItemFromSer(getDest())); //explode this item
		break;
	case 18: //Polymorph spell by AntiChrist 9/99
		if(pc_s->polymorph)//let's ensure it's under polymorph effect!
		{
			pc_s->id1=pc_s->xid1;
			pc_s->id2=pc_s->xid2;
			pc_s->polymorph=false;
			teleport(s);
		}
		break;
	case 19: //Incognito spell by AntiChrist 12/99
		reverseIncognito(pc_s);
		break;
		
	case 20: // LSD potions, LB 5'th nov 1999
		k=calcSocketFromChar(s);
		if (k==-1) return;
		LSD[k]=0;
		sysmessage(k,"LSD has worn off");
		pc_s->stm=3; // stamina near 0
		pc_s->mn=3;
		pc_s->hp=pc_s->hp/7;
		impowncreate(k,s,0);
		all_items(k); // absolutely necassairy here !!!
		for (ccc =0; ccc<charcount; ccc++) // that hurts, but there's no other good way
		{
			if (chardist(s,ccc)<15 && ( online(ccc) || chars[ccc].isNpc() ) ) updatechar(ccc);
		}
		break;
		
	case 21:
		int toDrop;
		toDrop = more1; //Effect->more1;
		if( ( pc_s->baseskill[PARRYING] - toDrop ) < 0 )
			pc_s->baseskill[PARRYING] = 0;
		else
			pc_s->baseskill[PARRYING] -= toDrop;
		break;
		
	case 33: // delayed hiding for gms after flamestrike effect
		k=calcSocketFromChar(s);
		sysmessage(k,"You have hidden yourself well.");
		pc_s->hidden=1;
		updatechar(s);
		break;
		
	case 34: // delayed unhide for gms
		// Changed to be uniform with delayed hideing  (Aldur)
		k = calcSocketFromChar(s); 
		sysmessage(k, "You are now visible."); 
		pc_s->hidden = 0; 
		updatechar(s); 
		break;
		
	case 35: //heals some pf - solarin
		int iHp;
		iHp=(int)more1;
		pc_s->hp+=iHp;
		updatestats(s, 0);
		if (!more2)
			tempeffect(s,s,35,more1+1,1,more3,0);
		break;
		
	default:
		LogErrorVar("Fallout of switch (num = %i).", num);
		break;
	}
	Items->CheckEquipment(s); //AntiChrist - checks equipments for stats requirements
}