summaryrefslogblamecommitdiff
path: root/npc/craft/options.txt
blob: 47c382dc9a8aacf44feb5eff35f40b32ca02acec (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11










                                                             



                                                                   




                                                                
                                                       
 
                                     
                       
                                         


                                
                                   
     



                                        

                                                                 

                                     
                         
                                                  
                                                  

                         
                                                  
                                                    


                                                  
                                                    




                                                  




                          


                                                                 









                                                        

                                                   














                                                             

                                                 












                                                             


                                                    














                                                              
                                                





                          

                                                                 







                                                       
                                                


                          












                                                        
                                                   












                                                      
                                                            













                                                           
                                                   


                          
                 
     
 















                                                                 

                                                            


















                                                           




                                                         













                                                       
                                                    












                                                             

                                                             

















                                                                 
 
                                   



                               

 






















                                                                                  





                                                                       
 











                                                            

 






                                                  









                               



                                   
                     



                              
                     
                
                     



             

                                                                 
                                       


                                           
                                     
 
                              

                                                








                                                                       

                                                                                

                                         

                                                                          
                                                




                                                                        
                                                                     
                                                             
                                                                                  





                                        
                                                                        
                              
                                              




                                                                        
                                                                     







                                                             



 

























                                        



                                         
                                                           



                                          
                                                                         




                                           




                                                                                 
                                                         



                                   
                                                          


























































                                                                
                                                  

                                                  




              








                                                 



                                                    
 










































































                                                               












                                                                  

                   
























                                                              
     
                                                                 
 

 
                             

                                                       
                                                 

                               
                                                                                       



              
















                                                   























































                                                                                         
                                                         
               
                                                         
               
                                                         
               
                                                         
               
                                                         



           
// TMW2 Script
// Author:
//  Jesusalva
// Description:
//  Item Option System
// Notes:
//  Awarded for crafters and their own base skill tree system

// Player knowledge structure
// CRAFTSYS[ SKILL_SCOPE ] = SKILL_LV

// Player craft skills selection:
// CRAFTSYS_CURRENT

// Generate() takes the scope and finds out the skills on the group
// It'll fill the following variables:
//      @csys_attr → Available attributes
//      @csys_penalty → Penalty attribute array
//
//      use getarraysize(@csys_attr) to know how many are there.
// Players can active the bonus groups they want to use

// csys_Generate( cr_id{, preserve} )
// Return average level
function	script	csys_Generate	{
    .@gid=getarg(0);
    if (!getarg(1, false)) {
        deletearray(@csys_attr);
        deletearray(@csys_penalty);
    }
    //.@lvl=getd("CRAFTSYS["+.@gid+"]");
    .@avg=0;
    .@stk=0;

    /////////////////////////////////////////////////////////////
    // Basic tier
    if (.@gid & CRGROUP_BASE) {
        .@lvl=CRAFTSYS[CRGROUP_BASE];
        if (.@lvl >= 1) {
            array_push(@csys_attr, VAR_STRAMOUNT);
            array_push(@csys_attr, VAR_INTAMOUNT);
        }
        if (.@lvl >= 3) {
            array_push(@csys_attr, VAR_DEXAMOUNT);
            array_push(@csys_attr, VAR_MAXHPAMOUNT);
        }
        if (.@lvl >= 5) {
            array_push(@csys_attr, VAR_AGIAMOUNT);
            array_push(@csys_attr, VAR_MAXSPAMOUNT);
        }
        if (.@lvl >= 7) {
            array_push(@csys_attr, VAR_LUKAMOUNT);
            array_push(@csys_attr, VAR_VITAMOUNT);
        }

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }

    /////////////////////////////////////////////////////////////
    // First tier
    if (.@gid & CRGROUP_ATK) {
        .@lvl=CRAFTSYS[CRGROUP_ATK];
        if (.@lvl >= 1) {
            array_push(@csys_attr, VAR_ATTPOWER);
            array_push(@csys_attr, VAR_ATTMPOWER);
        }
        if (.@lvl >= 5) {
            array_push(@csys_attr, VAR_MAGICATKPERCENT);
            array_push(@csys_attr, VAR_ATKPERCENT);
        }
        array_push(@csys_penalty, VAR_VITAMOUNT);
        array_push(@csys_penalty, VAR_MAXHPAMOUNT);

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }
    if (.@gid & CRGROUP_DEF) {
        .@lvl=CRAFTSYS[CRGROUP_DEF];
        if (.@lvl >= 1) {
            array_push(@csys_attr, VAR_ITEMDEFPOWER);
            array_push(@csys_attr, VAR_MDEFPOWER);
        }
        if (.@lvl >= 5) {
            array_push(@csys_attr, DAMAGE_CRI_USER);
            array_push(@csys_attr, RANGE_ATTACK_DAMAGE_USER);
        }
        array_push(@csys_penalty, VAR_DEXAMOUNT);
        array_push(@csys_penalty, VAR_INTAMOUNT);

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }
    if (.@gid & CRGROUP_ACC) {
        .@lvl=CRAFTSYS[CRGROUP_ACC];
        if (.@lvl >= 1) {
            array_push(@csys_attr, VAR_HITSUCCESSVALUE);
        }
        if (.@lvl >= 5) {
            array_push(@csys_attr, VAR_CRITICALSUCCESSVALUE);
        }
        array_push(@csys_penalty, VAR_LUKAMOUNT);
        array_push(@csys_penalty, VAR_MDEFPOWER);
        array_push(@csys_penalty, VAR_ITEMDEFPOWER);

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }
    if (.@gid & CRGROUP_EVD) {
        .@lvl=CRAFTSYS[CRGROUP_EVD];
        if (.@lvl >= 1) {
            array_push(@csys_attr, VAR_AVOIDSUCCESSVALUE);
        }
        if (.@lvl >= 5) {
            array_push(@csys_attr, VAR_PLUSAVOIDSUCCESSVALUE);
        }
        array_push(@csys_penalty, VAR_ATTPOWER);
        array_push(@csys_penalty, VAR_ATTMPOWER);
        array_push(@csys_penalty, IOPT_CRITDMG);

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }

    /////////////////////////////////////////////////////////////
    // Second tier
    if (.@gid & CRGROUP_REGEN) {
        .@lvl=CRAFTSYS[CRGROUP_REGEN];
        if (.@lvl >= 1) {
            array_push(@csys_attr, VAR_HPACCELERATION);
        }
        if (.@lvl >= 5) {
            array_push(@csys_attr, VAR_SPACCELERATION);
        }
        array_push(@csys_penalty, VAR_PLUSASPD);

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }
    if (.@gid & CRGROUP_SPEED) {
        .@lvl=CRAFTSYS[CRGROUP_SPEED];
        if (.@lvl >= 1) {
            array_push(@csys_attr, VAR_PLUSASPD);
        }
        if (.@lvl >= 3) {
            array_push(@csys_attr, VAR_PLUSASPDPERCENT);
        }
        if (.@lvl >= 5) {
            array_push(@csys_attr, IOPT_WALKSPEED);
        }
        array_push(@csys_penalty, VAR_MAXSPAMOUNT);

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }
    if (.@gid & CRGROUP_DOUBLE) {
        .@lvl=CRAFTSYS[CRGROUP_DOUBLE];
        if (.@lvl >= 1) {
            array_push(@csys_attr, IOPT_CRITDMG);
        }
        if (.@lvl >= 5) {
            array_push(@csys_attr, IOPT_DOUBLEATTACK);
        }
        array_push(@csys_penalty, RANGE_ATTACK_DAMAGE_USER);

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }
    if (.@gid & CRGROUP_MAXPC) {
        .@lvl=CRAFTSYS[CRGROUP_MAXPC];
        if (.@lvl >= 1) {
            array_push(@csys_attr, VAR_MAXHPPERCENT);
            array_push(@csys_attr, VAR_MAXSPPERCENT);
        }
        if (.@lvl >= 5) {
            array_push(@csys_attr, CLASS_DAMAGE_BOSS_USER);
        }
        array_push(@csys_penalty, DAMAGE_CRI_USER);

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }

    /////////////////////////////////////////////////////////////
    // Third tier
    if (.@gid & CRGROUP_SCRESIST) {
        .@lvl=CRAFTSYS[CRGROUP_SCRESIST];
        if (.@lvl >= 1) {
            array_push(@csys_attr, IOPT_SCRESIST_POISON);
        }
        if (.@lvl >= 2) {
            array_push(@csys_attr, IOPT_SCRESIST_SILENCE);
        }
        if (.@lvl >= 3) {
            array_push(@csys_attr, IOPT_SCRESIST_BLIND);
        }
        if (.@lvl >= 4) {
            array_push(@csys_attr, IOPT_SCRESIST_CURSE);
        }
        array_push(@csys_penalty, VAR_CRITICALSUCCESSVALUE);
        array_push(@csys_penalty, IOPT_CRITDMG);

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }
    if (.@gid & CRGROUP_SCINFLICT) {
        .@lvl=CRAFTSYS[CRGROUP_SCINFLICT];
        if (.@lvl >= 1) {
            array_push(@csys_attr, IOPT_SCPROVOKE_POISON);
        }
        if (.@lvl >= 2) {
            array_push(@csys_attr, IOPT_SCPROVOKE_SILENCE);
        }
        if (.@lvl >= 3) {
            array_push(@csys_attr, IOPT_SCPROVOKE_BLIND);
        }
        if (.@lvl >= 4) {
            array_push(@csys_attr, IOPT_SCPROVOKE_CURSE);
        }
        array_push(@csys_penalty, IOPT_SCRESIST_POISON);
        array_push(@csys_penalty, IOPT_SCRESIST_SILENCE);
        array_push(@csys_penalty, IOPT_SCRESIST_BLIND);
        array_push(@csys_penalty, IOPT_SCRESIST_CURSE);
        array_push(@csys_penalty, VAR_MAXHPAMOUNT);

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }
    if (.@gid & CRGROUP_MANAUSE) {
        .@lvl=CRAFTSYS[CRGROUP_MANAUSE];
        if (.@lvl >= 1) {
            array_push(@csys_attr, SP_DRAIN);
        }
        if (.@lvl >= 5) {
            array_push(@csys_attr, DEC_SP_CONSUMPTION);
        }
        array_push(@csys_penalty, VAR_ATTPOWER);
        array_push(@csys_penalty, VAR_ITEMDEFPOWER);

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }
    if (.@gid & CRGROUP_BOSSATK) {
        .@lvl=CRAFTSYS[CRGROUP_BOSSATK];
        if (.@lvl >= 1) {
            array_push(@csys_attr, HP_DRAIN);
        }
        if (.@lvl >= 5) {
            array_push(@csys_attr, CLASS_DAMAGE_BOSS_TARGET);
        }
        array_push(@csys_penalty, VAR_AVOIDSUCCESSVALUE);
        array_push(@csys_penalty, VAR_PLUSAVOIDSUCCESSVALUE);

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }

    /////////////////////////////////////////////////////////////
    // Final tier (needs minimum lv 3)
    if (.@gid & CRGROUP_FINAL) {
        .@lvl=CRAFTSYS[CRGROUP_FINAL];
        if (.@lvl >= 3) {
            array_push(@csys_attr, IOPT_EXPGAIN);
        }

        // Update averages
        .@avg+=.@lvl;
        .@stk+=1;
    }

    ///////////////////////////////
    // Return the average level
    if (!.@stk)
        return 0;
    return (.@avg/.@stk);
}

// Confirms if player really wants to tweak a craft.
// Do not cast after new crafts. Returns false to stop script.
// csys_Confirm( invindex )
function	script	csys_Confirm	{
    .@id=getarg(0);

    // Sanitize input
    if (.@id < 0)
        return false;

    // *getequipisenableopt(<equipment slot>) → cannot use here
    // Not an equipment
    if (!getiteminfo(.@id, ITEMINFO_LOC))
        return false;

    mesc l("Really try to tweak this item? All current options will be deleted.");
    next;
    if (askyesno() == ASK_NO)
        return false;

    return true;
}

// Check if you'll have success in applying options or not
// Returns true if you was successful, and also cleans previous options
// If you only want cleaning, just disregard the output.
// csys_Check( invindex )
function	script	csys_Check	{
    .@id=getarg(0);

    // Clear all five options
    setitemoptionbyindex(.@id, 0, 0, 0);
    setitemoptionbyindex(.@id, 1, 0, 0);
    setitemoptionbyindex(.@id, 2, 0, 0);
    setitemoptionbyindex(.@id, 3, 0, 0);
    setitemoptionbyindex(.@id, 4, 0, 0);

    // Base Success Rate is: 40% + 5% each craft skill level
    .@base=4000+(getskilllv(TMW2_CRAFT)*500);
    if (rand(10000) < .@base)
        return true;
    return false;
}

// csys_Multiplier( cr_id )
// Returns a multiplier for bonus (it can be zero)
function	script	csys_Multiplier	{
    .@sk=getarg(0);
    switch (.@sk) {
        case IOPT_SPLASHDAMAGE:
            return 0;
        case VAR_STRAMOUNT:
        case VAR_AGIAMOUNT:
        case VAR_VITAMOUNT:
        case VAR_INTAMOUNT:
        case VAR_DEXAMOUNT:
        case VAR_LUKAMOUNT:
        case HP_DRAIN:
        case SP_DRAIN:
        case IOPT_DOUBLEATTACK:
            return 1;
        case IOPT_SCRESIST_POISON:
        case IOPT_SCRESIST_SILENCE:
        case IOPT_SCRESIST_CURSE:
        case IOPT_SCRESIST_BLIND:
            return 3;
        case VAR_MAXHPAMOUNT:
        case VAR_MAXSPAMOUNT:
        case VAR_ITEMDEFPOWER:
        case VAR_MDEFPOWER:
            return 5;
        default:
            return 2;
    }
    return 0;
}

// Attribute item options
// Does NOT performs success chance check, and can be used by NPC
// csys_Apply( invindex{, lvl, scope} )
function	script	csys_Apply	{
    .@id=getarg(0);
    .@lv=getarg(1, getskilllv(TMW2_CRAFT));
    .@sc=getarg(1, CRAFTSYS_CURRENT);

    .@lv2=csys_Generate(.@sc);
    // @csys_attr → Available attributes
    // @csys_penalty → Penalty attribute array

    // Shuffle the arrays
    array_shuffle(@csys_attr);
    array_shuffle(@csys_penalty);

    // How many bonuses we'll have? Never more than 3 bonus and 2 onus.
    .@max_attr=getarraysize(@csys_attr);
    .@max_pena=getarraysize(@csys_penalty);

    //debugmes "We have %d attributes and %d penalties", .@max_attr, .@max_pena;

    .@slot=0;
    while (.@slot < min(3, .@max_attr)) {
        // You have 100% for first bonus, -35% each, depending on skill lv
        .@base=3500-(.@lv*75);
        if (rand(10000) > 10000-(.@base*.@slot))
            break;

        // Apply a bonus using array_pop (it was shuffled so we're fine)
        // A pity 1 str and 1 hp is so different.
        .@vartp=array_pop(@csys_attr);
        .@bonus=rand(1, (.@lv+.@lv2)/2+1)*csys_Multiplier(.@vartp)+1;
        setitemoptionbyindex(.@id, .@slot, .@vartp, .@bonus);
        //debugmes "Bonus applied: %d at %d (slot: %d)", .@vartp, .@bonus, .@slot;
        .@slot+=1;
    }

    // We need a new temp var
    .@slt=0;
    while (.@slt < min(2, .@max_pena)) {
        // You have 95% for first onus, -30% each, depending on skill lv
        .@base=3000+(.@lv*75);
        if (rand(10000) > 9500-(.@base*.@slt))
            break;

        // Apply a bonus using array_pop (it was shuffled so we're fine)
        // A pity 1 str and 1 hp is so different.
        .@vartp=array_pop(@csys_penalty);
        .@bonus=rand(1, (.@lv+.@lv2)/2+1)*csys_Multiplier(.@vartp)+1;
        setitemoptionbyindex(.@id, .@slot, .@vartp, .@bonus);
        .@slot+=1;
        .@slt+=1;
    }

    // The options have been attributed
    return;
}

























////////////////////////////////////////
/////////////////
///////
// Interface System for Options Craft

// csysGUI_Report(  )
// Report craft skill levels
function	script	csysGUI_Report	{

    mes l("Crafting Skill: Lv @@", getskilllv(TMW2_CRAFT));
    mes "";
    mes ".:: " + l("First Tier") + " ::.";
    mesc l("Craft Min Level: 1");
    mes "";
    mes l("@@: Lv @@", getitemlink(CRITEM_BASE), CRAFTSYS[CRGROUP_BASE]);
    next;
    mes "";
    mes ".:: " + l("Second Tier") + " ::.";
    mesc l("Craft Min Level: 2");
    mes "";
    // Maybe we should either add a icon for attack skill group
    // Or make it a 74xx fake item so player can hover for the information
    // where effects="requeriments" and desc="Attributes". Just need Names on db.
    // Final struct would be: l("@@: Lv @@", getitemlink(CRITEM_ATK), CRAFTSYS...
    // It could still use 16x16 icons. But then, we need a curse SI (TODO)
    mes l("ATTACK SKILLS: Lv @@", CRAFTSYS[CRGROUP_ATK]);
    mesc l("BASIC Min Level: 2");
    mesc l("Lv 1 - Atk, MAtk");
    mesc l("Lv 5 - Atk %, MAtk %");
    mes "";
    mes l("DEFENSE SKILLS: Lv @@", CRAFTSYS[CRGROUP_DEF]);
    mesc l("BASIC Min Level: 2");
    mesc l("Lv 1 - Def, MDef");
    mesc l("Lv 5 - Crit DEF, Ranged DEF");

    next;
    return;
}


// csysGUI_CRName( cr )
// Return group name for CR
function	script	csysGUI_CRName	{
    .@cr=getarg(0);
    switch (.@cr) {
        case CRGROUP_BASE:
            return l("0 - Base Bonus");
        // Tier 1
        case CRGROUP_ATK:
            return l("1 - Attack Bonus");
        case CRGROUP_DEF:
            return l("1 - Defense Bonus");
        case CRGROUP_ACC:
            return l("1 - Accuracy Bonus");
        case CRGROUP_EVD:
            return l("1 - Evasion Bonus");
        // Tier 2
        case CRGROUP_REGEN:
            return l("2 - Regeneration Bonus");
        case CRGROUP_SPEED:
            return l("2 - Speed Bonus");
        case CRGROUP_DOUBLE:
            return l("2 - Double Power Bonus");
        case CRGROUP_MAXPC:
            return l("2 - Max Stats Bonus");
        // Tier 3
        case CRGROUP_SCRESIST:
            return l("3 - SC Resist Bonus");
        case CRGROUP_SCINFLICT:
            return l("3 - SC Inflict Bonus");
        case CRGROUP_MANAUSE:
            return l("3 - Mana Economy Bonus");
        case CRGROUP_BOSSATK:
            return l("3 - Boss Techniques Bonus");
        case CRGROUP_FINAL:
            return l("4 - EXP Bonus");
        default:
            return Exception("Invalid optname group: "+.@cr);
    }
    return Exception("Definitely Invalid optname group: "+.@cr);
}


// csysGUI_OptToogleMenu( cr )
// Returns a Toogle Menu for option group (CR)
//
function	script	csysGUI_OptToogleMenu	{
    .@sk=getarg(0);
    if (getd("CRAFTSYS["+.@sk+"]")) {
        if (CRAFTSYS_CURRENT & .@sk)
            return "Remove "+csysGUI_CRName(.@sk);
        else
            return "Active "+csysGUI_CRName(.@sk);
    }
    return "";
}


// csysGUI_ChangeOpt( cr )
// Change option
function	script	csysGUI_ChangeOpt	{
    .@sk=getarg(0);
    CRAFTSYS_CURRENT=CRAFTSYS_CURRENT^.@sk;
    return;
}


// csysGUI_OptReq( cr )
// Return true if all requisites for Option were met
function	script	csysGUI_OptReq	{
    .@sk=getarg(0);

    switch (.@sk) {
        case CRGROUP_BASE:
            return (getskilllv(TMW2_CRAFT) >= 1);
        // Tier 1
        case CRGROUP_ATK:
            return (getskilllv(TMW2_CRAFT) >= 2 &&
                    CRAFTSYS[CRGROUP_BASE]);
        case CRGROUP_DEF:
            return (getskilllv(TMW2_CRAFT) >= 2 &&
                    CRAFTSYS[CRGROUP_BASE]);
        case CRGROUP_ACC:
            return (getskilllv(TMW2_CRAFT) >= 2 &&
                    CRAFTSYS[CRGROUP_BASE]);
        case CRGROUP_EVD:
            return (getskilllv(TMW2_CRAFT) >= 2 &&
                    CRAFTSYS[CRGROUP_BASE]);
        // Tier 2
        case CRGROUP_REGEN:
            return (getskilllv(TMW2_CRAFT) >= 3 &&
                    CRAFTSYS[CRGROUP_ATK] &&
                    CRAFTSYS[CRGROUP_DEF] &&
                    CRAFTSYS[CRGROUP_BASE] >= 2);
        case CRGROUP_SPEED:
            return (getskilllv(TMW2_CRAFT) >= 3 &&
                    CRAFTSYS[CRGROUP_ACC] &&
                    CRAFTSYS[CRGROUP_EVD] &&
                    CRAFTSYS[CRGROUP_BASE] >= 2);
        case CRGROUP_DOUBLE:
            return (getskilllv(TMW2_CRAFT) >= 3 &&
                    CRAFTSYS[CRGROUP_ATK] &&
                    CRAFTSYS[CRGROUP_ACC] &&
                    CRAFTSYS[CRGROUP_BASE] >= 2);
        case CRGROUP_MAXPC:
            return (getskilllv(TMW2_CRAFT) >= 3 &&
                    CRAFTSYS[CRGROUP_DEF] &&
                    CRAFTSYS[CRGROUP_EVD] &&
                    CRAFTSYS[CRGROUP_BASE] >= 2);
        // Tier 3
        case CRGROUP_SCRESIST:
            return (getskilllv(TMW2_CRAFT) >= 4 &&
                    CRAFTSYS[CRGROUP_MAXPC] >= 2 &&
                    CRAFTSYS[CRGROUP_REGEN] >= 2 &&
                    CRAFTSYS[CRGROUP_BASE] >= 4);
        case CRGROUP_SCINFLICT:
            return (getskilllv(TMW2_CRAFT) >= 4 &&
                    CRAFTSYS[CRGROUP_SPEED] >= 2 &&
                    CRAFTSYS[CRGROUP_DOUBLE] >= 2 &&
                    CRAFTSYS[CRGROUP_BASE] >= 4);
        case CRGROUP_MANAUSE:
            return (getskilllv(TMW2_CRAFT) >= 4 &&
                    CRAFTSYS[CRGROUP_DEF] >= 3 &&
                    CRAFTSYS[CRGROUP_EVD] >= 3 &&
                    CRAFTSYS[CRGROUP_BASE] >= 4);
        case CRGROUP_BOSSATK:
            return (getskilllv(TMW2_CRAFT) >= 4 &&
                    CRAFTSYS[CRGROUP_ATK] >= 3 &&
                    CRAFTSYS[CRGROUP_HIT] >= 3 &&
                    CRAFTSYS[CRGROUP_BASE] >= 4);
        case CRGROUP_FINAL:
            return (getskilllv(TMW2_CRAFT) >= 5 &&
                    CRAFTSYS[CRGROUP_BOSSATK] &&
                    CRAFTSYS[CRGROUP_MANAUSE] &&
                    CRAFTSYS[CRGROUP_SCINFLICT] &&
                    CRAFTSYS[CRGROUP_SCRESIST] &&
                    CRAFTSYS[CRGROUP_BASE] >= 6);
        default:
            return Exception("Invalid optreq group: "+.@sk);
    }
    return Exception("Definitely Invalid optreq group: "+.@sk);
}

// csysGUI_OptPrice( cr )
// Return group option price and requisites
function	script	csysGUI_OptPrice	{
    .@sk=getarg(0);
    .@lv=getd("CRAFTSYS["+.@sk+"]")+1;

    // Every 3 skills levels (including the 0), price raises in 1
    .@lv+=(.@lv/3);

    // Every 10 skills levels (including the 0), price raises in 3
    .@lv+=((.@lv/10)*3);

    // Every 25 skills levels (including the 0), price raises in 5
    .@lv+=((.@lv/25)*5);

    // Every 99 skills levels (including the 0), price raises in 7
    .@lv+=((.@lv/99)*7);

    switch (.@sk) {
        case CRGROUP_BASE:
            return 1000*.@lv;
        // Tier 1
        case CRGROUP_ATK:
        case CRGROUP_DEF:
        case CRGROUP_ACC:
        case CRGROUP_EVD:
            return 10000*.@lv;
        // Tier 2
        case CRGROUP_REGEN:
        case CRGROUP_SPEED:
        case CRGROUP_DOUBLE:
        case CRGROUP_MAXPC:
            return 40000*.@lv;
        // Tier 3
        case CRGROUP_SCRESIST:
        case CRGROUP_SCINFLICT:
        case CRGROUP_MANAUSE:
        case CRGROUP_BOSSATK:
            return 120000*.@lv;
        // Final
        case CRGROUP_FINAL:
            return 200000*.@lv;
        default:
            return Exception("Invalid optprice group: "+.@cr);
    }
    return Exception("Definitely Invalid optprice group: "+.@cr);
}


// csysGUI_OptLearnMenu( cr )
// Returns the menu entry to learn the group skill.
// Cost is NOT taken as requisite, must check it later.
function	script	csysGUI_OptLearnMenu	{
    .@sk=getarg(0);
    if (csysGUI_OptReq(.@sk)) {
        return "Upgrade "+csysGUI_CRName(.@sk)+" for "+csysGUI_OptPrice(.@sk)+" Mobpt";
    }
    return "";
}


// csysGUI_RaiseOpt( cr )
// Returns true if can raise group, false otherwise
function	script	csysGUI_RaiseOpt	{
    .@sk=getarg(0);
    .@pc=csysGUI_OptPrice(.@sk);
    if (csysGUI_OptReq(.@sk)) {
        if (Mobpt >= .@pc) {
            Mobpt-=.@pc;
            .@lv=getd("CRAFTSYS["+.@sk+"]");
            setd("CRAFTSYS["+.@sk+"]", .@lv+1);
            return true;
        }
    }
    return false;
}

























////////////////////////////////////////
/////////////////
///////
// Misc Functions for Options Craft

// CsysNpcCraft( itemid, {bonus 1, value 1], {bonus 2, value 2}... )
// Create a craft item in a NPC's stead. Needless to say, never fails.
function	script	CsysNpcCraft	{
    // Illegal param number
    if (getargcount() % 2 != 1)
        return Exception("Invalid craft NPC argument count", RB_DEFAULT|RB_IRCBROADCAST);

    // Setup variables
    .@it=getarg(0);
    .@opt1=getarg(1,0);
    .@val1=getarg(2,0);
    .@opt2=getarg(3,0);
    .@val2=getarg(4,0);
    .@opt3=getarg(5,0);
    .@val3=getarg(6,0);
    .@opt4=getarg(7,0);
    .@val4=getarg(8,0);
    .@opt5=getarg(9,0);
    .@val5=getarg(10,0);

    getitem(.@it, 1);
    delinventorylist(); // Needed, because we'll rely on rfind()
    getinventorylist();
    .@index=array_rfind(@inventorylist_id, .@it);

    // Apply the bonuses if needed
    if (.@opt1)
        setitemoptionbyindex(.@index, 0, .@opt1, .@val1);
    if (.@opt2)
        setitemoptionbyindex(.@index, 1, .@opt2, .@val2);
    if (.@opt3)
        setitemoptionbyindex(.@index, 2, .@opt3, .@val3);
    if (.@opt4)
        setitemoptionbyindex(.@index, 3, .@opt4, .@val4);
    if (.@opt5)
        setitemoptionbyindex(.@index, 4, .@opt5, .@val5);

    return;
}