From 3840fe22259022e6f02f9bb767bb2802de0325a3 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Sat, 25 Jan 2020 18:03:12 -0300 Subject: *Cough cough* I present to yall, Tolchi Special Requests system. The latest, newest, most powerful money sink on the whole game. It beats lottery with so much grace and efficiency! Dear Saulc. --- npc/001-1/mahul.txt | 1 - npc/005-4/tolchi.txt | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ npc/functions/array.txt | 48 +++++++++++++++++++++++++ npc/functions/util.txt | 1 + 4 files changed, 143 insertions(+), 1 deletion(-) (limited to 'npc') diff --git a/npc/001-1/mahul.txt b/npc/001-1/mahul.txt index 5d0483350..fa4cd282a 100644 --- a/npc/001-1/mahul.txt +++ b/npc/001-1/mahul.txt @@ -21,7 +21,6 @@ goto L_NotEnoughBottles; if (Zeny < .@Cost) goto L_NotEnoughMoney; - getinventorylist; inventoryplace BottleOfDivineWater, .@count; Zeny=Zeny-.@Cost; diff --git a/npc/005-4/tolchi.txt b/npc/005-4/tolchi.txt index 133e6a3fe..117ae7ad8 100644 --- a/npc/005-4/tolchi.txt +++ b/npc/005-4/tolchi.txt @@ -20,6 +20,7 @@ function quest_second; function quest_third; function tolchi_arrows; + function tolchi_tweaks; ///////////////////////////////////////////////////////////////////////////// @q = getq(CandorQuest_Tolchi); @@ -61,6 +62,9 @@ case 4: quest_third(); break; + case 5: + tolchi_tweaks(); + break; default: quest_close(); goodbye; @@ -230,6 +234,96 @@ function tolchi_arrows { close; } +// Supreme Tweaking +function tolchi_tweaks { + // Price: the sky is the limit + .@price=max(120, 200-(@q*25)); + mesn; + mes l("Hmm, no, not really. However, I can try my hand at tweaking an item options :3"); + next; + mesn; + mesq l("Options are %s. Any craftsman can make them. Adventurers tend to be the best craftsman in the world.", b(l("item dependant bonuses"))); + next; + mesn; + mesq l("Usually you can only tweak if the item already have another option, but I am Tolchi. So, which item you want to tweak?"); + next; + + // Request and confirm + .@id=requestitemindex(); + if (!csys_Confirm(.@id)) + return false; + + // Find numeric ID + delinventorylist(); + getinventorylist(); + .@handle=@inventorylist_id[.@id]; + + // Multiple + if (countitem(.@handle) != 1) { + mesn; + mesq l("Sorry, but you have multiple %s.", getitemlink(.@handle)); + close; + } + + // Calculate price + .@lv=getiteminfo(.@handle, ITEMINFO_ELV); + .@price=.@lv**3; // Cubic function to determine price. + // Lv 1: 3 GP | Lv 10: 1kGP | Lv 20: 8kGP | Lv 40: 64kGP | Lv 60: 216kGP + // Lv 80: 512k GP | Lv 100: 1 Million GP! + mesn; + mesq l("That will be %s GP. Are you sure?", col(format_number(.@price), 1)); + next; + + if (Zeny < .@price || askyesno() == ASK_NO) { + close2; + goodbye; + } else { + mes ""; + // Okay, time to force a tweaking + Zeny=Zeny-.@price; + + // Options which Tolchi knows + setarray .@vartps, 0, + IOPT_RICHNESS, 11, + IOPT_EXPGAIN, 9, + IOPT_CRITDMG, 25, + VAR_HPACCELERATION, 30, + VAR_MAXHPAMOUNT, 35; + + // Select a bonus and purge it + .@vartp=relative_array_random(.@vartps); + .@popindex=getarrayindex(.@vartp); + deletearray(.@popindex, 1); + deletearray(.@popindex, 1); + + // Apply the bonus + setitemoptionbyindex(.@id, 0, .@vartp, .@bonus); + + // Re-roll: Easier for lower levels. Equip based. + if (rand2(1000) < 250-(.@lv*2)) { + .@vartp=relative_array_random(.@vartps); + .@popindex=getarrayindex(.@vartp); + deletearray(.@popindex, 1); + deletearray(.@popindex, 1); + setitemoptionbyindex(.@id, 1, .@vartp, .@bonus); + } + + // Final re-roll: Easier for lower levels. Equip based. Nearly impossible. + if (rand2(10000) < 250-(.@lv*2)) { + .@vartp=relative_array_random(.@vartps); + .@popindex=getarrayindex(.@vartp); + deletearray(.@popindex, 1); + deletearray(.@popindex, 1); + setitemoptionbyindex(.@id, 1, .@vartp, .@bonus); + } + + mesn; + mesc l("Well, here you are. I hope you enjoy ^^", 3); + close; + } + close; +} + OnTimer1000: domovestep; diff --git a/npc/functions/array.txt b/npc/functions/array.txt index ca2d7fbd6..1bc54610d 100644 --- a/npc/functions/array.txt +++ b/npc/functions/array.txt @@ -447,3 +447,51 @@ function script array_highest { return .@idx; } +// relative_array_random() +// returns a random entry from the array, by relative probability +// the first key of the array should be 0 and every entries are a tuple +// of [value, probability] + +function script relative_array_random { + .@is_str = getdatatype(getarg(0)) & DATATYPE_STR; + .@total_prob = getelementofarray(getarg(0), 0); + .@initial_index = getarrayindex(getarg(0)); + .@initial_index = .@initial_index ? .@initial_index : 1; + freeloop(true); + + if (.@total_prob < 1 || getarg(1, false)) + { + // first calculation, or forced re-calculation + .@total_prob = 0; + .@size = getarraysize(getarg(0)); + + for (.@i = .@initial_index + 1; .@i < .@size; .@i += 2) { + if (.@is_str) { + .@total_prob += max(1, atoi(getelementofarray(getarg(0), .@i))); + } else { + .@total_prob += max(1, getelementofarray(getarg(0), .@i)); + } + } + + // we cache on the first key + set(getelementofarray(getarg(0), 0), .@total_prob); + } + + .@target_sum = rand(0, .@total_prob); + + for (.@i = .@initial_index; .@sum < .@target_sum; .@i += 2) { + if (.@is_str) { + .@sum += atoi(getelementofarray(getarg(0), .@i + 1)); + } else { + .@sum += getelementofarray(getarg(0), .@i + 1); + } + + if (.@sum >= .@target_sum) { + break; + } + } + + freeloop(false); + return getelementofarray(getarg(0), .@i); +} + diff --git a/npc/functions/util.txt b/npc/functions/util.txt index d829c4524..b87bc89b1 100644 --- a/npc/functions/util.txt +++ b/npc/functions/util.txt @@ -934,3 +934,4 @@ function script NewcomerEXPDROPUP { return .@BONUS; } + -- cgit v1.2.3-60-g2f50