// TMW-2 script.
// Author:
// Jesusalva
// Description:
// Recipe Books in TMW2
- script #RecipeBook NPC_HIDDEN,{
function showRecipe;
function readCooking;
function readAlchemy;
function readCrafting;
OnUse:
setnpcdialogtitle l("Recipe Book");
mesc l("You open the Recipe Book. Each recipe you get can be put here.");
next;
do {
mesc l("Which recipes do you want to read?");
select
l("Nothing."),
l("Cooking Recipes."),
l("Alchemy Recipes."),
l("Crafting Recipes.");
mes "";
switch (@menu) {
case 2:
readCooking(); break;
case 3:
readAlchemy(); break;
case 4:
readCrafting(); break;
}
} while (@menu != 1);
closeclientdialog;
close;
// Expects: @scope$
// showRecipe( recipe{, recipe...} )
function showRecipe {
if (@scope$ == "")
return Exception("Faulty recipe skill command invoked - error");
freeloop(true);
for (.@a = 0; .@a < getargcount(); ++.@a) {
.@const$ = data_to_string(getarg(.@a));
if (startswith(.@const$, "Craft")) {
// infer the item constant from the craft constant
.@recipe = getarg(.@a);
.@item = string_to_data(substr(.@const$, 5, getstrlen(.@const$) - 1));
} else {
// infer the craft constant from the item constant
.@recipe = string_to_data(sprintf("Craft%s", .@const$));
.@item = getarg(.@a);
}
if (.@item <= 0) {
// target item not found
consolebug("ERROR, INVALID ITEM ID DETECTED at showRecipe");
continue;
}
if (!getd("RECIPES_"+@scope$+"["+.@recipe+"]") && !$@GM_OVERRIDE) {
// does not have the recipe
continue;
}
for (.@inv = 0; .@inv < 9; ++.@inv) {
.@size = getcraftrecipe(.@recipe, .@inv, .@qty[0], .@item_id[0]);
if (.@size < 0) {
if (.@size == -1) {
// recipe does not exist
break;
}
// inventory does not exist
break;
}
mes(l(".:: %s Recipe ::.", getitemlink(.@item)));
for (.@it = 0; .@it < .@size; ++.@it) {
.@recipe_item = .@item_id[.@it];
.@recipe_qty = .@qty[.@it];
if (.@recipe_item <= 0) {
break;
}
mesc(sprintf("%d/%d %s", countitem(.@recipe_item), .@recipe_qty, getitemlink(.@recipe_item)));
}
mes("");
.@count++;
}
}
freeloop(false);
return .@count > 0;
}
// =============================== Cooking Functions
function readCooking {
setnpcdialogtitle l("Cooking Recipes");
@scope$="COOKING";
mesc l("Eating is a necessity, but cooking is an art.");
mesc l("(All items must be placed exactly in this order.)");
next;
mesc l("List of known cooking recipes:");
mes "";
//showRecipe(0, Iten, WarpedLog, 9999);
next;
@scope$="";
return;
}
// =============================== Cooking Functions
function readAlchemy {
setnpcdialogtitle l("Alchemy Recipes");
@scope$="ALCHEMY";
mesc l("Alchemy. The art of having quasi-magical effects without magic.");
mesc l("(All items must be placed exactly in this order.)");
next;
mesc l("List of known alchemy recipes:");
mes "";
// Healing
mesc "----------"+l("Healing Recipes")+"----------", 2;
showRecipe(PiberriesInfusion,
AtroposMixture,
Coffee);
dnext;
// General Boosts
mesc "----------"+l("General Boosts")+"----------", 2;
showRecipe(HastePotion,
StrengthPotion,
StatusResetPotion, // BROKEN
HomunResetPotion,
MoveSpeedPotion, // BROKEN
PrecisionPotion,
DodgePotion,
SacredLifePotion,
SacredManaPotion,
SacredImmortalityPotion,
MagicApple);
dnext;
// Stats Boosts
mesc "----------"+l("Stat Boost Recipes")+"----------", 2;
showRecipe(LukPotionA,
LukPotionB,
LukPotionC);
showRecipe(IntPotionA,
IntPotionB,
IntPotionC);
showRecipe(VitPotionA,
VitPotionB,
VitPotionC);
showRecipe(AgiPotionA,
AgiPotionB,
AgiPotionC);
showRecipe(DexPotionA,
DexPotionB,
DexPotionC);
// Scrolls
mesc "----------"+l("Magic Scrolls")+"----------", 2;
showRecipe(ScrollSCave,
ScrollSMaggot,
ScrollSWolvern,
ScrollSYeti,
ScrollSTerranite,
ScrollSDragon,
ScrollMagnusHealA,
ScrollAngelLightA,
ScrollBattlePlansA,
ScrollDefenseBlessA,
ScrollCriticalFortuneA);
// General Stuff
mesc "----------"+l("Reagents & Other Potions")+"----------", 2;
showRecipe(IcedBottle,
PurificationPotion,
DeathPotion,
BrokenWarpCrystal,
SmokeGrenade,
ScentGrenade,
Grenade,
Insurance,
InsuranceContract);
next;
@scope$="";
return;
}
// =============================== Crafting Functions
function readCrafting {
setnpcdialogtitle l("Crafting Recipes");
@scope$="EQUIPMENT";
mesc l("There is only one way towards the best equipment: Smith away!");
mesc l("(All items must be placed exactly in this order.)");
next;
mesc l("List of known crafting recipes:");
mes "";
// Melee Weapons: Never use Titanium nor Lead. Iron-based, no silver
mesc "----------"+l("One Hand Weapon Recipes")+"----------", 2;
showRecipe(Dagger,
WoodenSword,
BugSlayer,
ShortGladius,
Backsword,
ShortSword,
Kitana,
BoneKnife,
LongSword,
RockKnife,
DivineSword);
dnext;
// Two Hands Melee Weapons: Never use Titanium nor Lead. Silver-based.
mesc "----------"+l("Two Hands Weapon Recipes")+"----------", 2;
// Reserved ID 63 and 64
// Halberd is really cheap as it doesn't uses Platinum/Iridium :P
showRecipe(MiereCleaver,
Broadsword,
Halberd,
ImmortalSword);
dnext;
// Archery Weapons: Always use Wood, Root and Carp.
mesc "----------"+l("Archery Weapon Recipes")+"----------", 2;
showRecipe(ShortBow,
ForestBow,
ElficBow,
ChampionshipBow,
BansheeBow);
dnext;
// Magical Weapons: Wood + powders
mesc "----------"+l("Magical Weapon Recipes")+"----------", 2;
showRecipe(TrainingWand,
NoviceWand,
ApprenticeWand,
LeaderWand,
MysticWand);
dnext;
// Firestaff Weapons: Lead + Titanium
mesc "----------"+l("Fire Staffs Recipes")+"----------", 2;
showRecipe(PynRevolver,
PynRifle,
PynGatling,
PynShotgun);
dnext;
// Shields: May use Leather. Titanium or Lead, but never both
mesc "----------"+l("Shield Recipes")+"----------", 2;
// Exception to shield rule: Braknar Shield
showRecipe(WoodenShield,
BladeShield,
BraknarShield,
BritShield,
BromenalShield,
BlueKnightShield,
SteelShield,
DragonShield,
SaviorShield);
dnext;
// Chest Armors -> Primary Ore + Secondary Ore + Iron Powder + Earth Powder
mesc "----------"+l("Chest Armor Recipes")+"----------", 2;
showRecipe(LeatherShirt,
LieutenantArmor,
Chainmail,
CopperArmor,
LightPlatemail,
GoldenLightPlatemail,
WarlordPlate,
GoldenWarlordPlate,
BromenalChest,
AssassinChest);
dnext;
// Pants -> Primary Item + Secondary Item + Leather Patch + Earth Powder
mesc "----------"+l("Pants Recipes")+"----------", 2;
showRecipe(JeansShorts,
RaidTrousers,
LeatherTrousers,
JeansChaps,
SilkPants,
ChainmailSkirt,
BromenalPants,
WarlordPants,
AssassinPants);
dnext;
// Gloves: Gloves items
mesc "----------"+l("Gloves Recipes")+"----------", 2;
showRecipe(SilkGloves,
LeatherGloves,
BromenalGloves,
ManaGloves,
WarlordGloves,
AssassinGloves);
dnext;
// Helmets: Helmet items
mesc "----------"+l("Helmet Recipes")+"----------", 2;
showRecipe(InfantryHelmet,
DesertHelmet,
BromenalHelmet,
CandleHelmet,
CrusadeHelmet,
WarlordHelmet,
VikingHelmet,
TerraniteHelmet,
CenturionHelmet,
BullHelmet,
DarkHelm,
DarkKnightHelmet,
SamuraiHelmet);
dnext;
// Misc: Misc items
mesc "----------"+l("Miscellaneous Recipes")+"----------", 2;
showRecipe(GoldenRing,
TerranitePants,
TerraniteArmor,
Skypiercer);
next;
@scope$="";
return;
}
OnInit:
.sex = G_OTHER;
.distance = 1;
end;
}
// Below this line are utils for Gacha. We use callfunc() on itemDB.
// Types: CRAFT_COOKING, CRAFT_ALCHEMY, CRAFT_EQUIPMENT
// Rarity: 1 - basic, 2 - intermediary, 4 - advanced, 8 - expert, 16 - master
// Level equivalents: 1: (1~20) 2: (21~44), 3: (45~75), 4: (76~99), 5: 100+
function script MakeBlueprint {
.@type=getarg(0, -1);
.@rarity=getarg(1, 1);
switch (.@type) {
/////////////////////////////////////////////////////
///// Alchemy Recipes
/////////////////////////////////////////////////////
case CRAFT_ALCHEMY:
if (.@rarity & CRAFT_BASIC) {
array_push(.@recipes, CraftPiberriesInfusion);
array_push(.@recipes, CraftHastePotion);
array_push(.@recipes, CraftStrengthPotion);
array_push(.@recipes, CraftCoffee);
array_push(.@recipes, CraftScrollSCave);
array_push(.@recipes, CraftScrollSMaggot);
}
if (.@rarity & CRAFT_INTERMEDIARY) {
array_push(.@recipes, CraftLukPotionA);
array_push(.@recipes, CraftDexPotionA);
array_push(.@recipes, CraftIntPotionA);
array_push(.@recipes, CraftAgiPotionA);
array_push(.@recipes, CraftVitPotionA);
array_push(.@recipes, CraftSpeedPotion);
array_push(.@recipes, CraftIcedBottle);
array_push(.@recipes, CraftInsuranceContract);
array_push(.@recipes, CraftScrollSWolvern);
}
if (.@rarity & CRAFT_ADVANCED) {
array_push(.@recipes, CraftResetPotion);
array_push(.@recipes, CraftPrecisionPotion);
array_push(.@recipes, CraftDodgePotion);
array_push(.@recipes, CraftDeathPotion);
array_push(.@recipes, CraftSmokeGrenade);
array_push(.@recipes, CraftScentGrenade);
array_push(.@recipes, CraftGrenade);
array_push(.@recipes, CraftInsurance);
array_push(.@recipes, CraftScrollSYeti);
}
if (.@rarity & CRAFT_EXPERT) {
array_push(.@recipes, CraftLukPotionB);
array_push(.@recipes, CraftDexPotionB);
array_push(.@recipes, CraftIntPotionB);
array_push(.@recipes, CraftAgiPotionB);
array_push(.@recipes, CraftVitPotionB);
array_push(.@recipes, CraftAtroposMixture);
array_push(.@recipes, CraftPurificationPotion);
array_push(.@recipes, CraftHomunResetPotion);
array_push(.@recipes, CraftScrollSTerranite);
array_push(.@recipes, CraftScrollMagnusHealA);
}
if (.@rarity & CRAFT_MASTER) {
array_push(.@recipes, CraftLukPotionC);
array_push(.@recipes, CraftDexPotionC);
array_push(.@recipes, CraftIntPotionC);
array_push(.@recipes, CraftAgiPotionC);
array_push(.@recipes, CraftVitPotionC);
array_push(.@recipes, CraftSacredLifePotion);
array_push(.@recipes, CraftSacredManaPotion);
array_push(.@recipes, CraftSacredImmortalityPotion);
array_push(.@recipes, CraftBrokenWarpCrystal);
array_push(.@recipes, CraftMagicApple);
array_push(.@recipes, CraftScrollSDragon);
if (getcharid(2) > 0) {
if (getguildlvl(getcharid(2)) >= 4)
array_push(.@recipes, CraftScrollAngelLightA);
if (getguildlvl(getcharid(2)) >= 5)
array_push(.@recipes, CraftScrollBattlePlansA);
if (getguildlvl(getcharid(2)) >= 3)
array_push(.@recipes, CraftScrollDefenseBlessA);
if (getguildlvl(getcharid(2)) >= 6)
array_push(.@recipes, CraftScrollCriticalFortuneA);
}
}
// Now you'll learn some recipe!
.@rcp=any_of(.@recipes);
// Half precision failsafe
if (RECIPES_EQUIPMENT[.@rcp] && any(true, false))
.@rcp=any_of(.@recipes);
// Maybe you already knew it?
if (RECIPES_ALCHEMY[.@rcp]) {
.@mpot=rand2(900, 1000*.@rarity);
dispbottom l("It was a recipe you already knew... (+ @@ Mobpt)", .@mpot);
getexp (BaseLevel+JobLevel)*rand2(1,.@rarity), JobLevel+rand2(1,.@rarity);
// Give you some Monster Points to use with Intense Beard
// You do NOT need to be registered with Aidan for this.
Mobpt+=.@mpot;
} else {
dispbottom l("Learned a new recipe!");
RECIPES_ALCHEMY[.@rcp]=true;
}
break;
/////////////////////////////////////////////////////
///// Equipment Recipes
/////////////////////////////////////////////////////
// array_push(.@recipes, Craft);
case CRAFT_EQUIPMENT:
if (.@rarity & CRAFT_BASIC) {
array_push(.@recipes, CraftWoodenSword);
array_push(.@recipes, CraftWoodenShield);
array_push(.@recipes, CraftTrainingWand);
array_push(.@recipes, CraftShortBow);
array_push(.@recipes, CraftSilkGloves);
array_push(.@recipes, CraftInfantryHelmet);
array_push(.@recipes, CraftLeatherShirt);
array_push(.@recipes, CraftJeansShorts);
}
if (.@rarity & CRAFT_INTERMEDIARY) {
array_push(.@recipes, CraftBugSlayer);
array_push(.@recipes, CraftShortGladius);
array_push(.@recipes, CraftMiereCleaver);
array_push(.@recipes, CraftBladeShield);
array_push(.@recipes, CraftNoviceWand);
array_push(.@recipes, CraftForestBow);
array_push(.@recipes, CraftLeatherGloves);
array_push(.@recipes, CraftDesertHelmet);
array_push(.@recipes, CraftBromenalHelmet);
array_push(.@recipes, CraftLieutenantArmor);
array_push(.@recipes, CraftRaidTrousers);
}
if (.@rarity & CRAFT_ADVANCED) {
array_push(.@recipes, CraftBacksword);
array_push(.@recipes, CraftShortSword);
array_push(.@recipes, CraftBoneKnife);
array_push(.@recipes, CraftKitana);
array_push(.@recipes, CraftBroadsword);
array_push(.@recipes, CraftPynRevolver);
array_push(.@recipes, CraftApprenticeWand);
array_push(.@recipes, CraftElficBow);
array_push(.@recipes, CraftBritShield);
array_push(.@recipes, CraftBromenalShield);
array_push(.@recipes, CraftBlueKnightShield);
array_push(.@recipes, CraftBromenalGloves);
array_push(.@recipes, CraftCandleHelmet);
array_push(.@recipes, CraftCrusadeHelmet);
array_push(.@recipes, CraftWarlordHelmet);
array_push(.@recipes, CraftVikingHelmet);
array_push(.@recipes, CraftChainmail);
array_push(.@recipes, CraftCopperArmor);
array_push(.@recipes, CraftLightPlatemail);
array_push(.@recipes, CraftWarlordPlate);
array_push(.@recipes, CraftBromenalChest);
array_push(.@recipes, CraftLeatherTrousers);
array_push(.@recipes, CraftJeansChaps);
array_push(.@recipes, CraftSilkPants);
array_push(.@recipes, CraftChainmailSkirt);
array_push(.@recipes, CraftBromenalPants);
array_push(.@recipes, CraftWarlordPants);
}
if (.@rarity & CRAFT_EXPERT) {
array_push(.@recipes, CraftGoldenRing);
array_push(.@recipes, CraftLongSword);
array_push(.@recipes, CraftRockKnife);
array_push(.@recipes, CraftHalberd);
array_push(.@recipes, CraftPynRifle);
array_push(.@recipes, CraftPynGatling);
array_push(.@recipes, CraftLeaderWand);
array_push(.@recipes, CraftChampionshipBow);
array_push(.@recipes, CraftSteelShield);
array_push(.@recipes, CraftDragonShield);
array_push(.@recipes, CraftManaGloves);
array_push(.@recipes, CraftWarlordGloves);
array_push(.@recipes, CraftTerraniteHelmet);
array_push(.@recipes, CraftCenturionHelmet);
array_push(.@recipes, CraftBullHelmet);
array_push(.@recipes, CraftDarkHelm);
array_push(.@recipes, CraftTerraniteArmor);
array_push(.@recipes, CraftTerranitePants);
array_push(.@recipes, CraftAssassinChest);
array_push(.@recipes, CraftAssassinPants);
}
if (.@rarity & CRAFT_MASTER) {
array_push(.@recipes, CraftDivineSword);
array_push(.@recipes, CraftImmortalSword);
array_push(.@recipes, CraftPynShotgun);
array_push(.@recipes, CraftMysticWand);
array_push(.@recipes, CraftBansheeBow);
array_push(.@recipes, CraftAssassinGloves);
array_push(.@recipes, CraftDarkKnightHelmet);
array_push(.@recipes, CraftSamuraiHelmet);
}
// Now you'll learn some recipe!
.@rcp=any_of(.@recipes);
// Double precision failsafe
if (RECIPES_EQUIPMENT[.@rcp])
.@rcp=any_of(.@recipes);
// Maybe you already knew it?
if (RECIPES_EQUIPMENT[.@rcp]) {
.@mpot=rand2(900*.@rarity, 1000*.@rarity);
dispbottom l("It was a recipe you already knew... (+ @@ Mobpt)", .@mpot);
getexp (BaseLevel+JobLevel)*rand2(1,.@rarity), JobLevel+rand2(1,.@rarity);
// Give you some Monster Points to use with Intense Beard
// You do NOT need to be registered with Aidan for this.
Mobpt+=.@mpot;
} else {
dispbottom l("Learned a new recipe!");
RECIPES_EQUIPMENT[.@rcp]=true;
}
break;
default:
return Exception("Invalid blueprint type "+.@type+" - item was lost.");
}
return;
}
// Create a blueprint based on level. Extra chance for weaker Blueprint.
// Level equivalents: 1: (1~20) 2: (21~44), 3: (45~75), 4: (76~99), 5: 100+
function script MakeRandomBlueprint {
array_push(.@blueprints, AlchemyBlueprintA);
array_push(.@blueprints, EquipmentBlueprintA);
if (BaseLevel > 20) {
array_push(.@blueprints, AlchemyBlueprintB);
array_push(.@blueprints, EquipmentBlueprintB);
}
if (BaseLevel > 44) {
array_push(.@blueprints, AlchemyBlueprintB);
array_push(.@blueprints, EquipmentBlueprintB);
array_push(.@blueprints, AlchemyBlueprintC);
array_push(.@blueprints, EquipmentBlueprintC);
}
if (BaseLevel > 75) {
array_push(.@blueprints, AlchemyBlueprintC);
array_push(.@blueprints, EquipmentBlueprintC);
array_push(.@blueprints, AlchemyBlueprintD);
array_push(.@blueprints, EquipmentBlueprintD);
}
if (BaseLevel > 100) {
array_push(.@blueprints, AlchemyBlueprintD);
array_push(.@blueprints, EquipmentBlueprintD);
if (any(true,false)) {
array_push(.@blueprints, AlchemyBlueprintE);
array_push(.@blueprints, EquipmentBlueprintE);
}
}
getitem any_of(.@blueprints), 1;
return;
}