Exemplo n.º 1
0
// Learn Skill
//bool CWorldServer::LearnSkill( CPlayer* thisclient, UINT skill )
bool CWorldServer::LearnSkill( CPlayer* thisclient, UINT skill, bool takeSP)
{
    /*
    0 - already learned
    1 - he learned
    2 - not job
    3 - another skill is absent
    4 - not status points the (lvl)
    5 - it is not possible to raise of lvl the skill
    6 - incorrect number of skill
    7 - you do not have sufficient sp
    */

    int b=1;
    CSkills* thisskill = GetSkillByID( skill );
    if( thisskill==NULL )
        return false;

    //LMA: Is it an empty skill?
    if(GServer->SkillList[skill]->skill_tab==0)
    {
        Log(MSG_WARNING,"%s:: Incorrect or empty skill %i",thisclient->CharInfo->charname,skill);
        b=6;
    }

    if(takeSP&&thisclient->CharInfo->SkillPoints<thisskill->sp )
    {
        Log(MSG_WARNING,"%s:: not enough skill points (%u<%u) for skill %u",thisclient->CharInfo->charname,thisclient->CharInfo->SkillPoints,thisskill->sp,skill);
        b=7;
    }
    else if( thisskill->clevel>thisclient->Stats->Level )
    {
        Log(MSG_WARNING,"%s:: incorrect level for skill %u (%u<%u)",thisclient->CharInfo->charname,skill,thisskill->clevel,thisclient->Stats->Level);
        b=4;
    }

    if(b==1)
    {
        UINT rclass = 0;
        for(UINT i=0;i<4; i++)
        {
            if (thisskill->c_class[i] == 0)
            {
                continue;
            }

            if (thisskill->c_class[i] == 41)
            {
                rclass = 111;
            }
             else if (thisskill->c_class[i] == 42)
            {
                rclass = 211;
            }
            else if (thisskill->c_class[i] == 43)
            {
                rclass = 311;
            }
            else if (thisskill->c_class[i] == 44)
            {
                rclass = 411;
            }
            else if (thisskill->c_class[i] == 61)
            {
                rclass = 121;
            }
            else if (thisskill->c_class[i] == 62)
            {
                rclass = 122;
            }
            else if (thisskill->c_class[i] == 63)
            {
                rclass = 221;
            }
            else if (thisskill->c_class[i] == 64)
            {
                rclass = 222;
            }
            else if (thisskill->c_class[i] == 65)
            {
                rclass = 321;
            }
            else if (thisskill->c_class[i] == 66)
            {
                rclass = 322;
            }
            else if (thisskill->c_class[i] == 67)
            {
                rclass = 421;
            }
            else if (thisskill->c_class[i] == 68)
            {
                rclass = 422;
            }

            //LMA: new way, so "old" job skill can be learned...
            //if(rclass == thisclient->CharInfo->Job)
            if(CheckCompatibleClass(rclass,thisclient->CharInfo->Job))
            {
                b=1;
                break;
            }
            else
            {
                Log(MSG_WARNING,"%s:: Incompatible class for skill %u (%u)",thisclient->CharInfo->charname,skill,rclass);
                b=2;
            }
        }
    }
    if(b==1)
    {
        for(UINT i=0;i<3; i++)
        {
            if(thisskill->rskill[i] != 0)
            {
                UINT rskill = thisclient->GetPlayerSkill(thisskill->rskill[i]);
                if(rskill == 0xffff)
                {
                    Log(MSG_WARNING,"%s:: Necessary skill %u not found to learn %u",thisclient->CharInfo->charname,thisskill->rskill[i],skill);
                    b=3;
                }
                else
                {
                    if(thisskill->lskill[i] > thisclient->cskills[rskill].level)
                    {
                        Log(MSG_WARNING,"%s:: Necessary skill (%u) level incorrect (%u>%u) to learn %u",thisclient->CharInfo->charname,thisskill->rskill[i],thisskill->lskill[i],thisclient->cskills[rskill].level,skill);
                        b=5;
                    }

                }

            }

        }

    }

    if(b==1)
    {
        //LMA: Looking for good place to save it now...
        int family=thisclient->GoodSkill(skill);
        if(family==-1)
        {
            Log(MSG_WARNING,"%s:: Can't find family for skill %i",thisclient->CharInfo->charname,skill);
            b=6;
        }
        else
        {
            int index=thisclient->FindSkillOffset(family);
            if(index==-1)
            {
                Log(MSG_WARNING,"%s:: Can't find index in family %i for skill %i",thisclient->CharInfo->charname,family,skill);
                b=6;
            }
            else
            {
                thisclient->cskills[index].id=skill;
                thisclient->cskills[index].level=1;
                thisclient->cskills[index].thisskill = thisskill;

                if (takeSP)
                {
                    thisclient->CharInfo->SkillPoints -= thisskill->sp;
                }
                //in the good family now.
                //thisclient->SaveSkillInfo(family,thisclient->cur_max_skills[family],skill,1);
                thisclient->saveskills();

                BEGINPACKET( pak, 0x7b0 );
                ADDBYTE    ( pak, b);
                ADDWORD    ( pak, index);
                ADDWORD    ( pak, skill);
                ADDWORD    ( pak, thisclient->CharInfo->SkillPoints);
                thisclient->client->SendPacket( &pak);
                thisclient->SetStats( );


                return true;
                //LMA: new way end.
            }

        }

    }

    BEGINPACKET( pak, 0x7b0 );
    ADDBYTE    ( pak, b);
    ADDWORD    ( pak, thisclient->p_skills-1);
    ADDWORD    ( pak, skill);
    ADDWORD    ( pak, thisclient->CharInfo->SkillPoints);
    thisclient->client->SendPacket( &pak);

    Log(MSG_WARNING,"%s:: skill %i not learned (error %i)",thisclient->CharInfo->charname,skill,b);


    return false;
}
Exemplo n.º 2
0
// Get Consumible Item Info
CUseInfo* CWorldServer::GetUseItemInfo(CPlayer* thisclient, unsigned int slot )
{
    if(thisclient->items[slot].count<1)
        return NULL;
    CUseInfo* useitem = new (nothrow) CUseInfo;
    if(useitem==NULL)
    {
        Log(MSG_WARNING, "Error allocing memory GetUseItemInfo");
        return useitem;
    }
    useitem->itemnum = 0;
    useitem->itemtype = 0;
    useitem->usescript = 0;
    useitem->usetype = 0;
    useitem->usevalue = 0;
    unsigned int type = 0;
    useitem->itemnum = thisclient->items[slot].itemnum;
    useitem->itemtype = thisclient->items[slot].itemtype;
    type = UseList.Index[useitem->itemnum]->type;
    switch(type)
    {
        case 311://Medicine
        case 312://Food
        {
            useitem->usescript = 1;
            useitem->usetype = UseList.Index[useitem->itemnum]->useeffect[0];
            useitem->usevalue = UseList.Index[useitem->itemnum]->useeffect[1];
        }
        break;
        case 313://Magic Item [scrolls/summons/fireworks/etc]
        {
            // scrolls [maxhp,attackpower up, ... ]
            if((useitem->itemnum >= 301 && useitem->itemnum <= 323)|| (useitem->itemnum >= 961 && useitem->itemnum <= 964) ||(useitem->itemnum >= 331 && useitem->itemnum <= 340))
            {
                useitem->usescript = 7;
                useitem->usetype = UseList.Index[useitem->itemnum]->useeffect[1];
                useitem->usevalue = 0;
            }
            else//Return Scrolls
            if(useitem->itemnum > 349 && useitem->itemnum < 367) 
            {
                if( thisclient->Stats->MP < 33 ){delete useitem;}
                thisclient->Stats->MP -= 32;
                useitem->usescript = 2;
                switch( useitem->itemnum )
                {
                    //Adventure plain [credits to tomiz]
                    case 350:
                        useitem->usetype = 22;
                        useitem->usevalue = 51105310;
                    break;
                    //Zant
                    case 351:
                        useitem->usetype = 1;
                        useitem->usevalue = 52405192;
                    break;
                    //Junon
                    case 352:
                        useitem->usetype = 2;
                        useitem->usevalue = 55095283;
                    break;
                    //Eucar
                    case 353:
                        useitem->usetype = 51;
                        useitem->usevalue = 53665099;
                    break;
                    //Xita
                    case 354:
                        useitem->usetype = 61;
                        useitem->usevalue = 54344607;
                    break;
                    //Goblin cave
                    case 360:
                        useitem->usetype = 31;
                        useitem->usevalue = 55185444;
                    break;
                    //Desert of dead
                    case 361:
                        useitem->usetype = 29;
                        useitem->usevalue = 50825013;
                    break;
                    //El Verloon
                    case 362:
                        useitem->usetype = 24;
                        useitem->usevalue = 55275377;
                    break;
                    //George of Silence
                    case 363:
                        useitem->usetype = 28;
                        useitem->usevalue = 54674783;
                    break;
                    //Shady Jungle
                    case 364:
                        useitem->usetype = 62;
                        useitem->usevalue = 57515196;
                    break;
                    //Sunshine Beach
                    case 366:
                        useitem->usetype = 37;
                        useitem->usevalue = 50055382;
                    break;

                }
            }
            else //Charm Scrolls
            if( (useitem->itemnum>380 && useitem->itemnum<384) )
            {
                useitem->usescript = 3;
                useitem->usetype = UseList.Index[useitem->itemnum]->useeffect[1];
                thisclient->CharInfo->stamina -= 5000;
            }
            else //Dance Scroll
            if( (useitem->itemnum>370 && useitem->itemnum<377) ||
                (useitem->itemnum>389 && useitem->itemnum<398) )
            {
                useitem->usescript = 12; // should not be treated the same as firecrackers. this is a skill
                useitem->usetype = UseList.Index[useitem->itemnum]->useeffect[1];
            }
            else // Firecrackers
            if( useitem->itemnum == 913 || (useitem->itemnum >= 921 && useitem->itemnum <= 929) ||
                (useitem->itemnum >= 991 && useitem->itemnum <= 995) )
            {
                useitem->usescript = 13;
                useitem->usetype = UseList.Index[useitem->itemnum]->useeffect[1];
                //useitem->usevalue = UseList.Index[useitem->itemnum]->useeffect[1];
            }
            else // Emotions
            if( (useitem->itemnum>970 && useitem->itemnum<979) )
            {
                useitem->usescript = 4;
                useitem->usetype = UseList.Index[useitem->itemnum]->useeffect[0];
                useitem->usevalue = UseList.Index[useitem->itemnum]->useeffect[1];
            }
            else // Summons
            if(useitem->itemnum > 400 && useitem->itemnum < 440)
            {
                if( thisclient->CharInfo->stamina < 100 )
                    return NULL;
                thisclient->CharInfo->stamina -= 100;
                useitem->usescript = 5;
                useitem->usetype = UseList.Index[useitem->itemnum]->useeffect[1];
                CSkills* skill = GetSkillByID(useitem->usetype);
                if(skill == NULL)
                {
                    Log(MSG_INFO,"Useitem returnd a NULL skill");
                    return NULL;
                }
                useitem->usevalue = skill->svalue1;
            }
            else // Summons 2. Special summons such as goodie bags
            if(useitem->itemnum > 908 && useitem->itemnum < 918)
            {
                if( thisclient->CharInfo->stamina < 100 )
                    return NULL;
                thisclient->CharInfo->stamina -= 100;
                useitem->usescript = 5; // testing at 11 for a bit. Gives no owner to the summons.
                useitem->usetype = UseList.Index[useitem->itemnum]->useeffect[1];
                CSkills* skill = GetSkillByID(useitem->usetype);
                if(skill == NULL)
                {
                    Log(MSG_INFO,"Useitem returnd a NULL skill");
                    return NULL;
                }
                useitem->usevalue = skill->svalue1;
            }
            else // Snowball
            if( useitem->itemnum == 326 )
            {
                useitem->usescript = 6;
                useitem->usetype = UseList.Index[useitem->itemnum]->useeffect[0];
                useitem->usevalue = UseList.Index[useitem->itemnum]->useeffect[1];
            }
            else
            {
                Log( MSG_WARNING, "Unknown Item %i - Type %i",useitem->itemnum,type);
                delete useitem;
                return NULL;
            }
        }
        break;
        case 314://Skill Book
        {
            useitem->usescript = 10;
            useitem->usetype = UseList.Index[useitem->itemnum]->useeffect[0];
            useitem->usevalue = UseList.Index[useitem->itemnum]->useeffect[1];
        }
        break;
        case 315://Repair Tool
            delete useitem;
            return NULL;
        break;
        case 316://Quest Scroll
            delete useitem;
            return NULL;
        break;
        case 317://Engine Fuel
            delete useitem;
            return NULL;
        break;
        case 320://Automatic Consumption
            delete useitem;
            return NULL;
        break;
        case 321://Time Coupon / shop coupon / storage expansion coupon
            
            switch( useitem->itemnum )
            {
                case 954: //shop coupon A
                {
                    delete useitem;
                    thisclient->Shop->ShopType = 1;
                }
                case 955: //shop coupon B
                {
                    delete useitem;
                    thisclient->Shop->ShopType = 2;
                }
                case 956: //shop coupon C
                {
                    delete useitem;
                    thisclient->Shop->ShopType = 3;
                }
            }
            return NULL;
        break;
        default:
            Log( MSG_WARNING, "Unknown use item type: %i",type);
            return NULL;
        break;

    }
    useitem->itemtype -= 1;
    return useitem;
}