Example #1
0
// Build Drop the PY way
CDrop* CWorldServer::GetPYDrop( CMonster* thismon, UINT droptype )
{   //if droptype = 1 then it is a normal drop. if it is 2 then it is a potential side drop.
    //Log( MSG_INFO, "PYDrops function selected" );
    //Log( MSG_INFO, "monster is %i", thismon->montype );
    if(droptype == 2) // monster is still alive
    {
        // this part of the function reserved for the later addition of side drops
        //return NULL;  //temporary bypass for the side drop function
        // kicks it straight back if the monster is not dead
        if(thismon->thisnpc->side != 0) //perhaps we get a side drop??
        {
            if(GServer->RandNumber(0,100) < thismon->thisnpc->sidechance)
            {
                droptype = thismon->thisnpc->side;
            }
            else
            {
                return NULL;  //No drop this time
            }
        }
        else
        {
            return NULL;  //No drop this time
        }
    }
    CDrop* newdrop = new (nothrow) CDrop;
    if(newdrop==NULL)
    {
        Log(MSG_WARNING, "Error allocing memory [getdrop]" );
        return NULL;
    }
    newdrop->clientid = GetNewClientID( );
    newdrop->posMap = thismon->Position->Map;
    newdrop->pos = RandInCircle( thismon->Position->current, 3 );
    newdrop->droptime = time(NULL);
    newdrop->owner = thismon->MonsterDrop->firsthit;
    newdrop->thisparty = thismon->thisparty;
    ClearItem(newdrop->item);

    CPlayer* thisclient = GServer->GetClientByCID(thismon->MonsterDrop->firsthit);

    // code to modify drop chance for different levels
    //float charm = 0;
    //float droprate = thismon->thisnpc->dropchance;
    float droprate = Config.DROP_RATE;
    float leveldif = (float)thismon->thisnpc->level - (float)thisclient->Stats->Level;
    float dropchance = (droprate + (droprate * 0.01 * leveldif));
    if(dropchance < 10) dropchance = 10; //always a small chance of a drop even when the mob is more than 20 levels beneath your own
    if(thismon->thisnpc->level == 1)
        dropchance = 80;
    if (GServer->RandNumber(0, 100)> dropchance)
        return NULL; // no drop here. not this time anyway.

    CItemType prob[MDropList.size()];
    bool isdrop = false;
    int n = 0;
    int test = 0;
    long int probmax = 0;
    int itemnumber[MDropList.size()];
    int itemtype[MDropList.size()];
    int probability[MDropList.size()];
    int alternate[MDropList.size()][8];

    if( thismon->IsGhost())
    {
        // Stuff to do if the mob is a ghost of any type
        int selection = 1 + rand()%10;
        if( selection <= 5 )
        {
            newdrop->type = 1; //Drop Zuly.
            newdrop->amount = thismon->thisnpc->level * 10 * Config.ZULY_RATE + RandNumber( 1, 10 );
            return  newdrop;
        }
        else
        {
            for(int i=0; i<SkillbookList.size( ); i++)
            {
                newdrop->type = 2;
                CMDrops* thisdrop = GServer->SkillbookList.at(i);
                if(thisdrop->level_min <= thismon->thisnpc->level &&  thisdrop->level_max >= thismon->thisnpc->level)
                {
                    itemnumber[n] = thisdrop->itemnum;
                    itemtype[n] = thisdrop->itemtype;
                    probability[n] = thisdrop->prob;
                    probmax += thisdrop->prob;
                    n++;
                }
            }
        }
    }
    else // Stuff to do if the mob isn't a ghost
    {
        int dropmode = 0;
        int randv = RandNumber( 1, 100);
        // Each monster has its own rates for zuly and item drops defined in the database
        if(randv > thismon->thisnpc->item + thismon->thisnpc->money) return NULL; // did not qualify to drop anything this time
        if(randv <= thismon->thisnpc->money) // zuly drop instead of item drop
        {
            newdrop->type = 1;
            newdrop->amount = thismon->thisnpc->level * 5 * Config.ZULY_RATE + RandNumber( 1, 10 );
            return  newdrop;
        }
        // this means it is an item drop
        randv = RandNumber( 1, 100);
        if(randv > 70) // 30% map drop
        {
            dropmode = 1; // map drop selected
        }
        else if(randv > 30) // 40% mob drop
        {
            dropmode = 2; //mob drop selected
        }
        else // 30% level drop
        {
            dropmode = 3; //leveldrop selected
        }

        int randomdrop = GServer->RandNumber(1, 100);
        for(int i=0; i<MDropList.size( ); i++)
        {
            isdrop=false;
            CMDrops* thisdrop = GServer->MDropList.at(i);
            if(thisdrop->mob == thismon->montype && dropmode == 2) // monster drop
            {
                test = GServer->RandNumber(1, 1000);
                if(test < thisdrop->prob)
                {
                    isdrop = true;
                }
            }
            if(thisdrop->map == thismon->Position->Map && dropmode == 1) // map drop
            {
                test = GServer->RandNumber(1, 1000);
                if(thismon->thisnpc->level == 1)
                   test = GServer->RandNumber(1, 10000); // make it less likely to get map drops from event mobs
                if(test < thisdrop->prob)
                {
                    isdrop = true;
                }
            }
            if(thismon->thisnpc->level >= thisdrop->level_min && thismon->thisnpc->level <= thisdrop->level_max && dropmode == 3)
            {
                //Log(MSG_INFO, "Level drop selected. type %i number %i", thisdrop->itemtype, thisdrop->itemnum );
                test = GServer->RandNumber(1, 1000);
                if(test < thisdrop->prob)
                {
                    isdrop = true;
                }
                //else
            }
            if(isdrop == true)
            {
                if(droptype != 1) //side drops only. Skip if the item is not a match for side type
                {
                    if(itemtype[n] != droptype)continue;
                }
                //droptype 1 is a regular drop
                itemnumber[n] = thisdrop->itemnum;
                itemtype[n] = thisdrop->itemtype;
                //probability[n] = thisdrop->prob;
                alternate[n][0] = 0;
                for(int i=1;i<8;i++)
                {
                    alternate[n][i] = thisdrop->alt[i];
                }
                n++;
            }
        }
    }
    int newn = n;
    if(n == 0)
        return NULL;
    int maxitems = n;
    // randomize the item from the list
    n = GServer->RandNumber(0, maxitems);
    newdrop->item.itemnum = itemnumber[n];
    newdrop->item.itemtype = itemtype[n];
    newdrop->type = 2;

    newdrop->item.lifespan = 10 + rand()%80;
    float dmod = 0; //random number from 0 to 100 made up of 4 sub numbers to keep
    //the average value near to 50
    for(int i=0; i<4; i++)
    {
        float r1 = rand()%20;
        dmod += r1;
    }
    newdrop->item.durability = 10 + (int)dmod;
    if( newdrop->item.itemtype == 8 || newdrop->item.itemtype == 9 )
    {
        //This probability is now configurable from WorldServer.conf
        int psocked = rand()%101; //Probability of finding a socketed item
        if( psocked < Config.SlotChance) //default should be around 5% needs to be rare
        {
            newdrop->item.socketed = true;
        }
        else
        {
             newdrop->item.socketed = false;
        }
    }
    else
    {
        newdrop->item.socketed = false;
    }
    //Log( MSG_INFO, "Socket are OK");
    newdrop->item.appraised = false;
    newdrop->item.stats = 0;
    newdrop->item.count = 1;

    //int chamod = 0;
    int chamod = (int)floor(thisclient->Attr->Cha / 30);
    if(chamod <0) chamod = 0;
    int basedrop = 6 + chamod; //Base number of items to be dropped. add CHA to increase this.
    if( newdrop->item.itemtype == 10 || newdrop->item.itemtype == 12 )
    {
        newdrop->item.count = RandNumber(0, basedrop);
        if(thismon->thisnpc->level == 1 && newdrop->item.count > 6) newdrop->item.count = 6; //limit the drop rate of items from level 1 event mobs
        if(newdrop->item.count==0)
            newdrop->item.count = 1;
        if(newdrop->item.itemtype == 10)
        {
            if(newdrop->item.itemnum >=441 && newdrop->item.itemnum <= 888)// skillbooks
                newdrop->item.count = 1;
        }
        if(newdrop->item.itemtype == 11) //gems only get 1
            newdrop->item.count = 1;
        if(newdrop->item.itemtype == 12)
        {
            if(newdrop->item.itemnum > 300 && newdrop->item.itemnum < 360) //bullets get a lot higher count.
            {
                newdrop->item.count *= 10;
                newdrop->item.count += 10;
            }
        }
    }
    else if( newdrop->item.itemtype >1 && newdrop->item.itemtype !=7 && newdrop->item.itemtype < 10)
    {
        // check to see if the item will be refined
        int prefine = rand()%100; //Probability of finding a refined item
        int refinechance = Config.RefineChance;
        if(prefine < refinechance) // default = 5%
        {
            int refinelevel = rand()%101;  //which level of refine do we actually get
            if( refinelevel < 5)        //default 5%
                newdrop->item.refine = 4 * 16;
            else if( refinelevel < 15 )   //10%
                newdrop->item.refine = 3 * 16;
            else if(refinelevel < 35 )   // 20%
                newdrop->item.refine = 2 * 16;
            else                          // 65%
                newdrop->item.refine = 16;
        }
        else //99%
            newdrop->item.refine = 0;

        // will the item be a blue?
        bool blue = false;
        int bluechance1 = RandNumber( 1, 100);
        int bluechance2 = Config.BlueChance + chamod;
        Log( MSG_INFO, "Blue chance = %i", bluechance2);
        //This probability is now configurable from WorldServer.conf. CHA also has an effect
        if(bluechance1 < bluechance2) // some percentage of drops will be specials or blues whenever one is available.
        {
            Log( MSG_INFO, "Selected a blue item");
            int p = 1;
            while(alternate[n][p] != 0 && p < 8)
            {
                p++;
            }
            if(p > 1) // blues available for this item
            {
                //Log( MSG_INFO, "blue item available");
                p--;
                int bluenum = RandNumber( 1, p);
                newdrop->item.itemnum = alternate[n][bluenum];
                blue=true;
            }
        }
        // will the items get stats? All blue items will. Uniques count as blues.
        int pstats = rand()%101; //Probability of the item having stats. default = 5%
        if(blue == true)
        {
            pstats = 1;
        }
        int StatChance = Config.StatChance;
        if( pstats < StatChance)        // default 5%
            newdrop->item.stats = RandNumber( 1, 300);
    }
    newdrop->item.gem = 0;
    return newdrop;
}
Example #2
0
// Build Drop
CDrop* CWorldServer::GetDrop( CMonster* thismon )
{
    try{
    CDrop* newdrop = new (nothrow) CDrop;
    if(newdrop==NULL)
    {
        Log(MSG_WARNING, "Error allocing memory [getdrop]" );
        return NULL;
    }
    newdrop->clientid = GetNewClientID( );
    newdrop->posMap = thismon->Position->Map;
    newdrop->pos = RandInCircle( thismon->Position->current, 3 );
    newdrop->droptime = time(NULL);
    newdrop->owner = thismon->MonsterDrop->firsthit;
    newdrop->thisparty = thismon->thisparty;
    ClearItem(newdrop->item);
    int randv = RandNumber( 1, 100);
    if(thismon->MonsterDrop->mapdrop->level_max<thismon->MonsterDrop->firstlevel) randv = 100;
    if(randv<=30)//30% zuly [zulies will count as mapdrop]
    {
        if(thismon->MonsterDrop->mapdrop->level_max>=thismon->MonsterDrop->firstlevel)
        {
            newdrop->type = 1; //Drop Zuly
            newdrop->amount = thismon->thisnpc->level*5*Config.ZULY_RATE + RandNumber( 1, 10 );
            return  newdrop;
        }
        delete newdrop;
        return NULL;
    }
    CMDrops* thisdrops;
    newdrop->type = 2; //drop item drop
    switch( Config.DROP_TYPE )
    {
        case 0://only map
            thisdrops = thismon->MonsterDrop->mobdrop;
            if(thisdrops->level_max<thismon->MonsterDrop->firstlevel)
            {
                delete newdrop;
                return NULL;
            }
        break;
        case 1://mob only
            thisdrops = thismon->MonsterDrop->mapdrop;
            if(thismon->thisnpc->level-thismon->MonsterDrop->firstlevel<-14)
            {
                delete newdrop;
                return NULL;
            }
        break;
        default://both
            randv = RandNumber(1,100);
            if(thismon->MonsterDrop->mapdrop!=NULL)
                if(thismon->MonsterDrop->mapdrop->level_max<thismon->MonsterDrop->firstlevel)
                    randv = 100;
            if(randv>60)//select wich drop will use (map or mob) //40 - 60%
            {
                thisdrops = thismon->MonsterDrop->mobdrop;
                if((int)(thismon->thisnpc->level-thismon->MonsterDrop->firstlevel) < -14)
                {
                    delete newdrop;
                    return NULL;
                }
            }
            else
            {
                thisdrops = thismon->MonsterDrop->mapdrop;
                if(thisdrops->level_max<thismon->MonsterDrop->firstlevel)
                {
                    delete newdrop;
                    return NULL;
                }
            }
        break;
    }
    if(thisdrops==NULL)
    {
        thisdrops = thismon->MonsterDrop->mobdrop;
        if(thisdrops==NULL)
        {
            thisdrops = thismon->MonsterDrop->mapdrop;
            if(thisdrops==NULL)
            {
                newdrop->type = 1; //Drop Zuly
                newdrop->amount = thismon->thisnpc->level*5*Config.ZULY_RATE - RandNumber( 1, 20 );
                return  newdrop;
            }
        }
    }
    randv = 0;
    randv = RandNumber( 1, thisdrops->probmax );
    DWORD prob = 1;
    for(UINT i=0;i<thisdrops->Drops.size();i++)
    {
        CDropInfo* dropinfo = thisdrops->Drops.at( i );
        prob += dropinfo->prob;
        if(randv<=prob)
        {
            newdrop->item.itemtype = dropinfo->type;
            newdrop->item.itemnum = dropinfo->item;
            break;
        }
    }
    if(newdrop->item.itemtype==0)
    {
        Log(MSG_WARNING, "Drop Probability Highter: %i", randv );
        delete newdrop;
        return NULL;
    }
    if(newdrop->item.itemtype>1 && newdrop->item.itemtype<10 && newdrop->item.itemtype!=JEWEL)
    {
        // Items drop with 0 refine
        newdrop->item.refine = 0;
        newdrop->item.lifespan = RandNumber( 30, 100 );
        newdrop->item.durability = RandNumber( 35, 70 );
        newdrop->item.socketed = false;
        randv = RandNumber( 1, 100 );
        if( randv < 30 )        // 30%
            newdrop->item.stats = rand()%300;
        newdrop->item.appraised = newdrop->item.stats==0?true:false;
    }
    else
    {
         newdrop->item.lifespan = 100;
         newdrop->item.durability = 40;
         newdrop->item.socketed = false;
         newdrop->item.stats = 0;
    }
    newdrop->item.count = 1;
    if( newdrop->item.itemtype == 10 || newdrop->item.itemtype == 12 )
    {
        newdrop->item.count = RandNumber( 1, 3 );
    }
    if(newdrop->item.durability>100)newdrop->item.durability=100;
    if(newdrop->item.lifespan>100)newdrop->item.lifespan=100;
    newdrop->item.gem = 0;
    return newdrop;
    }
    catch(...)
    {
       Log(MSG_WARNING, "Error in CWorldServer::GetDrop( CMonster* thismon )(serverFunctions.cpp)" );
       return NULL;
    }
}
Example #3
0
//hidden
// Build Drop the PY way
CDrop* CWorldServer::GetPYDrop( CMonster* thismon, UINT droptype )
{   //if droptype = 1 then it is a normal drop. if it is 2 then it is a potential side drop.
    //Log(MSG_INFO,"GetPYDrop, monster %i, droptype %i",thismon->montype,droptype);

    if(droptype == 2) // monster is still alive
    {
        // kicks it straight back if the monster is not dead
        if(thismon->thisnpc->side != 0) //perhaps we get a side drop??
        {
            if(GServer->RandNumber(0,100) < thismon->thisnpc->sidechance)
            {
                droptype = thismon->thisnpc->side;
            }
            else
            {
                return NULL;  //No drop this time
            }
        }
        else
        {
            return NULL;  //No drop this time
        }
    }

    CDrop* newdrop = new (nothrow) CDrop;
    if(newdrop==NULL)
    {
        Log(MSG_WARNING, "Error allocing memory [getdrop]" );
        return NULL;
    }
    newdrop->clientid = GetNewClientID( );
    newdrop->posMap = thismon->Position->Map;
    newdrop->pos = RandInCircle( thismon->Position->current, 3 );
    newdrop->droptime = time(NULL);
    newdrop->owner = thismon->MonsterDrop->firsthit;
    newdrop->thisparty = thismon->thisparty;
    ClearItem(newdrop->item);

    CPlayer* thisclient = GServer->GetClientByCID(thismon->MonsterDrop->firsthit);
    if(thisclient == NULL)
    {
        Log(MSG_WARNING,"GetPYDrop:: Failed to create player");
        return NULL;
    }

    // code to modify drop chance for different levels
    //float charm = 0;
    float charm = (float)thisclient->Attr->Cha / 5;
    float leveldif = (float)thismon->thisnpc->level - (float)thisclient->Stats->Level;
    float droprate = (float)GServer->Config.DROP_RATE + charm;  //basic server rate + extra for player charm
    float dropchance = (droprate + (droprate * 0.01 * leveldif));
    //Log(MSG_INFO,"charm %.2f, leveldif %.2f, droprate %.2f, dropchance %.2f",charm,leveldif,droprate,dropchance);
    if(dropchance < 10) dropchance = 10; //always a small chance of a drop even when the mob is more than 20 levels beneath your own
    //Log(MSG_INFO,"dropchance %.2f",dropchance);
    if(thismon->thisnpc->level == 1)
        dropchance = 80;
    //Log(MSG_INFO,"dropchance %.2f",dropchance);
    UINT lma_save_rand=0;
    lma_save_rand=GServer->RandNumber(0, 100);
    if (lma_save_rand>dropchance)
    {
        //Log(MSG_INFO,"no drop, %i > %.2f",lma_save_rand,dropchance);
        return NULL; // no drop here. not this time anyway.
    }

    //Log(MSG_INFO,"drop possible, %i <= %.2f",lma_save_rand,dropchance);

    CItemType prob[MDropList.size()];
    bool isdrop = false;
    int n = 0;
    int test = 0;
    long int probmax = 0;
    int itemnumber[MDropList.size()];
    int itemtype[MDropList.size()];
    int probability[MDropList.size()];
    int alternate[MDropList.size()][8];

    if( thismon->IsGhost())
    {
        // Stuff to do if the mob is a ghost of any type
        int selection = 1 + rand()%10;
        if( selection <= 3 ) //MP water
        {
            newdrop->type = 2;
            itemnumber[n] = 399;
            itemtype[n] = 12;
            probability[n] = 10;
            probmax =10;
            n++;
        }
        else if( selection <=6 ) //HP water
        {
            newdrop->type = 2;
            itemnumber[n] = 400;
            itemtype[n] = 12;
            probability[n] = 10;
            probmax =10;
            n++;
        }
        else  //skillbooks
        {
            for(int i=0; i<SkillbookList.size( ); i++)
            {
                newdrop->type = 2;
                CMDrops* thisdrop = GServer->SkillbookList.at(i);
                if(thisdrop->level_min <= thismon->thisnpc->level &&  thisdrop->level_max >= thismon->thisnpc->level)
                {
                    itemnumber[n] = thisdrop->itemnum;
                    itemtype[n] = thisdrop->itemtype;
                    probability[n] = thisdrop->prob;
                    probmax += thisdrop->prob;
                    n++;
                }
            }
        }
    }
    else
    {
        int randv = RandNumber( 1, 100);
        if(randv <= 30)//30% zuly drop instead of item drop
        {
            newdrop->type = 1; //Drop Zuly
            newdrop->amount = thismon->thisnpc->level * 5 * Config.ZULY_RATE + RandNumber( 1, 10 );
            //Log(MSG_INFO,"zuly drop %i",newdrop->amount);
            return  newdrop;
        }
        // Stuff to do if the mob isn't a ghost

        int randomdrop = GServer->RandNumber(1, 100);
        //enable the next line for debug purposes if you want to confirm a drop is working.
        //Log(MSG_INFO, "Mob type %i. Map = %i. Level = %i", thismon->montype, thismon->Position->Map,thismon->thisnpc->level);

        for(int i=0; i<MDropList.size( ); i++)
        {
            isdrop=false;
            CMDrops* thisdrop = GServer->MDropList.at(i);
            if(thisdrop->mob == thismon->montype)
            {
                //Mob drop possible.
                test = GServer->RandNumber(1, 1000);
                if(test < thisdrop->prob)
                {
                    isdrop = true;
                    //item will be added to the short list
                }
            }
            if(thisdrop->map == thismon->Position->Map)
            {
                //Map drop possible.
                test = GServer->RandNumber(1, 1000);
                if(thismon->thisnpc->level == 1)
                   test = GServer->RandNumber(1, 10000); // make it less likely to get map drops from event mobs
                if(test < thisdrop->prob)
                {
                    isdrop = true;
                    //item will be added to the short list
                }
            }
            if(thismon->thisnpc->level >= thisdrop->level_min && thismon->thisnpc->level <= thisdrop->level_max)
            {
                //Level drop possible
                test = GServer->RandNumber(1, 1000);
                if(test < thisdrop->prob)
                {
                    isdrop = true;
                    //item will be added to the short list
                }
            }
            if(isdrop == true) //Add item to the short list
            {
                if(droptype != 1) //side drops only. Skip if the item is not a match for side type
                {
                    if(itemtype[n] != droptype)continue;
                }
                //droptype 1 is a regular drop
                itemnumber[n] = thisdrop->itemnum;
                itemtype[n] = thisdrop->itemtype;
                //probability[n] = thisdrop->prob;
                alternate[n][0] = 0;
                for(int i=1;i<8;i++)
                {
                    alternate[n][i] = thisdrop->alt[i];
                }
                n++;
            }
        }
    }
    int newn = n;
    if(n == 0)
        return NULL;
    int maxitems = n;
    //maxitems is the number of items in the shortlist

    // randomize the item from the shortlist. items get equal chance
    n = GServer->RandNumber(0, maxitems);

    newdrop->item.itemnum = itemnumber[n];
    newdrop->item.itemtype = itemtype[n];
    newdrop->type = 2;

    newdrop->item.lifespan = 10 + rand()%80;
    float dmod = 0; //random number from 0 to 100 made up of 4 sub numbers to keep
    //the average value near to 50
    for(int i=0; i<4; i++)
    {
        float r1 = rand()%20;
        dmod += r1;
    }
    newdrop->item.durability = 10 + (int)dmod;
    if( newdrop->item.itemtype == 8 || newdrop->item.itemtype == 9 )
    {
        //This probability is now configurable from WorldServer.conf
        int psocked = rand()%101; //Probability of finding a socketed item
        if( psocked < Config.SlotChance) //default should be around 5% needs to be rare
        {
            newdrop->item.socketed = true;
        }
        else
        {
             newdrop->item.socketed = false;
        }
    }
    else
    {
        newdrop->item.socketed = false;
    }
    newdrop->item.appraised = false;
    newdrop->item.stats = 0;
    newdrop->item.count = 1;

    //chamod = a modifier based on the character's CHA stat. Increases the number of drops
    int chamod = (int)floor(thisclient->Attr->Cha / 20);
    if(chamod <0) chamod = 0;
    int basedrop = 6 + chamod; //Base number of items to be dropped. add CHA to increase this.
    if( newdrop->item.itemtype == 10 || newdrop->item.itemtype == 12 )
    {
        newdrop->item.count = RandNumber(0, basedrop);
        if(thismon->thisnpc->level == 1 && newdrop->item.count > 6) newdrop->item.count = 6; //limit the drop rate of items from level 1 event mobs
        if(newdrop->item.count==0)
            newdrop->item.count = 1;
        // Skillbooks & Chests
        if(newdrop->item.itemtype == 10)
        {
            if((newdrop->item.itemnum >=441 && newdrop->item.itemnum <= 888) ||
               (newdrop->item.itemnum >=247 && newdrop->item.itemnum <= 249) ||
               (newdrop->item.itemnum >=270 && newdrop->item.itemnum <= 275) ||
               (newdrop->item.itemnum >=1001 && newdrop->item.itemnum <= 1028) ||
               (newdrop->item.itemnum >=1110 && newdrop->item.itemnum <= 1178) ||
               (newdrop->item.itemnum >=1080 && newdrop->item.itemnum <= 1090) )
                newdrop->item.count = 1;   // just one skill book or chest per drop
        /*
        441-888    Skills
        247-249    Christmas Presents
        270-275    Dirty Stones
        1001-1028  Prison Chests
        1110-1178  Dispensers
        1080-1090  Event Boxes
        1200-1201  Christmas Gift - Present Box - Mileage
        1202-1203  Boy and Girl Snow Suit - Mileage
        */
        }
        // Gem Drops
        if(newdrop->item.itemtype == 11)
            newdrop->item.count = 1;   // just one gem per drop

        if(newdrop->item.itemtype == 12)
        {
            if(newdrop->item.itemnum > 300 && newdrop->item.itemnum < 360) //bullets get a lot higher count.
            {
                newdrop->item.count *= 10;
                newdrop->item.count += 10;
            }
        }
    }
    else if( newdrop->item.itemtype >1 && newdrop->item.itemtype !=7 && newdrop->item.itemtype < 10)
    {
        // check to see if the item will be refined
        int prefine = rand()%100; //Probability of finding a refined item
        if(prefine < Config.RefineChance) // default = 5%
        {
            int refinelevel = rand()%101;  //which level of refine do we actually get
            if( refinelevel < 5)        //default 5%
                newdrop->item.refine = 3 * 16;
            else if( refinelevel < 11 )   //10%
                newdrop->item.refine = 2 * 16;
            else                          // 90%
                newdrop->item.refine = 16;
        }
        else //99%
            newdrop->item.refine = 0;

        // will the item be a blue?
        int blue = 0;
        int bluechance1 = RandNumber( 1, 100);
        int bluechance2 = Config.BlueChance + chamod;


        // will the items get stats? All blue items will.
        int pstats = rand()%101; //Probability of the item having stats. default = 5%

        //This probability is now configurable from WorldServer.conf. CHA also has an effect
        if(bluechance1 < bluechance2) // some percentage of drops will be specials or blues whenever one is available.
        {
            //Log( MSG_INFO, "Selected a blue item");
            int p = 1;
            while(alternate[n][p] != 0 && p < 8)
            {
                p++;
            }
            if(p > 1) // blues available for this item
            {
                p--;
                int bluenum = RandNumber( 1, p);
                newdrop->item.itemnum = alternate[n][bluenum];
                pstats = 1; //make sure we get stats for this item
            }
            /*else
            {
                //Sorry blue item not available for this item
            }*/
        }
        //Uniques count as blues.
        if(newdrop->item.itemnum > 900)pstats = 1; //make sure we get stats for this unique item
        if( pstats < Config.StatChance)
        {   // default 5%
            //PY stats
            newdrop->item.stats = GetExtraStats( 0 );
            //newdrop->item.stats = rand()%300;
        }

    }
    newdrop->item.gem = 0;

    //Log(MSG_INFO,"drop %i* (%i:%i)",newdrop->amount,newdrop->type,newdrop->item);
    return newdrop;
}