// 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 (in future, TODO) // Max Level for base: 10 // Max Level for first tier: 5 // Max Level for second tier: // Max Level for third tier: // Max Level for ultimate tier: 1 // 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); if (.@lvl >= 2) array_push(@csys_attr, VAR_VITAMOUNT); if (.@lvl >= 3) array_push(@csys_attr, VAR_AGIAMOUNT); if (.@lvl >= 4) array_push(@csys_attr, VAR_INTAMOUNT); if (.@lvl >= 5) array_push(@csys_attr, VAR_DEXAMOUNT); if (.@lvl >= 6) array_push(@csys_attr, VAR_LUKAMOUNT); if (.@lvl >= 8) array_push(@csys_attr, VAR_MAXHPAMOUNT); if (.@lvl >= 10) array_push(@csys_attr, VAR_MAXSPAMOUNT); // 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_ITEMDEFPOWER); array_push(@csys_penalty, VAR_MDEFPOWER); // 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_ATTPOWER); array_push(@csys_penalty, VAR_ATTMPOWER); // 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_ATTPOWER); array_push(@csys_penalty, VAR_ATTMPOWER); // 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); // 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_ATTPOWER); array_push(@csys_penalty, VAR_ATTMPOWER); // 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_ATTPOWER); array_push(@csys_penalty, VAR_ATTMPOWER); // 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, VAR_ATTPOWER); array_push(@csys_penalty, VAR_ATTMPOWER); // 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, VAR_ATTPOWER); array_push(@csys_penalty, VAR_ATTMPOWER); // 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_ATTPOWER); array_push(@csys_penalty, VAR_ATTMPOWER); // 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, VAR_ATTPOWER); array_push(@csys_penalty, VAR_ATTMPOWER); // 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_ATTMPOWER); // 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_ATTPOWER); array_push(@csys_penalty, VAR_ATTMPOWER); // 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() → 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 IOPT_SCRESIST_POISON: case IOPT_SCRESIST_SILENCE: case IOPT_SCRESIST_CURSE: case IOPT_SCRESIST_BLIND: return 2; case VAR_MAXHPAMOUNT: case VAR_MAXSPAMOUNT: case VAR_ITEMDEFPOWER: case VAR_MDEFPOWER: return 3; default: return 1; } 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/onus, -30% each, depending on skill lv .@base=3000-(.@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)*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 100% for first bonus/onus, -30% each, depending on skill lv .@base=3000+(.@lv*75); if (rand(10000) > 10000-(.@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)*csys_Multiplier(.@vartp)+1; setitemoptionbyindex(.@id, .@slot, .@vartp, .@bonus); .@slot+=1; .@slt+=1; } // The options have been attributed return; }