예제 #1
0
// Party Chat
bool CWorldServer::pakPartyChat( CPlayer* thisclient, CPacket* P )
{
    CParty* party = thisclient->Party->party;
    if(party==NULL)
        return true;
	BEGINPACKET( pak, 0x786 );
    ADDWORD    ( pak, thisclient->clientid );
	ADDSTRING  ( pak, P->Buffer );
	ADDBYTE    ( pak, 0 );
    party->SendToMembers( &pak );
    return true;
}
예제 #2
0
// Change Party Options
bool CWorldServer::pakPartyOption( CPlayer* thisclient, CPacket* P )
{
    if(!thisclient->Party->IsMaster)
        return true;
    CParty* party = thisclient->Party->party;
    if(party==NULL)
        return true;
    party->Option = GETBYTE((*P),0);
    BEGINPACKET( pak, 0x7d7 );
    ADDBYTE    ( pak, party->Option );
    ADDBYTE    ( pak, 0x00 );
    party->SendToMembers( &pak );
    return true;
}
예제 #3
0
// Party Manager
bool CWorldServer::pakPartyManager( CPlayer* thisclient, CPacket* P )
{
    unsigned int action = GETBYTE((*P),0);
    switch(action)
    {
        case 0x02://Acepto
        {
            if(thisclient->Party->party!=NULL)// have party
                return true;
            unsigned int clientid = GETWORD((*P),1);
            if (clientid == thisclient->clientid)
            {
               Log(MSG_WARNING, "User %s tried to party with himself\n", thisclient->CharInfo->charname);
               return false; //kick the cheater
            }
            CPlayer* otherclient = GetClientByID( clientid, thisclient->Position->Map );
            if(otherclient==NULL)
            {
                BEGINPACKET( pak, 0x7d1 );
                ADDBYTE    ( pak, 0x00 );//No encontro el ID
                ADDWORD    ( pak, clientid );
                ADDBYTE    ( pak, 0x00 );
                thisclient->client->SendPacket( &pak );
                return true;
            }
            CParty* party = otherclient->Party->party;
            if(party!=NULL)
            {
                //LMA: Refreshing Capacity if needed
                party->RefreshMax();
                if(party->Members.size()>=party->Capacity)
                {
                    SendSysMsg( thisclient, "Party is Full" );
                    return true;
                }
            }
            if(abs(otherclient->Stats->Level-thisclient->Stats->Level)>(Config.Partygap+1))
            {
                BEGINPACKET( pak, 0x7d1 );
                ADDBYTE    ( pak, 0x07 );//Level inapropiado
                ADDWORD    ( pak, clientid );
                ADDBYTE    ( pak, 0x00 );
                thisclient->client->SendPacket( &pak );
                return true;
            }
            BEGINPACKET( pak, 0x7d1 );
            ADDBYTE    ( pak, 0x02 );//Acepto Party
            ADDWORD    ( pak, otherclient->clientid );
            ADDBYTE    ( pak, 0x00 );
            otherclient->client->SendPacket( &pak );
            if( party==NULL )
            {   // new party
                CParty* thisparty = new CParty;
                thisparty->AddPlayer( otherclient );
                AddParty( thisparty );
                otherclient->Party->IsMaster = true;
                party = thisparty;
            }
            //Send Party Level and Party Exp
            RESETPACKET( pak, 0x7d4 ); //
            ADDBYTE    ( pak, party->PartyLevel );
            ADDDWORD   ( pak, party->Exp );
            thisclient->client->SendPacket( &pak );
            thisclient->Party->IsMaster = false;
            // Send New Party Member info to other players
            RESETPACKET( pak, 0x7d2 );
            ADDBYTE    ( pak, party->Option );
            ADDBYTE    ( pak, 0x01 );
            ADDDWORD   ( pak, thisclient->CharInfo->charid );
            ADDWORD    ( pak, thisclient->clientid );
            ADDWORD    ( pak, thisclient->Stats->MaxHP );
            ADDWORD    ( pak, thisclient->Stats->HP );
            //ADDDWORD   ( pak, 0x00000000 );//Tomiz: Was not commented before
            ADDDWORD   ( pak, BuildBuffs( thisclient ));//Tomiz: Buff Data
            //ADDDWORD   ( pak, 0x0000000f );//Tomiz: Was not commented before
            ADDDWORD   ( pak, 0x1f40008c );//Tomiz
            ADDWORD    ( pak, 0x1388 );
            ADDSTRING  ( pak, thisclient->CharInfo->charname );
            ADDBYTE    ( pak, 0x00 );
            party->SendToMembers( &pak );


            // Send To New Party Member the members List
            RESETPACKET( pak, 0x7d2 );
            ADDBYTE    ( pak, party->Option );
            ADDBYTE    ( pak, party->Members.size() );
            for(int i=0;i<party->Members.size();i++)
            {
                CPlayer* member= party->Members.at(i);
                ADDDWORD   ( pak, member->CharInfo->charid );
                ADDWORD    ( pak, member->clientid );
                ADDWORD    ( pak, member->Stats->MaxHP );
                ADDWORD    ( pak, member->Stats->HP );
                //ADDDWORD   ( pak, 0x00000000 );//Tomiz: Was not commented before
                ADDDWORD   ( pak, BuildBuffs( member ));//Tomiz: Buff Data
                //ADDDWORD   ( pak, 0x0000000f );//Tomiz: Was not commented before
                ADDDWORD   ( pak, 0x7200005b );//Tomiz
                ADDWORD    ( pak, 0x1388 );
                ADDSTRING  ( pak, member->CharInfo->charname );
                ADDBYTE    ( pak, 0x00 );
            }
            thisclient->client->SendPacket( &pak );
            party->AddPlayer( thisclient );
        }
        break;
        case 0x04://No acepto
        {
            unsigned int clientid = GETWORD((*P),1);
            CPlayer* otherclient = GetClientByID( clientid, thisclient->Position->Map );
            if(otherclient==NULL)
            {
                BEGINPACKET( pak, 0x7d1 );
                ADDBYTE    ( pak, 0x00 );//No encontro el ID
                ADDWORD    ( pak, clientid );
                ADDBYTE    ( pak, 0x00 );
                thisclient->client->SendPacket( &pak );
                return true;
            }
            BEGINPACKET( pak, 0x7d1 );
            ADDBYTE    ( pak, 0x04 );//No acepto
            ADDWORD    ( pak, thisclient->clientid );
            ADDBYTE    ( pak, 0x00 );
            otherclient->client->SendPacket( &pak );
        }
        break;
        default:
            Log(MSG_WARNING,"Party Manager unknown action: %i", action);
    }
    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;
}