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