summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFedja Beader <fedja@protonmail.ch>2024-08-31 00:52:33 +0200
committerFedja Beader <fedja@protonmail.ch>2024-08-31 00:52:33 +0200
commit10afd8ee8116d98617ca78c7558498b31c683e0a (patch)
tree9a690e58ea48dcf50fe7cd56c316fa97d3f93fbd
parent50df9c89d23e93b13d21e63c9298d17001fcaaad (diff)
downloadserverdata-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.txt78
-rw-r--r--npc/magic/transmigration.txt321
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;