Beispiel #1
0
void CBirthdays::Clear()
{
	for (int i = 0; i < Count(); i++)
		ClearItem(i);

	count = 0;
}
	RowAdder(CGridCtrlComp & g, CHexEditView * phev) : grid_(g)
	{
		fcc_ = grid_.GetFixedColumnCount();

		// Set fields for default item
		ClearItem(item_);

		// Set fields for text items
		ClearItem(item_ins_);
		item_ins_.strText = "Inserted";
		item_ins_.crBkClr = phev->GetCompareBgCol();
		ClearItem(item_rep_);
		item_rep_.strText = "Replaced";
		item_rep_.crFgClr = phev->GetCompareCol();
		item_rep_.crBkClr = phev->GetBackgroundCol();
		ClearItem(item_del_);
		item_del_.strText = "Deleted";
		item_del_.crFgClr = phev->GetCompareCol();
		item_del_.crBkClr = ::opp_hue(phev->GetCompareBgCol());
		ClearItem(item_equ_);
		item_equ_.strText = "Equal";

		// Set fields for address/length items
		ClearItem(item_hex_);
		item_hex_.nFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS;
		item_hex_.crBkClr = phev->GetBackgroundCol();
		item_hex_.crFgClr = phev->GetHexAddrCol();
		ClearItem(item_dec_);
		item_dec_.nFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS;
		item_dec_.crBkClr = phev->GetBackgroundCol();
		item_dec_.crFgClr = phev->GetDecAddrCol();

		item_.row = grid_.GetRowCount();       // start adding at the end
	}
Beispiel #3
0
int CBirthdays::Remove(int index)
{
	if ((index >= 0) && (index < count)) {
		for (int i = index + 1; i < count; i++)
			birthdays[i - 1] = birthdays[i];

		ClearItem(count--);
		return 0;
	}
	return -1;
}
Beispiel #4
0
void CPlayer::ReduceABC( )
{
    unsigned int weapontype = 0;
    weapontype = GServer->EquipList[WEAPON].Index[items[7].itemnum]->type;
    switch(weapontype)
    {
        case 231:
            items[132].count--;
            if(items[132].count<=0)
            {
                ClearBattle( Battle );
                ClearItem( items[132] );
            }
        break;
        case 232:
            items[133].count--;
            if(items[133].count<=0)
            {
                ClearBattle( Battle );
                ClearItem( items[133] );
            }
        break;
        case 233:
            items[134].count--;
            if(items[134].count<=0)
            {
                ClearBattle( Battle );
                ClearItem( items[134] );
            }
        break;
        case 271:
            items[132].count--;
            if(items[132].count<=0)
            {
                ClearBattle( Battle );
                ClearItem( items[135] );
            }
        break;
    }
}
Beispiel #5
0
 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
 {
     player->PlayerTalkClass->SendCloseGossip();
     switch (action)
     {
         case ACTION_TRANSMOGRIFY_ADD_DISPLAY:
             TransmogrifyItem(player, creature);
             break;
         case ACTION_TRANSMOGRIFY_REMOVE_DISPLAY:
             ClearItem(player, creature);
             break;
     }
     return true;
 }
