// 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; }
// 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; }