From ee1eb5bd900192e735162132dd2b0b085427efd1 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Sun, 18 Aug 2019 00:36:33 -0300 Subject: Basic version of Erik the Homunculus Dispatcher --- npc/017-10/dispatcher.txt | 272 ++++++++++++++++++++++++++++++++++++++++++++-- npc/functions/util.txt | 15 +++ 2 files changed, 279 insertions(+), 8 deletions(-) (limited to 'npc') diff --git a/npc/017-10/dispatcher.txt b/npc/017-10/dispatcher.txt index 3e4625b76..a5a7e16e9 100644 --- a/npc/017-10/dispatcher.txt +++ b/npc/017-10/dispatcher.txt @@ -3,16 +3,22 @@ // Jesusalva // Description: // Deploys an Homunculus in a mission during your offline time +// Variables +// HOMUN_DEPLOYDATE +// When the Homunculus is scheduled to arrive +// HOMUN_DEPLOYFIELD +// ID of the field which Homunculus was deployed -017-10,61,34,0 script Dispatcher NPC_JOURNALMAN,{ +017-10,61,34,0 script Erik NPC_JOURNALMAN,{ + function lootField; mesn; - mesq l("Hello."); - if (!is_admin()) - close; + mesq l("Hello. My name is Erik, and I have Homunculus go out in errands in my stead."); if (!gethominfo(0)) { mesc l("You do not own an Homunculus."), 1; + close; } + switch (homstatus()) { case 0: mesc l("Your homunculus is ready!"), 2; @@ -23,34 +29,284 @@ break; case 2: mesc l("Your homunculus is already on a mission!"), 1; + mesc l("It should be back in @@", FuzzyTime(HOMUN_DEPLOYDATE)), 1; + close; break; default: - mesc l("ERROR! code "+homstatus()), 1; + Exception("ERROR! homstatus code "+homstatus(), RB_DEFAULT|RB_SPEECH|RB_ISFATAL); break; } + + if (gettimetick(2) < HOMUN_DEPLOYDATE) { + Exception("ERROR: YOU WERE BANNED FROM USING ERIK SERVICES. (might be a bug).", RB_SPEECH|RB_ISFATAL); + close; + } + + if (!is_admin()) + close; + + // Homunculus should return from mission if (homstatus()) { select l("Recall"); recallhomunculus(); - gethomunexp(50000); + gethomunexp(lootField(HOMUN_DEPLOYFIELD)); close; } +L_Main: select l("Deploy to Piou Fields [1h]"), - rif(gethominfo(6) >= 10, l("Deploy to Mines [1h]")), + l("Deploy to Herb Fields [1h]"), + rif(gethominfo(6) >= 10, l("Deploy to Ore Mines [2h]")), + rif(gethominfo(6) >= 10, l("Deploy to Rare Mines [2h]")), + rif(gethominfo(6) >= 15, l("Deploy to Slime Nest [2h]")), + rif(gethominfo(6) >= 30, l("Deploy to Snake Pit [3h]")), l("Don't deploy"); mes ""; - // Ignored + // Common drops: At least 90% drop + // Rare drops: 5% or less drop rate + switch (@menu) { + case 1: + mesc ".:: " + l("Piou Fields") + " ::."; + mesc l("The most basic grinding camp for your homunculus."); + mesc l("Average EXP: 100"), 3; + mesc l("Common Drops: "+ + getitemlink(PiouFeathers)); + mesc l("Regular Drops: "+ + getitemlink(PiouLegs)+ + getitemlink(HalfEggshell)); + mesc l("Rare Drops: "+ + getitemlink(GoldenApple)); + next; + .@dest=.PIOUFIELDS; + .@hours=1; + break; + case 2: + mesc ".:: " + l("Herb Fields") + " ::."; + mesc l("If you need more herbs, the best place to look."); + mesc l("Average EXP: 5"), 3; + mesc l("Common Drops: "+ + getitemlink(ArtichokeHerb)); + mesc l("Regular Drops: "+ + getitemlink(CobaltHerb)+ + getitemlink(GambogeHerb)+ + getitemlink(MauveHerb)+ + getitemlink(AlizarinHerb)); + mesc l("Rare Drops: "+ + getitemlink(ReedBundle)); + next; + .@dest=.HERBFIELDS; + .@hours=1; + break; + case 3: + mesc ".:: " + l("Ore Mines") + " ::."; + mesc l("Send your Homunculus to mineration!"); + mesc l("Average EXP: 12"), 3; + mesc l("Common Drops: "+ + getitemlink(Coal)); + mesc l("Regular Drops: "+ + getitemlink(IronOre)+ + getitemlink(CopperOre)+ + getitemlink(SilverOre)+ + getitemlink(GoldOre)); + mesc l("Rare Drops: "+ + getitemlink(TinOre)+ + getitemlink(LeadOre)+ + getitemlink(TitaniumOre)+ + getitemlink(IridiumOre)+ + getitemlink(PlatinumOre)); + next; + .@dest=.OREMINES; + .@hours=2; + break; + case 4: + mesc ".:: " + l("Rare Mines") + " ::."; + mesc l("Send your Homunculus to mineration!"); + mesc l("Average EXP: 15"), 3; + mesc l("Common Drops: "+ + getitemlink(Pearl)); + mesc l("Regular Drops: "+ + getitemlink(Diamond)+ + getitemlink(Ruby)+ + getitemlink(Emerald)+ + getitemlink(Sapphire)+ + getitemlink(Topaz)+ + getitemlink(Amethyst)); + mesc l("Rare Drops: "+ + getitemlink(LightGreenDiamond)+ + getitemlink(BlackPearl)+ + getitemlink(BlueManaPearl)); + next; + .@dest=.RAREMINES; + .@hours=2; + break; + case 5: + mesc ".:: " + l("Slime Nest") + " ::."; + mesc l("Send your Homunculus to a slime nest!"); + mesc l("Average EXP: 500"), 3; + mesc l("Common Drops: "+ + getitemlink(MaggotSlime)+ + getitemlink(Arrow)); + mesc l("Regular Drops: "+ + getitemlink(IronArrow)+ + getitemlink(TreasureKey)+ + getitemlink(CactusDrink)+ + getitemlink(CoinBag)+ + getitemlink(CasinoCoins)+ + getitemlink(Coal)+ + getitemlink(Dagger)+ + getitemlink(Candy)+ + getitemlink(ChocolateBar)); + mesc l("Rare Drops: "+ + getitemlink(Milk)+ + getitemlink(IcedBottle)); + next; + .@dest=.SLIMENEST; + .@hours=3; + break; + case 6: + mesc ".:: " + l("Snake Pit") + " ::."; + mesc l("Send your Homunculus to hold off snakes!"); + mesc l("Average EXP: 1000"), 3; + mesc l("Common Drops: "+ + getitemlink(SnakeEgg)+ + getitemlink(SnakeTongue)); + mesc l("Regular Drops: "+ + getitemlink(SnakeSkin)); + mesc l("Rare Drops: "+ + getitemlink(JeansShorts)+ + getitemlink(DivineApple)+ + getitemlink(Kanabo)); + next; + .@dest=.SNAKEPIT; + .@hours=3; + break; + default: + close; + } + + // Confirmation + mesc l("Really deploy your homunculus?"), 1; + if (askyesno() == ASK_NO) + goto L_Main; + + // Deploy Homunculus (if possible) if (!homstatus() && gethominfo(0)) { deployhomunculus(); mesc l("Deployed!"), 2; + HOMUN_DEPLOYFIELD=.@dest; + HOMUN_DEPLOYDATE=gettimetick(2)+(60*.@hours); } close; +// lootField (Field ID) +// Returns amount of Homunculus EXP to get +function lootField { + // Ensure you have free space + inventoryplace Iten, 3, NPCEyes, 10; + .@lv=gethominfo(6); + + // Base EXP is based on Homunculus level and intimacy + .@val=.@lv*min(10000, gethominfo(3))/10000; + + switch (getarg(0)) { + case .PIOUFIELDS: + .@val+=100; + anyloot(PiouFeathers, .@lv, 10000, + PiouLegs, max(1, .@lv/2), 8000, + HalfEggshell, .@lv, 6000, + GoldenApple, 1, 100); + break; + case .HERBFIELDS: + .@val+=5; + anyloot(ArtichokeHerb, .@lv, 10000, + CobaltHerb, max(1, .@lv/2), 6000, + GambogeHerb, max(1, .@lv/2), 6000, + MauveHerb, max(1, .@lv/2), 6000, + AlizarinHerb, max(1, .@lv/2), 6000, + ShadowHerb, max(1, .@lv/3), 4000, + ReedBundle, 2, 800); + break; + case .OREMINES: + .@val+=12; + anyloot(Coal, .@lv, 9999, + IronOre, max(1, .@lv/2), 2000, + CopperOre, max(1, .@lv/2), 1000, + SilverOre, max(1, .@lv/3), 700, + GoldOre, max(1, .@lv/4), 450, + TinOre, max(1, .@lv/5), 350, + LeadOre, max(1, .@lv/6), 300, + TitaniumOre, max(1, .@lv/8), 100, + IridiumOre, max(1, .@lv/10), 80, + PlatinumOre, 1, 20); + break; + case .RAREMINES: + .@val+=15; + anyloot(Pearl, 1, 9999, + Diamond, limit(1, .@lv/2, 3), 2000, + Ruby, limit(1, .@lv/2, 3), 1700, + Emerald, limit(1, .@lv/2, 3), 1400, + Sapphire, limit(1, .@lv/2, 3), 1100, + Topaz, limit(1, .@lv/2, 3), 800, + Amethyst, limit(1, .@lv/2, 3), 500, + LightGreenDiamond, 1, 100, + BlackPearl, 1, 10, + BlueManaPearl, 1, 1); + break; + case .SLIMENEST: + .@val+=500; + anyloot(MaggotSlime, .@lv, 10000, + Arrow, .@lv, 9000, + IronArrow, .@lv, 4000, + TreasureKey, max(1, .@lv/10), 6000, + CactusDrink, limit(1, .@lv/10, 3), 4000, + CoinBag, limit(1, .@lv/8, 5), 4000, + CasinoCoins, limit(1, .@lv/6, 10), 3200, + Coal, limit(1, .@lv/10, 3), 3000, + Dagger, limit(1, .@lv/15, 3), 3000, + Candy, limit(1, .@lv/5, 6), 2000, + ChocolateBar, limit(1, .@lv/20, 3), 1000, + Milk, 1, 200, + IcedBottle, 1, 60); + break; + case .SNAKEPIT: + .@val+=1000; + anyloot(SnakeEgg, limit(1, .@lv/8, 10), 9600, + SnakeTongue, limit(1, .@lv/16, 5), 9500, + SnakeSkin, limit(1, .@lv/20, 3), 7000, + JeansShorts, 1, 300, + DivineApple, 1, 10, + Kanabo, 1, 1); // Teasing Xanthem for mapping here + break; + case .ADVENTURE: + .@val+=100; + anyloot(PiouFeathers, .@lv, 10000, + PiouLegs, max(1, .@lv/2), 8000, + HalfEggshell, .@lv, 6000, + GoldenApple, 1, 100); + break; + } + // A final boost for sake of randomness + .@val+=rand2(0, 3); + return .@val; +} + OnInit: .sex=G_MALE; .distance=5; + + // Custom constants + .PIOUFIELDS=1; + .HERBFIELDS=2; + .OREMINES= 3; + .RAREMINES= 4; + .SLIMENEST= 5; + .SNAKEPIT= 6; + .ADVENTURE= 7; + + // Special field + .MARKET= 10; end; } diff --git a/npc/functions/util.txt b/npc/functions/util.txt index 7a47a8cae..21abcd1f2 100644 --- a/npc/functions/util.txt +++ b/npc/functions/util.txt @@ -736,6 +736,21 @@ function script abizit { return min(MAGIC_EXP/.@base, 5); } +// anyloot( {item 1, amount 1, chance 1}, {item 2, amount 2, chance 2}... ) +// Give chance (standard 1~10000 roll) to obtain item, capped at amount. +function script anyloot { + if (getargcount() < 3 || getargcount() % 3 != 0) + return Exception("Faulty anyloot skill command invoked - error"); + + // Get Items + for (.@i=0;.@i < getargcount(); .@i++) { + if (rand2(10000) < getarg(.@i+2)) + getitem getarg(.@i), rand2(1, getarg(.@i+1)); + .@i++; + } + return true; +} + // Returns, based on a 1-5 range, the title for both thief and merc ranks // thiefrank() / mercrank() -- cgit v1.2.3-60-g2f50