void cTmpEff::Off(P_CHAR pc)
{
	if (!pc)
		return;

	switch(this->num)
	{
	case 1:	pc->priv2 &= 0xFD;			break;
	case 2:	pc->fixedlight='\xFF';		break;
	case 3:	pc->chgDex(this->more1);	break;
	case 4:	pc->in+=this->more1;		break;
	case 5:	pc->st+=this->more1;		break;
	case 6:	pc->chgDex(-1 * this->more1);break;
	case 7:	pc->in-=this->more1;		break;
	case 8:	pc->st-=this->more1;		break;
	case 11:
		pc->st-=this->more1;
		pc->chgDex(-1 * this->more2);
		pc->in-=this->more3;
		break;
	case 12:
		pc->st+=this->more1;
		pc->chgDex(this->more2);
		pc->in+=this->more3;
		break;
	}
}
void cTmpEff::On(P_CHAR pc)
{
	if (!pc)
		return;
	
	switch(this->num)
	{
	case 1:	pc->priv2 |= 0x02;		break;
	case 2:	pc->fixedlight = SrvParams->worldBrightLevel();break;
	case 3:	pc->chgDex(-1 * this->more1);	break;
	case 4:	pc->in-=this->more1;		break;
	case 5:	pc->st-=this->more1;		break;
	case 6:	pc->chgDex(this->more1);	break;
	case 7:	pc->in+=this->more1;		break;
	case 8:	pc->st+=this->more1;		break;
	case 11:
		pc->st+=this->more1;
		pc->chgDex(this->more2);
		pc->in+=this->more3;
		break;
	case 12:
		pc->st-=this->more1;
		pc->chgDex(-1 * this->more2);
		pc->in-=this->more3;
		break;
	}
}
// Name:	item_bounce3
// Purpose:	holds some statements that were COPIED some 50 times
// Remarks:	temporary functions to revamp the 30 occurences of the 'bouncing bugfix'
// History:	init Duke, 10.8.2000
static void item_bounce3(const P_ITEM pi)
{
	pi->SetContSerial(pi->oldcontserial);
	pi->pos.x=pi->oldx;
	pi->pos.y=pi->oldy;
	pi->pos.z=pi->oldz;
	pi->layer=pi->oldlayer;
	pi->flags.isBeeingDragged=false;
	P_CHAR pc = FindCharBySerial(pi->oldcontserial);

	if (pi->layer > 0 && pc != NULL)
	{
		pc->st += pi->st2;
		pc->chgDex(pi->dx2);
		pc->in += pi->in;
	}
}
// Tries to equip an item
// if that fails it tries to put the item in the users backpack
// if *that* fails it puts it at the characters feet
// That works for NPCs as well
void equipItem( P_CHAR wearer, P_ITEM item )
{
	tile_st tile;

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

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

		item->toBackpack( wearer );
		return;
	}

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

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

		wearer->removeItemBonus( equip );
	}

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

	// Add the item bonuses
	wearer->st = (wearer->st + item->st2);
	wearer->chgDex( item->dx2 );
	wearer->in = (wearer->in + item->in2);
}
bool cAllTmpEff::Add(P_CHAR pc_source, P_CHAR pc_dest, int num, unsigned char more1, unsigned char more2, unsigned char more3, short dur)
{
    unsigned int ic; // antichrist' changes
    int color, color1, color2, socket; //used for incognito spell
    int	loopexit=0;

    if ( pc_source == NULL || pc_dest == NULL )
        return false;

    if (teffectcount>=cmem*5)
        return false;

    cTmpEff *pTE;
    for (ic=0; ic<teffectcount; ic++)	// If there is already an effect of the same or similar kind, reverse it first (Duke)
    {
        pTE = &teffects[ic];
        if (pTE->getDest() == pc_dest->serial)
        {
            if ((pTE->num==3 && num==3)||
                    (pTE->num==4 && num==4)||
                    (pTE->num==5 && num==5)||
                    (pTE->num==6 && num==6)||
                    (pTE->num==7 && num==7)||
                    (pTE->num==8 && num==8)||
                    (pTE->num==11&& num==11)||
                    (pTE->num==12&& num==12)||
                    (pTE->num==18&& num==18)|| //added Poly reverse - AntiChrist (9/99)
                    (pTE->num==21&& num==21)||
                    (pTE->num==19&& num==19)|| //added Incognito reverse - AntiChrist (12/99)
                    (pTE->num==18&& num==19)|| //reverse poly effect if we have to use incognito - AntiChrist (12/99)
                    (pTE->num==19&& num==18) )  //reverse incognito effect if we have to use poly - AntiChrist (12/99)
            {
                pTE->Reverse();
                AllTmpEff->Remove(pTE);
            }
        }
    }

    pTE=new cTmpEff;
    pTE->Init();
    pTE->setSour(pc_source->serial);
    pTE->setDest(pc_dest->serial);
    pTE->num=num;

    switch (num)
    {
    case 1:
        pc_dest->priv2 |= 0x02;
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/100);
        pTE->more1=0;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 2:	// night sight
        pc_dest->fixedlight=worldbrightlevel;
        dolight(calcSocketFromChar((pc_dest)), worldbrightlevel);
        Magic->afterParticles(6, pc_dest); // shows particles for UO:3D clients, like On OSI servers

        if(dur > 0)		// if a duration is given (potions), use that (Duke, 30.12.2000)
            pTE->setExpiretime_s(dur);
        else
            pTE->setExpiretime_s(pc_source->skill[MAGERY]*10);
        pTE->more1=0;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 3:
        if (pc_dest->effDex()<more1)
            more1=pc_dest->effDex();
        pc_dest->chgDex(-1 * more1);
        pc_dest->stm=min(pc_dest->stm, (int)pc_dest->effDex());
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 4:
        if (pc_dest->in<more1)
            more1=pc_dest->in;
        pc_dest->in-=more1;
        pc_dest->mn=min(pc_dest->mn, pc_dest->in);
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 5:
        if (pc_dest->st<more1)
            more1=pc_dest->st;
        pc_dest->st-=more1;
        pc_dest->hp=min(pc_dest->hp, pc_dest->st);
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 6:
        if (pc_dest->effDex()+more1>250)
            more1=250-pc_dest->effDex();
        pc_dest->chgDex(more1);
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        if(dur > 0)		// if a duration is given (potions), use that (Duke, 31.10.2000)
            pTE->setExpiretime_s(dur);
        else
            pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 7:
        if (pc_dest->in+more1>255)
            more1=pc_dest->in-255;
        pc_dest->in+=more1;
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 8:
        if (pc_dest->st+more1>255)
            more1=pc_dest->st-255;
        pc_dest->st+=more1;
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        if(dur > 0)		// if a duration is given (potions), use that (Duke, 31.10.2000)
            pTE->setExpiretime_s(dur);
        else			// else use caster's skill
            pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 9:
        pTE->setExpiretime_s(more2);
        pTE->more1=more1;
        pTE->more2=more2;
        break;
    case 10:
        pTE->setExpiretime_s(12);
        pTE->more1=more1;
        pTE->more2=more2;
        break;
    case 11: // Bless
        if (pc_dest->st+more1>255)
            more1=pc_dest->st-255;
        if (pc_dest->effDex()+more2>250)
            more2=250-pc_dest->effDex();
        if (pc_dest->in+more3>255)
            more3=pc_dest->in-255;
        pc_dest->st+=more1;
        pc_dest->chgDex(more2);
        pc_dest->in+=more3;
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=more2;
        pTE->more3=more3;
        pTE->dispellable=1;
        break;
    case 12: // Curse
        if (pc_dest->st<more1)
            more1=pc_dest->st;
        if (pc_dest->effDex()<more2)
            more2=pc_dest->effDex();
        if (pc_dest->in<more3)
            more3=pc_dest->in;
        pc_dest->st-=more1;
        pc_dest->chgDex(-1 * more2);
        pc_dest->in-=more3;
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=more2;
        pTE->more3=more3;
        pTE->dispellable=1;
        break;
    case 15: // Reactive armor
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->dispellable=1;
        break;
    case 16: //Explosion potions	Tauriel
        pTE->setExpiretime_s(more2);
        pTE->more1=more1; //item/potion
        pTE->more2=more2; //seconds
        pTE->more3=more3; //countdown#
        break;
    case 18: //Polymorph - AntiChrist 09/99
        pTE->setExpiretime_s(polyduration);

        int c1,b,k;
        //Grey flag when polymorphed - AntiChrist (9/99)
        pc_dest->crimflag=(polyduration*MY_CLOCKS_PER_SEC)+uiCurrentTime;
        if(pc_dest->onhorse)
            k = unmounthorse(calcSocketFromChar(pc_dest));
        k=(more1<<8)+more2;

        pc_dest->xid = pc_dest->id();//let's backup previous id

        if (k>=0x000 && k<=0x3e1) // lord binary, body-values >0x3e crash the client
        {
            pc_dest->id1=k>>8; // allow only non crashing ones
            pc_dest->id2=k%256;

            c1 = pc_dest->skin; // transparency for monsters allowed, not for players,
            // if polymorphing from monster to player we have to switch from transparent to semi-transparent
            b=c1&0x4000;
            if (b==16384 && (k >=0x0190 && k<=0x03e1))
            {
                if (c1!=0x8000)
                {
                    pc_dest->skin = pc_dest->xskin = 0xF000;
                }
            }
        }
        pc_dest->polymorph=true;
        break;
    case 19://incognito spell - AntiChrist (10/99)//revised by AntiChrist - 9/12/99
    {
        pTE->setExpiretime_s(90);

        //AntiChrist 11/11/99
        //If char is already under polymorph effect, let's reverse the
        //polymorph effect to avoid problems
        if(pc_dest->polymorph)
        {
            pc_dest->setId(pc_dest->xid);
            pc_dest->polymorph=false;
            teleport(pc_dest);
        }
        int j;

        //first: let's search for beard and hair serial
        //(we could use alredy saved serials...but it's better
        //to recalculate them)
        pc_dest->hairserial=-1;
        pc_dest->beardserial=-1;

        P_ITEM pi;
        unsigned int ci;
        vector<SERIAL> vecContainer = contsp.getData(pc_dest->serial);
        for ( ci = 0; ci < vecContainer.size(); ci++)
        {
            pi = FindItemBySerial(vecContainer[ci]);
            if(pi->layer==0x10)//beard
                pc_dest->beardserial=pi->serial;
            if(pi->layer==0x0B)//hairs
                pc_dest->hairserial=pi->serial;
        }
        // ------ SEX ------
        pc_dest->xid = pc_dest->id();
        pc_dest->id1=0x01;
        //if we already have a beard..can't turn to female
        if(pc_dest->beardserial>-1)
        {   //if character has a beard...only male
            pc_dest->id2='\x90';//male
        } else
        {   //if no beard let's randomly change
            if((rand()%2)==0) pc_dest->id2='\x90';//male
            else pc_dest->id2='\x91';//or female
        }

        // --- SKINCOLOR ---
        pc_dest->xskin = pc_dest->skin;
        color=rand()%6;
        switch(color)
        {
        case 0:
            pc_dest->skin = 0x83EA;
            break;
        case 1:
            pc_dest->skin = 0x8405;
            break;
        case 2:
            pc_dest->skin = 0x83EF;
            break;
        case 3:
            pc_dest->skin = 0x83F5;
            break;
        case 4:
            pc_dest->skin = 0x841C;
            break;
        case 5:
            pc_dest->skin = 0x83FB;
            break;
        default:
            break;
        }

        // ------ NAME -----
        pc_dest->orgname = pc_dest->name;

        if(pc_dest->id2==0x90)
            setrandomname(pc_dest, "1");//get a name from male list
        else
            setrandomname(pc_dest, "2");//get a name from female list

        //
        //damn..this formula seems to include also some bad color...
        //i'll test this later
        //AntiChrist
        //
        //use unique color for hair&beard
        //color=0x044E+(rand()%(0x04AD-0x044E));

        //i had to track down some valid value
        //for hair/beard colors, cause that
        //formula contained some bad value =(
        //but now it works perfectly :)
        //AntiChrist-11/11/99
        color=rand()%8;
        switch(color)
        {
        case 0:
            color=0x044e;
            break;
        case 1:
            color=0x0455;
            break;
        case 2:
            color=0x045e;
            break;
        case 3:
            color=0x0466;
            break;
        case 4:
            color=0x046a;
            break;
        case 5:
            color=0x0476;
            break;
        case 6:
            color=0x0473;
            break;
        case 7:
            color=0x047c;
            break;
        default://it should not go here...but..who nows =P
            color=0x044e;
        }
        color1=color>>8;
        color2=color%256;

        // ------ HAIR -----
        if(pc_dest->hairserial>-1)//if hairs exist
        {   //change hair style/color
            P_ITEM pHair = FindItemBySerial(pc_dest->hairserial);
            if(pHair)
            {
                //stores old hair values...
                pHair->moreb1 = static_cast<unsigned char>(pHair->color>>8);
                pHair->moreb2 = static_cast<unsigned char>(pHair->color%256);
                pHair->moreb3=pHair->id1;
                pHair->moreb4=pHair->id2;

                //and change them with random ones
                switch(rand()%10)
                {
                case 0:
                    pHair->id2='\x3B';
                    break;
                case 1:
                    pHair->id2='\x3C';
                    break;
                case 2:
                    pHair->id2='\x3D';
                    break;
                case 3:
                    pHair->id2='\x44';
                    break;
                case 4:
                    pHair->id2='\x45';
                    break;
                case 5:
                    pHair->id2='\x46';
                    break;
                case 6:
                    pHair->id2='\x47';
                    break;
                case 7:
                    pHair->id2='\x48';
                    break;
                case 8:
                    pHair->id2='\x49';
                    break;
                case 9:
                    pHair->id2='\x4A';
                    break;
                default:
                    pHair->id2='\x4A';
                    break;
                }

                //random color
                pHair->color = color;
                //let's check for invalid values
                if ( pHair->color < 0x044E || pHair->color > 0x04AD )
                {
                    pHair->color = 0x044E;
                }

                pHair->incognito = true;//AntiChrist
            }//if j!=-1
        }//if hairserial!=-1


        // -------- BEARD --------
        if(pc_dest->id2==0x90)// only if a man
            if(pc_dest->beardserial>-1)//if beard exist
            {   //change beard style/color
                P_ITEM pBeard = FindItemBySerial(pc_dest->beardserial);
                if(pBeard)
                {
                    //clConsole.send("BEARD FOUND!!\n");
                    //stores old beard values
                    pBeard->moreb1 = static_cast<unsigned char>(pBeard->color>>8);
                    pBeard->moreb2 = static_cast<unsigned char>(pBeard->color%256);
                    pBeard->moreb3 = static_cast<unsigned char>(pBeard->id() >> 8);
                    pBeard->moreb4 = static_cast<unsigned char>(pBeard->id()%256);

                    //changes them with random ones
                    switch(rand()%7)
                    {
                    case 0:
                        pBeard->id2='\x3E';
                        break;
                    case 1:
                        pBeard->id2='\x3F';
                        break;
                    case 2:
                        pBeard->id2='\x40';
                        break;
                    case 3:
                        pBeard->id2='\x41';
                        break;
                    case 4:
                        pBeard->id2='\x4B';
                        break;
                    case 5:
                        pBeard->id2='\x4C';
                        break;
                    case 6:
                        pBeard->id2='\x4D';
                        break;
                    default:
                        pBeard->id2='\x4D';
                        break;
                    }

                    //random color
                    pBeard->color = color;

                    if ( pBeard->color < 0x044E || pBeard->color > 0x04AD )
                    {
                        pBeard->color = 0x044E;
                    }

                    pBeard->incognito=true;//AntiChrist
                }//if j!=-1
            }//if beardserial!=-1
void cDragItems::equipItem( P_CLIENT client )
{
	// Get the packet information
	SERIAL itemId = LongFromCharPtr( &buffer[ client->socket() ][ 1 ] );
	SERIAL playerId = LongFromCharPtr( &buffer[ client->socket() ][ 6 ] );

	P_ITEM pItem = FindItemBySerial( itemId );
	P_CHAR pWearer = FindCharBySerial( playerId );

	if( !pItem || !pWearer )
		return;

	P_CHAR pChar = client->player();

	// We're dead and can't do that
	if( pChar->dead )
	{
		client->sysMessage( "You are dead and can't do that." );
		bounceItem( client, pItem );
		return;
	}

	// Our target is dead
	if( ( pWearer != pChar ) && pWearer->dead )
	{
		client->sysMessage( "You can't equip dead players." );
		bounceItem( client, pItem );
		return;
	}

	// Get our tile-information
	tile_st pTile;
	Map->SeekTile( pItem->id(), &pTile );

	// Is the item wearable ? ( layer == 0 | equip-flag not set )
	// Multis are not wearable are they :o)
	if( pTile.layer == 0 || !( pTile.flag3 & 0x40 ) || pItem->isMulti() )
	{
		client->sysMessage( "This item cannot be equipped." );
		bounceItem( client, pItem );
		return;
	}

	// Required Strength
	if( pItem->st > pWearer->st )
	{
		if( pWearer == pChar )
			client->sysMessage( "You cannot wear that item, you seem not strong enough" );
		else
			client->sysMessage( "This person can't wear that armor, it seems not strong enough" );

		bounceItem( client, pItem );
		return;
	}

	// Required Dexterity
	if( pItem->dx > pWearer->effDex() )
	{
		if( pWearer == pChar )
			client->sysMessage( "You cannot wear that item, you seem not agile enough" );
		else
			client->sysMessage( "This person can't wear that armor, it seems not agile enough" );

		bounceItem( client, pItem );
		return;
	}
	
	// Required Intelligence
	if( pItem->in > pWearer->in )
	{
		if( pWearer == pChar )
			client->sysMessage( "You cannot wear that item, you seem not smart enough" );
		else
			client->sysMessage( "This person can't wear that armor, it seems not smart enough" );

		bounceItem( client, pItem );
		return;
	}

	// Males can't wear female armor
	if( ( pChar->id() == 0x0190 ) && ( pItem->id() >= 0x1C00 ) && ( pItem->id() <= 0x1C0D ) )
	{
		client->sysMessage( "You cannot wear female armor." );
		bounceItem( client, pItem );
		return;
	}

	// Needs a check (!)
	// Checks for equipment on the same layer
	// If there is any it tries to unequip it
	// If that fails it cancels
	UI08 layer = pItem->layer();
	vector< SERIAL > equipment = contsp.getData( pWearer->serial );

	for( UI32 i = 0; i < equipment.size(); i++ )
	{
		P_ITEM pEquip = FindItemBySerial( equipment[ i ] );

		if( pEquip )
			continue;

		// We found an item which is on the same layer (!)
		// Unequip it if we can 
		bool twoHanded = false;

		if( pEquip->twohanded() && ( layer == 1 || layer == 2 ) )
			twoHanded = true;

		if( pItem->twohanded() && ( pEquip->layer() == 1 || pEquip->layer() == 2 ) )
			twoHanded = true;
			
		if( ( pEquip->layer() == layer ) || twoHanded )
		{
			if( pChar->canPickUp( pEquip ) ) // we're equipping so we do the check
				pEquip->toBackpack( pWearer );

			// If it's still on the char: cancel equipment
			if( pEquip->contserial == pWearer->serial )
			{
				client->sysMessage( "You already have an item on that layer." );
				bounceItem( client, pItem );
				return;
			}
		}
	}

	// At this point we're certain that we can wear the item
	pItem->setContSerial( playerId );
	pItem->setLayer( pTile.layer ); // Don't trust the user input on this one

	// Handle the weight if the item is leaving our "body"
	if( pWearer != pChar )
	{
		pChar->weight -= pItem->getWeight();
		pWearer->weight += pItem->getWeight();

		// Update the status-windows
		statwindow( client->socket(), pChar );
		statwindow( calcSocketFromChar( pWearer ), pWearer );
	}

	if( pTile.layer == 0x19 )
		pWearer->setOnHorse( true );

	// Apply the bonuses
	pWearer->st += pItem->st2;
	pWearer->chgDex( pItem->dx2 );
	pWearer->in += pItem->in2;

	// Show debug information if requested
	if( showlayer )
		clConsole.send( QString( "Item (%1) equipped on layer %2" ).arg( pItem->name() ).arg( pItem->layer() ) );

	// I don't think we need to remove the item
	// as it's only visible to the current char
	// And he looses contact anyway
	// SndRemoveitem( pi->serial );

	// Build our packets
	cWornItems wearItem( pWearer->serial, pItem->serial, pItem->layer(), pItem->id(), pItem->color() );
	cSoundEffect soundEffect( 0x57, pWearer->pos );

	// Send to all sockets in range
	// ONLY the new equipped item and the sound-effect
	for( UOXSOCKET s = 0; s < now; s++ )
		if( perm[s] && inrange1p( pWearer, currchar[s] ) )
		{
			soundEffect.send( s );
			wearItem.send( s );
		}

	// Lord Binaries Glow stuff
	if( pItem->glow != INVALID_SERIAL )
	{
		pChar->removeHalo( pItem );
		pWearer->addHalo( pItem );
		pWearer->glowHalo( pItem );
	}
}