Пример #1
0
// Clan Manager
bool CWorldServer::pakClanManager ( CPlayer* thisclient, CPacket* P )
{    
    int action = GETBYTE((*P),0);
    switch(action)
    {
        case 0xf0:
        {
            MYSQL_ROW row;                
            int charid = GETWORD((*P),1);
            int clanid = GETWORD((*P),3);        
            CPlayer* otherclient = GetClientByCID ( charid );
            if(otherclient==NULL)
                return true;
    	    MYSQL_RES *result = DB->QStore("SELECT logo,back,name,grade FROM list_clan where id=%i", clanid);
    	    if(result==NULL) return true;
        	if(mysql_num_rows(result)!=1)
        	{
                Log(MSG_WARNING, "Invalid clan %i", clanid );
                DB->QFree( );
          	    return true;
            }
            row = mysql_fetch_row(result);
        	otherclient->Clan->logo = atoi(row[0]);
    	    otherclient->Clan->back = atoi(row[1]);    	   
    	    strcpy(otherclient->Clan->clanname,row[2]);
    	    otherclient->Clan->grade = atoi(row[3]);
        	DB->QFree( );
            BEGINPACKET( pak, 0x7e0 );
            ADDBYTE    ( pak, 0x35 );//funcion
            ADDWORD    ( pak, otherclient->clientid );//cleint id
            ADDWORD    ( pak, clanid );//?
            ADDWORD    ( pak, 0x0000 );//?
            ADDWORD    ( pak, otherclient->Clan->back );//?
            ADDWORD    ( pak, otherclient->Clan->logo );//?
            ADDBYTE    ( pak, otherclient->Clan->grade );
            ADDBYTE    ( pak, otherclient->Clan->clanrank);
            ADDSTRING  ( pak, otherclient->Clan->clanname );            
            ADDBYTE    ( pak, 0x00 );  
            SendToVisible( &pak, otherclient );
            Log(MSG_INFO,"[WS] pakClanManager 0x7e0, case 0xf0 (new member too?) %s",otherclient->CharInfo->charname);
        }
        case 0xfa://new member added
        {
        	MYSQL_ROW row;                
            int charid = GETWORD((*P),1);
            int clanid = GETWORD((*P),3);        
            CPlayer* otherclient = GetClientByCID ( charid );
            if(otherclient==NULL)
                return true;
    	    MYSQL_RES *result = DB->QStore("SELECT logo,back,name,grade FROM list_clan where id=%i", clanid);
    	    if(result==NULL) return true;
        	if(mysql_num_rows(result)!=1)
        	{
                Log(MSG_WARNING, "Invalid clan %i", clanid );
                DB->QFree( );
          	    return true;
            }
            row = mysql_fetch_row(result);
        	otherclient->Clan->logo = atoi(row[0]);
    	    otherclient->Clan->back = atoi(row[1]);    	   
    	    strcpy(otherclient->Clan->clanname,row[2]);
    	    otherclient->Clan->grade = atoi(row[3]);
        	DB->QFree( );   
            otherclient->Clan->clanid=clanid;
            otherclient->Clan->clanrank=1;
            BEGINPACKET( pak, 0x7e0 );
            ADDBYTE    ( pak, 0x35 );//funcion
            ADDWORD    ( pak, otherclient->clientid );//cleint id
            ADDWORD    ( pak, clanid );//?
            ADDWORD    ( pak, 0x0000 );//?
            ADDWORD    ( pak, otherclient->Clan->back );//?
            ADDWORD    ( pak, otherclient->Clan->logo );//?
            ADDBYTE    ( pak, otherclient->Clan->grade );
            ADDBYTE    ( pak, otherclient->Clan->clanrank );
            ADDSTRING  ( pak, otherclient->Clan->clanname );
            ADDBYTE    ( pak, 0x00 );  
            SendToVisible( &pak, otherclient );
            Log(MSG_INFO,"[WS] pakClanManager 0x7e0, new member %s",otherclient->CharInfo->charname);
        }
        break;
        case 0xfb://Member Kicked
        {
           char nick[30];
           memcpy( nick, &P->Buffer[1], P->Size );    
           CPlayer* otherclient = GetClientByCharName( nick );
           if(otherclient!=NULL)
           {
                otherclient->Clan->clanid=0;
                otherclient->Clan->clanrank=1;
	            otherclient->Clan->back=0;
	            otherclient->Clan->logo=0;
	            otherclient->Clan->grade=0;
	            strcpy(otherclient->Clan->clanname,"");
                BEGINPACKET( pak, 0x7e0 );
                ADDBYTE    ( pak, 0x35 );
                ADDWORD    ( pak, otherclient->clientid );
                ADDQWORD   ( pak, 0 );
                ADDWORD    ( pak, 0x0001 );
                SendToVisible( &pak, otherclient );
                Log(MSG_INFO,"[WS] pakClanManager 0x7e0, member kicked, %s",nick);
           }                    
        }
        break;
        case 0xfc://member change rank
        {
           char nick[30];
           int newrank = GETBYTE((*P),1);
           memcpy( nick, &P->Buffer[2], P->Size );    
           CPlayer* otherclient = GetClientByCharName( nick );
           if(otherclient!=NULL)
           {
                otherclient->Clan->clanrank = newrank;
                Log(MSG_INFO,"[WS] pakClanManager 0x7e0, change rank for %s to %i",nick,newrank);
           }           
        }
        break;      
        case 0xfd://disorg
        {
            unsigned int clanid = GETWORD((*P),1);
            unsigned int charid = GETWORD((*P),3);
            CPlayer* tclient = GetClientByCID( charid );
            if(tclient==NULL)
                return true;
            tclient->Clan->clanid = 0;
            tclient->Clan->clanrank = 1;
            tclient->Clan->grade = 0;
            tclient->Clan->back = 0;
            tclient->Clan->logo = 0;
            memset( &tclient->Clan->clanname, '\0', 17 );
            BEGINPACKET( pak, 0x7e0 );
            ADDBYTE    ( pak, 0x35 );
            ADDWORD    ( pak, tclient->clientid );
            ADDQWORD   ( pak, 0 );
            ADDWORD    ( pak, 0x0001 );
            SendToVisible( &pak, tclient );
            Log(MSG_INFO,"[WS] pakClanManager 0x7e0, disorg");                           
        }
        break;  
        case 0xfe://Member Leave
        {
           char nick[17];
           memcpy( nick, &P->Buffer[1], P->Size );    
           CPlayer* otherclient = GetClientByCharName(nick);
           if(otherclient!=NULL)
           {
                otherclient->Clan->clanid=0;
                otherclient->Clan->clanrank=0;
	            otherclient->Clan->back=0;
	            otherclient->Clan->logo=0;
	            otherclient->Clan->grade=0;
	            strcpy(otherclient->Clan->clanname,"");
                BEGINPACKET( pak, 0x7e0 );
                ADDBYTE    ( pak, 0x35 );
                ADDWORD    ( pak, otherclient->clientid );
                ADDQWORD   ( pak, 0 );
                ADDWORD    ( pak, 0x0001 );
                SendToVisible( &pak, otherclient );
                Log(MSG_INFO,"[WS] pakClanManager 0x7e0, member left");	                            
           }                    
        }
        break;    
        case 0xff: // update clan mark
        {    
            unsigned int clanid = GETWORD((*P),1);
            unsigned int clanlogo = GETDWORD((*P), 3 );   
            for(unsigned int i=0;i<ClientList.size();i++)
            {
                if(ClientList.at(i)->player==NULL) continue;
                CPlayer* player = (CPlayer*)ClientList.at(i)->player;
                if(player->Clan->clanid==clanid)
                {
                    player->Clan->back = 0;
                    player->Clan->logo = clanlogo;
                    BEGINPACKET( pak, 0x7e0 );
                    ADDBYTE    ( pak, 0x35 );//funcion
                    ADDWORD    ( pak, player->clientid );//cleint id
                    ADDWORD    ( pak, clanid );//?
                    ADDWORD    ( pak, 0x0000 );//?
                    ADDWORD    ( pak, player->Clan->back );//?
                    ADDWORD    ( pak, player->Clan->logo );//?
                    ADDBYTE    ( pak, player->Clan->grade );
                    ADDBYTE    ( pak, player->Clan->clanrank );
                    ADDSTRING  ( pak, player->Clan->clanname );                    
                    ADDBYTE    ( pak, 0x00 );  
                    SendToVisible( &pak, player );   
                    Log(MSG_INFO,"[WS] pakClanManager 0x7e0, update clan mark");
                }
            }                 
        }
        break;
        default:
            Log( MSG_INFO, "Clan manager unknown action %i", action );
    }
    return true;
}
Пример #2
0
// Give Exp
bool CWorldServer::GiveExp( CMonster* thismon, UINT special_lvl, UINT special_exp )
{       
    if( thismon->owner != 0) // Summon 
	{          
        MapList.Index[thismon->Position->Map]->DeleteMonster( thismon );
	    return true;
    }
    // Give Experience Drops and Quest Items
    vector<CPartyExp*> PartyExp;    
    for(UINT i=0;i<thismon->PlayersDamage.size();i++)
    {                     
        MonsterDamage* thisplayer = thismon->PlayersDamage.at(i);              
		CPlayer* thisclient = GetClientByCID( thisplayer->charid, thismon->Position->Map );        		
		if( thisplayer->damage>0 && thisclient!=NULL )
        {                        
    		if( thisclient->Battle->target == thismon->clientid )    
            {     
                ClearBattle( thisclient->Battle )
                thisclient->Position->destiny = thisclient->Position->current; //GIVE EXP FUNCTION
            }                                     
            if( thismon->MonsterDrop->firsthit == thisclient->CharInfo->charid )
            {
                // Give Quest Item
                QUESTS* myquest = thisclient->GetQuestByMob( thismon->montype );
                if( myquest!=0 )
                {
                    BEGINPACKET( pak, 0x731 )
                    ADDWORD    ( pak, thismon->montype );
                    thisclient->client->SendPacket( &pak );                    
                }
            }    
            
            //LMA BEGIN
            //20070621-211100
            //mods for CF...
            unsigned int exp = (unsigned int)ceil((thismon->thisnpc->exp * thisplayer->damage) / (thismon->thisnpc->hp*thismon->thisnpc->level)+special_exp);
            //LMA END
                                  
            /*unsigned int cp = (unsigned int)ceil((thismon->thisnpc->level/6 * thisplayer->damage) / thismon->thisnpc->hp);  
            //ADD Clan points under any condition
            if ((thismon->Position->Map>=11 && thismon->Position->Map<= 13) || thismon->Position->Map== 59) //So far only junon maps
            {
               thisclient->AddClanPoints(GetColorExp( cp));
            }*/
            
            exp = exp * Config.EXP_RATE * 6;            
            if( thisclient->Party->party!=NULL )
            {                                        
                bool pflag = false;
                
                for(int i=0;i<PartyExp.size();i++)
                {
                    CPartyExp* thisparty = PartyExp.at( i );
                    if( thisparty->thisparty == thisclient->Party->party )
                    {
                        thisparty->exp += exp;
                        thisparty->exp += exp * ((thisclient->Party->party->PartyLevel*2) / 100);
                        pflag = true;
                    }
                }
                if( !pflag )
                {
                    CPartyExp* thisparty = new CPartyExp;
                    thisparty->thisparty = thisclient->Party->party;
                    thisparty->exp = exp;
                    thisparty->flag = false;
                    thisparty->exp += exp * ((thisclient->Party->party->PartyLevel*2) / 100);
                    thisparty->num = 1;
                    thisparty->partymember[0] = thisclient->CharInfo->charid;
                    thisparty->maxlevel = thisclient->Stats->Level;
                    for(int p=0;p<thisclient->VisiblePlayers.size();p++)
                    {
                        CPlayer* otherclient = thisclient->VisiblePlayers.at( p );
                        if(otherclient->Party->party==NULL) continue;
                        if( thisclient->Party->party == otherclient->Party->party )
                        {
                            thisparty->partymember[thisparty->num] = otherclient->CharInfo->charid;
                            thisparty->num++;
                            thisparty->maxlevel += otherclient->Stats->Level;
                        }
                    }
                    PartyExp.push_back( thisparty );
                }
                continue;   
            }
            
             //LMA BEGIN
             //20070621-211100
            //mod for CF
            //Adding bonusxp (mileage)
            thisclient->CharInfo->Exp +=  thisclient->bonusxp*GetColorExp( thisclient->Stats->Level, thismon->thisnpc->level + special_lvl, exp );
            //LMA END
            
            BEGINPACKET( pak, 0x79b );
            ADDDWORD   ( pak, thisclient->CharInfo->Exp );
            ADDWORD    ( pak, thisclient->CharInfo->stamina );
            ADDWORD    ( pak, 0 );
            thisclient->client->SendPacket( &pak );                                
        }        
    } 
    for(int p=0;p<PartyExp.size();p++)
    {
        CPartyExp* thisparty = PartyExp.at( p );
        for(int i=0;i<thisparty->num;i++)
        {
            CPlayer* partyclient = GetClientByCID( thisparty->partymember[i], thismon->Position->Map );
            if( partyclient==NULL )
                continue;
            if(partyclient->Party->party==NULL)
                continue;                   
            if(!thisparty->flag)
            {
                partyclient->Party->party->Exp += (thisparty->exp / 6) / 2;
                if( partyclient->Party->party->PartyLevel == 50)
                {
                    partyclient->Party->party->Exp = 0;
                }
                if( partyclient->Party->party->Exp > GetMaxPartyExp( partyclient->Party->party->PartyLevel ) )
                {
                    partyclient->Party->party->PartyLevel++;
                    partyclient->Party->party->Exp -= GetMaxPartyExp( partyclient->Party->party->PartyLevel-1 );
                }                
                BEGINPACKET( pak, 0x7d4 );
                ADDBYTE    ( pak, partyclient->Party->party->PartyLevel );
                ADDDWORD   ( pak, partyclient->Party->party->Exp );
                partyclient->Party->party->SendToMembers( &pak );
                thisparty->flag = true;
            }             
             
            //LMA Begin
            //20070621-211100
            //mods for CF
            unsigned int expoption = partyclient->Party->party->Option%0x80;       
            if( expoption==0 )           
            {
                
                partyclient->CharInfo->Exp +=  GetColorExp( partyclient->Stats->Level, thismon->Stats->Level + special_lvl, (UINT)round(thisparty->exp / thisparty->num) );                
            }
            else
            {
                partyclient->CharInfo->Exp +=  GetColorExp( partyclient->Stats->Level, thismon->Stats->Level + special_lvl, (UINT)round(partyclient->Stats->Level * thisparty->exp / thisparty->maxlevel) );                                                               
            }
            //LMA END
                       		
    		BEGINPACKET( pak, 0x79b );
    		ADDDWORD   ( pak, partyclient->CharInfo->Exp );
    		ADDWORD    ( pak, partyclient->CharInfo->stamina );
    		ADDWORD    ( pak, 0 );
    		partyclient->client->SendPacket( &pak );   
        }            
    }                 
    MapList.Index[thismon->Position->Map]->DeleteMonster( thismon );
    return true;		
}        
Пример #3
0
// Give Exp
bool CWorldServer::GiveExp( CMonster* thismon, UINT special_lvl, UINT special_exp )
{
    if( thismon->owner != 0) // Summon
	{
        MapList.Index[thismon->Position->Map]->DeleteMonster( thismon );
	    return true;
    }

    //LMA TEST
    bool lma_debug=false;
   if(thismon->Position->respawn==4589)
   {
       lma_debug=true;
       Log(MSG_INFO,"GiveExp Spawn %u CID %u",thismon->Position->respawn,thismon->clientid);
   }

    // Give Experience Drops and Quest Items
    vector<CPartyExp*> PartyExp;
    for(UINT i=0;i<thismon->PlayersDamage.size();i++)
    {
        MonsterDamage* thisplayer = thismon->PlayersDamage.at(i);
		CPlayer* thisclient = GetClientByCID( thisplayer->charid, thismon->Position->Map );

        //LMA: Player mustn't be dead.
		if( thisplayer->damage>0 && thisclient!=NULL && !thisclient->IsDead())
        {
    		if( thisclient->Battle->target == thismon->clientid )
            {
                ClearBattle( thisclient->Battle )
                thisclient->Position->destiny = thisclient->Position->current; //GIVE EXP FUNCTION
            }
            if( thismon->MonsterDrop->firsthit == thisclient->CharInfo->charid )
            {
                for( int q=0;q<10;q++)
                {
                    // Give Quest Item
                    if( thisclient->quest.quests[q].QuestID!=0 )
                    {
                        BEGINPACKET( pak, 0x731 )
                        ADDWORD    ( pak, thismon->montype );
                        thisclient->client->SendPacket( &pak );
                        break;
                    }
                }

            }

            //LMA BEGIN
            //20070621-211100
            //mods for CF...
            //unsigned int exp = (unsigned int)ceil((thismon->thisnpc->exp * thisplayer->damage) / (thismon->thisnpc->hp*thismon->thisnpc->level)+special_exp);
            unsigned long long exp = (unsigned long long)ceil((thismon->thisnpc->exp * thisplayer->damage) / (thismon->thisnpc->hp*thismon->thisnpc->level)+special_exp);
            //LMA END

            /*unsigned int cp = (unsigned int)ceil((thismon->thisnpc->level/6 * thisplayer->damage) / thismon->thisnpc->hp);
            //ADD Clan points under any condition
            if ((thismon->Position->Map>=11 && thismon->Position->Map<= 13) || thismon->Position->Map== 59) //So far only junon maps
            {
               thisclient->AddClanPoints(GetColorExp( cp));
            }*/

            exp = exp * (unsigned long long) (Config.EXP_RATE * 6);
            if( thisclient->Party->party!=NULL )
            {
                bool pflag = false;

                for(int i=0;i<PartyExp.size();i++)
                {
                    CPartyExp* thisparty = PartyExp.at( i );
                    if( thisparty->thisparty == thisclient->Party->party )
                    {
                        //LMA: We get exp only if we deserve it.
                        //thisparty->exp += exp;
                        thisparty->exp += GetColorExp( thisclient->Stats->Level, thismon->thisnpc->level + special_lvl, exp );
                        //LMA: bug...
                        //thisparty->exp += exp * (unsigned long long) ((thisclient->Party->party->PartyLevel*2) / 100);
                        thisparty->exp += (unsigned long long) ((exp*thisclient->Party->party->PartyLevel*2) / 100);
                        pflag = true;
                    }
                }

                if( !pflag )
                {
                    CPartyExp* thisparty = new CPartyExp;
                    thisparty->thisparty = thisclient->Party->party;
                    //LMA: We get exp only if we deserve it.
                    thisparty->exp = exp;
                    thisparty->exp = GetColorExp( thisclient->Stats->Level, thismon->thisnpc->level + special_lvl, exp );
                    thisparty->flag = false;
                    //LMA: bug
                    //thisparty->exp += exp * (unsigned long long) ((thisclient->Party->party->PartyLevel*2) / 100);
                    thisparty->exp += (unsigned long long) ((exp*thisclient->Party->party->PartyLevel*2) / 100);
                    thisparty->num = 1;
                    thisparty->partymember[0] = thisclient->CharInfo->charid;
                    thisparty->cheat_max_lvl=thisclient->Stats->Level;
                    thisparty->cheat_min_lvl=thisclient->Stats->Level;
                    thisparty->maxlevel = thisclient->Stats->Level;
                    for(unsigned int p=0;p<ClientList.size();p++)
                    {
                        CPlayer* otherclient = (CPlayer*) ClientList.at( p )->player;
                        if(otherclient->client==NULL) continue;
                        if(otherclient->Party->party==NULL) continue;
                        if(!otherclient->client->isActive) continue;
                        if(!otherclient->Session->inGame) continue;

                        //LMA: checking the gap between the max and min level of people in the party.
                        if (thisclient->Party->party == otherclient->Party->party)
                        {
                            if(otherclient->Stats->Level>thisparty->cheat_max_lvl)
                            {
                                thisparty->cheat_max_lvl=otherclient->Stats->Level;
                            }

                            if(otherclient->Stats->Level<thisparty->cheat_min_lvl)
                            {
                                thisparty->cheat_min_lvl=otherclient->Stats->Level;
                            }

                        }

                        if( IsVisible(thisclient, otherclient))
                        {
                            if(thisclient->Party->party == otherclient->Party->party )
                            {
                                //LMA: Little stupid check.
                                if (thisparty->num==7)
                                {
                                    Log(MSG_WARNING,"Too many people in this party, already at max, skipping");
                                    break;
                                }

                                thisparty->partymember[thisparty->num] = otherclient->CharInfo->charid;
                                thisparty->num++;
                                thisparty->maxlevel += otherclient->Stats->Level;
                            }
                        }
                    }
                    PartyExp.push_back( thisparty );
                }
                continue;
            }

             //LMA BEGIN
             //20070621-211100
            //mod for CF
            //Adding bonusxp (mileage)
            //UINT prev_xp=thisclient->CharInfo->Exp;

            //LMA: Xp nullifier.
            if(!thisclient->no_exp)
            {
                thisclient->CharInfo->Exp +=  thisclient->bonusxp*GetColorExp( thisclient->Stats->Level, thismon->thisnpc->level + special_lvl, exp );
            }

            //Log(MSG_INFO,"Bonus XP %i, previous XP, %i, new: %i",thisclient->bonusxp,prev_xp,thisclient->CharInfo->Exp);
            //LMA END

            //LMA: We don't send exp packet if there is a level up coming up next.
            if(thisclient->CharInfo->Exp<thisclient->GetLevelEXP())
            {
                //LMA: TEST
                //Log(MSG_INFO,"new exp in giveexp %I64i",thisclient->CharInfo->Exp);
                BEGINPACKET( pak, 0x79b );
                ADDDWORD   ( pak, thisclient->CharInfo->Exp );
                ADDWORD    ( pak, thisclient->CharInfo->stamina );
                //ADDWORD    ( pak, 0 );
                ADDWORD    ( pak, thismon->clientid );
                thisclient->client->SendPacket( &pak );
            }

        }

    }


    for(int p=0;p<PartyExp.size();p++)
    {
        CPartyExp* thisparty = PartyExp.at( p );
        //LMA: no exp if a player has a too low level... This is another version in this case, NONE of the guys got exp...
        //HIGHRATEPARTYEXPNONE
        /*if(abs(thisparty->cheat_min_lvl-thisparty->cheat_max_lvl)>(Config.Partygap+1))
        {
            Log(MSG_HACK,"A Party tryes to get exp which has min_lvl %i and max_lvl %i that don't fit max gap %i",thisparty->cheat_min_lvl,thisparty->cheat_max_lvl,Config.Partygap+1);
            continue;
        }*/
        //LMA: End of HIGHRATEPARTYEXPNONE.

        for(int i=0;i<thisparty->num;i++)
        {
            CPlayer* partyclient = GetClientByCID( thisparty->partymember[i], thismon->Position->Map );
            if( partyclient==NULL )
                continue;
            if(partyclient->Party->party==NULL)
                continue;

            //LMA: no exp if a player has a too low level...
            //Uncomment this part of code below if you want to use it... (HIGHRATEPARTYEXP)
            /*if(abs(partyclient->Stats->Level-thisparty->cheat_max_lvl)>(Config.Partygap+1))
            {
                Log(MSG_HACK,"Player %s is lvl %i and tryes to get exp in a party which has max_lvl %i and max gap %i",partyclient->CharInfo->charname,partyclient->Stats->Level,thisparty->cheat_max_lvl,Config.Partygap+1);
                continue;
            }*/
            //Uncomment should end here for HIGHRATEPARTYEXP.

            if(!thisparty->flag)
            {
                //partyclient->Party->party->Exp += (thisparty->exp / 6) / 2;
                partyclient->Party->party->Exp += (thisparty->exp / 6) / 6; //Tomiz: thisparty->exp decreased
                if( partyclient->Party->party->PartyLevel == 50)
                {
                    partyclient->Party->party->Exp = 0;
                }

                //LMA: old code
                /*if( partyclient->Party->party->Exp > GetMaxPartyExp( partyclient->Party->party->PartyLevel ) )
                {
                    partyclient->Party->party->PartyLevel++;
                    partyclient->Party->party->Exp -= GetMaxPartyExp( partyclient->Party->party->PartyLevel-1 );
                }
                */

                //New code.
                bool new_level=false;
                while(partyclient->Party->party->PartyLevel<50&&partyclient->Party->party->Exp > GetMaxPartyExp( partyclient->Party->party->PartyLevel ) )
                {
                    partyclient->Party->party->PartyLevel++;
                    partyclient->Party->party->Exp -= GetMaxPartyExp( partyclient->Party->party->PartyLevel-1 );
                    Log(MSG_INFO,"Going from party level %i to %i, exp left %I64i",partyclient->Party->party->PartyLevel-1,partyclient->Party->party->PartyLevel,partyclient->Party->party->Exp);
                    new_level=true;
                }

                if( partyclient->Party->party->PartyLevel == 50)
                {
                    partyclient->Party->party->Exp = 0;
                }

                //Strange thing when a new level:
                unsigned long long send_exp=partyclient->Party->party->Exp;
                if(new_level)
                {
                    send_exp+=0x80000000;
                }

                Log(MSG_INFO,"Exp sent: %I64i",send_exp);
                //End of code.

                BEGINPACKET( pak, 0x7d4 );
                ADDBYTE    ( pak, partyclient->Party->party->PartyLevel );

                //LMA: little change.
                //ADDDWORD   ( pak, partyclient->Party->party->Exp );
                ADDDWORD   ( pak, send_exp );

                partyclient->Party->party->SendToMembers( &pak );
                thisparty->flag = true;
            }

            //LMA: no exp for dead people.
            if(partyclient->IsDead())
            {
                Log(MSG_INFO,"No exp for player %s, he's dead.",partyclient->CharInfo->charname);
                continue;
            }

            //LMA Begin
            //20070621-211100
            //mods for CF
            unsigned int expoption = partyclient->Party->party->Option%0x80;
            //LMA: Exp nullfier.
            if(!partyclient->no_exp)
            {
                if( expoption==0 )
                {

                    partyclient->CharInfo->Exp +=  GetColorExp( partyclient->Stats->Level, thismon->Stats->Level + special_lvl, (UINT)round(thisparty->exp / thisparty->num) );
                }
                else
                {
                    partyclient->CharInfo->Exp +=  GetColorExp( partyclient->Stats->Level, thismon->Stats->Level + special_lvl, (UINT)round(partyclient->Stats->Level * thisparty->exp / thisparty->maxlevel) );
                }

            }
            //LMA END

            if(partyclient->CharInfo->Exp<partyclient->GetLevelEXP())
            {
                //LMA: TEST
                //Log(MSG_INFO,"new exp in giveexp %I64i",partyclient->CharInfo->Exp);
                BEGINPACKET( pak, 0x79b );
                ADDDWORD   ( pak, partyclient->CharInfo->Exp );
                ADDWORD    ( pak, partyclient->CharInfo->stamina );
                //ADDWORD    ( pak, 0 );
                ADDWORD    ( pak, thismon->clientid );
                partyclient->client->SendPacket( &pak );
            }

        }
    }

    //LMA: cleaning time.
    for(int p=0;p<PartyExp.size();p++)
    {
        //It seems it's ok, the class party destructor isn't beeing called...
        delete PartyExp.at(p);
    }

    if (lma_debug)
    {
        Log(MSG_INFO,"END GiveExp Spawn %u CID %u",thismon->Position->respawn,thismon->clientid);
    }

    MapList.Index[thismon->Position->Map]->DeleteMonster( thismon );


    return true;
}
Пример #4
0
// Give Exp
bool CWorldServer::GiveExp( CMonster* thismon )
{
    Log(MSG_DEBUG,"Awarding EXP");
    int tmpMult = 1;
    if( thismon->owner != 0) // Summon
	{
        MapList.Index[thismon->Position->Map]->DeleteMonster( thismon );
	    return true;
    }
    // Give Experience Drops and Quest Items
    vector<CPartyExp*> PartyExp;
    vector<CParty*> PartyList;
	CMap* map = GServer->MapList.Index[thismon->Position->Map];
    for(UINT i=0;i<thismon->PlayersDamage.size();i++)
    {
        MonsterDamage* thisplayer = thismon->PlayersDamage.at(i);
		CPlayer* thisclient = GetClientByCID( thisplayer->charid, thismon->Position->Map );
		if( thisplayer->damage > 0 && thisclient != NULL ) //player did some damage
        {
    		Log(MSG_DEBUG,"Player did %i damage. max = %i",thisplayer->damage,thismon->Stats->MaxHP);
    		float MyPercent = (float)thisplayer->damage / thismon->Stats->MaxHP;
			if(MyPercent > thisclient->CharInfo->HighestOverkill)
			{
				thisclient->CharInfo->HighestOverkill = MyPercent;
				SendPM(thisclient, "Congratulations!! You have exceeded your highest ever Overkill rate. New Best: %f",thisclient->CharInfo->HighestOverkill);
			}
    		if(MyPercent > GServer->Config.MaxOverkill)MyPercent = GServer->Config.MaxOverkill;   //set overkill ceiling
			Log(MSG_DEBUG,"Percentage multiplier %f",MyPercent);
            if( thisclient->Battle->target == thismon->clientid )
            {
                ClearBattle( thisclient->Battle )
                thisclient->Position->destiny = thisclient->Position->current;
                //Log(MSG_DEBUG,"(GiveExp) Destiny set to current position X: %f Y: %f.",thisclient->Position->current.x,thisclient->Position->current.y);
            }
            if( thismon->MonsterDrop->firsthit == thisclient->CharInfo->charid )
            {
                for( int q=0;q<10;q++)
                {
                    // Give Quest Item
                    if( thisclient->quest.quests[q].QuestID != 0 )
                    {
                        Log(MSG_DEBUG,"Giving quest reward item for quest %i Killed monster type %i",thisclient->quest.quests[q].QuestID,thismon->montype);
                        //P: Suppressing this completely for a test of the drop code added below
						//BEGINPACKET( pak, 0x731 )
                        //ADDWORD    ( pak, thismon->montype );
                        //thisclient->client->SendPacket( &pak );
						
						//PY: thismon->thisnpc->die_quest contains the hash needed to complete the trigger so we can just bypass the initial part of this process
						int success = thisclient->ExecuteQuestTrigger(thismon->thisnpc->die_quest);
						if(success == 5) // quest success
						{
							Log(MSG_DEBUG,"Death QSD Trigger %i successful. Sending success: ",thismon->thisnpc->die_quest);
							BEGINPACKET ( pak, 0x730);
							ADDBYTE ( pak, success);
							ADDBYTE ( pak, 0);
							ADDDWORD( pak, thismon->thisnpc->die_quest);
							thisclient->client->SendPacket(&pak);
						}
                        break;
                    }
                }
            }
            //assign my own exp for monsters that I personally damaged
            unsigned int exp = (unsigned int)floor(thismon->thisnpc->exp * MyPercent);
            //unsigned int exp = (unsigned int)ceil((double)((thismon->thisnpc->exp * thisplayer->damage) / (thismon->thisnpc->hp*thismon->thisnpc->level)));
            exp = exp * Config.EXP_RATE * map->mapXPRate;      //calculate base exp for this client. No medals or stuff accounted for yet
			
            Log(MSG_DEBUG,"MonXP: %i config rate: %i Map rate : %i My percent: %f Total XP: %i", thismon->thisnpc->exp, Config.EXP_RATE, map->mapXPRate, MyPercent, exp);
            thisclient->CharInfo->Pending_Exp += (exp * thisclient->Stats->xprate);    //store exp into thisclient's pending_exp using personal xprate adjustments
			Log(MSG_DEBUG,"My personal XPrate: %i ", thisclient->Stats->xprate);
            if( thisclient->Party->party!=NULL )
            {
                //Log(MSG_DEBUG,"Player is in a party");
                //player is in a party so scan the party members
                CParty* party = thisclient->Party->party; //assign a party
                if(party == NULL)
                    return true;
                //Log(MSG_DEBUG,"party found. Counted = %i", party->counted);
                for(UINT p=0;p<party->Members.size();p++) //loop through all the members in the party
                {
                    //Log(MSG_DEBUG,"member %i being parsed", p);
                    if(!party->counted)
                    {
                        //Log(MSG_DEBUG,"party added to list. level = %i", party->PartyLevel);
                        party->counted = true; //tag the party so we don't add it to the list twice
                        PartyList.push_back( party ); //we will need this list later to convert pending exp to real exp
                    }
                    CPlayer* thismember = party->Members.at(p); //find a party member
                    if(thismember == NULL)
                        return true;
					float RawTmpExp = (exp * (party->PartyLevel + 25) / 50);
                    unsigned int tempxp =(unsigned int)(floor)(RawTmpExp);
                    if (tempxp < 1)tempxp = 1;
                    //Log(MSG_DEBUG,"member %i pending exp = %i tempxp: %i", p, thismember->CharInfo->Pending_Exp, tempxp);
                    thismember->CharInfo->Pending_Exp += tempxp; // add a percentage of thisclient's non-adjusted exp to all party members including himself

                    //Log(MSG_DEBUG,"member %i pending exp (after tempxp) = %i", p, thismember->CharInfo->Pending_Exp);
                }
                if(party->PartyLevel < 50) //only give party exp if party level is under 50
                {

                    party->Pending_Exp += exp; //add thisclient's non-adjusted xp to the pending exp of the party
                }

               
            }
            else //not in a party so deal with all the exp now
            {
                //SendPM(thisclient, "You receive %i EXP",thisclient->CharInfo->Pending_Exp);
                //Log(MSG_DEBUG,"Player awarded %i experience points",thisclient->CharInfo->Pending_Exp);
				thisclient->CharInfo->Exp += thisclient->CharInfo->Pending_Exp;
                thisclient->CharInfo->Pending_Exp = 0;
                //if(!thisclient->CheckPlayerLevelUP())
				if(thisclient->CharInfo->Exp < thisclient->GetLevelEXP())
                {
					BEGINPACKET( pak, 0x79b );
                    ADDDWORD   ( pak, thisclient->CharInfo->Exp );
                    ADDWORD    ( pak, thisclient->CharInfo->stamina );
					ADDWORD    ( pak, thismon->clientid );
                    thisclient->client->SendPacket( &pak );
                }
            }
        }
    }
    for(int p=0;p<PartyList.size();p++) //loop through our party list to assign final exp to all party members. We already did non-party members up there^
    {

        CParty* thisparty = PartyList.at( p );

        if(thisparty == NULL)
        {
            //Log(MSG_DEBUG,"Party not valid");
            continue;
        }
        //Log(MSG_DEBUG,"Party %i exp: %i pending exp: %i", p, thisparty->Exp, thisparty->Pending_Exp );
        thisparty->counted = false;         //reset the boolean for next time
        for(UINT i=0;i<thisparty->Members.size();i++) //loop through all the members in the party
        {
            CPlayer* thismember = thisparty->Members.at(i); //find a party member
            if(thismember == NULL)
                return true;
            thismember->CharInfo->Exp += thismember->CharInfo->Pending_Exp;
            //Log(MSG_DEBUG,"Added pending exp %i to regular exp %i for member %i", thismember->CharInfo->Pending_Exp, thismember->CharInfo->Exp, i);
            thismember->CharInfo->Pending_Exp = 0;
            if(!thismember->CheckPlayerLevelUP( ))
            {
                BEGINPACKET( pak, 0x79b );
                ADDDWORD   ( pak, thismember->CharInfo->Exp );
                ADDWORD    ( pak, thismember->CharInfo->stamina );
                //ADDWORD    ( pak, 0 );		//PY: not needed
				ADDWORD    ( pak, thismon->clientid );
                thismember->client->SendPacket( &pak );
            }

        }
        thisparty->Exp += thisparty->Pending_Exp;
        thisparty->Pending_Exp = 0;
		thisparty->m_bitLevelUP = 0;
        if( thisparty->Exp > GetMaxPartyExp(thisparty->PartyLevel)) //level up the party
        {
            thisparty->PartyLevel++;
            thisparty->Exp -= GetMaxPartyExp(thisparty->PartyLevel-1);
			thisparty->m_iEXP = thisparty->Exp;
			thisparty->m_bitLevelUP = 1;	//set levelup bit. See client structure below
        }
		//PY: structure of 0x7d4
		/*
		BYTE				m_btLEVEL;
		struct 
		{
			unsigned int	m_iEXP		 : 31;
			unsigned int	m_bitLevelUP : 1;
		} ;
		*/
        BEGINPACKET	( pak, 0x7d4 );
        ADDBYTE		( pak, thisparty->PartyLevel );
        ADDWORD		( pak, thisparty->m_iEXP );			// defined as 31 bits
		ADDWORD		( pak, thisparty->m_bitLevelUP );	// defined as 1 bit
        thisparty->SendToMembers( &pak );
    }
    return true;
}