//===== Athena Script =====================================//= Achievement System//===== By ================================================//= Loki1991//===== Version ===========================================//= 1.0 - First release//===== Description =======================================//= A full working Achivement System without any source edit!//= A well guide about this script can be found in rathena!//=========================================================- script achievementSystem -1,{OnInit://config startset $a_cache_expire,120;set $a_effect_id,908;set $a_cutin_delay,8000;//config end. Don't change anything below if you don't know what ya doingset $a_cached,0;
end;//Cache achivements for .@cache_expire secoundsOnPCLoginEvent:if(gettimetick(2)-$a_cached <= $a_cache_expire && $a_cached !=0)gotoInventoryChecker;
query_sql("SELECT * FROM achievement",.@id,.@name$,.@desc$,.@mode,.@deleted$,.@cutin$,.@points,.@single_val,.@val1,.@val1amount,.@val2,.@val2amount,.@val3,.@val3amount,.@val4,.@val4amount,.@val5,.@val5amount,.@val6,.@val6amount,.@val7,.@val7amount,.@val8,.@val8amount,.@val9,.@val9amount);set.@i,0;set $a_mode_other,0;set $a_mode_item,0;set $a_mode_mob,0;set $a_mode_mvp,0;set $a_mode_pvp,0;set $a_mode_lvl,0;set $a_mode_jlvl,0;while(.@i< getarraysize(.@id)){
setd("$a_name_"+.@id[.@i]+"$",.@name$[.@i]);
setd("$a_desc_"+.@id[.@i]+"$",.@desc$[.@i]);
setd("$a_mode_"+.@id[.@i],.@mode[.@i]);
setd("$a_del_"+.@id[.@i]+"$",.@deleted$[.@i]);
setd("$a_cutin_"+.@id[.@i]+"$",.@cutin$[.@i]);
setd("$a_points_"+.@id[.@i],.@points[.@i]);
setd("$a_val1_"+.@id[.@i],.@val1[.@i]);
setd("$a_val1a_"+.@id[.@i],.@val1amount[.@i]);
setd("$a_val2_"+.@id[.@i],.@val2[.@i]);
setd("$a_val2a_"+.@id[.@i],.@val2amount[.@i]);
setd("$a_val3_"+.@id[.@i],.@val3[.@i]);
setd("$a_val3a_"+.@id[.@i],.@val3amount[.@i]);
setd("$a_val4_"+.@id[.@i],.@val4[.@i]);
setd("$a_val4a_"+.@id[.@i],.@val4amount[.@i]);
setd("$a_val5_"+.@id[.@i],.@val5[.@i]);
setd("$a_val5a_"+.@id[.@i],.@val5amount[.@i]);
setd("$a_val6_"+.@id[.@i],.@val6[.@i]);
setd("$a_val6a_"+.@id[.@i],.@val6amount[.@i]);
setd("$a_val7_"+.@id[.@i],.@val7[.@i]);
setd("$a_val7a_"+.@id[.@i],.@val7amount[.@i]);
setd("$a_val8_"+.@id[.@i],.@val8[.@i]);
setd("$a_val8a_"+.@id[.@i],.@val8amount[.@i]);
setd("$a_val9_"+.@id[.@i],.@val9[.@i]);
setd("$a_val9a_"+.@id[.@i],.@val9amount[.@i]);
setd("$a_sval_"+.@id[.@i]+"$",.@single_val[.@i]);switch(.@mode[.@i]){default:set $a_mode_other,$a_mode_other+1;break;case1:set $a_mode_item,$a_mode_item+1;break;case2:set $a_mode_mob,$a_mode_mob+1;break;case3:set $a_mode_mvp,$a_mode_mvp+1;break;case4:set $a_mode_pvp,$a_mode_pvp+1;break;case5:set $a_mode_lvl,$a_mode_lvl+1;break;case6:set $a_mode_jlvl,$a_mode_jlvl+1;break;}set.@i,.@i+1;}set $achive_amount,.@i;set $a_cached,gettimetick(2);
end;//Monsterkills (mode mob,mvp) OnNPCKillEvent://killedridif($a_mode_mob>0|| $a_mode_mvp>0){set.@i,0;while(.@i< $achive_amount){set.@i,.@i+1;if((getd("$a_mode_"+.@i)!=2&& getd("$a_mode_"+.@i)!=3)|| getd("a_done_"+.@i)==1|| getd("$a_del_"+.@i+"$")=="y")continue;if(getd("$a_mode_"+.@i)==2&& $a_mode_mob >0&& achieve_mob < $a_mode_mob){set.@valCount,0;set.@ok,0;while(.@valCount<9){set.@valCount,.@valCount+1;if(getd("$a_val"+.@valCount+"_"+.@i)==0|| getd("$a_val"+.@valCount+"a_"+.@i)==0){set.@ok,.@ok+1;continue;}//Skip trash or emptyif(killedrid == getd("$a_val"+.@valCount+"_"+.@i)) setd("a_state_"+.@i+"_"+.@valCount,getd("a_state_"+.@i+"_"+.@valCount)+1);if(getd("a_state_"+.@i+"_"+.@valCount)== getd("$a_val"+.@valCount+"a_"+.@i))set.@ok,.@ok+1;}if(.@ok==9) callfunc "achieve",.@i;}elseif(getd("$a_mode_"+.@i)==3&& $a_mode_mvp >0&& achieve_mvp < $a_mode_mvp){switch(killedrid){default:break;case1511:case1647:case1785:case1630:case1929:case1039:case1874:case1272:case1719:case1046:case1389:case1112:case1115:case1957:case1418:case1871:case1252:case1768:case1086:case1649:case1651:case1832:case1492:case1734:case1251:case1779:case1688:case1646:case1373:case1147:case1059:case1150:case1956:case1087:case1190:case1038:case1157:case1159:case1502:case1623:case1650:case1583:case1708:case1312:case1751:case1685:case1648:case1917:case1658:case1885:case2068:case2238:case2240:case2236:case2241:case1980:case2156:case2022:case2235:case2237:case2087:case2165:case2239:
setd("a_state_"+.@i,getd("a_state_"+.@i)+1);if(getd("a_state_"+.@i)>= getd("$a_sval_"+.@i)) callfunc "achieve",.@i;break;}}}}gotoInventoryChecker;
end;//PvP (mode pvp) OnPCKillEvent:if($a_mode_pvp==0|| achieve_pvp==$a_mode_pvp) end;set pvp_counter,pvp_counter+1;set.@i,0;while(.@i< $achive_amount){set.@i,.@i+1;if(getd("$a_mode_"+.@i)!=4|| getd("a_done_"+.@i)==1|| getd("$a_del_"+.@i+"$")=="y")continue;if(pvp_counter >= getd("$a_sval_"+.@i)) callfunc "achieve",.@i;}
end;//LevelUP (mode lvl)OnPcBaseLvUpEvent:if($a_mode_lvl==0|| achieve_lvl==$a_mode_lvl) end;set.@i,0;while(.@i< $achive_amount){
setd("a_done_"+.@i,0);set.@i,.@i+1;if(getd("$a_mode_"+.@i)!=5|| getd("a_done_"+.@i)==1|| getd("$a_del_"+.@i+"$")=="y")continue;
dispbottom getd("$a_sval_"+.@i);if(BaseLevel>= getd("$a_sval_"+.@i)) callfunc "achieve",.@i;}
end;//JobLevelUP (mode jlvl)OnPcJobLvUpEvent:if($a_mode_jlvl==0|| achieve_jlvl==$a_mode_jlvl) end;set.@i,0;while(.@i< $achive_amount){set.@i,.@i+1;if(getd("$a_mode_"+.@i)!=6|| getd("a_done_"+.@i)==1|| getd("$a_del_"+.@i+"$")=="y")continue;if(JobLevel>= getd("$a_sval_"+.@i)) callfunc "achieve",.@i;}
end;//Get X Amount of Items in your inventar (mode item)//will be called after mob kill or map changeInventoryChecker:if($a_mode_item==0|| achieve_item==$a_mode_item) end;set.@i,0;while(.@i< $achive_amount){set.@i,.@i+1;if(getd("$a_mode_"+.@i)!=1|| getd("a_done_"+.@i)==1|| getd("$a_del_"+.@i+"$")=="y")continue;set.@valCount,0;set.@ok,0;while(.@valCount<9){set.@valCount,.@valCount+1;if(getd("$a_val"+.@valCount+"_"+.@i)==0|| getd("$a_val"+.@valCount+"a_"+.@i)==0){set.@ok,.@ok+1;continue;}//Skip trash or emptyif(countitem(getd("$a_val"+.@valCount+"_"+.@i))>= getd("$a_val"+.@valCount+"a_"+.@i))set.@ok,.@ok+1;}if(.@ok==9) callfunc "achieve",.@i;}
end;//special (mode special)//No script. Just place 'callfunc "achieve",<<yourAchievementId>>;' anywhere in your script (below).}
function script achieve {set.@achieveId,getarg(0);if(.@achieveId<=0) end;//Param missing. WTF
query_sql("SELECT id FROM achievement_log WHERE ach_id='"+.@achieveId+"' AND char_id='"+.@achieveId+"'",.@id);if(.@id>0){ setd("a_done_"+.@achieveId,1); end;}//User already got this achievement... Strange//Everything looks fine, lets do it
query_sql("INSERT INTO achievement_log(ach_id,char_id,crdate) VALUES('"+.@achieveId+"','"+getcharid(0)+"','"+gettimetick(2)+"')");switch(getd("$a_mode_"+.@achieveId)){default:set achieve_other,achieve_other+1;break;case1:set achieve_item,achieve_item+1;break;case2:set achieve_mob,achieve_mob+1;break;case3:set achieve_mvp,achieve_mvp+1;break;case4:set achieve_pvp,achieve_pvp+1;break;case5:set achieve_lvl,achieve_lvl+1;break;case6:set achieve_jlvl,achieve_jlvl+1;break;}if($a_effect_id>0){
specialeffect2 $a_effect_id;}
announce strcharinfo(0)+" got the achievement ["+getd("$a_name_"+.@achieveId+"$")+"]!",0;
setd("a_done_"+.@achieveId,1);
query_sql("UPDATE `char` SET achievement_points=achievement_points+"+getd("$a_points_"+.@achieveId)+" WHERE char_id="+getcharid(0));if(getd("$a_cutin_"+.@achieveId+"$")!=""){
cutin getd("$a_cutin_"+.@achieveId+"$"),1;
sleep2 $a_cutin_delay;
cutin "",255;}
end;}
function script getMonsterNameById {if(getarg(0)<=0) end;
query_sql("SELECT iName FROM mob_db WHERE ID="+getarg(0)+" UNION SELECT iName FROM mob_db2 WHERE ID="+getarg(0),.@mobName$);return.@mobName$;}
prontera,164,172,4 script AchievementBob899,{//Bob Config Params set.@name$,"[^FF0000Achiement Bob^000000]";set.@cutin$,"sc_vicente01";set.@GmMenuAtWhichLevel,40;set.@text_gmMenu$,"Hi there GM. Which kind of menu do you want to see?";set.@text_startInfo$,"I have all information about the achievements which are activated on this server.";set.@text_category$,"Please choose your category.";set.@text_whichAch$,"For which achievement do you want to get details?";set.@text_points$,"You have this achievement points:";set.@text_close$,"I'm not interested.";set.@text_worth$,"Worth:";set.@text_getPoints$,"points";set.@text_bye$,"Have a nice day.";set.@text_kill$,"Kill";set.@text_mvp$,"any kind of MvP";set.@text_pvp$,"any other player";set.@text_lvl$,"Reach base level";set.@text_jlvl$,"Reach job level";set.@text_mode_item$,"Item achievements";set.@text_mode_mob$,"Monster achievements";set.@text_mode_mvp$,"MvP achievements";set.@text_mode_pvp$,"PvP achievements";set.@text_mode_lvl$,"Base Level achievements";set.@text_mode_jlvl$,"Job Level achievements";set.@text_mode_other$,"Other Achievements";
query_sql("SELECT achievement_points FROM `char` WHERE char_id="+getcharid(0),.@points);//Check if a gm has set the player to a force action
query_sql("SELECT ach_id, mode FROM achievement_force WHERE done='n' AND char_id="+getcharid(0),.@ach_id,.@mode$);if(getarraysize(.@ach_id)>0){set.@i,0;while(.@i< getarraysize(.@ach_id)){//Clear log before there is to much trash inside
query_sql("SELECT id FROM achievement_log WHERE ach_id="+.@ach_id[.@i]+" AND char_id="+getcharid(0),.@log_id);
query_sql("UPDATE achievement_force SET done='y' WHERE done='n' AND ach_id="+.@ach_id[.@i]+" AND char_id="+getcharid(0));if(.@log_id>0) query_sql("DELETE FROM achievement_log WHERE id="+.@log_id);if(.@mode$=="add"){if(getd("a_done_"+.@ach_id[.@i])==1){
query_sql("UPDATE `char` SET achievement_points=achievement_points-"+getd("$a_points_"+.@ach_id[.@i])+" WHERE char_id="+getcharid(0));}
setd("a_done_"+.@ach_id[.@i],0);
callfunc "achieve",.@ach_id[.@i];}else{
query_sql("SELECT mode FROM achievement WHERE id="+.@ach_id[.@i],.@mode);if(.@mode==2){set.@j,0;while(.@j<9){set.@j,.@j+1;
setd("a_state_"+.@ach_id[.@i]+"_"+.@j,0);}}elseif(.@mode==3){
setd("a_state_"+.@ach_id[.@i],0);}if(getd("a_done_"+.@ach_id[.@i])==1){
query_sql("UPDATE `char` SET achievement_points=achievement_points-"+getd("$a_points_"+.@ach_id[.@i])+" WHERE char_id="+getcharid(0));}
setd("a_done_"+.@ach_id[.@i],0);
dispbottom "Achievement "+getd("$a_name_"+.@ach_id[.@i]+"$")+" was removed!";}set.@i,.@i+1;}}//Start the true script
cutin .@cutin$,2;//If a gm talks to this npc, call the gm menu, else the normal scriptif(getgmlevel()>=.@GmMenuAtWhichLevel){
mes .@name$;
mes .@text_gmMenu$;
next;
menu "GM Menu",L_GM,"Player Menu",-,.@text_close$,L_end;}
mes .@name$;
mes .@text_startInfo$;
next;
mes .@name$;
mes .@text_points$+" ^00AA00"+.@points+"^000000";
mes .@text_category$;
next;set.@i,0;if($a_mode_other >0){set.@menu$,.@menu$+.@text_mode_other$+":"; setarray .@tempAr1[.@i],0;set.@i,.@i+1;}if($a_mode_item >0){set.@menu$,.@menu$+.@text_mode_item$+":"; setarray .@tempAr1[.@i],1;set.@i,.@i+1;}if($a_mode_mob >0){set.@menu$,.@menu$+.@text_mode_mob$+":"; setarray .@tempAr1[.@i],2;set.@i,.@i+1;}if($a_mode_mvp >0){set.@menu$,.@menu$+.@text_mode_mvp$+":"; setarray .@tempAr1[.@i],3;set.@i,.@i+1;}if($a_mode_pvp >0){set.@menu$,.@menu$+.@text_mode_pvp$+":"; setarray .@tempAr1[.@i],4;set.@i,.@i+1;}if($a_mode_lvl >0){set.@menu$,.@menu$+.@text_mode_lvl$+":"; setarray .@tempAr1[.@i],5;set.@i,.@i+1;}if($a_mode_jlvl >0){set.@menu$,.@menu$+.@text_mode_jlvl$+":"; setarray .@tempAr1[.@i],6;set.@i,.@i+1;}if(.@i==0){ mes .@name$; mes "Woot. No Achivements found."; cutin "",255; close;}set.@menu$,.@menu$+.@text_close$;set.@choose,select(.@menu$);set.@choose,.@choose-1;if(.@choose==.@i)goto L_end;
next;
mes .@name$;
mes .@text_whichAch$;set.@i,0;set.@j,0;set.@menu$,"";while(.@i< $achive_amount){set.@i,.@i+1;if(getd("$a_mode_"+.@i)!=.@tempAr1[.@choose]|| getd("$a_del_"+.@i+"$")=="y")continue;if(getd("a_done_"+.@i)==1){set.@menu$,.@menu$+"^00AA00";}else{set.@menu$,.@menu$+"^FF0000";}set.@menu$,.@menu$+getd("$a_name_"+.@i+"$")+" ["+getd("$a_points_"+.@i)+"]^000000"+":";
setarray .@tempAr2[.@j],.@i;set.@j,.@j+1;}set.@menu$,.@menu$+.@text_close$;set.@choose2,select(.@menu$);set.@choose2,.@choose2-1;if(.@choose2==.@j){ next;goto L_end;}
next;
mes .@name$;if(getd("$a_desc_"+.@tempAr2[.@choose2]+"$")!=""){
mes getd("$a_desc_"+.@tempAr2[.@choose2]+"$");
next;
mes .@name$;}
mes "^0000AA"+.@text_worth$+" "+getd("$a_points_"+.@tempAr2[.@choose2])+" "+.@text_getPoints$+"^000000";if(.@tempAr1[.@choose]>0){if(.@tempAr1[.@choose]==1||.@tempAr1[.@choose]==2){set.@i,0;while(.@i<9){set.@i,.@i+1;if(getd("$a_val"+.@i+"_"+.@tempAr2[.@choose2])>0&& getd("$a_val"+.@i+"a_"+.@tempAr2[.@choose2])>0){if(.@tempAr1[.@choose]==1){
mes "^0000AA"+getitemname(getd("$a_val"+.@i+"_"+.@tempAr2[.@choose2]))+" ["+countitem(getd("$a_val"+.@i+"_"+.@tempAr2[.@choose2]))+"/"+getd("$a_val"+.@i+"a_"+.@tempAr2[.@choose2])+"]^000000";}else{
mes "^0000AA"+.@text_kill$+" "+callfunc("getMonsterNameById",getd("$a_val"+.@i+"_"+.@tempAr2[.@choose2]))+" ["+getd("a_state_"+.@tempAr2[.@choose2]+"_"+.@i)+"/"+getd("$a_val"+.@i+"a_"+.@tempAr2[.@choose2])+"]^000000";}}}}else{if(.@tempAr1[.@choose]==3) mes "^0000AA"+.@text_kill$+" "+getd("$a_sval_"+.@tempAr2[.@choose2])+" "+.@text_mvp$+" ["+getd("a_state_"+.@tempAr2[.@choose2])+"/"+getd("$a_sval_"+.@tempAr2[.@choose2])+"]^000000";if(.@tempAr1[.@choose]==4) mes "^0000AA"+.@text_kill$+" "+getd("$a_sval_"+.@tempAr2[.@choose2])+" "+.@text_pvp$+" ["+pvp_counter+"/"+getd("$a_sval_"+.@tempAr2[.@choose2])+"]^000000";if(.@tempAr1[.@choose]==5) mes "^0000AA"+.@text_lvl$+" "+getd("$a_sval_"+.@tempAr2[.@choose2])+" ["+BaseLevel+"/"+getd("$a_sval_"+.@tempAr2[.@choose2])+"]^000000";if(.@tempAr1[.@choose]==6) mes "^0000AA"+.@text_jlvl$+" "+getd("$a_sval_"+.@tempAr2[.@choose2])+" ["+JobLevel+"/"+getd("$a_sval_"+.@tempAr2[.@choose2])+"]^000000";}}
next;goto L_end;
L_GM:
mes .@name$;
mes .@text_category$;
next;switch(select("Force Player Achievement","Enable/Disable Achievements","Clear cache","Compare log with achivement points",.@text_close$)){case1:
mes .@name$;
mes "If the player you write here talks to this npc, you can set some actions which will happen, for example get a achivement or revoke a achivement.";
mes "What is the name of the player?";
next;
input .@char_name$;
next;
mes .@name$;
query_sql("SELECT char_id FROM `char` WHERE name='"+.@char_name$+"'",.@char_id);if(.@char_id>0){
mes "Which achivement?";
next;set.@i,0;set.@j,0;set.@menu$,"";while(.@i< $achive_amount){set.@i,.@i+1;if(getd("$a_del_"+.@i+"$")=="y")continue;set.@menu$,.@menu$+getd("$a_name_"+.@i+"$")+":";set.@j,.@j+1;
setarray .@tempAr1[.@j],.@i;}set.@menu$,.@menu$+.@text_close$;set.@choose,select(.@menu$);if(.@choose==.@j+1)goto L_GM;
next;
mes .@name$;
mes "Adding or removing this achivement?";
next;switch(select("Add","Remove",.@text_close$)){case1:set.@mode$,"add";break;case2:set.@mode$,"del";break;case3:goto L_GM;break;}
next;
mes .@name$;
mes "Player: "+.@char_name$;
mes "Achivement: "+getd("$a_name_"+.@tempAr1[.@choose]+"$")+" (id="+.@tempAr1[.@choose]+")";
mes "Mode: "+.@mode$;
mes "Are you sure?";
next;
menu "Yes!",-,"No",L_GM;
mes .@name$;
query_sql("INSERT INTO achievement_force(ach_id,char_id,mode) VALUES('"+.@tempAr1[.@choose]+"','"+.@char_id+"','"+.@mode$+"')");if(.@mode$=="del"){switch(getd("$a_mode_"+.@tempAr1[.@choose])){default:set achieve_other,achieve_other-1;break;case1:set achieve_item,achieve_item-1;break;case2:set achieve_mob,achieve_mob-1;break;case3:set achieve_mvp,achieve_mvp-1;break;case4:set achieve_pvp,achieve_pvp-1;break;case5:set achieve_lvl,achieve_lvl-1;break;case6:set achieve_jlvl,achieve_jlvl-1;break;}}
mes "Action added! "+.@char_name$+" should talk to me now!";
next;}else{
mes "Player not found!";
next;}goto L_GM;break;case2:
mes .@name$;
mes "Red=disabled, green=enabled";
mes "Be carefull on your achivements you added without triggers (mode 0). If you don't check there if the achivement is deleted, it may cause problems";set.@i,0;set.@menu$,"";while(.@i< $achive_amount){set.@i,.@i+1;if(getd("$a_del_"+.@i+"$")=="n"){set.@menu$,.@menu$+"^00AA00";}else{set.@menu$,.@menu$+"^FF0000";}set.@menu$,.@menu$+getd("$a_name_"+.@i+"$")+"^000000:";}set.@menu$,.@menu$+.@text_close$;
next;set.@choose,select(.@menu$);if(.@choose<=.@i){if(getd("$a_del_"+.@choose+"$")=="n"){set.@updateTo$,"y";}else{set.@updateTo$,"n";}
query_sql("UPDATE achievement SET deleted='"+.@updateTo$+"' WHERE id="+.@choose);
dispbottom "Achivement "+getd("$a_name_"+.@choose+"$")+" updated to deleted='"+.@updateTo$+"'!";
dispbottom "Clear Cache to see any effects!!!";goto L_GM;}break;case3:set $a_cached,0;
dispbottom "Cache remove Flag has been set. When the next player login, the cache will be cleared";goto L_GM;break;case4://if you build in something like "For 100 achivement points get 1 Cookie", this function would be buggy!
query_sql("SELECT char_id,achievement_points,name FROM `char`",.@char_id,.@ach_points,.@char_name$);set.@i,0;
dispbottom "Sync started!";while(.@i< getarraysize(.@char_id)){
cleararray .@ach_id[0],0,getarraysize(.@ach_id);
query_sql("SELECT ach_id FROM achievement_log WHERE char_id="+.@char_id[.@i],.@ach_id);set.@j,0;set.@points,0;while(.@j< getarraysize(.@ach_id)){set.@points,.@points+getd("$a_points_"+.@ach_id[.@j]);set.@j,.@j+1;}if(.@ach_points[.@i]!=.@points){
query_sql("UPDATE `char` SET achievement_points="+.@points+" WHERE char_id="+.@char_id[.@i]);
dispbottom .@char_name$[.@i]+" had "+.@ach_points[.@i]+" points, but should have "+.@points+" points. Fixed!";}set.@i,.@i+1;}
dispbottom "Sync done!";goto L_GM;break;case5:break;}goto L_end;
L_end:
mes .@name$;
mes .@text_bye$;
close2;
cutin "",255;
end;}
Is it possible to make a npc shop for the points earned in this achievement script? If yes I would like to request it.
Question
AllHailCarl
Is it possible to make a npc shop for the points earned in this achievement script? If yes I would like to request it.
Link to comment
Share on other sites
2 answers to this question
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.