diff options
author | Fedja Beader <fedja@protonmail.ch> | 2024-08-31 00:52:33 +0200 |
---|---|---|
committer | Fedja Beader <fedja@protonmail.ch> | 2024-08-31 00:52:33 +0200 |
commit | 10afd8ee8116d98617ca78c7558498b31c683e0a (patch) | |
tree | 9a690e58ea48dcf50fe7cd56c316fa97d3f93fbd | |
parent | 50df9c89d23e93b13d21e63c9298d17001fcaaad (diff) | |
download | serverdata-10afd8ee8116d98617ca78c7558498b31c683e0a.tar.gz serverdata-10afd8ee8116d98617ca78c7558498b31c683e0a.tar.bz2 serverdata-10afd8ee8116d98617ca78c7558498b31c683e0a.tar.xz serverdata-10afd8ee8116d98617ca78c7558498b31c683e0a.zip |
Refactor transmigration to use a transaction array and add support
functions for handling this.
+ add Cancel option in main transmute menu (accidental keypress?)
+ might fix "repeat" option not working
-rw-r--r-- | npc/functions/util.txt | 78 | ||||
-rw-r--r-- | npc/magic/transmigration.txt | 321 |
2 files changed, 190 insertions, 209 deletions
diff --git a/npc/functions/util.txt b/npc/functions/util.txt index cbac0246e..e81035537 100644 --- a/npc/functions/util.txt +++ b/npc/functions/util.txt @@ -1015,6 +1015,84 @@ function script transcheck { return true; } +// transcheck( {item 1, amount 1}, {item 2, amount 2}... ) +// returns true upon success +function script transCheckArray { + if (!(getdatatype(getarg(0)) & DATATYPE_VAR)) + Exception("Inadequate argument type - Must be var", RB_DEFAULT|RB_ISFATAL); + + copyarray(.@array, getarg(0), getarraysize(getarg(0))); + + if (getarraysize(.@array) % 2 != 0) + Exception("Invalid array size: " + getarraysize(.@array$), + RB_DEFAULT|RB_ISFATAL); + + // First pass, check if player has items. + freeloop(true); + for (.@index = 0; .@index < getarraysize(.@array); .@index++) { + .@amount = .@array[.@index + 1]; + if (.@amount > 0) // gains + continue; + + .@itemId = .@array[.@index]; + if (countitem(.@itemId) < (-.@amount)) + return false; + } + + // Second pass, take the requirements away. + for (.@index = 0; .@index < getarraysize(.@array); .@index++) { + .@amount = .@array[.@index + 1]; + if (.@amount > 0) // gains + continue; + + .@itemId = .@array[.@index]; + delitem .@itemId, (-.@amount); + } + freeloop(false); + + // Third pass, give what the player is supposed to gain in return. + for (.@index = 0; .@index < getarraysize(.@array); .@index++) { + .@amount = .@array[.@index + 1]; + if (.@amount < 0) // requirements + continue; + + .@itemId = .@array[.@index]; + getitem .@itemId, .@amount; + } + freeloop(false); + + return true; +} + +// transDisplayReqArray(<array>) +// <array> is of the form item1, amount1, item2, amount2,... +// negative amounts are taken as requirements and displayed. +// Displays requirements in the form "* <have>/<need> <what>" +function script transDisplayReqArray { + if (!(getdatatype(getarg(0)) & DATATYPE_VAR)) + Exception("Inadequate argument type - Must be var", RB_DEFAULT|RB_ISFATAL); + + copyarray(.@array, getarg(0), getarraysize(getarg(0))); + + if (getarraysize(.@array) % 2 != 0) + Exception("Invalid array size: " + getarraysize(.@array$), + RB_DEFAULT|RB_ISFATAL); + + freeloop(true); + for (.@index = 0; .@index < getarraysize(.@array); .@index++) { + .@itemId = .@array[.@index]; + .@amount = .@array[.@index + 1]; + if (.@amount > 0) + continue; + + mesc l("* %2d/%d %s", countitem(.@itemId), + .@amount, + getitemlink(.@itemId)); + } + freeloop(false); +} + + // 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. // TODO: Fill an array, then inventoryplace() and getitem() diff --git a/npc/magic/transmigration.txt b/npc/magic/transmigration.txt index e9ed9d462..2beb845d8 100644 --- a/npc/magic/transmigration.txt +++ b/npc/magic/transmigration.txt @@ -7,6 +7,11 @@ // This is actually referred as transmutation in human-readable forms, and // transmigration in scripts. +// Variables: +// @transmemo: array of item1, amount1, ... +// first element must be the main result item +// (for display purposes). + - script sk#mkpot 32767,{ end; OnCall: @@ -27,7 +32,7 @@ OnCall: mesc l("What will you transmute today?"); mes ""; menuint - rif(@transmemo, l("Repeat ")+getitemname(@transmemo)), @transmemo, + rif(@transmemo, l("Repeat %s", getitemname(@transmemo[0])), 1, l("Crazy Rum"), CrazyRum, l("Coal"), 9901, // 9901 cheat code l("Mouboo Figurine"), MoubooFigurine, @@ -36,285 +41,185 @@ OnCall: rif(.@q >= 9, l("Downgrade Snake Tongue")), SnakeTongue, rif(.@q >= 7, l("Downgrade Scorpion Stinger")), ScorpionStinger, rif(.@q >= 7, l("Downgrade Scorpion Claw")), ScorpionClaw, - l("Downgrade Ore"), IronOre; - - mes ""; - @menuret = (@menuret == WoodenLog ? 9901 : @menuret); - .@itemid=(@menuret == 9901 ? Coal : @menuret); - mesc l("Transmutating @@ will require:", getitemlink(@menuret)); + l("Downgrade Ore"), IronOre, + l("Cancel"), 0; - // Requeriments listing + // Possible submenu. switch (@menuret) { - case CrazyRum: - mesc l("* @@/@@ @@", countitem(Plushroom), 18, getitemlink(Plushroom)); - mesc l("* @@/@@ @@", countitem(Milk), 5, getitemlink(Milk)); - break; - case 9901: // This is coal - mesc l("* @@/@@ @@", countitem(WoodenLog), 6, getitemlink(WoodenLog)); - break; - case MoubooFigurine: - mesc l("* @@/@@ @@", countitem(WoodenLog), 1, getitemlink(WoodenLog)); - break; - case MountainSnakeSkin: - case CaveSnakeSkin: case SnakeSkin: menuint - l("Black Mamba Skin -> Mountain Snake Skin"), MountainSnakeSkin, - l("Mountain Snake Skin -> Snake Skin"), SnakeSkin, - l("Snake Skin -> Cave Snake Skin"), CaveSnakeSkin, - l("Cancel"), 0; + l("Black Mamba Skin -> Mountain Snake Skin"), MountainSnakeSkin, + l("Mountain Snake Skin -> Snake Skin"), SnakeSkin, + l("Snake Skin -> Cave Snake Skin"), CaveSnakeSkin, + l("Cancel"), 0; break; - case MountainSnakeEgg: - case CaveSnakeEgg: case SnakeEgg: menuint - l("Black Mamba Egg -> Mountain Snake Egg"), MountainSnakeEgg, - l("Mountain Snake Egg -> Snake Egg"), SnakeEgg, - l("Snake Egg -> Cave Snake Egg"), CaveSnakeEgg, - l("Cancel"), 0; + l("Black Mamba Egg -> Mountain Snake Egg"), MountainSnakeEgg, + l("Mountain Snake Egg -> Snake Egg"), SnakeEgg, + l("Snake Egg -> Cave Snake Egg"), CaveSnakeEgg, + l("Cancel"), 0; break; - case MountainSnakeTongue: - case CaveSnakeTongue: case SnakeTongue: menuint - l("Black Mamba Tongue -> Mountain Snake Tongue"), MountainSnakeTongue, - l("Mountain Snake Tongue -> Snake Tongue"), SnakeTongue, - l("Snake Tongue -> Cave Snake Tongue"), CaveSnakeTongue, - l("5x Snake Tongues -> Tortuga Tongue"), TortugaTongue, - l("Cancel"), 0; + l("Black Mamba Tongue -> Mountain Snake Tongue"), MountainSnakeTongue, + l("Mountain Snake Tongue -> Snake Tongue"), SnakeTongue, + l("Snake Tongue -> Cave Snake Tongue"), CaveSnakeTongue, + l("5x Snake Tongues -> Tortuga Tongue"), TortugaTongue, + l("Cancel"), 0; break; - case RedScorpionStinger: case ScorpionStinger: menuint - l("Black Scorpion Stinger -> Red Scorpion Stinger"), RedScorpionStinger, - l("Red Scorpion Stinger -> Scorpion Stinger"), ScorpionStinger, - l("Cancel"), 0; + l("Black Scorpion Stinger -> Red Scorpion Stinger"), RedScorpionStinger, + l("Red Scorpion Stinger -> Scorpion Stinger"), ScorpionStinger, + l("Cancel"), 0; break; - case BlackScorpionClaw: - case RedScorpionClaw: case ScorpionClaw: menuint - l("Golden Scorpion Claw -> Black Scorpion Claw"), BlackScorpionClaw, - l("Black Scorpion Claw -> Red Scorpion Claw"), RedScorpionClaw, - l("Red Scorpion Claw -> Scorpion Claw"), ScorpionClaw, - l("Cancel"), 0; + l("Golden Scorpion Claw -> Black Scorpion Claw"), BlackScorpionClaw, + l("Black Scorpion Claw -> Red Scorpion Claw"), RedScorpionClaw, + l("Red Scorpion Claw -> Scorpion Claw"), ScorpionClaw, + l("Cancel"), 0; break; - case IridiumOre: - case TitaniumOre: - case LeadOre: - case TinOre: - case GoldOre: - case SilverOre: - case CopperOre: - case Coal: case IronOre: menuint - l("Platinum Ore -> Iridium Ore"), IridiumOre, - l("Iridium Ore -> Titanium Ore"), TitaniumOre, - l("Titanium Ore -> Lead Ore"), LeadOre, - l("Lead Ore -> Tin Ore"), TinOre, - l("Tin Ore -> Gold Ore"), GoldOre, - l("Gold Ore -> Silver Ore"), SilverOre, - l("Silver Ore -> Copper Ore"), CopperOre, - l("Copper Ore -> Iron Ore"), IronOre, - l("Iron Ore -> Coal"), Coal, - l("Cancel"), 0; + l("Platinum Ore -> Iridium Ore"), IridiumOre, + l("Iridium Ore -> Titanium Ore"), TitaniumOre, + l("Titanium Ore -> Lead Ore"), LeadOre, + l("Lead Ore -> Tin Ore"), TinOre, + l("Tin Ore -> Gold Ore"), GoldOre, + l("Gold Ore -> Silver Ore"), SilverOre, + l("Silver Ore -> Copper Ore"), CopperOre, + l("Copper Ore -> Iron Ore"), IronOre, + l("Iron Ore -> Coal"), Coal, + l("Cancel"), 0; break; default: - Exception("ERROR, INVALID TRANSMIGRATION OPTION", RB_DEFAULT|RB_SPEECH); @menuret=0; break; - } - // Confirmation - if (@menuret) { - next; - mesc l("Transmute?!"); - .@me=@menuret; - if (askyesno() == ASK_NO) - @menuret=0; - else - @menuret=.@me; + break; // @menuret is final. } - } while (!@menuret); - // Close the dialog - closeclientdialog; - // Check and Consume the reagents - switch (@menuret) { + // Set requirements. + switch (@menuret) { + case 1:// Skip display, just repeat. + break; case CrazyRum: - if (!transcheck(Plushroom, 18, Milk, 5)) { - dispbottom l("Not enough items!"); - end; - } - percentheal 0, -2; // Additionally takes 2% of your MP + setarray @transmemo, CrazyRum, 2, Plushroom, -18, Milk, -5; + break; + case 9901: // This is coal + setarray @transmemo, Coal, 2, WoodenLog, -6; break; case MoubooFigurine: - if (!transcheck(WoodenLog, 1)) { - dispbottom l("Not enough items!"); - end; - } - break; - case 9901: // Coal cheat code - if (!transcheck(WoodenLog, 6)) { - dispbottom l("Not enough items!"); - end; - } - .@me=WoodenLog; - @menuret=Coal; - break; - // Snake Skin Chain + setarray @transmemo, MoubooFigurine, 1, WoodenLog, -1; + break; + case MountainSnakeSkin: - if (!transcheck(BlackMambaSkin, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, MountainSnakeSkin, 2, BlackMambaSkin, -1; break; case SnakeSkin: - if (!transcheck(MountainSnakeSkin, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, SnakeSkin, 2, MountainSnakeSkin, -1; break; case CaveSnakeSkin: - if (!transcheck(SnakeSkin, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, CaveSnakeSkin, 2, SnakeSkin, -1; break; + // Snake Egg Chain case MountainSnakeEgg: - if (!transcheck(BlackMambaEgg, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, MountainSnakeEgg, 2, BlackMambaEgg, -1; break; case SnakeEgg: - if (!transcheck(MountainSnakeEgg, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, SnakeEgg, 2, MountainSnakeEgg, -1; break; case CaveSnakeEgg: - if (!transcheck(SnakeEgg, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, CaveSnakeEgg, 2, SnakeEgg, -1; break; + // Snake Tongue Chain case MountainSnakeTongue: - if (!transcheck(BlackMambaTongue, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, MountainSnakeTongue, 2, BlackMambaTongue, -1; break; case SnakeTongue: - if (!transcheck(MountainSnakeTongue, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, SnakeTongue, 2, MountainSnakeTongue, -1; break; case CaveSnakeTongue: - if (!transcheck(SnakeTongue, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, CaveSnakeTongue, 2, SnakeTongue, -1; break; case TortugaTongue: - if (!transcheck(SnakeTongue, 5)) { - dispbottom l("Not enough items!"); - end; - } - break; - // Scorpion Stinger Chain - case RedScorpionStinger: - if (!transcheck(BlackScorpionStinger, 1)) { - dispbottom l("Not enough items!"); - end; - } - break; - case ScorpionStinger: - if (!transcheck(RedScorpionStinger, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, TortugaTongue, 2, SnakeTongue, -5; break; + // Scorpion Claw Chain case BlackScorpionClaw: - if (!transcheck(GoldenScorpionClaw, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, BlackScorpionClaw, 2, GoldenScorpionClaw, -1; break; case RedScorpionClaw: - if (!transcheck(BlackScorpionClaw, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, RedScorpionClaw, 2, BlackScorpionClaw, -1; break; case ScorpionClaw: - if (!transcheck(RedScorpionClaw, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, ScorpionClaw, 2, RedScorpionClaw, -1; + break; + + // Scorpion Stinger Chain + case RedScorpionStinger: + setarray @transmemo, RedScorpionStinger, 2, BlackScorpionStinger, -1; break; + case ScorpionStinger: + setarray @transmemo, ScorpionStinger, 2, RedScorpionStinger, -1; + break; + // Ore Chain (the biggest one) case IridiumOre: - if (!transcheck(PlatinumOre, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, IridiumOre, 2, PlatinumOre, -1; break; case TitaniumOre: - if (!transcheck(IridiumOre, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, TitaniumOre, 2, IridiumOre, -1; break; case LeadOre: - if (!transcheck(TitaniumOre, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, LeadOre, 2, TitaniumOre, -1; break; case TinOre: - if (!transcheck(LeadOre, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, TinOre, 2, LeadOre, -1; break; case GoldOre: - if (!transcheck(TinOre, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, GoldOre, 2, TinOre, -1; break; case SilverOre: - if (!transcheck(GoldOre, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, SilverOre, 2, GoldOre, -1; break; case CopperOre: - if (!transcheck(SilverOre, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, CopperOre, 2, SilverOre, -1; break; case IronOre: - if (!transcheck(CopperOre, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, IronOre, 2, CopperOre, -1; break; case Coal: - if (!transcheck(IronOre, 1)) { - dispbottom l("Not enough items!"); - end; - } + setarray @transmemo, Coal, 2, IronOre, -1; break; - default: - Exception("ERROR, INVALID TRANSMIGRATION REAGENTS", RB_DEFAULT|RB_SPEECH|RB_ISFATAL); break; - } + Exception("ERROR, INVALID TRANSMIGRATION OPTION", RB_DEFAULT|RB_SPEECH); @menuret=0; break; + } + + transDisplayReqArray(@transmemo); + + // Confirmation + if (@menuret) { + next; + mesc l("Transmute?!"); + .@me=@menuret; + if (askyesno() == ASK_NO) + @menuret=0; + else + @menuret=.@me; + } + } while (!@menuret); + + // Close the dialog + closeclientdialog; + + // Check and Consume the reagents + // Failing to make crazy rum had this side effect: + // percentheal 0, -2; // Additionally takes 2% of your MP + // Do the roll from 1 to 100 // Base success chance is 0% @@ -334,14 +239,12 @@ OnCall: dispbottom l("Your spell takes a mind of its own and shapes in something else!"); getitem any(WarpedLog, .@me), 1; // You were successful - } else { + } else if (transCheckArray(@transmemo)) dispbottom l("*plim*"); - getitem @menuret, (@menuitem == MoubooFigurine ? 1 : 2); + } else { + dispbottom l("Not enough items"); } - // Store to memory - @transmemo=.@me; - // set cooldown @mkpot_at=gettimetick(2); @mkpot_at=@mkpot_at+6; |