Beispiel #6
0
void CBDCApp::ClearToday()
{
	ClearItem(&m_todayID);
}
Beispiel #7
0
void CBDCApp::ClearBirthday(CBirthday *pbd)
{
	ClearItem(&pbd->m_listid_bd);
}
Beispiel #8
0
void CBDCApp::ClearKnown(CBirthday *pbd)
{
	ClearItem(&pbd->m_listid_known);
}
Beispiel #9
0
CPlayer::CPlayer( CClientSocket* CLIENT )
{

    client = CLIENT;
    is_invisible=false;
    is_born=false;   //LMA: brand new player.

    pvp_id=-1;  //LMA: Pvp ID (set by qsd most of the time).

     #ifdef LMA_SPAWNM
        lastSpawnUpdate=0;
        last_monster=0;
        last_monstercid=0;
        mdeb=0;
        mend=0;
        playertime=0;
        xx=0;
        yy=0;
    #endif

    skip_qsd_zone=false;

    map_warp_zone=0;
    Warp_Zone.x=0;
    Warp_Zone.y=0;
    Warp_Zone.z=0;

    //Special AIP case.
    if (CLIENT==NULL)
    {
        is_invisible=true;
    }

    // USED ITEM
    UsedItem = new USEDITEM;
    assert(UsedItem);
    UsedItem->lastRegTime = 0;
    UsedItem->usevalue = 0;
    UsedItem->usetype = 0;
    UsedItem->userate = 0;
    UsedItem->used = 0;
    // CHARINFO
    CharInfo = new INFO;
    assert(CharInfo);
    memset( &CharInfo->charname, '\0', 17 );
	CharInfo->charid = 0;
    CharInfo->Sex = 0;
    CharInfo->Face = 0;
    CharInfo->Hair = 0;
    CharInfo->Exp = 0;
    CharInfo->Job = 0;
    CharInfo->Zulies = 0;
    CharInfo->Storage_Zulies = 0;
    CharInfo->LastGlobal = 0;
    CharInfo->StatPoints = 0;
    CharInfo->SkillPoints = 0;
    CharInfo->stamina = 0;
    CharInfo->isGM = 0; // GM Security

    // RIDE
    Ride = new RIDE;
    assert(Ride);
    Ride->Drive = false;
    Ride->Ride = false;
    Ride->charid = 0;

    // TRADE
    Trade = new TRADE;
    assert(Trade);
    for(int i=0;i<10;i++)
        Trade->trade_itemid[i] = 0;
    for(int i=0;i<11;i++)
        Trade->trade_count[i] = 0;
    Trade->trade_status = 0;
    Trade->trade_target = 0;

    //PARTY
    Party = new PARTY;
    assert(Party);
    Party->party = NULL;
    Party->IsMaster = true;

    //GAGROUP
    Groupga = new GROUPGA;
    assert(Groupga);
    Groupga->Groupga = NULL;
    Groupga->IsMaster = true;

    // SHOP
    Shop = new SHOP;
    assert(Shop);
    Shop->open = false;
    memset( &Shop->name, '\0',64 );
    for(int i=0;i<30;i++)
    {
        ClearItem(Shop->BuyingList[i].item);
        Shop->BuyingList[i].slot = 0;
        Shop->BuyingList[i].count = 0;
        Shop->BuyingList[i].price = 0;
        Shop->SellingList[i].slot = 0;
        Shop->SellingList[i].count = 0;
        Shop->SellingList[i].price = 0;
    }

    Shop->Buying = 0;
    Shop->Selling = 0;
    Shop->ShopType = 0;
    Shop->mil_shop_time=0;

    //bonusxp
    timerxp=0;
    bonusxp=1;
    wait_validation=0;
    once=false;

    //LMA: Exp nullfier
    timer_no_exp=0;
    no_exp=false;

    //bonus Medal of Fortune(id.1300/type.10)_One additional drop chance for defeating a monster is added (Double Drop -> ddrop)
    timerddrop = 0;
    bonusddrop = 0;             //default value = 0 for no extra drops
    wait_validation_ddrop = 0;  //default = 0. What does this even do???
    once_ddrop = false;

    //bonus Medal of Excellence(id.1301/type.10)_find equipment of excellence and will result in better bonus stats than normal (statdrop)
    timerstatdrop=0;
    bonusstatdrop=1;
    wait_validation_statdrop=0;
    once_statdrop=false;

     //bonus Medal of Retrieval(id.1302/type.10)_you are able to retreive items from monsters that would normally not drop items for you. (graydrop)
    timergraydrop=0;
    bonusgraydrop=0;
    wait_validation_graydrop=0;
    once_graydrop=false;

    attack_fuel=0;
    pc_rebate=0;
    pc_craft_talent=0;
    pc_up=0;

    // SESSION
    Session = new SESSION;
    assert(Session);
	Session->userid = 0;
	memset( &Session->username, '\0', 17 );
	memset( &Session->password, '\0', 33 );
	Session->accesslevel = 0;
	Session->isLoggedIn = false;
	Session->inGame = false;

	// Inventory / storage
    for(unsigned int i=0;i<MAX_INVENTORY;i++)
        ClearItem( items[i] );

    for(unsigned int i=0;i<MAX_STORAGE;i++)
        ClearItem( storageitems[i] );

    // Clan
    Clan = new CLAN;
    assert(Clan);
    Clan->clanid = 0;
    Clan->clanrank = 0;
    Clan->grade = 0;
    Clan->logo = 0;
    Clan->back = 0;
    Clan->CP= 0;
    memset( &Clan->clanname, '\0', 17 );
    // ATTRIBUTES
    Attr = new ATTRIBUTES;
    assert(Attr);
    Attr->Str = 0;
    Attr->Dex = 0;
    Attr->Int = 0;
    Attr->Con = 0;
    Attr->Cha = 0;
    Attr->Sen = 0;
    Attr->Estr = 0;
    Attr->Edex = 0;
    Attr->Eint = 0;
    Attr->Econ = 0;
    Attr->Echa = 0;
    Attr->Esen = 0;
    Attr->STRbuff= 0;
    Attr->DEXbuff= 0;
    Attr->INTbuff= 0;
    Attr->CONbuff= 0;
    Attr->CHAbuff= 0;
    Attr->SENbuff= 0;
    Attr->ALLbuff=0;

    CharType = TPLAYER;

    questdebug = false;
    Session->codedebug = false;
    Session->first_id=true;
    Saved = false;
    isInvisibleMode = false;
    Fairy = false;
    hits = 0;
    uw_kills=0;

    //FairyTime = 0;
    nstorageitems = 0;
    nsitemmallitems = 0;
    p_skills = 0;

    //LMA: New way
    for(int i=0;i<MAX_ALL_SKILL;i++)
    {
        cskills[i].id = 0;
        cskills[i].level = 0;
        cskills[i].thisskill=NULL;
    }

    for(int i=0;i<MAX_QUICKBAR;i++)
        quickbar[i] = 0;

    //quest.selectedNpc = NULL;
    quest.RefNPC=0; //LMA: selected NPC.
    for(int i=0;i<10;i++)
    {
        if(i<5)
        {
            quest.EpisodeVar[i]=0;
            quest.ClanVar[i]=0;
        }

        if (i<3)
        {
            quest.JobVar[i]=0;
        }

        if (i<7)
        {
            quest.PlanetVar[i]=0;
        }

        quest.UnionVar[i]=0;
        //quest.quests[i]=NULL;
    }

    for(int i=0;i<0x40;i++)
    {
        quest.flags[i]=0;
    }

    ActiveQuest = 0;
    lastRegenTime = 0;
    lastSaveTime = clock( );
    lastDpTime = clock();
    lastShowTime=0;
    firstlogin=clock();     //LMA for fairy
    lastGG = 0;
    VisiblePlayers.clear( );
    VisibleDrops.clear( );
    VisibleMonsters.clear( );
    VisibleNPCs.clear( );
}
Beispiel #10
0
CPlayer::CPlayer( CClientSocket* CLIENT )
{  
    client = CLIENT;
    // USED ITEM
    UsedItem = new USEDITEM;
    assert(UsedItem);
    UsedItem->lastRegTime = 0;
    UsedItem->usevalue = 0;
    UsedItem->usetype = 0;
    UsedItem->userate = 0;
    UsedItem->used = 0; 
    // CHARINFO
    CharInfo = new INFO;
    assert(CharInfo);
    memset( &CharInfo->charname, '\0', 17 );
	CharInfo->charid = 0;	    	
    CharInfo->Sex = 0;
    CharInfo->Face = 0;
    CharInfo->Hair = 0;
    CharInfo->Exp = 0;
    CharInfo->Job = 0;
    CharInfo->Zulies = 0;
    CharInfo->Storage_Zulies = 0;
    CharInfo->LastGlobal = 0;
    CharInfo->StatPoints = 0;
    CharInfo->SkillPoints = 0;
    CharInfo->stamina = 0;

    // RIDE
    Ride = new RIDE;
    assert(Ride);
    Ride->Drive = false;
    Ride->Ride = false;
    Ride->charid = 0;
    // TRADE
    Trade = new TRADE;
    assert(Trade);
    for(int i=0;i<10;i++)
        Trade->trade_itemid[i] = 0;
    for(int i=0;i<11;i++)    
        Trade->trade_count[i] = 0;    
    Trade->trade_status = 0;
    Trade->trade_target = 0;
    //PARTY
    Party = new PARTY;
    assert(Party);
    Party->party = NULL;
    Party->IsMaster = true;
    // SHOP    
    Shop = new SHOP;
    assert(Shop);
    Shop->open = false;
    memset( &Shop->name, '\0',64 );
    for(int i=0;i<30;i++)
    {
        ClearItem(Shop->BuyingList[i].item);
        Shop->BuyingList[i].slot = 0;
        Shop->BuyingList[i].count = 0;
        Shop->BuyingList[i].price = 0;
        Shop->SellingList[i].slot = 0;
        Shop->SellingList[i].count = 0;
        Shop->SellingList[i].price = 0;        
    }
    Shop->Buying = 0;
    Shop->Selling = 0;
    Shop->ShopType = 0;
    Shop->mil_shop_time=0;
    
    //bonusxp
    timerxp=0;
    bonusxp=1;
    wait_validation=0;
    once=false;
    
    // SESSION
    Session = new SESSION;
    assert(Session);
	Session->userid = 0;
	memset( &Session->username, '\0', 17 );
	memset( &Session->password, '\0', 33 );	
	Session->accesslevel = 0;
	Session->isLoggedIn = false;
	Session->inGame = false;
	// Inventory / storage
    for(unsigned int i=0;i<MAX_INVENTORY;i++)
        ClearItem( items[i] );
    for(unsigned int i=0;i<MAX_STORAGE;i++)
        ClearItem( storageitems[i] );    
    // Clan
    Clan = new CLAN;
    assert(Clan);
    Clan->clanid = 0;
    Clan->clanrank = 0;
    Clan->grade = 0;
    Clan->logo = 0;
    Clan->back = 0;
    memset( &Clan->clanname, '\0', 17 );
    // ATTRIBUTES
    Attr = new ATTRIBUTES;
    assert(Attr);
    Attr->Str = 0;
    Attr->Dex = 0;
    Attr->Int = 0;
    Attr->Con = 0;
    Attr->Cha = 0;
    Attr->Sen = 0;    
    Attr->Estr = 0;
    Attr->Edex = 0;
    Attr->Eint = 0;
    Attr->Econ = 0;
    Attr->Echa = 0;
    Attr->Esen = 0;   
    
    CharType = TPLAYER;

    questdebug = false;
    Saved = false;
    isInvisibleMode = false;
    Fairy = false;
    hits = 0;
    //FairyTime = 0;
    nstorageitems = 0;
    nsitemmallitems = 0;
    p_skills = 0;
    for(int i=0;i<MAX_SKILL;i++)
    {
        cskills[i].id = 0;
        cskills[i].level = 0;
    }
    for(int i=0;i<MAX_BASICSKILL;i++)
        bskills[i] = 0;
    for(int i=0;i<MAX_QUICKBAR;i++)
        quickbar[i] = 0;
    MyQuest.clear( );
    ActiveQuest = 0;
    lastRegenTime = 0;
    lastSaveTime = clock( );
    firstlogin=clock();     //LMA for fairy
    lastGG = 0;
    VisiblePlayers.clear( );
    VisibleDrops.clear( );
    VisibleMonsters.clear( );
    VisibleNPCs.clear( );
}
Beispiel #11
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;
    }
}
Beispiel #12
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;
}
void EnemyPlane::UpdatePlane()
{
	if (g_Time - m_ShowTime < m_Delay)
	{
		return;
	}

	switch (m_iState)
	{
	case P_ALIVE:
		if (abs(m_iDesX-m_iX)>m_iSpeed || abs(m_iDesY-m_iY)>m_iSpeed)
		{
			m_iAngle = atan((double)(m_iDesX-m_iX)/(double)(m_iDesY-m_iY));

			if (m_iDesY > m_iY)
			{
				SetX(m_iX + (int)(m_iSpeed*sin(m_iAngle)));
				SetY(m_iY + (int)(m_iSpeed*cos(m_iAngle)));
			}
			else if(m_iDesY < m_iY)
			{
				SetX(m_iX - (int)(m_iSpeed*sin(m_iAngle)));
				SetY(m_iY - (int)(m_iSpeed*cos(m_iAngle)));
			}
			else
			{
				if (m_iDesX > m_iX)
				{
					SetX(m_iX+m_iSpeed);
				}
				else
				{
					SetX(m_iX-m_iSpeed);
				}
			}

			//更新发射器的位置
			for (int i=0; i<(int)m_vShooterGroup.size(); i++)
			{
				for (int j=0; j<(int)m_vShooterGroup[i].size(); j++)
				{
					m_vShooterGroup[i][j]->SetPos(m_iX, m_iY);
				}
			}
			
			//更新所携带物品的位置
			for (int i=0; i<(int)items.size(); i++)
			{
				items[i]->SetPos(m_iX, m_iY);
			}
		}
		else
		{
			m_bMoveable = true;
			vector<Shooter*> *pShooters = NULL;
			if (!m_vShooterGroup.empty())
			{
				pShooters = &m_vShooterGroup[m_iNowShooterGroup];
				for (int i=0; i<(int)pShooters->size(); i++)
				{
					if (m_bFireCommand)
					{
						(*pShooters)[i]->SetCommand(true);
						m_bMoveable &= (*pShooters)[i]->Fire(false); 
					}
				}
			}

			if (m_bMoveable)
			{
				m_iNowPos++;

				if (m_iNowPos >= (int)posMap.size())
				{
					m_iNowPos = 0;
				}

				m_iDesX = posMap[m_iNowPos].x;
				m_iDesY = posMap[m_iNowPos].y;

				if (pShooters)
				{
					m_iNowShooterGroup = rand()%(int)m_vShooterGroup.size();

					for (int i=0; i<(int)pShooters->size(); i++)
					{
						(*pShooters)[i]->SetCommand(false);
						(*pShooters)[i]->Reload(); 
					}
				}
			}
		}

		{
			//判断与子弹的碰撞
			vector<Bullet*> *pBullets = g_Manager.GetMyBulletVector();
			for (int i=0; i<(int)pBullets->size(); i++)
			{
				if (!(*pBullets)[i])
				{
					continue;
				}

				if (IsImpact((*pBullets)[i]->GetImpactBox()))
				{
					delete (*pBullets)[i];
					(*pBullets)[i] = NULL;
					g_Manager.AddScore(10);

					m_iHp--;
					if (m_iHp <= 0)
					{
						//弹出物品
						for (int i=0; i<(int)items.size(); i++)
						{
							if(!items[i]) continue;

							g_Manager.AddItemToVector(items[i]);
						}
						ClearItem();

						//飞机爆炸
						PlaySound(".\\Sound\\explosion.wav", NULL,SND_ASYNC|SND_NODEFAULT|SND_FILENAME);
						m_bExplodeOver = false;
						m_iState = P_EXPLODE;
						m_Time = g_Time;
						
						if (m_bIsBoss)
						{
							g_Manager.GetHeroPlane()->AddBoom();
							g_Manager.GetHeroPlane()->BoomStart(false);
						}
					}
				}
			}
		}
		break;

	case P_EXPLODE:
		if (!m_bExplodeOver)
		{
		}
		else
		{
			m_iState = P_DISAPPEAR;
		}
		break;

	case P_DISAPPEAR:
		break;
	}
}
// Get this clients character list
bool CCharServer::pakGetCharacters( CCharClient* thisclient, CPacket* P )
{
	if (!thisclient->isLoggedIn) return false;
    if(!DB->QExecute( "DELETE FROM characters WHERE deletetime>0 AND deletetime<=%i",GetServerTime( ) ))
        return false;
	MYSQL_RES *result;
	MYSQL_ROW row;
	CItem items[10];
	unsigned int charnum=0;
	CCharacter chars[5];
	            //        0       1      2    3      4      5     6      7
	result = DB->QStore("SELECT char_name,level,face,hairStyle,sex,classid,id,deletetime FROM characters WHERE account_name='%s'", thisclient->username);
	if(result==NULL) return false;
	while (row = mysql_fetch_row(result))
    {
        memset( &chars[charnum].char_name, '\0', 17 );
		strcpy( chars[charnum].char_name , row[0] );
		chars[charnum].level = atoi(row[1]);
		chars[charnum].face = atoi(row[2]);
		chars[charnum].hairStyle = atoi(row[3]);
		chars[charnum].sex = atoi(row[4]);
		chars[charnum].classid = atoi(row[5]);
		chars[charnum].id = atoi(row[6]);
        chars[charnum].DeleteTime = atoi(row[7]);
		if(chars[charnum].DeleteTime > 0)
		{
            chars[charnum].DeleteTime = chars[charnum].DeleteTime - GetServerTime( );
        }
		charnum++;
	}
	DB->QFree( );
	BEGINPACKET( pak, 0x0712 );
	ADDBYTE    ( pak, charnum );
	for (unsigned k=0;k<charnum;k++)
    {
		for(unsigned j=0; j<10; j++)
            ClearItem( items[j] );
                    //       0       1      2         3         4        5
		result = DB->QStore("SELECT itemnum,itemtype,refine,durability,lifespan,slotnum FROM items WHERE owner=%i AND slotnum<10", chars[k].id);
		if(result==NULL) return false;
		while(row = mysql_fetch_row(result))
        {
			unsigned itemnum = atoi(row[5]);
			items[itemnum].itemnum = atoi(row[0]);
			items[itemnum].itemtype = atoi(row[1]);
			items[itemnum].refine = atoi(row[2]);
			items[itemnum].durability = atoi(row[3]);
			items[itemnum].lifespan = atoi(row[4]);

            //LMA: now with 2010/05, naRose handles until refine 15
            //LMA: little check, refine from 1 to 15 are not valid since it's refine*16 that's we're supposed to store now...
            if(items[itemnum].refine>0&&items[itemnum].refine<=15)
            {
                Log(MSG_WARNING,"Invalid refine %i for item (%i:%i) for %s",items[itemnum].refine,items[itemnum].itemtype,items[itemnum].itemnum,thisclient->username);
                items[itemnum].refine*=16;
            }

            //Another check, just to be sure.
            //LMA: up to refine 15 now (2010/05)...
            switch (items[itemnum].refine)
            {
                case 0:
                case 16:
                case 32:
                case 48:
                case 64:
                case 80:
                case 96:
                case 112:
                case 128:
                case 144:
                case 160:
                case 176:
                case 192:
                case 208:
                case 224:
                case 240:
                {
                    //Ok.
                }
                break;
                default:
                {
                    Log(MSG_WARNING,"Invalid refine %i for item (%i:%i) for %s",items[itemnum].refine,items[itemnum].itemtype,items[itemnum].itemnum,thisclient->username);
                    items[itemnum].refine=0;
                }
                break;

            }

		}
		DB->QFree( );

		ADDSTRING ( pak, chars[k].char_name );
		ADDBYTE   ( pak, 0x00 );
		ADDBYTE   ( pak, chars[k].sex );			// SEX
		ADDWORD   ( pak, chars[k].level );		// LEVEL
		ADDWORD   ( pak, chars[k].classid );		// CLASSID
		ADDDWORD  ( pak, chars[k].DeleteTime );			// DELETE TIME
		ADDBYTE   ( pak, 0x00 );//thisclient->platinum?0x01:0x00 );					// IS PLATINUM?  00-NO;01-YES;02-YES BUT USER IS NOT
		ADDDWORD  ( pak, chars[k].face );		// FACE
		ADDDWORD  ( pak, chars[k].hairStyle );	// HAIR
		ADDWORD   ( pak, items[2].itemnum );		// CAP
		ADDWORD   ( pak, items[2].refine );		// CAP REFINE
		ADDWORD   ( pak, items[3].itemnum );		// BODY
		ADDWORD   ( pak, items[3].refine );		// BODY REFINE
		ADDWORD   ( pak, items[5].itemnum );		// GLOVES
		ADDWORD   ( pak, items[5].refine );		// GLOVES REFINE
		ADDWORD   ( pak, items[6].itemnum );		// BOOTS
		ADDWORD   ( pak, items[6].refine );		// BOOTS REFINE
		ADDWORD   ( pak, items[1].itemnum );		// FACE
		ADDWORD   ( pak, items[1].refine );		// FACE REFINE
		ADDWORD   ( pak, items[4].itemnum );		// BACK
		ADDWORD   ( pak, items[4].refine );		// BACK REFINE
		ADDWORD   ( pak, items[7].itemnum );		// WEAPON
		ADDWORD   ( pak, items[7].refine );		// WEAPON REFINE
		ADDWORD   ( pak, items[8].itemnum );		// SUBWEAPON
		ADDWORD   ( pak, items[8].refine );		// SUBWEAPON REFINE
	}
	thisclient->SendPacket( &pak );

	//LMA: we clean the chat ID.
	if (thisclient->chatroom_id!=0)
	{
	    DisconnectClientFromChat(thisclient);
	}


	return true;
}
Beispiel #15
0
// Get this clients character list
bool CCharServer::pakGetCharacters( CCharClient* thisclient, CPacket* P )
{
	if (!thisclient->isLoggedIn) return false;
    if(!DB->QExecute( "DELETE FROM characters WHERE deletetime>0 AND deletetime<=%i",GetServerTime( ) ))
        return false;
	MYSQL_RES *result;
	MYSQL_ROW row;
	CItem items[10];
	unsigned int charnum=0;
	CCharacter chars[5];    
	            //        0       1      2    3      4      5     6      7
	result = DB->QStore("SELECT char_name,level,face,hairStyle,sex,classid,id,deletetime FROM characters WHERE account_name='%s'", thisclient->username);
	if(result==NULL) return false;
	while (row = mysql_fetch_row(result)) 
    {
        memset( &chars[charnum].char_name, '\0', 17 );
		strcpy( chars[charnum].char_name , row[0] );
		chars[charnum].level = atoi(row[1]);
		chars[charnum].face = atoi(row[2]);
		chars[charnum].hairStyle = atoi(row[3]);
		chars[charnum].sex = atoi(row[4]);
		chars[charnum].classid = atoi(row[5]);
		chars[charnum].id = atoi(row[6]);
        chars[charnum].DeleteTime = atoi(row[7]);		
		if(chars[charnum].DeleteTime > 0)
		{
            chars[charnum].DeleteTime = chars[charnum].DeleteTime - GetServerTime( );    						
        }
		charnum++;
	}
	DB->QFree( );
	BEGINPACKET( pak, 0x0712 );	
	ADDBYTE    ( pak, charnum );
	for (unsigned k=0;k<charnum;k++) 
    {
		for(unsigned j=0; j<10; j++) 
            ClearItem( items[j] );
                    //       0       1      2         3         4        5
		result = DB->QStore("SELECT itemnum,itemtype,refine,durability,lifespan,slotnum FROM items WHERE owner=%i AND slotnum<10", chars[k].id);
		if(result==NULL) return false;
		while(row = mysql_fetch_row(result)) 
        {
			unsigned itemnum = atoi(row[5]);
			items[itemnum].itemnum = atoi(row[0]);
			items[itemnum].itemtype = atoi(row[1]);
			items[itemnum].refine = atoi(row[2]);
			items[itemnum].durability = atoi(row[3]);
			items[itemnum].lifespan = atoi(row[4]);
		}
		DB->QFree( );

		ADDSTRING ( pak, chars[k].char_name );
		ADDBYTE   ( pak, 0x00 );
		ADDBYTE   ( pak, chars[k].sex );			// SEX
		ADDWORD   ( pak, chars[k].level );		// LEVEL
		ADDWORD   ( pak, chars[k].classid );		// CLASSID
		ADDDWORD  ( pak, chars[k].DeleteTime );			// DELETE TIME
		ADDBYTE   ( pak, 0x00 );//thisclient->platinum?0x01:0x00 );					// IS PLATINUM?  00-NO;01-YES;02-YES BUT USER IS NOT
		ADDDWORD  ( pak, chars[k].face );		// FACE
		ADDDWORD  ( pak, chars[k].hairStyle );	// HAIR
		ADDWORD   ( pak, items[2].itemnum );		// CAP
		ADDWORD   ( pak, items[2].refine );		// CAP REFINE
		ADDWORD   ( pak, items[3].itemnum );		// BODY
		ADDWORD   ( pak, items[3].refine );		// BODY REFINE
		ADDWORD   ( pak, items[5].itemnum );		// GLOVES
		ADDWORD   ( pak, items[5].refine );		// GLOVES REFINE
		ADDWORD   ( pak, items[6].itemnum );		// BOOTS
		ADDWORD   ( pak, items[6].refine );		// BOOTS REFINE
		ADDWORD   ( pak, items[1].itemnum );		// FACE
		ADDWORD   ( pak, items[1].refine );		// FACE REFINE
		ADDWORD   ( pak, items[4].itemnum );		// BACK
		ADDWORD   ( pak, items[4].refine );		// BACK REFINE 
		ADDWORD   ( pak, items[7].itemnum );		// WEAPON
		ADDWORD   ( pak, items[7].refine );		// WEAPON REFINE
		ADDWORD   ( pak, items[8].itemnum );		// SUBWEAPON
		ADDWORD   ( pak, items[8].refine );		// SUBWEAPON REFINE
	}
	thisclient->SendPacket( &pak );
	return true;
}
Beispiel #16
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;
}