summaryrefslogtreecommitdiff
path: root/npc/commands
diff options
context:
space:
mode:
Diffstat (limited to 'npc/commands')
-rw-r--r--npc/commands/bodytype.txt53
-rwxr-xr-xnpc/commands/changesex.txt31
-rwxr-xr-xnpc/commands/class.txt30
-rw-r--r--npc/commands/debug-look.txt83
-rw-r--r--npc/commands/debug-preset.txt253
-rw-r--r--npc/commands/debug-quest.txt217
-rw-r--r--npc/commands/debug-skill.txt94
-rwxr-xr-x[-rw-r--r--]npc/commands/debug.txt1109
-rwxr-xr-xnpc/commands/destroynpc.txt34
-rw-r--r--npc/commands/event.txt57
-rw-r--r--npc/commands/gm.txt41
-rwxr-xr-xnpc/commands/hug.txt24
-rwxr-xr-xnpc/commands/marry.txt68
-rw-r--r--npc/commands/mobinfo.txt29
-rw-r--r--npc/commands/motd.txt194
-rwxr-xr-x[-rw-r--r--]npc/commands/music.txt88
-rwxr-xr-xnpc/commands/mute.txt92
-rwxr-xr-xnpc/commands/npctalk.txt22
-rwxr-xr-xnpc/commands/numa.txt127
-rwxr-xr-xnpc/commands/pullrabbit.txt25
-rw-r--r--npc/commands/python.txt24
-rw-r--r--npc/commands/rate-management.txt107
-rwxr-xr-xnpc/commands/remotecmd.txt61
-rw-r--r--npc/commands/resync.txt40
-rw-r--r--npc/commands/scheduled-broadcasts.txt227
-rw-r--r--npc/commands/super-menu.txt68
-rwxr-xr-x[-rw-r--r--]npc/commands/warp.txt129
-rwxr-xr-x[-rw-r--r--]npc/commands/zeny.txt160
28 files changed, 1628 insertions, 1859 deletions
diff --git a/npc/commands/bodytype.txt b/npc/commands/bodytype.txt
deleted file mode 100644
index 290c6fd6..00000000
--- a/npc/commands/bodytype.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-// @bodytype atcommand
-// changes or returns the body type
-
-- script @bodytype 32767,{
- end;
-
-OnCall:
- if (.@atcmd_parameters$[0] == "") {
- dispbottom("Your current body type is " + bodytypeToString());
- end;
- }
-
- .@desired = stringToBodytype(.@atcmd_parameters$[0]);
-
- if (.@desired == BodyType) {
- dispbottom("Your body type is already " + bodytypeToString());
- } else {
- BodyType = .@desired;
- dispbottom("Body type changed to " + bodytypeToString());
- }
- end;
-
-OnInit:
- bindatcmd("gender", "@bodytype::OnCall", 99, 99, false);
- bindatcmd("bodytype", "@bodytype::OnCall", 99, 99, false);
- bindatcmd("body", "@bodytype::OnCall", 99, 99, false);
- bindatcmd("type", "@bodytype::OnCall", 99, 99, false);
- bindatcmd("changesex", "@bodytype::OnCall", 99, 99, false);
-
- add_group_command("gender", 40, true, false);
- add_group_command("bodytype", 40, true, false);
- add_group_command("body", 40, true, false);
- add_group_command("type", 40, true, false);
- add_group_command("changesex", 40, true, false);
-
- add_group_command("gender", 50, true, false);
- add_group_command("bodytype", 50, true, false);
- add_group_command("body", 50, true, false);
- add_group_command("type", 50, true, false);
- add_group_command("changesex", 50, true, false);
-
- add_group_command("gender", 60, true, false);
- add_group_command("bodytype", 60, true, false);
- add_group_command("body", 60, true, false);
- add_group_command("type", 60, true, false);
- add_group_command("changesex", 60, true, false);
-
- add_group_command("gender", 80, true, false);
- add_group_command("bodytype", 80, true, false);
- add_group_command("body", 80, true, false);
- add_group_command("type", 80, true, false);
- add_group_command("changesex", 80, true, false);
-}
diff --git a/npc/commands/changesex.txt b/npc/commands/changesex.txt
new file mode 100755
index 00000000..de20d91b
--- /dev/null
+++ b/npc/commands/changesex.txt
@@ -0,0 +1,31 @@
+- script @changesex NPC32767,{
+ callfunc "argv_splitter";
+ .@n$ = if_then_else(@argv$[1] != "", "char", "") + "changecharsex()";
+ if (GM < CMD_CHANGESex && GM < G_SYSOP) goto L_GM; // check if you can use it on self
+ .@target_id = BL_ID;
+ if (@argv$[1] != "") set .@target_id, getcharid(3, @argv$[1]);
+ if (@argv$[1] != "" && !(isloggedin(.@target_id))) goto L_Failed; // do NOT fallback to self
+ if (@argv$[1] != "" && GM < CMD_CHARCHANGESex && GM < G_SYSOP) goto L_GM; // when target is not self, use charchangecharsex() permission
+
+ set .@s, 3; // default to non-binary
+ if (@argv$[0] == "M" || @argv$[0] == "m") set .@s, 1;
+ if (@argv$[0] == "F" || @argv$[0] == "f") set .@s, 0;
+ Sex = .@s, .@target_id;
+ gmlog "@"+.@n$+" " + @args$;
+ message strcharinfo(0), .@n$+" : The operation succeeded.";
+ end;
+
+L_Failed:
+ // XXX: should we allow GMs to change Sex of users that are not logged in?
+ message strcharinfo(0), .@n$+" : Impossible to attach to the target player. Did you try putting the name in \"quotation marks\"?";
+ end;
+
+L_GM:
+ message strcharinfo(0), .@n$+" : GM command is level "+ if_then_else(@argv$[1] != "", CMD_CHARCHANGESex, CMD_CHANGESex) +", but you are level " + GM;
+ end;
+
+OnInit:
+ registercmd chr(ATCMD_SYMBOL) + "changecharsex()", strnpcinfo(0);
+ registercmd chr(ATCMD_SYMBOL) + "charchangecharsex()", strnpcinfo(0);
+ end;
+}
diff --git a/npc/commands/class.txt b/npc/commands/class.txt
new file mode 100755
index 00000000..81ac0c7c
--- /dev/null
+++ b/npc/commands/class.txt
@@ -0,0 +1,30 @@
+- script @class NPC32767,{
+ callfunc "argv_splitter";
+ .@n$ = if_then_else(@argv$[1] != "", "char", "") + "class";
+ if (GM < CMD_CLASS && GM < G_SYSOP) goto L_GM; // check if you can use it on self
+ .@target_id = BL_ID;
+ if (@argv$[1] != "") set .@target_id, getcharid(3, @argv$[1]);
+ if (@argv$[1] != "" && !(isloggedin(.@target_id))) goto L_Failed; // do NOT fallback to self
+ if (@argv$[1] != "" && GM < CMD_CHARCLASS && GM < G_SYSOP) goto L_GM; // when target is not self, use charclass permission
+
+ set .@c, 1; // default to human
+ if (@argv[0] >= 1 || @argv[0] <= 32767) set .@c, @argv[0];
+ Class = .@c, .@target_id;
+ gmlog "@"+.@n$+" " + @args$;
+ message strcharinfo(0), .@n$+" : The operation succeeded.";
+ end;
+
+L_Failed:
+ // XXX: should we allow GMs to change class of users that are not logged in?
+ message strcharinfo(0), .@n$+" : Impossible to attach to the target player. Did you try putting the name in \"quotation marks\"?";
+ end;
+
+L_GM:
+ message strcharinfo(0), .@n$+" : GM command is level "+ if_then_else(@argv$[1] != "", CMD_CHARCLASS, CMD_CLASS) +", but you are level " + GM;
+ end;
+
+OnInit:
+ registercmd chr(ATCMD_SYMBOL) + "class", strnpcinfo(0);
+ registercmd chr(ATCMD_SYMBOL) + "charclass", strnpcinfo(0);
+ end;
+}
diff --git a/npc/commands/debug-look.txt b/npc/commands/debug-look.txt
deleted file mode 100644
index 0a4a953b..00000000
--- a/npc/commands/debug-look.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-function script BarberDebug {
- function setStyle {
- clear;
- setnpcdialogtitle l("Appearance Debug - Barber");
- mes l("Hair style") + ": " + getlook(LOOK_HAIR);
- next;
- mes l("Please enter the desired style") + " (1-255)";
- input .@h, 1, 0xFF;
- setlook LOOK_HAIR, max(1, min(0xFF, .@h));
- return;
- }
- function setColor {
- clear;
- setnpcdialogtitle l("Appearance Debug - Barber");
- mes l("Hair color") + ": " + getlook(LOOK_HAIR_COLOR);
- next;
- mes l("Please enter the desired color") + " (0-255)";
- input .@h, 0, 0xFF;
- setlook LOOK_HAIR_COLOR, max(0, min(0xFF, .@h));
- return;
- }
- function setRace {
- clear;
- setnpcdialogtitle l("Appearance Debug - Race");
- mes l("Race") + ": " + Class + " (" + get_race(GETRACE_FULL) + ")";
- next;
- mes l("Please enter the desired race") + " (0-32767)";
- input .@r, 0, 0x7FFF;
- jobchange max(0, min(0x7FFF, .@r));
- return;
- }
-
- do
- {
- clear;
- setnpcdialogtitle l("Appearance Debug");
- mes l("This menu allows you to customize your appearance.");
- mes "";
-
- mes "---";
- mes l("Body type") + ": " + bodytypeToString(BodyType);
- mes l("Hair style") + ": " + getlook(LOOK_HAIR);
- mes l("Hair color") + ": " + getlook(LOOK_HAIR_COLOR);
- mes l("Race") + ": " + Class + " (" + get_race() + ")";;
- mes "---";
-
- next;
- mes l("What do you want to change?");
- select
- menuimage("actions/edit", l("Body type") + " [" + l("Requires logout") + "]"),
- menuimage("actions/edit", l("Hair style")),
- menuimage("actions/edit", l("Hair color")),
- menuimage("actions/edit", l("Race")),
- rif(getarg(0,0), menuimage("actions/back", l("Return to Debug menu")));
-
- switch (@menu)
- {
- case 1: BarberChangeBodyType(); break;
- case 2: setStyle; break;
- case 3: setColor; break;
- case 4: setRace; break;
- case 5: return;
- }
- } while (1);
-}
-
-
-
-- script @look 32767,{
- end;
-
-OnCall:
- if (!debug && !is_dev())
- {
- end;
- }
- BarberDebug;
- closeclientdialog;
- end;
-
-OnInit:
- bindatcmd "look", "@look::OnCall", 0, 99, 0;
-}
diff --git a/npc/commands/debug-preset.txt b/npc/commands/debug-preset.txt
deleted file mode 100644
index 1fbad520..00000000
--- a/npc/commands/debug-preset.txt
+++ /dev/null
@@ -1,253 +0,0 @@
-// Preset / routine system
-// Author:
-// gumi
-// Description:
-// allows to execute multiple commands in a single step
-// to ease testing and debugging
-//
-// usage: @pre [options] <instruction>[, <instruction>...]
-// usage: DoRoutine "[options] <instruction>[, <instruction>...]";
-//
-// example: @pre -s a22 v14
-// resets all stats, gives 22 agi, gives 14 vit
-//
-// ^ actual documentation may come one day, when I feel like it
-// *hides*
-
-function script DoRoutine {
-
- function parsev {
- // parsev(base, patterns{, min{, max}}) => value
- .@value = getarg(0, 0);
- .@raw$ = getarg(1, "");
- .@patterns = explode(.@patterns$, .@raw$, "|");
-
- for (.@pattern = 0; .@pattern < .@patterns; ++.@pattern)
- {
- .@pattern$ = .@patterns$[.@pattern];
- .@len = getstrlen(.@pattern$);
-
- if (charat(.@pattern$, 0) == "=" && .@len >= 2)
- {
- .@value = atoi(delchar(.@pattern$, 0));
- break;
- }
-
- else if (charat(.@pattern$, 0) == "+" && .@len >= 2)
- {
- if (charat(.@pattern$, 1) == "+" && getargcount() >= 4)
- .@value = getarg(3);
- else
- .@value += atoi(delchar(.@pattern$, 0));
- }
-
- else if (charat(.@pattern$, 0) == "-" && .@len >= 2)
- {
- if (charat(.@pattern$, 1) == "-" && getargcount() >= 3)
- .@value = getarg(2);
- else
- .@value -= atoi(delchar(.@pattern$, 0));
- }
-
- else if (charat(.@pattern$, 0) == ">" && .@len >= 2)
- {
- if (charat(.@pattern$, 1) == "=" && .@len >= 3)
- .@value = max(atoi(substr(.@pattern$, 2, .@len - 1)), .@value);
- else
- .@value = max(atoi(delchar(.@pattern$, 0)) + 1, .@value);
- }
-
- else if (charat(.@pattern$, 0) == "<" && .@len >= 2)
- {
- if (charat(.@pattern$, 1) == "=" && .@len >= 3)
- .@value = min(atoi(substr(.@pattern$, 2, .@len - 1)), .@value);
- else
- .@value = min(atoi(delchar(.@pattern$, 0)) - 1, .@value);
- }
-
- else if (.@len >= 1)
- {
- .@value = atoi(.@pattern$);
- break;
- }
- }
-
- if (getargcount() >= 3)
- .@value = max(getarg(2), .@value);
-
- if (getargcount() >= 4)
- .@value = min(getarg(3), .@value);
-
- return .@value;
- }
-
- .@routine$ = strip(getarg(0,""));
- .@m = explode(.@routine$[0], .@routine$, " "); // prep the base array
-
- if (charat(.@routine$[0], 0) == "-")
- {
- if (compare(.@routine$[0], "t"))
- {
- clearitem;
- }
-
- if (compare(.@routine$[0], "e"))
- {
- nude;
- }
-
- if (compare(.@routine$[0], "k"))
- {
- resetskill;
- }
-
- if (compare(.@routine$[0], "s"))
- {
- resetstatus;
- }
-
- if (compare(.@routine$[0], "x"))
- {
- resetlvl 2;
- }
-
- if (compare(.@routine$[0], "q"))
- {
- //doevent "::OnGlobalQuestReset"; // executes in all quest npcs // FIXME: maybe have a `resetquest` buildin?
- // FIXME: ^ need a buildin that can run *right now* instead of on script end
- }
-
- if (compare(.@routine$[0], "n"))
- {
- closeclientdialog;
- }
-
- .@i = 1;
- }
-
- for (; .@i < .@m; ++.@i)
- {
- .@type = ord(charat(strip(.@routine$[.@i]), 0));
-
- if (.@type > 0)
- {
- .@raw$ = delchar(.@routine$[.@i], 0);
- .@args = explode(.@args$, .@raw$, ",");
- .@a = atoi(.@args$[0]);
- .@b = atoi(.@args$[1]);
- .@c = atoi(.@args$[2]);
- .@d = atoi(.@args$[3]);
- .@e = atoi(.@args$[4]);
-
- switch (.@type)
- {
- case 97: /* a => Agi */
- .@base = readparam(bAgi);
- statusup2 bAgi, parsev(.@base, .@args$[0], 1, 99) - .@base;
- break;
- case 98: /* b => body type */
- .@desired_bt = max(1, min(3, .@a));
- break;
- case 99: /* c => job */
- jobchange max(0, min(6, .@a));
- break;
- case 100: /* d => Dex */
- .@base = readparam(bDex);
- statusup2 bDex, parsev(.@base, .@args$[0], 1, 99) - .@base;
- break;
- case 101: /* e => equip */
- equip max(1, min(32767, .@a));
- break;
- /* (f) */
- /* (g) */
- /* (h) */
- case 105: /* i => Int */
- .@base = readparam(bInt);
- statusup2 bInt, parsev(.@base, .@args$[0], 1, 99) - .@base;
- break;
- /* (j) */
- case 107: /* k => skill */
- .@k = max(1, min(32767, .@a));
- skill .@k, parsev(getskilllv(.@k), .@args$[1], 0, 10), 0;
- break;
- case 108: /* l => luk */
- .@base = readparam(bLuk);
- statusup2 bLuk, parsev(.@base, .@args$[0], 1, 99) - .@base;
- break;
- /* (m) => mercenary (reserved) */
- /* (n) => talk to npc (reserved) */
- /* (o) */
- case 112: /* p => pet */
- makepet max(1002, min(32767, .@a));
- break;
- case 113: /* q => quest */
- .@q = max(0, min(32767, .@a));
- setq .@q, parsev(getq(.@q), .@args$[1]),
- parsev(getq2(.@q), .@args$[2]),
- parsev(getq3(.@q), .@args$[3]),
- parsev(getqtime(.@q), .@args$[4]);
- break;
- /* (r) */
- case 115: /* s => Str */
- .@base = readparam(bStr);
- statusup2 bStr, parsev(.@base, .@args$[0], 1, 99) - .@base;
- break;
- case 116: /* t => item */
- .@t = max(1, min(32767, .@a));
- .@c = countitem(.@t);
- .@v = parsev(.@c, .@args$[1], 0, 32767);
- if (.@c > .@v)
- delitem .@t, .@c - .@v;
- else if (.@c < .@v)
- getitem .@t, .@v - .@c;
- break;
- /* (u) */
- case 118: /* v => vit */
- .@base = readparam(bVit);
- statusup2 bVit, parsev(.@base, .@args$[0], 1, 99) - .@base;
- break;
- case 119: /* w => warp */
- warp .@args$[0], .@b, .@c;
- break;
- case 120: /* x => base level */
- BaseLevel = parsev(BaseLevel, .@args$[0], 1, 99);
- BaseExp = parsev(BaseExp, .@args$[1], 0);
- break;
- case 121: /* y => job level */
- JobLevel = parsev(JobLevel, .@args$[0], 1, 255);
- JobExp = parsev(JobExp, .@args$[1], 0);
- break;
- case 122: /* z => zeny */
- Zeny = parsev(Zeny, .@args$[0], 0, 0x7FFFFFFE);
- BankVault = parsev(BankVault, .@args$[1], 0, MAX_BANK_ZENY);
- break;
- }
- }
- }
-
- if (.@desired_bt && BodyType != .@desired_bt) {
- sleep2(500);
- BodyType = .@desired_bt; // this forces a logout so we must be it last
- }
-
- return;
-}
-
-- script @pre 32767,{
- end;
-
-OnCall:
- if (!debug && !is_admin())
- {
- end;
- }
- if (.@atcmd_parameters$[0] != "")
- {
- .@atcmd_parameters$[0] = implode(.@atcmd_parameters$[0], " ");
- }
- DoRoutine strip(.@atcmd_parameters$[0]);
- end;
-
-OnInit:
- bindatcmd "pre", "@pre::OnCall", 0, 99, 0;
-}
diff --git a/npc/commands/debug-quest.txt b/npc/commands/debug-quest.txt
deleted file mode 100644
index 580173d0..00000000
--- a/npc/commands/debug-quest.txt
+++ /dev/null
@@ -1,217 +0,0 @@
-function script GlobalQuestDebug {
-
- function qDebugShip {
- function qDebugGugli {
- do
- {
- clear;
- setnpcdialogtitle l("Quest debug") + " - " + l("Prologue") + " - Gugli";
- mes l("This menu gives access to quest debug menus for @@ quest subquests.", "Gugli");
- next;
- mes l("Please select a quest:");
-
- menuint
- menuimage("actions/back", l("Go back")), -1,
- l("Gugli (main quest)"), ShipQuests_Gugli,
- "Ale", ShipQuests_Ale,
- "Astapolos", ShipQuests_Astapolos,
- "Gulukan", ShipQuests_Gulukan,
- "Jalad", ShipQuests_Jalad,
- "Q'Muller", ShipQuests_QMuller,
- "Tibbo", ShipQuests_Tibbo;
-
- switch (@menuret)
- {
- case -1: return;
- default: callfunc "QuestDebug" + @menuret;
- }
- } while (1);
- }
-
- do
- {
- clear;
- setnpcdialogtitle l("Quest debug") + " - " + l("Prologue");
- mes l("This menu gives access to quest debug menus for @@ quests.", l("Prologue"));
- next;
- mes l("Please select a quest:");
-
- menuint
- menuimage("actions/back", l("Go back")), -1,
- "Julia", ShipQuests_Julia,
- "Arpan", ShipQuests_Arpan,
- "Alige", ShipQuests_Alige,
- "Peter", ShipQuests_Peter,
- "Nard", ShipQuests_Nard,
- l("Knife"), ShipQuests_Knife,
- l("Money"), ShipQuests_ArpanMoney,
- l("Door"), ShipQuests_Door,
- "Couwan", ShipQuests_Couwan,
- l("Treasure Chest"), ShipQuests_TreasureChest,
- "Gugli", ShipQuests_Gugli,
- "Gado", ShipQuests_ChefGado;
-
- switch (@menuret)
- {
- case 16: qDebugGugli; break;
- case -1: return;
- default: callfunc "QuestDebug" + @menuret;
- }
- } while (1);
- }
-
- function qDebugArtis {
- do
- {
- clear;
- setnpcdialogtitle l("Quest debug") + " - " + l("Artis");
- mes l("This menu gives access to quest debug menus for @@ quests.", "Artis");
- next;
- mes l("Please select a quest:");
-
- menuint
- menuimage("actions/back", l("Go back")), -1,
- l("Lazy Brother"), ArtisQuests_LazyBrother,
- l("Urchin"), ArtisQuests_Urchin,
- l("Catching a piou"), ArtisQuests_CatchPiou,
- "Eugene (" + l("fisherman") + ")", ArtisQuests_Fishman,
- "Q'Onan", ArtisQuests_QOnan,
- "Enora", ArtisQuests_Enora,
- "Fexil", ArtisQuests_Fexil,
- "Lloyd", ArtisQuests_Lloyd,
- l("Mona's dad"), ArtisQuests_MonaDad,
- l("Artis legion progress"), Artis_Legion_Progress,
- l("Legion training"), ArtisQuests_TrainingLegion,
- "Henry", ThiefQuests_Artis;
-
- switch (@menuret)
- {
- case -1: return;
- default: callfunc "QuestDebug" + @menuret;
- }
- } while (1);
- }
-
- function qDebugHurnscald {
- do
- {
- clear;
- setnpcdialogtitle l("Quest debug") + " - Hurnscald";
- mes l("This menu gives access to quest debug menus for @@ quests.", "Hurnscald");
- next;
- mes l("Please select a quest:");
-
- menuint
- menuimage("actions/back", l("Go back")), -1,
- "Hinnak", HurnscaldQuests_Hinnak,
- l("Maggot soup"), HurnscaldQuests_Soup,
- l("Inspector"), HurnscaldQuests_Inspector,
- l("Forest bow"), HurnscaldQuests_ForestBow,
- l("Wooden shield"), HurnscaldQuests_WoodenShield,
- "Kfahr", HurnscaldQuests_Kfahr,
- "Galimatia", ArgaesQuest_Galimatia,
- "Rossy", HurnscaldQuests_Rossy;
-
- switch (@menuret)
- {
- case -1: return;
- default: callfunc "QuestDebug" + @menuret;
- }
- } while (1);
- }
-
- function qDebugGeneral {
- do
- {
- clear;
- setnpcdialogtitle l("Quest debug") + " - " + l("Other");
- mes l("This menu gives access to quest debug menus for @@ quests.", strtolower(l("Other")));
- next;
- mes l("Please select a quest:");
-
- menuint
- menuimage("actions/back", l("Go back")), -1,
- "Hal", General_CptHal,
- l("Cookies"), General_Cookies,
- "Rumly", General_Rumly,
- l("Narrator"), General_Narrator,
- "Janus", General_Janus,
- l("Cooking"), General_Cooking,
- l("Brotherhood"), General_Brotherhood;
-
- switch (@menuret)
- {
- case -1: return;
- default: callfunc "QuestDebug" + @menuret;
- }
- } while (1);
- }
-
- do
- {
- clear;
- setnpcdialogtitle l("Quest debug");
- mes l("This menu gives access to all quest debug menus.");
- next;
- mes l("Please select a category:");
-
- select
- l("Prologue"),
- "Artis",
- "Hurnscald",
- l("Other"),
- rif(getarg(0,0), menuimage("actions/back", l("Return to Debug menu")));
-
- switch (@menu)
- {
- case 1: qDebugShip; break;
- case 2: qDebugArtis; break;
- case 3: qDebugHurnscald; break;
- case 4: qDebugGeneral; break;
- case 5: return;
- }
- } while (1);
-}
-
-
-
-- script @qdebug 32767,{
- end;
-
-OnCall:
- if (!debug && !is_trusted())
- {
- end;
- }
- GlobalQuestDebug;
- closeclientdialog;
- end;
-
-OnSetq:
- if (.@atcmd_numparameters < 2) {
- dispbottom "setq called with invalid arguments (min. 2)";
- dispbottom "GM Command syntax: @setq <quest_id> <val1> <val2> <val3>";
- end;
- }
- .@q=atoi(.@atcmd_parameters$[0]);
- switch (.@atcmd_numparameters) {
- case 4:
- setq3 .@q, atoi(.@atcmd_parameters$[3]);
- case 3:
- setq2 .@q, atoi(.@atcmd_parameters$[2]);
- case 2:
- setq1 .@q, atoi(.@atcmd_parameters$[1]);
- dispbottom l("Quest %s modified by GM", getquestlink(.@q));
- specialeffect 54, SELF, playerattached();
- break;
- default:
- dispbottom "setq called with invalid arguments (max. 4)";
- dispbottom "GM Command syntax: @setq <quest_id> <val1> <val2> <val3>";
- break;
- }
- end;
-
-OnInit:
- bindatcmd "qdebug", "@qdebug::OnCall", 0, 99, 0;
- bindatcmd "setq", "@qdebug::OnSetq", 99, 99, 1;
-}
diff --git a/npc/commands/debug-skill.txt b/npc/commands/debug-skill.txt
deleted file mode 100644
index 2a3ef551..00000000
--- a/npc/commands/debug-skill.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-function script GlobalSkillDebug {
-
- function modifySkill {
-
- function setSkill {
- clear;
- mes l("Enter desired skill level:");
- input .@y;
- skill getarg(0,1), max(0, min(10, .@y)), 0;
- return;
- }
-
- setnpcdialogtitle l("Skill Debug - Modify Skill");
- .@k = getarg(0,1);
- .@v = getskilllv(.@k);
- select
- menuimage("actions/abort", l("Abort")),
- rif(.@v > 0, menuimage("actions/remove", l("Remove this skill"))),
- rif(.@v < 10, menuimage("actions/raise", l("Raise this skill"))),
- rif(.@v > 0, menuimage("actions/lower", l("Lower this skill"))),
- menuimage("actions/edit", l("Set the level manually")),
- menuimage("actions/back", l("Return to skill debug menu"));
-
- switch (@menu)
- {
- case 2: skill .@k, 0, 0; break;
- case 3: skill .@k, min(10, .@v + 1), 0; break;
- case 4: skill .@k, max(0, .@v - 1), 0; break;
- case 5: setSkill .@k; break;
- }
-
- return;
- }
-
- do
- {
- clear;
- setnpcdialogtitle l("Skill Debug");
- mes l("This menu allows you to change your skills.");
- mes "";
-
- mes "---";
-
- .@size = getarraysize(getvariableofnpc(.debug_skills$, "@sdebug"));
-
- for (.@s = 0; .@s < .@size; ++.@s) {
- .@skill$ = getvariableofnpc(.debug_skills$[.@s], "@sdebug");
- mesf("%s: %d", .@skill$, getskilllv(string_to_data(.@skill$)));
- }
-
- mes "---";
-
- mes "";
- mes l("Which skill do you wish to change?");
- next;
-
- .@select$ = implode(getvariableofnpc(.debug_skills$, "@sdebug"), ":");
-
- if (getarg(0, 0)) {
- .@select$ += ":" + menuimage("actions/back", l("Return to Debug menu"));
- }
-
- select(.@select$);
-
- if (--@menu == .@size) {
- return;
- } else {
- .@skill$ = getvariableofnpc(.debug_skills$[@menu], "@sdebug");
- modifySkill(string_to_data(.@skill$));
- }
- } while (1);
-}
-
-
-
-- script @sdebug 32767,{
- end;
-
-OnCall:
- if (!debug && !is_admin())
- {
- end;
- }
- GlobalSkillDebug;
- closeclientdialog;
- end;
-
-OnInit:
- setarray(.debug_skills$,
- "NV_BASIC",
- "EVOL_CRAFTING");
-
- bindatcmd "sdebug", "@sdebug::OnCall", 0, 99, 0;
-}
diff --git a/npc/commands/debug.txt b/npc/commands/debug.txt
index 8cc1f1cd..c1ebf81d 100644..100755
--- a/npc/commands/debug.txt
+++ b/npc/commands/debug.txt
@@ -1,145 +1,984 @@
-function script GlobalDebugMenu {
- function resetAll {
- function doReset {
- resetstatus;
- resetskill;
- resetlvl 1;
- dispbottom l("Reset done!");
- if (getarg(0,0) == 3)
- {
- closeclientdialog;
- doevent "::OnGlobalQuestReset"; // executes in all quest npcs // FIXME: maybe have a `resetquest` buildin?
- Zeny = 0;
- BankVault = 0;
- clearitem;
- warp "000-0", 0, 0; // starting point
- end; // script must end for doevent to execute
- }
- return;
- }
- clear;
- setnpcdialogtitle l("Debug - Reset");
- mes l("What do you want to reset?");
- select
- menuimage("actions/abort", l("Abort")),
- menuimage("actions/reset", l("Reset stats, skills, level")),
- menuimage("actions/nuke", l("Reset EVERYTHING")),
- menuimage("actions/back", l("Return to Debug menu"));
-
- switch (@menu)
- {
- case 2:
- case 3: doReset @menu;
- }
-
- return;
- }
-
- function changeLevel {
- clear;
- setnpcdialogtitle l("Debug - Change level");
- mes l("To change your base level, use this command:");
- mes "";
- mes " " + col("@blvl <" + l("delta") + ">", 3);
- next;
- mes l("Example:");
- mes "@blvl 50";
- mes " " + l("Raises your base level by 50");
- mes "@blvl -50";
- mes " " + l("Reduces your base level by 50");
- next;
- mes l("To change your job level, use this command:");
- mes "";
- mes " " + col("@jlvl <" + l("delta") + ">", 3);
- next;
- mes l("Example:");
- mes "@jlvl 50";
- mes " " + l("Raises your job level by 50");
- mes "@jlvl -50";
- mes " " + l("Reduces your job level by 50");
- next;
- return;
- }
- function changeStats {
- clear;
- setnpcdialogtitle l("Debug - Change stats");
- mes l("To change your stats, use these commands:");
- mes "";
- mes " " + col("@str <" + l("delta") + ">", 3);
- mes " " + col("@agi <" + l("delta") + ">", 3);
- mes " " + col("@vit <" + l("delta") + ">", 3);
- mes " " + col("@int <" + l("delta") + ">", 3);
- mes " " + col("@dex <" + l("delta") + ">", 3);
- mes " " + col("@luk <" + l("delta") + ">", 3);
- next;
- mes l("Example:");
- mes "@int 50";
- mes " " + l("Raises your Int by 50");
- mes "@int -50";
- mes " " + l("Reduces your Int by 50");
- next;
- mes l("If you simply wish to get 99 in all stats:");
- mes "";
- mes " " + col("@allstats", 3);
- next;
- mes l("If you wish to reset your stats:");
- mes "";
- mes " " + col("@streset", 3);
- next;
- return;
- }
- do
- {
- clear;
- setnpcdialogtitle l("Debug");
- mes l("This menu allows you to modify your account data.");
- mes "";
- mes l("What do you want to do?");
- select
- menuimage("actions/manage", l("Change my level")),
- menuimage("actions/manage", l("Change my stats")),
- menuimage("actions/manage", l("Change my skills")),
- menuimage("actions/manage", l("Change my appearance")),
- menuimage("actions/add", l("Create items")),
- menuimage("actions/add", l("Get money")),
- menuimage("actions/edit", l("Change my quests")),
- rif(debug, menuimage("actions/reset", l("Set Legacy Account"))),
- menuimage("actions/reset", l("Reset")),
- rif(getarg(0,0), menuimage("actions/home", l("Return to Super Menu")));
-
- .@c = getarg(0,0) ? 2 : 1;
-
- switch (@menu)
- {
- case 1: changeLevel; break;
- case 2: changeStats; break;
- case 3: GlobalSkillDebug .@c; break;
- case 4: BarberDebug .@c; break;
- case 5: closeclientdialog; clientcommand "createitems"; end;
- case 6: Zeny = 0x7FFFFFFE; break;
- case 7: GlobalQuestDebug .@c; break;
- case 8: setfakelegacyaccount(); break;
- case 9: resetAll; break;
- case 10: return;
- }
- } while(1);
+
+function script Debug {
+ if(!@debug_npc) goto L_Begin;
+ mes "The debug NPCs have been deprecated. Please use this command instead:";
+ mes "";
+ mes "%%E ##a@debug##0";
+ @debug_npc = 0;
+ goto L_close;
+
+L_Begin:
+ @debug_mask = 65535;
+ @debug_shift = 0;
+ @mexp = ((MAGIC_EXPERIENCE & @debug_mask) >> @debug_shift);
+ mes "What do you want to do?";
+ menu
+ "Change my level.", L_Level,
+ "Change my stats.", L_Status,
+ "Change my basic skills.", L_BasicSkills,
+ "Change my focus skills.", L_FocusSkills,
+ "Change my magic skills.", L_MagicSkills,
+ "Add everything.", L_AddAll,
+ "Reset everything.", L_ResetAll,
+ "Close.", L_close;
+
+L_Level:
+ mes "What level do you want to be (min: 1 - max: 99)?";
+ input @lvl;
+ if (@lvl < 1)
+ goto L_LevelTooLow;
+ if (@lvl > 99)
+ goto L_LevelTooHigh;
+ if (BaseLevel == @lvl)
+ goto L_SameLevel;
+ BaseLevel = @lvl;
+ resetstatus;
+ mes "You are now level " + BaseLevel + ".";
+ goto L_Begin;
+
+L_LevelTooLow:
+ mes "Bad choice. Minimum level is 1.";
+ next;
+ goto L_Begin;
+
+L_LevelTooHigh:
+ mes "Bad choice. Maximum level is 99.";
+ next;
+ goto L_Begin;
+
+L_SameLevel:
+ mes "You already are level " + @lvl + ".";
+ next;
+ goto L_Begin;
+
+L_Status:
+ mes "What do you want to do?";
+ menu
+ "Set all of my stats myself.", L_ChangeStrength,
+ "Set one of my stats myself.", L_ChangeSingleStat,
+ "Get maximum points in all stats.", L_ChangeAllStats,
+ "Reset my status points.", L_ResetStatusPoints,
+ "Back to the main menu.", L_Begin,
+ "Close.", L_close;
+
+L_ChangeAllStats:
+ Str = 99;
+ Agi = 99;
+ Vit = 99;
+ Int = 99;
+ Dex = 99;
+ Luk = 99;
+ mes "You now have 99 in all stats.";
+ next;
+ goto L_Begin;
+
+L_ChangeStrength:
+ mes "How much strength do you want to have (min: 1 - max: 99)?";
+ input @str;
+ if (@str < 1)
+ goto L_StatTooLow;
+ if (@str > 99)
+ goto L_StatTooHigh;
+ Str = @str;
+ goto L_ChangeAgility;
+
+L_ChangeAgility:
+ mes "How much agility do you want to have (min: 1 - max: 99)?";
+ input @agi;
+ if (@agi < 1)
+ goto L_StatTooLow;
+ if (@agi > 99)
+ goto L_StatTooHigh;
+ Agi = @agi;
+ goto L_ChangeVitality;
+
+L_ChangeVitality:
+ mes "How much vitality do you want to have (min: 1 - max: 99)?";
+ input @vit;
+ if (@vit < 1)
+ goto L_StatTooLow;
+ if (@vit > 99)
+ goto L_StatTooHigh;
+ Vit = @vit;
+ goto L_ChangeIntelligence;
+
+L_ChangeIntelligence:
+ mes "How much intelligence do you want to have (min: 1 - max: 99)?";
+ input @int;
+ if (@int < 1)
+ goto L_StatTooLow;
+ if (@int > 99)
+ goto L_StatTooHigh;
+ Int = @int;
+ goto L_ChangeDexterity;
+
+L_ChangeDexterity:
+ mes "How much dexterity do you want to have (min: 1 - max: 99)?";
+ input @dex;
+ if (@dex < 1)
+ goto L_StatTooLow;
+ if (@dex > 99)
+ goto L_StatTooHigh;
+ Dex = @dex;
+ goto L_ChangeLuck;
+
+L_ChangeLuck:
+ mes "How much luck do you want to have (min: 1 - max: 99)?";
+ input @luk;
+ if (@luk < 1)
+ goto L_StatTooLow;
+ if (@luk > 99)
+ goto L_StatTooHigh;
+ Luk = @luk;
+ mes "You now have " + Str + " in strength.";
+ mes "You now have " + Agi + " in agility.";
+ mes "You now have " + Vit + " in vitality.";
+ mes "You now have " + Int + " in intelligence.";
+ mes "You now have " + Dex + " in dexterity.";
+ mes "You now have " + Luk + " in luck.";
+ next;
+ goto L_Begin;
+
+L_StatTooLow:
+ mes "Bad choice. Minimum stat value is 1. Aborting.";
+ next;
+ goto L_Status;
+
+L_StatTooHigh:
+ mes "Bad choice. Maximum stat value is 99. Aborting.";
+ next;
+ goto L_Status;
+
+L_ChangeSingleStat:
+ mes "Which stat do you want to change?";
+ menu
+ "Strength.", L_ChangeStrengthSingle,
+ "Agility.", L_ChangeAgilitySingle,
+ "Vitality.", L_ChangeVitalitySingle,
+ "Intelligence.", L_ChangeIntelligenceSingle,
+ "Dexterity.", L_ChangeDexteritySingle,
+ "Luck.", L_ChangeLuckSingle,
+ "Back to the main menu.", L_Begin,
+ "Close.", L_close;
+
+L_ChangeStrengthSingle:
+ mes "How much strength do you want to have (min: 1 - max: 99)?";
+ input @str;
+ if (@str < 1)
+ goto L_StatTooLow;
+ if (@str > 99)
+ goto L_StatTooHigh;
+ Str = @str;
+ mes "You now have " + Str + " in strength.";
+ next;
+ goto L_Begin;
+
+L_ChangeAgilitySingle:
+ mes "How much agility do you want to have (min: 1 - max: 99)?";
+ input @agi;
+ if (@agi < 1)
+ goto L_StatTooLow;
+ if (@agi > 99)
+ goto L_StatTooHigh;
+ Agi = @agi;
+ mes "You now have " + Agi + " in agility.";
+ next;
+ goto L_Begin;
+
+L_ChangeVitalitySingle:
+ mes "How much vitality do you want to have (min: 1 - max: 99)?";
+ input @vit;
+ if (@vit < 1)
+ goto L_StatTooLow;
+ if (@vit > 99)
+ goto L_StatTooHigh;
+ Vit = @vit;
+ mes "You now have " + Vit + " in vitality.";
+ next;
+ goto L_Begin;
+
+L_ChangeIntelligenceSingle:
+ mes "How much intelligence do you want to have (min: 1 - max: 99)?";
+ input @int;
+ if (@int < 1)
+ goto L_StatTooLow;
+ if (@int > 99)
+ goto L_StatTooHigh;
+ Int = @int;
+ mes "You now have " + Int + " in intelligence.";
+ next;
+ goto L_Begin;
+
+L_ChangeDexteritySingle:
+ mes "How much dexterity do you want to have (min: 1 - max: 99)?";
+ input @dex;
+ if (@dex < 1)
+ goto L_StatTooLow;
+ if (@dex > 99)
+ goto L_StatTooHigh;
+ Dex = @dex;
+ mes "You now have " + Dex + " in dexterity.";
+ next;
+ goto L_Begin;
+
+L_ChangeLuckSingle:
+ mes "How much luck do you want to have (min: 1 - max: 99)?";
+ input @luk;
+ if (@luk < 1)
+ goto L_StatTooLow;
+ if (@luk > 99)
+ goto L_StatTooHigh;
+ Luk = @luk;
+ mes "You now have " + Luk + " in luck.";
+ next;
+ goto L_Begin;
+
+L_ResetStatusPoints:
+ resetstatus;
+ mes "Stats successfully resetted.";
+ next;
+ goto L_Begin;
+
+L_BasicSkills:
+ @emote = getskilllv(SKILL_EMOTE);
+ @trade = getskilllv(SKILL_TRADE);
+ @party = getskilllv(SKILL_PARTY);
+ menu
+ "Overview of my basic skills.", L_BasicSkillsOverview,
+ "Add basic skills.", L_AddBasicSkills,
+ "Reset basic skills.", L_ResetBasicSkills,
+ "Back to main menu.", L_Begin,
+ "Close.", L_close;
+
+L_BasicSkillsOverview:
+ mes "Your level in the emote skill is " + @emote + ".";
+ mes "Your level in the trade skill is " + @trade + ".";
+ mes "Your level in the party skill is " + @party + ".";
+ next;
+ goto L_BasicSkills;
+
+L_AddBasicSkills:
+ menu
+ "Emote", L_ChangeEmoteSkill,
+ "Trade.", L_ChangeTradeSkill,
+ "Party.", L_ChangePartySkill,
+ "All basic skills to their maximum level.", L_AllBasicSkills,
+ "Back to the basic skills menu.", L_BasicSkills,
+ "Close.", L_close;
+
+L_ChangeEmoteSkill:
+ mes "Your level in the emote skill is " + @emote + ". What do you want to do?";
+ menu
+ "Get level 0.", L_Next,
+ "Get level 1.", L_ChangeEmoteSkill1;
+
+L_Next:
+ if (@menu == 1)
+ addtoskill SKILL_EMOTE, 0;
+ mes "Emote skill changed to level 0.";
+ next;
+ goto L_BasicSkills;
+
+L_ChangeEmoteSkill1:
+ addtoskill SKILL_EMOTE, 1;
+ mes "Emote skill changed to level 1.";
+ next;
+ goto L_BasicSkills;
+
+L_ChangeTradeSkill:
+ mes "Your level in the trade skill is " + @trade + ". What do you want to do?";
+ menu
+ "Get level 0.", L_Next1,
+ "Get level 1.", L_ChangeTradeSkill1;
+
+L_Next1:
+ if (@menu == 1)
+ addtoskill SKILL_TRADE, 0;
+ mes "Trade skill changed to level 0.";
+ next;
+ goto L_BasicSkills;
+
+L_ChangeTradeSkill1:
+ addtoskill SKILL_TRADE, 1;
+ mes "Trade skill changed to level 1.";
+ next;
+ goto L_BasicSkills;
+
+L_ChangePartySkill:
+ mes "Your level in the party skill is " + @trade + ". What do you want to do?";
+ menu
+ "Get level 0.", L_Next2,
+ "Get level 1.", L_ChangePartySkill1,
+ "Get level 2.", L_ChangePartySkill2;
+
+L_Next2:
+ if (@menu == 1)
+ addtoskill SKILL_PARTY, 0;
+ mes "Party skill changed to level 0.";
+ next;
+ goto L_BasicSkills;
+
+L_ChangePartySkill1:
+ addtoskill SKILL_PARTY, 1;
+ mes "Party skill changed to level 1.";
+ next;
+ goto L_BasicSkills;
+
+L_ChangePartySkill2:
+ addtoskill SKILL_PARTY, 2;
+ mes "Party skill changed to level 2.";
+ next;
+ goto L_BasicSkills;
+
+L_AllBasicSkills:
+ addtoskill SKILL_EMOTE, 1;
+ addtoskill SKILL_TRADE, 1;
+ addtoskill SKILL_PARTY, 2;
+ mes "Basic skills added.";
+ next;
+ goto L_BasicSkills;
+
+L_ResetBasicSkills:
+ addtoskill SKILL_EMOTE, 0;
+ addtoskill SKILL_TRADE, 0;
+ addtoskill SKILL_PARTY, 0;
+ mes "Basic skills removed.";
+ next;
+ goto L_BasicSkills;
+
+L_FocusSkills:
+ @pool = getskilllv(SKILL_POOL);
+ @mallard = getskilllv(SKILL_MALLARDS_EYE);
+ @brawling = getskilllv(SKILL_BRAWLING);
+ @speed = getskilllv(SKILL_SPEED);
+ @poison = getskilllv(SKILL_RESIST_POISON);
+ @astralsoul = getskilllv(SKILL_ASTRAL_SOUL);
+ @raging = getskilllv(SKILL_RAGING);
+ menu
+ "Overview of my focus skills.", L_SeeFocusSkills,
+ "Focus or unfocus.", L_Unfocus,
+ "Add focus skills.", L_ChangeFocusSkills,
+ "Reset focus skills.", L_ResetFocusSkills,
+ "Back to the main menu.", L_Begin,
+ "Close.", L_close;
+
+L_SeeFocusSkills:
+ cleararray @skilllist_name$[0], "", 8;
+ cleararray @skilllist_id[0], 0, 8;
+ cleararray @skilllist_count[0], 0, 8;
+ getactivatedpoolskilllist;
+ if (@skilllist_count == 0)
+ goto L_NotFocusedMessage;
+ if (@skilllist_count != 0)
+ mes "You are currently focused on the " + @skilllist_name$[@skilllist_count-1] + " skill.";
+ goto L_FocusSkills;
+
+L_NotFocusedMessage:
+ mes "You are not focused on any skill right now.";
+ goto L_FocusSkillsOverview;
+
+L_FocusSkillsOverview:
+ mes "Your focusing skill level is " + @pool + ".";
+ mes "Your mallard's eye skill level is " + @mallard + ".";
+ mes "Your brawling skill level is " + @brawling + ".";
+ mes "Your speed skill level is " + @speed + ".";
+ mes "Your resist poison skill level is " + @poison + ".";
+ mes "Your astral soul skill level is " + @astralsoul + ".";
+ mes "Your raging skill level is " + @raging + ".";
+ next;
+ goto L_FocusSkills;
+
+L_Unfocus:
+ cleararray @skilllist_name$[0], "", 8;
+ cleararray @skilllist_id[0], 0, 8;
+ cleararray @skilllist_count[0], 0, 8;
+ if (getskilllv(SKILL_POOL) == 0)
+ addtoskill SKILL_POOL, 1;
+ getactivatedpoolskilllist;
+ if (@skilllist_count == 0)
+ goto L_Focus;
+ getactivatedpoolskilllist;
+ if (@skilllist_count != 0)
+ goto L_AskUnfocus;
+ mes "You are not focused on a skill at the moment.";
+ goto L_FocusSkills;
+
+L_Focus:
+ cleararray @skilllist_name$[0], "", 8;
+ cleararray @skilllist_id[0], 0, 8;
+ cleararray @skilllist_count[0], 0, 8;
+ getunactivatedpoolskilllist;
+ if (@skilllist_count == 0)
+ goto L_NoFocusSkills;
+ @skilllist_id[@skilllist_count] = 0;
+ @skilllist_name$[@skilllist_count] = "Back to the focus skills menu.";
+ mes "You are not focused on any focus skill right now. Which one do you want to focus on?";
+ menu
+ @skilllist_name$[0], L_MenuItems,
+ @skilllist_name$[1], L_MenuItems,
+ @skilllist_name$[2], L_MenuItems,
+ @skilllist_name$[3], L_MenuItems,
+ @skilllist_name$[4], L_MenuItems,
+ @skilllist_name$[5], L_MenuItems,
+ @skilllist_name$[6], L_MenuItems,
+ @skilllist_name$[7], L_MenuItems;
+
+L_MenuItems:
+ @menu = @menu - 1;
+ poolskill @skilllist_id[@menu];
+ goto L_FocusSkills;
+
+L_NoFocusSkills:
+ mes "You have no skills to focus on or unfocus from.";
+ goto L_FocusSkills;
+
+L_AskUnfocus:
+ mes "Unfocus " + @skilllist_name$[@skilllist_count-1] + "?";
+ menu
+ "Yes.", L_Next3,
+ "No.", L_FocusSkills;
+
+L_Next3:
+ unpoolskill @skilllist_id[@skilllist_count-1];
+ goto L_FocusSkills;
+
+L_ChangeFocusSkills:
+ menu
+ "Focusing.", L_ChangeFocusingSkill,
+ "Mallard's Eye.", L_ChangeMallardsEyeSkill,
+ "Brawling.", L_ChangeBrawlingSkill,
+ "Speed.", L_ChangeSpeedSkill,
+ "Resist Poison.", L_ChangeResistPoisonSkill,
+ "Astral Soul.", L_ChangeAstralSoulSkill,
+ "Raging.", L_ChangeRagingSkill,
+ "All focus skills to their maximum level.", L_AllFocusSkills,
+ "Back to the focus skills menu.", L_FocusSkills,
+ "Close.", L_close;
+
+L_BadSkillLevel:
+ mes "Invalid skill level.";
+ next;
+ goto L_ChangeFocusSkills;
+
+L_ChangeFocusingSkill:
+ mes "Enter the level you want to be in this skill (min: 0 - max: 1).";
+ input @lvl;
+ if (@lvl > 1)
+ goto L_BadSkillLevel;
+ addtoskill SKILL_POOL, @lvl;
+ next;
+ goto L_FocusSkills;
+
+L_ChangeMallardsEyeSkill:
+ mes "Enter the level you want to be in this skill (min: 0 - max: 9).";
+ input @lvl;
+ if (@lvl > 9)
+ goto L_BadSkillLevel;
+ addtoskill SKILL_MALLARDS_EYE, @lvl;
+ next;
+ goto L_FocusSkills;
+
+L_ChangeBrawlingSkill:
+ mes "Enter the lvl you want to be in this skill (min: 0 - max: 9).";
+ input @lvl;
+ if (@lvl > 9)
+ goto L_BadSkillLevel;
+ addtoskill SKILL_BRAWLING, @lvl;
+ next;
+ goto L_FocusSkills;
+
+L_ChangeSpeedSkill:
+ mes "Enter the lvl you want to be in this skill (min: 0 - max: 9).";
+ input @lvl;
+ if (@lvl > 9)
+ goto L_BadSkillLevel;
+ addtoskill SKILL_SPEED, @lvl;
+ next;
+ goto L_FocusSkills;
+
+L_ChangeResistPoisonSkill:
+ mes "Enter the lvl you want to be in this skill (min: 0 - max: 9).";
+ input @lvl;
+ if (@lvl > 9)
+ goto L_BadSkillLevel;
+ addtoskill SKILL_RESIST_POISON, @lvl;
+ next;
+ goto L_FocusSkills;
+
+L_ChangeAstralSoulSkill:
+ mes "Enter the lvl you want to be in this skill (min: 0 - max: 9).";
+ input @lvl;
+ if (@lvl > 9)
+ goto L_BadSkillLevel;
+ addtoskill SKILL_ASTRAL_SOUL, @lvl;
+ next;
+ goto L_FocusSkills;
+
+L_ChangeRagingSkill:
+ mes "Enter the lvl you want to be in this skill (min: 0 - max: 9).";
+ input @lvl;
+ if (@lvl > 9)
+ goto L_BadSkillLevel;
+ addtoskill SKILL_RAGING, @lvl;
+ next;
+ goto L_FocusSkills;
+
+L_AllFocusSkills:
+ addtoskill SKILL_POOL, 1;
+ addtoskill SKILL_MALLARDS_EYE, 9;
+ addtoskill SKILL_BRAWLING, 9;
+ addtoskill SKILL_SPEED, 9;
+ addtoskill SKILL_RESIST_POISON, 9;
+ addtoskill SKILL_ASTRAL_SOUL, 9;
+ addtoskill SKILL_RAGING, 9;
+ mes "Focus skills added.";
+ next;
+ goto L_FocusSkills;
+
+L_ResetFocusSkills:
+ addtoskill SKILL_POOL, 0;
+ addtoskill SKILL_MALLARDS_EYE, 0;
+ addtoskill SKILL_BRAWLING, 0;
+ addtoskill SKILL_SPEED, 0;
+ addtoskill SKILL_RESIST_POISON, 0;
+ addtoskill SKILL_ASTRAL_SOUL, 0;
+ addtoskill SKILL_RAGING, 0;
+ mes "Focus skills removed.";
+ next;
+ goto L_FocusSkills;
+
+L_MagicSkills:
+ @general = getskilllv(SKILL_MAGIC);
+ @life = getskilllv(SKILL_MAGIC_LIFE);
+ @war = getskilllv(SKILL_MAGIC_WAR);
+ @trans = getskilllv(SKILL_MAGIC_TRANSMUTE);
+ @nature = getskilllv(SKILL_MAGIC_NATURE);
+ @astral = getskilllv(SKILL_MAGIC_ASTRAL);
+ @dark = getskilllv(SKILL_MAGIC_DARK);
+ menu
+ "Overview of my magical skills.", L_MagicSkillsOverview,
+ "Get magic skills.", L_ChangeMagicSkills,
+ "Get magic experience.", L_MagicExperience,
+ "All magic skills to their maximum level and maximum magic experience.", L_GetAllMagic,
+ "Reset magic skills and experience.", L_ResetMagicSkills,
+ "Back to the main menu.", L_Begin,
+ "Close.", L_close;
+
+L_MagicSkillsOverview:
+ mes "Your current magic experience skill is " + @mexp + ".";
+ mes "Your level in the general magic skill is " + @general + ".";
+ mes "Your level in the life magic skill is " + @life + ".";
+ mes "Your level in the war magic skill is " + @war + ".";
+ mes "Your level in the transmutation magic skill is " + @trans + ".";
+ mes "Your level in the nature magic skill is " + @nature + ".";
+ mes "Your level in the astral magic skill is " + @astral + ".";
+ mes "Your level in the dark magic skill is " + @dark + ".";
+ next;
+ goto L_MagicSkills;
+
+L_MagicExperience:
+ mes "Your current magic experience is " + @mexp + ".";
+ if (@general == 0
+ && @life == 0
+ && @war == 0
+ && @trans == 0
+ && @nature == 0
+ && @astral == 0
+ && @dark == 0)
+ goto L_NoMagicSkills;
+
+ goto L_ChangeMagicExperience;
+
+L_NoMagicSkills:
+ mes "You can't have magic experience, since you have no magic skills yet.";
+ goto L_MagicSkills;
+
+L_ChangeMagicExperience:
+ mes "Set the desired magic experience (min: 0 - max: 8000).";
+ input @value;
+ if (@value < 0 || @value > 8000)
+ goto L_WrongMagicExperience;
+ @mexp = @value;
+ callsub S_Update_Mask;
+ mes "You now have " + @mexp + " magic experience points.";
+ goto L_MagicSkills;
+
+L_WrongMagicExperience:
+ mes "Wrong value informed. Aborting.";
+ goto L_MagicSkills;
+
+L_ChangeMagicSkills:
+ menu
+ "General Magic.", L_ChangeGeneralMagicSkill,
+ "Life Magic.", L_ChangeLifeMagicSkill,
+ "War Magic.", L_ChangeWarMagicSkill,
+ "Transmutation Magic.", L_ChangeTransmutationMagicSkill,
+ "Nature Magic.", L_ChangeNatureMagicSkill,
+ "Astral Magic.", L_ChangeAstralMagicSkill,
+ "Dark Magic.", L_ChangeDarkMagicSkill,
+ "Back to the magic skills menu.", L_MagicSkills,
+ "Close.", L_close;
+
+L_ChangeGeneralMagicSkill:
+ mes "Your level in the general magic skill is " + @general + ". What do you want to do?";
+ menu
+ "Get level 0.", L_Next4,
+ "Get level 1.", L_ChangeGeneralMagicSkill1,
+ "Get level 2.", L_ChangeGeneralMagicSkill2;
+
+L_Next4:
+ if (@menu == 1)
+ addtoskill SKILL_MAGIC, 0;
+ mes "General Magic skill changed to level 0.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeGeneralMagicSkill1:
+ addtoskill SKILL_MAGIC, 1;
+ mes "General Magic skill changed to level 1.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeGeneralMagicSkill2:
+ addtoskill SKILL_MAGIC, 2;
+ if (@mexp < 100)
+ @mexp = 100;
+ callsub S_Update_Mask;
+ mes "General Magic skill changed to level 2.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeLifeMagicSkill:
+ mes "Your level in the life magic skill is " + @life + ". What do you want to do?";
+ menu
+ "Get level 0.", L_Next5,
+ "Get level 1.", L_ChangeLifeMagicSkill1,
+ "Get level 2.", L_ChangeLifeMagicSkill2;
+
+L_Next5:
+ if (@menu == 1)
+ addtoskill SKILL_MAGIC_LIFE, 0;
+ mes "Life Magic skill changed to level 0.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeLifeMagicSkill1:
+ addtoskill SKILL_MAGIC_LIFE, 1;
+ mes "Life Magic skill changed to level 1.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeLifeMagicSkill2:
+ addtoskill SKILL_MAGIC_LIFE, 2;
+ if (@mexp < 100)
+ @mexp = 100;
+ callsub S_Update_Mask;
+ mes "Life Magic skill changed to level 2.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeWarMagicSkill:
+ mes "Your level in the war magic skill is " + @war + ". What do you want to do?";
+ menu
+ "Get level 0.", L_Next6,
+ "Get level 1.", L_ChangeWarMagicSkill1,
+ "Get level 2.", L_ChangeWarMagicSkill2;
+
+L_Next6:
+ if (@menu == 1)
+ addtoskill SKILL_MAGIC_WAR, 0;
+ mes "War Magic skill changed to level 0.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeWarMagicSkill1:
+ addtoskill SKILL_MAGIC_WAR, 1;
+ mes "War Magic skill changed to level 1.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeWarMagicSkill2:
+ addtoskill SKILL_MAGIC_WAR, 2;
+ if (@mexp < 100)
+ @mexp = 100;
+ callsub S_Update_Mask;
+ mes "War Magic skill changed to level 2.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeTransmutationMagicSkill:
+ mes "Your level in the transmutation magic skill is " + @trans + ". What do you want to do?";
+ menu
+ "Get level 0.", L_Next7,
+ "Get level 1.", L_ChangeTransmutationMagicSkill1,
+ "Get level 2.", L_ChangeTransmutationMagicSkill2;
+
+L_Next7:
+ if (@menu == 1)
+ addtoskill SKILL_MAGIC_TRANSMUTE, 0;
+ mes "Transmutation Magic skill changed to level 0.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeTransmutationMagicSkill1:
+ addtoskill SKILL_MAGIC_TRANSMUTE, 1;
+ mes "Transmutation Magic skill changed to level 1.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeTransmutationMagicSkill2:
+ addtoskill SKILL_MAGIC_TRANSMUTE, 2;
+ if (@mexp < 100)
+ @mexp = 100;
+ callsub S_Update_Mask;
+ mes "Transmutation Magic skill changed to level 2.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeNatureMagicSkill:
+ mes "Your level in the nature magic skill is " + @nature + ". What do you want to do?";
+ menu
+ "Get level 0.", L_Next8,
+ "Get level 1.", L_ChangeNatureMagicSkill1,
+ "Get level 2.", L_ChangeNatureMagicSkill2;
+
+L_Next8:
+ if (@menu == 1)
+ addtoskill SKILL_MAGIC_NATURE, 0;
+ mes "Nature Magic skill changed to level 0.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeNatureMagicSkill1:
+ addtoskill SKILL_MAGIC_NATURE, 1;
+ mes "Nature Magic skill changed to level 1.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeNatureMagicSkill2:
+ addtoskill SKILL_MAGIC_NATURE, 2;
+ if (@mexp < 100)
+ @mexp = 100;
+ callsub S_Update_Mask;
+ mes "Nature Magic skill changed to level 2.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeAstralMagicSkill:
+ mes "Your level in the astral magic skill is " + @astral + ". What do you want to do?";
+ menu
+ "Get level 0.", L_Next9,
+ "Get level 1.", L_ChangeAstralMagicSkill1,
+ "Get level 2.", L_ChangeAstralMagicSkill2;
+
+L_Next9:
+ if (@menu == 1)
+ addtoskill SKILL_MAGIC_ASTAL, 0;
+ mes "Astral Magic skill changed to level 0.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeAstralMagicSkill1:
+ addtoskill SKILL_MAGIC_ASTRAL, 1;
+ mes "Astral Magic skill changed to level 1.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeAstralMagicSkill2:
+ addtoskill SKILL_MAGIC_ASTRAL, 2;
+ if (@mexp < 100)
+ @mexp = 100;
+ callsub S_Update_Mask;
+ mes "Astral Magic skill changed to level 2.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeDarkMagicSkill:
+ mes "Your level in the dark magic skill is " + @dark + ". What do you want to do?";
+ menu
+ "Get level 0.", L_Next10,
+ "Get level 1.", L_ChangeDarkMagicSkill1,
+ "Get level 2.", L_ChangeDarkMagicSkill2;
+
+L_Next10:
+ if (@menu == 1)
+ addtoskill SKILL_MAGIC_DARK, 0;
+ mes "Dark Magic skill changed to level 0.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeDarkMagicSkill1:
+ addtoskill SKILL_MAGIC_DARK, 1;
+ mes "Dark Magic skill changed to level 1.";
+ next;
+ goto L_MagicSkills;
+
+L_ChangeDarkMagicSkill2:
+ addtoskill SKILL_MAGIC_DARK, 2;
+ if (@mexp < 100)
+ @mexp = 100;
+ callsub S_Update_Mask;
+ mes "Dark Magic skill changed to level 2.";
+ next;
+ goto L_MagicSkills;
+
+S_Update_Mask:
+ set MAGIC_EXPERIENCE,
+ (MAGIC_EXPERIENCE & ~(@debug_mask))
+ | (@mexp << @debug_shift);
+ return;
+
+L_GetAllMagic:
+ addtoskill SKILL_MAGIC, 5;
+ addtoskill SKILL_MAGIC_LIFE, 5;
+ addtoskill SKILL_MAGIC_WAR, 5;
+ addtoskill SKILL_MAGIC_TRANSMUTE, 5;
+ addtoskill SKILL_MAGIC_NATURE, 5;
+ addtoskill SKILL_MAGIC_ASTRAL, 5;
+ addtoskill SKILL_MAGIC_DARK, 5;
+ @mexp = 8000;
+ callsub S_Update_Mask;
+ mes "Magic skills added.";
+ next;
+ goto L_MagicSkills;
+
+L_ResetMagicSkills:
+ addtoskill SKILL_MAGIC, 0;
+ addtoskill SKILL_MAGIC_LIFE, 0;
+ addtoskill SKILL_MAGIC_WAR, 0;
+ addtoskill SKILL_MAGIC_TRANSMUTE, 0;
+ addtoskill SKILL_MAGIC_NATURE, 0;
+ addtoskill SKILL_MAGIC_ASTRAL, 0;
+ addtoskill SKILL_MAGIC_DARK, 0;
+ @mexp = 0;
+ callsub S_Update_Mask;
+ mes "Magic skills removed.";
+ next;
+ goto L_MagicSkills;
+
+L_AddAll:
+ addtoskill SKILL_EMOTE, 1;
+ addtoskill SKILL_TRADE, 1;
+ addtoskill SKILL_PARTY, 2;
+ addtoskill SKILL_POOL, 1;
+ addtoskill SKILL_MALLARDS_EYE, 9;
+ addtoskill SKILL_BRAWLING, 9;
+ addtoskill SKILL_SPEED, 9;
+ addtoskill SKILL_RESIST_POISON, 9;
+ addtoskill SKILL_ASTRAL_SOUL, 9;
+ addtoskill SKILL_RAGING, 9;
+ addtoskill SKILL_MAGIC, 5;
+ addtoskill SKILL_MAGIC_LIFE, 5;
+ addtoskill SKILL_MAGIC_WAR, 5;
+ addtoskill SKILL_MAGIC_TRANSMUTE, 5;
+ addtoskill SKILL_MAGIC_NATURE, 5;
+ addtoskill SKILL_MAGIC_ASTRAL, 5;
+ addtoskill SKILL_MAGIC_DARK, 5;
+ @mexp = 8000;
+ resetstatus;
+ BaseLevel = 99;
+ mes "All skills added to their maximum level.";
+ mes "Maximum number of Magic Experience points.";
+ mes "You are now level " + BaseLevel + ".";
+ next;
+ goto L_Begin;
+
+L_ResetAll:
+ cleararray @skilllist_name$[0], "", 8;
+ cleararray @skilllist_id[0], 0, 8;
+ cleararray @skilllist_count[0], 0, 8;
+ addtoskill SKILL_EMOTE, 0;
+ addtoskill SKILL_TRADE, 0;
+ addtoskill SKILL_PARTY, 0;
+ addtoskill SKILL_POOL, 0;
+ addtoskill SKILL_MALLARDS_EYE, 0;
+ addtoskill SKILL_BRAWLING, 0;
+ addtoskill SKILL_SPEED, 0;
+ addtoskill SKILL_RESIST_POISON, 0;
+ addtoskill SKILL_ASTRAL_SOUL, 0;
+ addtoskill SKILL_RAGING, 0;
+ addtoskill SKILL_MAGIC, 0;
+ addtoskill SKILL_MAGIC_LIFE, 0;
+ addtoskill SKILL_MAGIC_WAR, 0;
+ addtoskill SKILL_MAGIC_TRANSMUTE, 0;
+ addtoskill SKILL_MAGIC_NATURE, 0;
+ addtoskill SKILL_MAGIC_ASTRAL, 0;
+ addtoskill SKILL_MAGIC_DARK, 0;
+ @mexp = 0;
+ callsub S_Update_Mask;
+ resetstatus;
+ BaseLevel = 1;
+ mes "All skills removed.";
+ mes "Minimum number of Magic Experience points.";
+ mes "You are now level " + BaseLevel + ".";
+ next;
+ goto L_Begin;
+
+L_close:
+ close2;
+ return;
+
}
+- script Debug Spell NPC32767,{
+ if(!debug && getgmlevel() < CMD_DEBUG) end;
+ callfunc "Debug";
+ end;
+OnDeprecated:
+ message strcharinfo(0), "Debug : ##3The #debug spell has been superseded by the ##B@debug##b command.";
+ end;
+OnInit:
+ registercmd "@debug", "Debug Spell";
+ registercmd "#debug", "Debug Spell::OnDeprecated";
+ end;
+}
+029-2,30,26,0 script Debug#0 NPC154,{
+ @debug_npc = 1;
+ callfunc "Debug";
+ end;
+OnInit:
+ if (!debug)
+ disablenpc "Debug#0";
+ end;
+}
-- script @debug 32767,{
+001-1,53,47,0 script Debug#1 NPC154,{
+ @debug_npc = 1;
+ callfunc "Debug";
+ end;
+OnInit:
+ if (!debug)
+ disablenpc "Debug#1";
end;
+}
-OnCall:
- if (!debug && !is_admin())
- {
- end;
- }
- GlobalDebugMenu;
- closeclientdialog;
+009-1,45,33,0 script Debug#2 NPC154,{
+ @debug_npc = 1;
+ callfunc "Debug";
+ end;
+OnInit:
+ if (!debug)
+ disablenpc "Debug#2";
end;
+}
+020-1,75,85,0 script Debug#3 NPC154,{
+ @debug_npc = 1;
+ callfunc "Debug";
+ end;
OnInit:
- bindatcmd "debug", "@debug::OnCall", 0, 99, 0;
- // TODO / FIXME: add a @test command that opens the help window for test-server
+ if (!debug)
+ disablenpc "Debug#3";
+ end;
+}
+
+027-2,125,103,0 script Debug#5 NPC154,{
+ @debug_npc = 1;
+ callfunc "Debug";
+ end;
+OnInit:
+ if (!debug)
+ disablenpc "Debug#5";
+ end;
}
diff --git a/npc/commands/destroynpc.txt b/npc/commands/destroynpc.txt
new file mode 100755
index 00000000..156c8200
--- /dev/null
+++ b/npc/commands/destroynpc.txt
@@ -0,0 +1,34 @@
+- script @destroynpc NPC32767,{
+ callfunc "argv_splitter";
+ if (GM < CMD_DESTROYNPC && GM < G_SYSOP)
+ goto L_GM;
+
+ .@id = getnpcid(@argv$[0]);
+ if (@argv$[0] == "" || .@id < 1)
+ goto L_Failed;
+ if (gettimetick(2) - @destroynpc[0] > 300 || @destroynpc[1] != .@id)
+ goto L_Confirm;
+
+ gmlog "@destroynpc " + @args$;
+ message strcharinfo(0), "destroynpc : The operation succeeded.";
+ debugmes "!!! => npc destroyed: `"+@argv$[0]+"` ("+.@id+")";
+ if (1==1) destroy .@id; // FIXME: allow destroy to work as a non-terminator when arg0 is given (TMWA)
+ end;
+
+L_Confirm:
+ message strcharinfo(0), "destroynpc : ##BDANGER ZONE!##b This command permanently destroys a npc and its puppets (if any). Use the command again to confirm.";
+ setarray @destroynpc[0], gettimetick(2), .@id;
+ end;
+
+L_Failed:
+ message strcharinfo(0), "destroynpc : Impossible to find the target npc. Did you try putting the name in \"quotation marks\"? Some npcs also have an invisible postfix in their name, ie `#_M`.";
+ end;
+
+L_GM:
+ message strcharinfo(0), "destroynpc : GM command is level "+ CMD_DESTROYNPC +", but you are level " + GM;
+ end;
+
+OnInit:
+ registercmd chr(ATCMD_SYMBOL) + "destroynpc", strnpcinfo(0);
+ end;
+}
diff --git a/npc/commands/event.txt b/npc/commands/event.txt
deleted file mode 100644
index 3f0d61de..00000000
--- a/npc/commands/event.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-function script GlobalEventMenu {
-
- function rateManagement {
- clear;
- mes l("To get the current rate:");
- mes col(" @exprate", 7);
- next;
- mes l("To set the exp rate:");
- mes col(" @exprate ##Brate##b hours", 7);
- next;
- mes l("To reset back to normal:");
- mes col(" @exprate default", 7); // note to translators: any non-numerical value will reset so "default" is safe to translate
- next;
- return;
- }
-
- do
- {
- clear;
- setnpcdialogtitle l("Event Management");
- mes l("This menu allows you to manage events and gives access to event-related tools.");
- mes "";
- mes l("What do you want to access?");
-
- select
- l("Rate management"),
- rif(getarg(0,0), menuimage("actions/home", l("Return to Super Menu")));
-
- //.@c = getarg(0,0) ? 2 : 1; // 1 = back to event menu, 2 = back to super menu
-
- switch (@menu)
- {
- case 1: rateManagement; break;
- default: return;
- }
-
- } while (true);
-}
-
-
-
-- script @event 32767,{
- end;
-
-OnCall:
- if (!is_evtc())
- {
- end;
- }
-
- GlobalEventMenu;
- closeclientdialog;
- end;
-
-OnInit:
- bindatcmd "event", "@event::OnCall", 0, 99, 0;
-}
diff --git a/npc/commands/gm.txt b/npc/commands/gm.txt
deleted file mode 100644
index b402cda8..00000000
--- a/npc/commands/gm.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-// @showgm/@hidegm atcommand
-// TEMPORALY hides GM level (or revert it)
-//
-// group lv: 20+
-// group char lv: 99
-// log: False
-//
-// usage:
-// @showgm
-// #showgm "char" <delta>
-//
-
-- script @group 32767,{
- end;
-
-OnHide:
- .@gm=getgroupid();
- if (.@gm < 20) end;
- if (.@gm % 10 != 0) end;
- setgroupid(.@gm+1);
- dispbottom "hidelevel : "+l("Your GM level is now hidden.");
- end;
-
-OnShow:
- .@gm=getgroupid();
- if (.@gm < 20) end;
- if (.@gm % 10 != 1) end;
- setgroupid(.@gm-1);
- dispbottom "showlevel : "+l("Your GM level is now visible.");
- end;
-
-OnInit:
- bindatcmd "showgroup", "@group::OnShow", 20, 99, 0;
- bindatcmd "showgm", "@group::OnShow", 20, 99, 0;
- bindatcmd "showlevel", "@group::OnShow", 20, 99, 0;
-
- bindatcmd "hidegroup", "@group::OnHide", 20, 99, 0;
- bindatcmd "hidegm", "@group::OnHide", 20, 99, 0;
- bindatcmd "hidelevel", "@group::OnHide", 20, 99, 0;
- end;
-}
diff --git a/npc/commands/hug.txt b/npc/commands/hug.txt
new file mode 100755
index 00000000..4f7c086d
--- /dev/null
+++ b/npc/commands/hug.txt
@@ -0,0 +1,24 @@
+- script nonmagic-hug NPC32767,{
+ explode .@name$[0], @args$, "*"; // strip the trailing *
+ @target_id = if_then_else(.@name$[0] != "", getcharid(3, .@name$[0]), BL_ID);
+ if (@target_id < 1 || !(isloggedin(@target_id))) set @target_id, BL_ID; // fallback to self
+ if (.@name$[0] == "Tree" || .@name$[0] == "tree") set @target_id, .tree_id;
+ .@range = if_then_else(@target_id == .tree_id, 3, 6);
+ if (distance(BL_ID, @target_id) >= .@range) end;
+ if (gettimetick(2) - @hugspell_time < 3) end;
+
+ @hugspell_time = gettimetick(2);
+ misceffect FX_HUG, strcharinfo(0);
+ if (@target_id != BL_ID) misceffect FX_HUG, @target_id;
+
+ if (@target_id != .tree_id) end;
+ @flag = 2;
+ callfunc "QuestTreeTrigger";
+ close;
+
+OnInit:
+ .tree_id = getnpcid("#DruidTree0#_M");
+ registercmd "*hugs", strnpcinfo(0); // eq: /me hugs (target)
+ registercmd "*hugs*", strnpcinfo(0); // eq: /me hugs
+ end;
+}
diff --git a/npc/commands/marry.txt b/npc/commands/marry.txt
new file mode 100755
index 00000000..ad2ed5fc
--- /dev/null
+++ b/npc/commands/marry.txt
@@ -0,0 +1,68 @@
+- script special-marry NPC32767,{
+ .@target_id = getcharid(3, @args$);
+ if (.@target_id < 1 || !(isloggedin(.@target_id)) || .@target_id == BL_ID) goto L_NotFound;
+ if (PARTNER || get(PARTNER, .@target_id)) goto L_AlreadyMarried;
+ if (isin("014-1",29,36,34,39) == 0 && isin("001-1",20,27,22,27) == 0) goto L_NotInArea;
+ if (distance(BL_ID, .@target_id) != 1) goto L_AwayFromPartner;
+ if (BaseLevel < WEDDING_MIN_LEVEL || get(BaseLevel, .@target_id) < WEDDING_MIN_LEVEL) goto L_TooYoung;
+ if (getequipid(equip_shield) != 702 || getequipid(equip_shield, @args$) != 702) goto L_NoRing;
+
+ if (get(@marriage[0], .@target_id) == BL_ID) goto L_Proceed;
+
+ setarray @marriage[0], .@target_id, gettimetick(2);
+ addtimer (.timeout * 1000), strnpcinfo(0) + "::OnTimeout";
+ announce strcharinfo(0) + " is asking " + strcharinfo(0, .@target_id) + " for marriage.", 2;
+ message strcharinfo(0, .@target_id), "Marriage : ##3##B" + strcharinfo(0) + " wishes to marry you. To accept, write `##1#marry "+strcharinfo(0)+"##3` within the next "+.timeout+" seconds.";
+ end;
+
+L_NotFound:
+ message strcharinfo(0), "Marriage : ##3##BThe target player is either not found or yourself.";
+ end;
+
+L_TooYoung:
+ message strcharinfo(0), "Marriage : ##3##BYou and your partner need to be at least level "+ WEDDING_MIN_LEVEL +".";
+ end;
+
+L_NoRing:
+ message strcharinfo(0), "Marriage : ##3##BYou and your partner need to have ["+ getitemlink("WeddingRing") +"] equipped.";
+ end;
+
+L_AwayFromPartner:
+ message strcharinfo(0), "Marriage : ##3##BYou and your partner need to be standing next to each other.";
+ end;
+
+L_NotInArea:
+ message strcharinfo(0), "Marriage : ##3##BYou are not standing in a designated marriage area.";
+ end;
+
+L_Proceed:
+ if ((gettimetick(2) - .timeout) > get(@marriage[1], .@target_id)) goto L_TooLate;
+ PARTNER = CHAR_ID, .@target_id;
+ if (PARTNER == get(CHAR_ID, .@target_id)) goto L_Success;
+ PARTNER = 0, .@target_id;
+ PARTNER = 0;
+ end;
+
+L_Success:
+ announce strcharinfo(0) + " and " + strcharinfo(0, .@target_id) + " are now married.", 2;
+ end;
+
+OnTimeout:
+ goto L_TooLate;
+
+L_TooLate:
+ message strcharinfo(0), "Marriage : ##3##BThe proposal expired. Please try again.";
+ message strcharinfo(0, @marriage[0]), "Marriage : ##3##BThe proposal expired. Please try again.";
+ @marriage[0] = 0, @marriage[0];
+ @marriage[0] = 0;
+ end;
+
+L_AlreadyMarried:
+ message strcharinfo(0), "Marriage : ##3##BYou"+ if_then_else(PARTNER, " are", "r partner is") +" already married.";
+ end;
+
+OnInit:
+ set .timeout, 30; // timeout for proposal
+ registercmd "#marry", strnpcinfo(0); // we NEED to use a # before `marry` because otherwise manaplus does not strip colors
+ end;
+}
diff --git a/npc/commands/mobinfo.txt b/npc/commands/mobinfo.txt
deleted file mode 100644
index 691bfb68..00000000
--- a/npc/commands/mobinfo.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-// The Mana World Script
-//
-// @monsterinfo <monsterAegis>
-// Sends @mobinfo with a delay (moved from atcommand.conf)
-// Requires EVOL_MONSTER_IDENTIFY
-//
-- script @monsterinfo 32767,{
- end;
-
-OnCall:
- // Check for skill level
- if (!getskilllv(EVOL_MONSTER_IDENTIFY))
- end;
-
- // ...
- if (@rsync_delay > gettimetick(2)) {
- dispbottom l("Not doing that to prevent flood.");
- end;
- }
-
- // Send @mobinfo and set a cooldown of 3 seconds.
- atcommand("@mobinfo " + implode(.@atcmd_parameters$, " "));
- @rsync_delay=gettimetick(2)+3;
- end;
-
-OnInit:
- bindatcmd "monsterinfo", "@monsterinfo::OnCall", 0, 60, 0;
- end;
-}
diff --git a/npc/commands/motd.txt b/npc/commands/motd.txt
deleted file mode 100644
index 2f6a5e2a..00000000
--- a/npc/commands/motd.txt
+++ /dev/null
@@ -1,194 +0,0 @@
-function script displayMOTD {
- .@size = getvariableofnpc(.size, "@motd");
- .@dsize = getvariableofnpc(.dsize, "@motd");
-
- // git stuff and such
- if (debug)
- {
- for (.@i = 0; .@i < .@dsize; ++.@i)
- {
- dispbottom $@Debug_Messages$[.@i]; // FIXME: send this to the Debug tab instead
- }
-
- if (.@dsize > 0)
- dispbottom "---";
- }
-
- // generic MOTD
- for (.@i = 0; .@i < .@size; ++.@i)
- {
- dispbottom $MOTD_Messages$[.@i];
- }
-
- return;
-}
-
-function script MOTDConfig {
-
- function toggleMOTD {
- $MOTD_Disabled = !($MOTD_Disabled);
- // FIXME: log to GM log
- }
-
- function addNewLine {
- clear;
- mes l("Please enter the new line.");
- input .@s$;
- .@s$ = strip(.@s$);
- if (.@s$ != "")
- {
- .@size = getvariableofnpc(.size, "@motd");
- $MOTD_Messages$[.@size] = .@s$;
- set getvariableofnpc(.size, "@motd"), getarraysize($MOTD_Messages$);
- // FIXME: log to GM log
- }
- }
-
- function modifyLine {
-
- function removeLine {
- .@l = getarg(0);
- deletearray $MOTD_Messages$[.@l], 1; // remove and shift
- mes l("Line @@ has been removed.", .@l);
- set getvariableofnpc(.size, "@motd"), getarraysize($MOTD_Messages$);
- // FIXME: log to GM log
- }
-
- function moveUp {
- .@l = getarg(0);
- .@top$ = $MOTD_Messages$[.@l - 1];
- $MOTD_Messages$[.@l - 1] = $MOTD_Messages$[.@l];
- $MOTD_Messages$[.@l] = .@top$;
- }
-
- function moveDown {
- .@l = getarg(0);
- .@bottom$ = $MOTD_Messages$[.@l + 1];
- $MOTD_Messages$[.@l + 1] = $MOTD_Messages$[.@l];
- $MOTD_Messages$[.@l] = .@bottom$;
- }
-
- function editLine {
- .@l = getarg(0);
- clear;
- mes l("Old line:");
- mes "---";
- mes $MOTD_Messages$[.@l];
- mes "---";
- mes "";
- mes l("Enter new line:");
- next;
- input .@s$;
- .@s$ = strip(.@s$);
- if (.@s$ != "")
- {
- $MOTD_Messages$[.@l] = .@s$;
- // FIXME: log to GM log
- }
- }
-
- .@max = (getarg(0) - 1);
-
- do
- {
- mes l("Enter line number:");
- next;
- input .@n;
- if ($MOTD_Messages$[.@n] != "")
- {
- clear;
- mes l("line @@: @@", .@n, $MOTD_Messages$[.@n]);
- next;
- select
- menuimage("actions/back", l("Modify another line")),
- menuimage("actions/remove", l("Remove this line")),
- menuimage("actions/edit", l("Modify this line")),
- rif(.@n > 0, menuimage("actions/raise", l("Move this line up"))),
- rif(.@n < .@max, menuimage("actions/lower", l("Move this line down"))),
- menuimage("actions/home", l("Return to main menu"));
-
- switch (@menu)
- {
- case 2: removeLine .@n; return;
- case 3: editLine .@n; return;
- case 4: moveUp .@n; return;
- case 5: moveDown .@n; return;
- case 6: return;
- }
- }
- } while (1);
- }
-
- do
- {
- clear;
- setnpcdialogtitle l("MOTD Config");
- mes l("This menu allows you to modify the generic message that is sent to players when they log in.");
- mes "";
-
- mes "---";
- .@size = getvariableofnpc(.size, "@motd");
- for (.@i = 0; .@i < .@size; ++.@i)
- {
- mes l("line @@: @@", .@i, $MOTD_Messages$[.@i]);
- }
- if (.@size == 0)
- {
- mes "(" + l("no active MOTD") + ")";
- }
- mes "---";
- .@d = $MOTD_Disabled;
- mes l("Enabled: @@", (.@d ? l("no") : l("yes")));
- next;
-
- select
- menuimage("actions/toggle", (.@d ? l("Enable") : l("Disable"))),
- menuimage("actions/add", l("Add a new line")),
- rif(.@size, menuimage("actions/manage", l("Modify, move, or remove a line"))),
- rif(.@size, menuimage("actions/test", l("Test MOTD"))),
- rif(getarg(0,0), menuimage("actions/home", l("Return to Super Menu")));
-
- switch (@menu)
- {
- case 1: toggleMOTD; break;
- case 2: addNewLine; break;
- case 3: modifyLine .@size; break;
- case 4: displayMOTD; break;
- default: return;
- }
- } while (1);
-}
-
-
-
-- script @motd 32767,{
- end;
-
-OnCall:
- if (!is_dev())
- {
- end;
- }
-
- MOTDConfig;
- closeclientdialog;
- end;
-
-OnInit:
- MOTD_debug_text;
- .size = getarraysize($MOTD_Messages$);
- .dsize = getarraysize($@Debug_Messages$);
- bindatcmd "motd", "@motd::OnCall", 0, 99, 0;
-}
-
-function script ReceiveMOTD {
- if ($MOTD_Disabled < 1)
- {
- displayMOTD;
- }
- if (debug)
- {
- dispbottom "##7<<##B @@help://test-server|" + col(l("Click here for instructions on how to use the test server."),6) + "@@ ##7>>";
- }
- return;
-}
diff --git a/npc/commands/music.txt b/npc/commands/music.txt
index b817b949..5c62f008 100644..100755
--- a/npc/commands/music.txt
+++ b/npc/commands/music.txt
@@ -1,75 +1,33 @@
-// @music atcommand
-// changes the music for all players on the map
-//
-// group lv: 2
-// group char lv: 99
-// log: True
-//
-// usage:
-// @music <short name>
-//
-// example:
-// @music fun
-
-- script @music 32767,{
+- script @music NPC32767,{
+ callfunc "argv_splitter";
+ if (GM < CMD_MUSIC && GM < G_SYSOP) goto L_GM;
+ if (@argv$[0] == "") goto L_Failed;
+
+ gmlog "@music " + @args$;
+ .@find = array_search(@argv$[0], .find$);
+ if (.@find >= 0)
+ @argv$[0] = .replace$[max(.@find, 0)];
+ .file$ = @argv$[0];
+ areatimer 0, getmapname(), (POS_X - .range), (POS_Y - .range), (POS_X + .range), (POS_Y + .range), 0, strnpcinfo(0)+"::OnPC";
+ message strcharinfo(0), "music : The music has ben temporarily changed.";
end;
-OnCall:
- if (!is_evtc())
- {
- end;
- }
-
- // TODO: tmw-like argv splitter
- .@map$ = getmap();
-
- .@m$ = strtolower(.@atcmd_parameters$[0]);
-
- // GMs might not know and want a list of musics
- if (.@m$ == "" || .@m$ == "list") {
- .@r$="list";
-
- freeloop(true);
- .@size=getarraysize($MUSIC_ARRAY$);
- for (.@i = 0; .@i < .@size; ++.@i) {
- .@r$+=", "+$MUSIC_ARRAY$[.@i];
- }
- freeloop(false);
-
- dispbottom("Music list: "+.@r$);
- end;
- }
-
- .@key = array_exists($MUSIC_ARRAY$, .@m$);
-
- if (!.@key)
- {
- //.@m$ = implode(.@atcmd_parameters$[0], " ");
- message(getcharid(CHAR_ID_ACCOUNT), sprintf("Can't broadcast: %s.ogg", .@m$));
- } else {
- message(getcharid(CHAR_ID_ACCOUNT), sprintf("Now broadcasting: %s", .@m$));
- changemusic .@map$, .@m$ + ".ogg";
- }
+OnPC:
+ music .file$ + ".ogg";
end;
-OnMyself:
- .@m$ = strtolower(.@atcmd_parameters$[0]);
- .@key = array_exists($MUSIC_ARRAY$, .@m$);
-
- // TODO: Check if you have the music unlocked? Bitmask? Array?
+L_Failed:
+ message strcharinfo(0), "music : You must specify a music file.";
+ end;
- if (!.@key)
- {
- //.@m$ = implode(.@atcmd_parameters$[0], " ");
- message(getcharid(CHAR_ID_ACCOUNT), sprintf("Can't play: %s.ogg", .@m$));
- } else {
- message(getcharid(CHAR_ID_ACCOUNT), sprintf("Now playing: %s", .@m$));
- changeplayermusic .@m$ + ".ogg";
- }
+L_GM:
+ message strcharinfo(0), "music : GM command is level "+ CMD_MUSIC +", but you are level " + GM;
end;
OnInit:
- bindatcmd "music", "@music::OnCall", 0, 99, 1;
- bindatcmd "jukebox", "@music::OnMyself", 0, 50, 0;
+ setarray .find$, "this", "cave", "chilling", "clouds", "dimond", "explorers", "gy", "reid", "magick", "mystique", "night", "ride", "sail", "snow", "forest", "xmas";
+ setarray .replace$, "this", "cavesong", "chilling-environment", "clouds-calling", "dimonds-cove", "explorers-melody", "graveyard", "inquisitive-inn", "magick-real", "mystique-forest", "night-is-calling", "ride-of-the-valkyries", "sail-away", "snow-village", "the-forest", "white-christmas";
+ set .range, 14; // FIXME: make this a const
+ registercmd chr(ATCMD_SYMBOL) + "music", strnpcinfo(0);
end;
}
diff --git a/npc/commands/mute.txt b/npc/commands/mute.txt
new file mode 100755
index 00000000..555fa724
--- /dev/null
+++ b/npc/commands/mute.txt
@@ -0,0 +1,92 @@
+- script @mute NPC32767,{
+ callfunc "argv_splitter";
+ if (GM < CMD_MUTE && GM < G_SYSOP) goto L_GM;
+ if (@argv$[1] == "") goto L_Failed;
+
+ .@target_id = getcharid(3, @argv$[1]);
+ if (.@target_id < 1 || !(isloggedin(.@target_id))) goto L_Failed;
+
+ if (@argv[0] > 120)
+ set @argv[0], 120; // max 2 hours
+
+ gmlog "@mute " + @args$;
+ if (@argv[0] == 0) goto L_UnMute;
+
+ message strcharinfo(0, .@target_id), "Server : ##BYou have been muted by a GM for "+@argv[0]+" minutes.";
+ MUTE_GLOBAL = 1, .@target_id;
+ #MUTE_UNTIL = (gettimetick(2) + (@argv[0] * 60)), .@target_id;
+ addtimer (@argv[0] * 60000) + 100, strnpcinfo(0) + "::OnCheckMute", .@target_id;
+ message strcharinfo(0), "mute : Player `"+strcharinfo(0, .@target_id)+"` has been muted for "+@argv[0]+" minutes.";
+ end;
+
+OnSTFU:
+ if (GM < CMD_MUTE && GM < G_SYSOP) goto L_GM;
+ callfunc "argv_splitter";
+ if (@argv[0] < 1) set @argv[0], 1;
+ if (@argv[0] > 10) set @argv[0], 10;
+ gmlog "@stfu " + @argv[0];
+ @stfu_nr = 0;
+ foreach 0, getmapname(), (POS_X - .range), (POS_Y - .range), (POS_X + .range), (POS_Y + .range), strnpcinfo(0)+"::OnSTFUPC";
+ message strcharinfo(0), "mute : Every player within "+.range+" tiles have been muted for "+@argv[0]+" minutes. ["+@stfu_nr+"]";
+ @stfu_nr = 0;
+ end;
+
+OnSTFUPC:
+ if (@target_id == BL_ID) end;
+ .@future = (gettimetick(2) + (@argv[0] * 60));
+ if (get(#MUTE_UNTIL, @target_id) > .@future) end; // if player already has a mute, don't reduce it
+ MUTE_GLOBAL = 1, @target_id;
+ #MUTE_UNTIL = .@future, @target_id;
+ addtimer (@argv[0] * 60000) + 100, strnpcinfo(0) + "::OnCheckMute", @target_id;
+ @stfu_nr = @stfu_nr + 1;
+ end;
+
+OnPCLoginEvent:
+ if (#MUTE_UNTIL < 1) end;
+ .@s = (#MUTE_UNTIL - gettimetick(2));
+ if (.@s < 5) goto L_ClearMute;
+ .@m = .@s / 60;
+ message strcharinfo(0), "Server : ##BYou have been muted for "+ max(1, .@m) +" minutes.";
+ MUTE_GLOBAL = 1;
+ addtimer (.@s * 1000) + 100, strnpcinfo(0) + "::OnCheckMute";
+ end;
+
+L_ClearMute:
+ message strcharinfo(0), "Server : ##BYour mute has expired while you were away. You have been automatically unmuted.";
+ if ((#MUTE_UNTIL - gettimetick(2)) >= (0 - 900))
+ wgm "=> Player `"+ strcharinfo(0) +"` has been automatically unmuted."; // only send if unmuted 15 minutes ago or less
+ #MUTE_UNTIL = 0;
+ end;
+
+OnCheckMute:
+ if (#MUTE_UNTIL < 1) end;
+ if (gettimetick(2) - #MUTE_UNTIL < 0) end;
+ message strcharinfo(0), "Server : ##BYou have been automatically unmuted.";
+ wgm "=> Player `"+ strcharinfo(0) +"` has been automatically unmuted.";
+ MUTE_GLOBAL = 0;
+ #MUTE_UNTIL = 0;
+ end;
+
+L_UnMute:
+ if (get(MUTE_GLOBAL, .@target_id))
+ message strcharinfo(0, .@target_id), "Server : ##BYou have been unmuted by a GM.";
+ MUTE_GLOBAL = 0, .@target_id;
+ #MUTE_UNTIL = 0, .@target_id;
+ message strcharinfo(0), "mute : Player `"+strcharinfo(0, .@target_id)+"` has been unmuted.";
+ end;
+
+L_Failed:
+ message strcharinfo(0), "mute : Impossible to attach to the target player. Did you try putting the name in \"quotation marks\"?";
+ end;
+
+L_GM:
+ message strcharinfo(0), "mute : GM command is level "+ CMD_MUTE +", but you are level " + GM;
+ end;
+
+OnInit:
+ set .range, 14; // FIXME: this should be a const
+ registercmd chr(ATCMD_SYMBOL) + "mute", strnpcinfo(0);
+ registercmd chr(ATCMD_SYMBOL) + "stfu", strnpcinfo(0) + "::OnSTFU";
+ registercmd chr(ATCMD_SYMBOL) + "areamute", strnpcinfo(0) + "::OnSTFU"; // alias of STFU
+ end;
+}
diff --git a/npc/commands/npctalk.txt b/npc/commands/npctalk.txt
new file mode 100755
index 00000000..b1179dc6
--- /dev/null
+++ b/npc/commands/npctalk.txt
@@ -0,0 +1,22 @@
+- script @npctalk NPC32767,{
+ callfunc "argv_splitter";
+ if (GM < CMD_NPCTALK && GM < G_SYSOP) goto L_GM;
+ if (@argv$[0] == "" || @argv$[1] == "") goto L_Failed;
+ if (getnpcid(@argv$[0]) < 1) goto L_Failed;
+
+ gmlog "@npctalk " + @args$;
+ npctalk @argv$[0], @argv$[1];
+ end;
+
+L_Failed:
+ message strcharinfo(0), "npctalk : Impossible to attach to the target npc. Did you try putting the name in \"quotation marks\"?";
+ end;
+
+L_GM:
+ message strcharinfo(0), "npctalk : GM command is level "+ CMD_NPCTALK +", but you are level " + GM;
+ end;
+
+OnInit:
+ registercmd chr(ATCMD_SYMBOL) + "npctalk", strnpcinfo(0);
+ end;
+}
diff --git a/npc/commands/numa.txt b/npc/commands/numa.txt
new file mode 100755
index 00000000..207ec032
--- /dev/null
+++ b/npc/commands/numa.txt
@@ -0,0 +1,127 @@
+
+- script SuperDebug NPC32767,{
+ if (GM < MAP_LOUNGE && GM < G_SYSOP && !debug) goto L_GM2; // make sure you can enter the gm lounge
+ if (target(BL_ID,getnpcid("Numa"),1)) goto L_Main;
+ npcaction 6, 12;
+ title "Numa";
+ goto L_Main;
+
+L_GM2:
+ message strcharinfo(0), "numa : GM command is level "+ MAP_LOUNGE +", but you are level " + GM;
+ end;
+
+L_Main:
+ mes "How may I help you?";
+ next;
+ menu
+ "Announcements", L_StoneBoard,
+ "MOTD", L_MOTD,
+ "Holiday debug", L_Holiday,
+ "Event debug", L_Event,
+ "Quest debug", L_Quest,
+ "Who are you?", L_WhoAmI,
+ "Close", L_close;
+ // todo: generic npcs
+ // todo: map list
+
+L_WhoAmI:
+ mes "I am Numa, also known as `SuperDebug`.";
+ mes "My sole purpose is to assist TMW staff from behind-the-scene.";
+ mes "Using me, you can access several debug menus.";
+ mes "You can call me from anywhere using the ##B@numa##b spell, or you can come see me in person.";
+ next;
+ goto L_Main;
+
+L_Holiday:
+ if (GM < DBG_HOLIDAY && GM < G_SYSOP) goto L_GM;
+ mes "What holiday do you want to debug?";
+ next;
+ menu
+ "Xmas.", L_XmasDebug,
+ "Halloween.", L_HalloweenDebug,
+ "Easter.", L_EasterDebug;
+
+L_XmasDebug:
+ gmlog strcharinfo(0) + " accessed the Xmas debug.";
+ callfunc "XmasDebug";
+ goto L_close;
+
+L_HalloweenDebug:
+ gmlog strcharinfo(0) + " accessed the Halloween debug.";
+ callfunc "HalloweenDebug";
+ goto L_close;
+
+L_EasterDebug:
+ gmlog strcharinfo(0) + " accessed the Easter debug.";
+ callfunc "Easter Debug";
+ goto L_close;
+
+L_Event:
+ if (GM < EVT_DEBUG && GM < G_EVENT) goto L_GM;
+ gmlog strcharinfo(0) + " accessed the GM event debug.";
+ callfunc "GmDebug";
+ goto L_close;
+
+L_StoneBoard:
+ if (GM < DBG_SCHEDULED && GM < G_SYSOP) goto L_GM;
+ callfunc "SBConfig";
+ goto L_close;
+
+L_MOTD:
+ if (GM < DBG_MOTD && GM < G_SYSOP) goto L_GM;
+ callfunc "MOTDConfig";
+ goto L_close;
+
+L_GM:
+ mes "I'm awfully sorry.";
+ mes "You do not have the required GM level to perform this action.";
+ goto L_close;
+
+L_Quest:
+ callfunc "QuestDebug";
+ goto L_close;
+
+L_close:
+ close;
+
+OnInit:
+ registercmd chr(ATCMD_SYMBOL) + "numa", strnpcinfo(0);
+ registercmd chr(ATCMD_SYMBOL) + "superdebug", strnpcinfo(0);
+ if (puppet("017-9", 30, 28, "Numa", 393) < 1) mapexit;
+ end;
+}
+
+function script QuestDebug {
+ goto L_ChooseContinent;
+
+L_ChooseContinent:
+ mes "Choose a continent.";
+ next;
+ menu
+ "Argeas", L_Argeas,
+ "Close", L_Return;
+
+L_Argeas:
+ mes "Choose an area.";
+ next;
+ menu
+ "Woodland", L_Woodland,
+ "Choose a continent", L_ChooseContinent,
+ "Close", L_Return;
+
+L_Woodland:
+ mes "Choose a quest.";
+ next;
+ menu
+ "Illia Sisters", L_Valia,
+ "Choose an area", L_Argeas,
+ "Close", L_Return;
+
+L_Return:
+ return;
+
+
+L_Valia:
+ callfunc "IlliaDebug";
+ goto L_Return;
+}
diff --git a/npc/commands/pullrabbit.txt b/npc/commands/pullrabbit.txt
new file mode 100755
index 00000000..8ca0a69a
--- /dev/null
+++ b/npc/commands/pullrabbit.txt
@@ -0,0 +1,25 @@
+- script @pullrabbit NPC32767,{
+ if (GM < EVT_KILLTHEGM && GM < G_SYSOP) end;
+ if (getequipid(equip_head) != 888) end;
+ getinventorylist;
+ if ((checkweight("MurdererCrown", 1) == 0) || (@inventorylist_count == 100))
+ goto L_Inventory;
+ // Get the current reward of the event. This may be changed later
+ getitem "MurdererCrown", 1;
+ // Set HP and SP to max
+ heal MaxHp, MaxSp;
+ // Display an effect
+ misceffect FX_CHANNELLING_CAST, strcharinfo(0);
+ // Log the usage of this spell
+ gmlog strcharinfo(0)+" used the Magic GM Top Hat.";
+ end;
+
+L_Inventory:
+ message strcharinfo(0), "You cannot create this item. You're too heavy or you don't have a free slot.";
+ end;
+
+OnInit:
+ registercmd chr(ATCMD_SYMBOL) + "pullrabbit", strnpcinfo(0);
+ registercmd chr(MAGIC_SYMBOL) + "pullrabbit", strnpcinfo(0); // former pullrabbit invocation
+ end;
+}
diff --git a/npc/commands/python.txt b/npc/commands/python.txt
deleted file mode 100644
index e2fdc5bf..00000000
--- a/npc/commands/python.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-// The Mana World script
-// Author: Gumi <gumi@themanaworld.org>
-// Author: Jesusalva <jesusalva@themanaworld.org>
-//
-// Stomp stomp stomp (use with caution)
-
-- script @python 32767,{
- end;
-
-// Soft Resync
-OnCall:
- specialeffect(69, AREA, playerattached());
- addtimer 380, .name$+"::OnKill";
- end;
-
-OnKill:
- percentheal -100, -100;
- //dispbottom l("Oh look, it is Cupid!");
- end;
-
-OnInit:
- bindatcmd "python", "@python::OnCall", 20, 20, 1;
- end;
-}
diff --git a/npc/commands/rate-management.txt b/npc/commands/rate-management.txt
deleted file mode 100644
index 995ef940..00000000
--- a/npc/commands/rate-management.txt
+++ /dev/null
@@ -1,107 +0,0 @@
-- script @exprate 32767,{
- end;
-
- function rateCleanUp {
- stopnpctimer;
- .hours = 0;
- .max_hours = 0;
- .current_rate = .original_exp_rate;
- setbattleflag("base_exp_rate", .original_exp_rate);
- setbattleflag("quest_exp_rate", .original_quest_rate);
- charcommand("@reloadmobdb"); // this is on purpose (callable without RID)
- charcommand("@reloadquestdb");
- }
-
- function remainingTime {
- .@total_seconds = (3600 * .max_hours);
- .@seconds_elapsed = (3600 * .hours) + (getnpctimer(0) / 1000);
- .@seconds_remaining = max(1, .@total_seconds - .@seconds_elapsed);
- return FuzzyTime(time_from_seconds(.@seconds_remaining), 2, 2);
- }
-
-OnCall:
- if (!is_evtc())
- {
- end;
- }
-
- .@special$ = strip(.@atcmd_parameters$[0]); // special value
- .@new_rate = min(atoi(.@special$), 1000); // or just a regular integer
- .@hours = min(0x7FFFFFFE, max(1, atoi(strip(.@atcmd_parameters$[1])))); // number of hours
-
- if (.@new_rate > 0)
- {
- // set new exp rate
- .hours = 0;
- .max_hours = .@hours;
- .current_rate = .@new_rate;
- setbattleflag("base_exp_rate", .@new_rate);
- setbattleflag("quest_exp_rate", .@new_rate);
- charcommand("@reloadmobdb");
- charcommand("@reloadquestdb");
- initnpctimer; // start counting
-
- dispbottom l("You successfully set the exp rate to @@%. It will reset to @@% (default value) in @@.",
- .@new_rate, .original_exp_rate, FuzzyTime(time_from_hours(.max_hours), 2, 2));
- dispbottom l("You can also manually stop it at any time with: @exprate default");
- }
-
- else if (.@new_rate == 0 && .@special$ == "")
- {
- // get current exp rate
- if (.current_rate == .original_exp_rate)
- {
- dispbottom l("Current exp rate is set to @@% (default value).", .current_rate);
- }
-
- else
- {
- dispbottom l("Current exp rate is set to @@%, and will reset to @@% (default value) in @@.",
- .current_rate, .original_exp_rate, remainingTime());
-
- dispbottom l("If you meant to reset the exp rate to its default value: @exprate default");
- }
- }
-
- else
- {
- // reset
- rateCleanUp;
- dispbottom l("Exp rate has been reset to @@% (default value).",
- .original_exp_rate);
- }
-
- end;
-
-OnTimer3600000:
- // runs every hour
- if (++.hours == .max_hours)
- {
- rateCleanUp;
- end;
- }
- initnpctimer;
- end;
-
-OnPCLoginEvent:
- if (.max_hours > 0)
- {
- dispbottom col(l("Exp rate is set to @@% for the next @@.",
- .current_rate, remainingTime()), 6);
- }
- end;
-
-OnInit:
- bindatcmd "exprate", "@exprate::OnCall", 0, 99, 1; // change exp rate
-
- // WARNING: using @reloadscript will change the "original" value
- .original_exp_rate = getbattleflag("base_exp_rate");
- .original_quest_rate = getbattleflag("quest_exp_rate");
- .current_rate = .original_exp_rate;
-
- // XXX: maybe in the future:
- //.original_item_rate = getbattleflag("item_rate_common");
- //.original_job_rate = getbattleflag("base_job_rate");
- //.original_pk_mode = getbattleflag("pk_mode");
- //.original_death_penalty = getbattleflag("death_penalty_type");
-}
diff --git a/npc/commands/remotecmd.txt b/npc/commands/remotecmd.txt
new file mode 100755
index 00000000..20f33f8c
--- /dev/null
+++ b/npc/commands/remotecmd.txt
@@ -0,0 +1,61 @@
+- script @remotecmd NPC32767,{
+ callfunc "argv_splitter";
+ if (GM < CMD_REMOTECMD && GM < G_SYSOP) goto L_GM; // check if you can use it on self
+ .@target_id = BL_ID;
+ .@t$ = @argv$[1];
+ setarray @remotecmd[0], 0, 1, 1; // nr, to_self, multi_target
+ if (.@t$ == "map") goto L_Map;
+ if (.@t$ == "map!") goto L_AllMap;
+ if (.@t$ == "area") goto L_Area;
+ if (.@t$ == "area!") goto L_AllArea;
+ if (.@t$ != "") set .@target_id, getcharid(3, @argv$[1]);
+ if (.@t$ != "" && !(isloggedin(.@target_id))) goto L_Failed; // do NOT fallback to self
+
+ @target_id = .@target_id;
+ set @remotecmd[2], 0; // only one target
+ addtimer 0, strnpcinfo(0) + "::OnPC";
+ end;
+
+L_Map:
+ set @remotecmd[1], 0; // do not include self
+ goto L_AllMap;
+
+L_AllMap:
+ foreach 0, getmapname(), 0, 0, 32767, 32767, strnpcinfo(0)+"::OnPC";
+ goto L_Success;
+
+L_Area:
+ set @remotecmd[1], 0; // do not include self
+ goto L_AllMap;
+
+L_AllArea:
+ foreach 0, getmapname(), (POS_X - .range), (POS_Y - .range), (POS_X + .range), (POS_Y + .range), strnpcinfo(0)+"::OnPC";
+ goto L_Success;
+
+OnPC:
+ if (@target_id == BL_ID && @remotecmd[1] < 1)
+ end;
+ remotecmd @argv$[0], strcharinfo(0, @target_id);
+ @remotecmd[0] = @remotecmd[0] + 1;
+ if (@remotecmd[2] < 1)
+ goto L_Success;
+ end;
+
+L_Success:
+ gmlog "@remotecmd " + @args$;
+ message strcharinfo(0), "remotecmd : The operation succeeded. ["+ @remotecmd[0] + "]";
+ end;
+
+L_Failed:
+ message strcharinfo(0), "remotecmd : Impossible to attach to the target player. Did you try putting the name in \"quotation marks\"?";
+ end;
+
+L_GM:
+ message strcharinfo(0), "remotecmd : GM command is level "+ CMD_REMOTECMD +", but you are level " + GM;
+ end;
+
+OnInit:
+ set .range, 14; // visible range
+ registercmd chr(ATCMD_SYMBOL) + "remotecmd", strnpcinfo(0);
+ end;
+}
diff --git a/npc/commands/resync.txt b/npc/commands/resync.txt
deleted file mode 100644
index a535a343..00000000
--- a/npc/commands/resync.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-// Evol script
-// Author: Jesusalva <admin@tmw2.org>
-//
-// Introduces @resync
-//
-// It'll cast slide to your own position
-// Hopefully making client update your real position without causing server warning
-
-- script @resync 32767,{
- end;
-
-// Soft Resync
-OnCall:
- // Sliding a dead player have undesired side effects
- if (ispcdead()) {
- dispbottom l("Impossible to resync: You are dead.");
- end;
- }
- // I add a small delay in case slide() trigger some invincibility timer or something
- if (@rsync_delay > gettimetick(2)) {
- dispbottom l("Not resync'ing to prevent flood.");
- end;
- }
-
- // This is a hack
- getmapxy(.@m$, .@x, .@y, 0);
- slide .@x, .@y;
- @rsync_delay=gettimetick(2)+rand(4,6);
-
- // Uncomment this line to cause server to resend every packet to ManaPlus
- // and get rid of latency effect (like dead mobs still being shown)
- //atcommand("@refresh");
- end;
-
-// Anyone can call @resync, but only support and upwards for other players.
-// ie. GMs can try to fix lag for other people.
-OnInit:
- bindatcmd "resync", "@resync::OnCall", 0, 20, 0;
- end;
-}
diff --git a/npc/commands/scheduled-broadcasts.txt b/npc/commands/scheduled-broadcasts.txt
deleted file mode 100644
index 8699c581..00000000
--- a/npc/commands/scheduled-broadcasts.txt
+++ /dev/null
@@ -1,227 +0,0 @@
-function script StoneBoard {
-
- function setMessage {
- do
- {
- clear;
- mes l("Please enter the message:");
- next;
- input .@msg$;
- .@msg$ = strip(.@msg$);
- if (.@msg$ != "")
- {
- return .@msg$;
- }
- mes l("The message cannot be empty");
- next;
- } while (1);
- }
-
- function setInterval {
- clear;
- mes l("Please select the interval:");
- next;
- menuint
- l("Every 1 hour"), 1,
- l("Every 3 hours"), 3,
- l("Every 5 hours"), 5,
- l("Every 6 hours"), 6,
- l("Every 12 hours"), 12,
- l("Every 24 hours"), 24,
- l("Never (only on login)"), 0;
-
- return @menuret;
- }
-
- function setMaxRep {
- if (getarg(0,0) == 0)
- {
- return 0;
- }
- clear;
- mes l("Repeat how many times?");
- next;
- menuint
- l("Send only once"), 1,
- l("Send 2 times"), 2,
- l("Send 3 times"), 3,
- l("Send 5 times"), 5,
- l("Send 10 times"), 10,
- l("Send 20 times"), 20,
- l("Send indefinitely"), 0;
-
- return @menuret;
- }
-
- function setOnLogin {
- if (getarg(0,0) == 0)
- {
- return 1;
- }
- clear;
- mes l("Send this message also on login?");
- next;
- select
- l("No"),
- l("Yes");
-
- return (@menu - 1);
- }
-
- function newBroadcast {
- do
- {
- setnpcdialogtitle l("Scheduled broadcasts - Create new");
-
- // go through all steps
- .@msg$ = setMessage();
- .@int = setInterval();
- .@max = setMaxRep(.@int);
- .@login = setOnLogin(.@int);
-
- // recap
- clear;
- mes l("Message:");
- mes "---";
- mes .@msg$;
- mes "---";
- if (.@int)
- {
- mes l("Interval: every @@ hour(s)", .@int);
- mes l("Repeat: @@ times", .@max ? .@max : "∞");
- mes l("Sent on login: @@", .@login ? l("yes") : l("no"));
- }
- else
- {
- mes l("Interval: (none, only sent on login)");
- mes l("Sent on login: yes");
- }
-
- next;
- select
- menuimage("actions/cancel", l("Discard")),
- menuimage("actions/edit", l("Start over")),
- menuimage("actions/test", l("Start broadcasting")),
- menuimage("actions/test", l("Start broadcasting, and make an extra broadcast right now"));
-
- switch (@menu)
- {
- case 3:
- case 4:
- stopnpctimer "@sched";
- $@SCHED_Opt[0] = .@login;
- $@SCHED_Opt[1] = .@int;
- $@SCHED_Opt[2] = 0;
- $@SCHED_Opt[3] = .@max;
- $@SCHED_Opt[4] = 0;
- $@SCHED_Msg$ = .@msg$;
- if (.@int)
- {
- initnpctimer "@sched";
- }
- if (@menu == 4)
- {
- announce $@SCHED_Msg$, bc_all;
- }
- case 1: return;
- }
-
- } while(1);
- }
-
- do
- {
- clear;
- setnpcdialogtitle l("Scheduled broadcasts");
- mes l("This menu allows you to set the scheduled broadcast that is sent to all players at a specific interval.");
- mes "";
-
- .@a = $@SCHED_Msg$ != ""; // any active broadcast?
- mes "---";
- mes .@a ? $@SCHED_Msg$ : "(" + l("no active broadcast") +")";
- mes "---";
- if (.@a)
- {
- mes l("Sent on login: @@", ($@SCHED_Opt[0] ? l("yes") : l("no")));
- if ($@SCHED_Opt[1])
- {
- .@next = max(1, ((3600000 * ($@SCHED_Opt[1] - $@SCHED_Opt[4])) - getnpctimer(0, "@sched")));
- mes l("Interval: every @@ hour(s)", $@SCHED_Opt[1]);
- mes l("Next broadcast: @@", FuzzyTime(time_from_ms(.@next), 0, 99));
- }
- else
- {
- mes l("Interval: (none, only sent on login)");
- mes l("Next broadcast: (never)");
- }
- mes l("Sent: @@ times out of @@", $@SCHED_Opt[2], ($@SCHED_Opt[3] ? $@SCHED_Opt[3] : "∞"));
- }
- next;
-
- select
- menuimage("actions/abort", l("Abort")),
- rif(.@a, menuimage("actions/test", l("Manually trigger the current broadcast"))),
- rif(.@a, menuimage("actions/remove", l("Stop broadcasting"))),
- rif(!(.@a), menuimage("actions/add", l("Set a new broadcast"))),
- rif(getarg(0,0), menuimage("actions/home", l("Return to Super Menu")));
-
- switch (@menu)
- {
- case 2: announce $@SCHED_Msg$, bc_all; break;
- case 3: $@SCHED_Msg$ = ""; break;
- case 4: newBroadcast; break;
- default: return;
- }
- } while (1);
-}
-
-
-
-- script @sched 32767,{
- end;
-
-OnTimer3600000:
- if ($@SCHED_Msg$ == "")
- {
- stopnpctimer;
- end;
- }
-
- ++$@SCHED_Opt[4]; // increase hours counter
- if ($@SCHED_Opt[4] == $@SCHED_Opt[1])
- {
- stopnpctimer;
- ++$@SCHED_Opt[2]; // increase total counter
- announce $@SCHED_Msg$, bc_all;
- $@SCHED_Opt[4] = 0; // reset hours counter
- if ($@SCHED_Opt[2] >= $@SCHED_Opt[3] && $@SCHED_Opt[3] > 0)
- {
- $@SCHED_Msg$ = ""; // reset message
- end;
- }
- }
- initnpctimer;
- end;
-
-OnCall:
- if (!is_evtc() && !is_dev())
- {
- end;
- }
-
- StoneBoard;
- closeclientdialog;
- end;
-
-OnInit:
- bindatcmd "sched", "@sched::OnCall", 0, 99, 0;
-}
-
-function script ReceiveScheduledBroadcast {
- if ($@SCHED_Opt[0] && $@SCHED_Msg$ != "")
- {
- announce $@SCHED_Msg$, bc_self;
- }
- return;
-}
-
diff --git a/npc/commands/super-menu.txt b/npc/commands/super-menu.txt
deleted file mode 100644
index 5ed7ced3..00000000
--- a/npc/commands/super-menu.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-function script SuperMenu {
- do
- {
- if (debug && !is_dev())
- {
- GlobalDebugMenu;
- return;
- }
-
- clear;
- setnpcdialogtitle l("Super Menu");
- mes l("This menu contains all options available to you, based on your access privileges.");
- mes "";
- mes l("What do you want to access?");
- next;
- select
- l("Scheduled broadcasts"),
- l("MOTD"),
- rif(is_evtc(), l("Event management")),
- l("Debug");
-
- switch (@menu)
- {
- case 1: StoneBoard 1; break;
- case 2: MOTDConfig 1; break;
- case 3: GlobalEventMenu 1; break;
- case 4: GlobalDebugMenu 1; break;
- }
- } while (1);
-}
-
-
-
-- script @super 32767,{
- end;
-
-OnCall:
-
- if (!debug && !is_dev())
- {
- dispbottom l("You do not have the required access privileges to use the Super Menu.");
- end;
- }
-
- SuperMenu;
- closeclientdialog;
- end;
-
-OnInit:
- bindatcmd "super", "@super::OnCall", 0, 99, 0;
- bindatcmd "numa", "@super::OnCall", 0, 99, 0; // alias for those used to TMW's @numa
-}
-
-function script GrantSuperSkill {
- .@debug_skill = getskilllv(EVOL_SUPER_MENU);
-
- if (.@debug_skill > 0 && !debug)
- {
- skill EVOL_SUPER_MENU, 0, 0; // remove debug skill. Not needed (skill tree)
- }
-
- else if (.@debug_skill < 1 && debug)
- {
- skill EVOL_SUPER_MENU, 1, 0; // give debug skill
- }
- return;
-}
-
diff --git a/npc/commands/warp.txt b/npc/commands/warp.txt
index 22eeda39..d2eee4e2 100644..100755
--- a/npc/commands/warp.txt
+++ b/npc/commands/warp.txt
@@ -1,91 +1,56 @@
-// @w atcommand
-// warps using anchors or map name
-//
-// group lv: 1
-// group char lv: 2
-// log: True
-//
-// usage:
-// @w <map or anchor> [, x [, y]]
-// #w "char" <map or anchor> [, x [, y]]
-//
-// example:
-// @w artis
-// #w "char" artis
-
-- script @w 32767,{
+- script @warp NPC32767,{
+ callfunc "argv_splitter";
+ if (@argv$[3] == "" && @argv$[2] == "" && @argv$[1] != "" && @argv[1] < 2)
+ @argv$[3] = @argv$[1];
+
+ .@n$ = if_then_else(@argv$[3] != "", "char", "") + "warp";
+ if (GM < CMD_WARP && GM < G_SYSOP) goto L_GM; // check if you can use it on self
+ .@target_id = BL_ID;
+ if (@argv$[3] != "") set .@target_id, getcharid(3, @argv$[3]);
+ if (@argv$[3] != "" && !(isloggedin(.@target_id))) goto L_Failed; // do NOT fallback to self
+ if (@argv$[3] != "" && GM < CMD_CHARWARP && GM < G_SYSOP) goto L_GM; // when target is not self, use charwarp permission
+
+ if (@argv$[0] == "")
+ @argv$[0] = getmapname();
+
+ setarray @map_anchor$[0], "", "", "", "";
+ callfunc "map2anchor";
+
+ gmlog "@"+.@n$+" " + @args$;
+ if (.@target_id != BL_ID)
+ message strcharinfo(0), .@n$+" : The operation succeeded.";
+
+ @GMWARP_map$ = @map_anchor$[0];
+ @GMWARP_x = if_then_else(@argv[1] > 1, @argv[1], @map_anchor$[1]);
+ @GMWARP_y = if_then_else(@argv[2] > 1, @argv[2], @map_anchor$[2]);
+ addtimer 0, strnpcinfo(0) + "::OnWarp", .@target_id;
+
+ if (@map_anchor$[3] == "no" && @knows_anchors < 1)
+ goto L_SuggestAnchors;
end;
-OnCall:
- .@params$ = strtoupper(strip(implode(.@atcmd_parameters$[0], " ")));
- .@request$ = replacestr(.@params$, " ", "");
-
- cleararray($@regexmatch$[1], "", 3);
- if (.@params$ ~= "^(.+) ([0-9]+) ([0-9]+)$")
- {
- .@request$ = replacestr(strip($@regexmatch$[1]), " ", "");
- .@req_x = atoi(strip($@regexmatch$[2]));
- .@req_y = atoi(strip($@regexmatch$[3]));
- }
-
- .@ht = getvariableofnpc(.ht, "__anchors__");
- .@it = htiterator(.@ht);
- for (.@key$ = htifirstkey(.@it); hticheck(.@it); .@key$ = htinextkey(.@it))
- {
- if (.@request$ ~= .@key$)
- {
- sscanf(htget(.@ht, .@key$, ""), "%s %d %d", .@map$, .@x, .@y);
- break;
- }
- }
- htidelete(.@it);
-
- .@map$ = .@map$ ? .@map$ : .@request$;
- .@x = .@req_y ? .@req_x : .@x;
- .@y = .@req_y ? .@req_y : .@y;
-
- if (!map_exists(.@map$))
- {
- if (map_exists(.@atcmd_parameters$[0]))
- {
- .@map$ = .@atcmd_parameters$[0];
- }
- else
- {
- dispbottom(l("Map or anchor not found: %s", .@atcmd_parameters$[0]));
- end;
- }
- }
+L_SuggestAnchors:
+ message strcharinfo(0), .@n$+" : The warp command has been improved. You might want to consider using [@@https://www.themanaworld.org/index.php/Dev:GM_Commands/anchors|map anchors@@].";
+ @knows_anchors = 1;
+ end;
- while (!checkcell(.@map$, .@x, .@y, cell_chkpass))
- {
- // FIXME: this whole cell finding loop is DIRTY!
- // we should have a command to get a random free coordinate
- // or we should make buildin_warp silently ignore 0,0
+OnWarp:
+ warp @GMWARP_map$, @GMWARP_x, @GMWARP_y;
+ @GMWARP_map$ = "";
+ @GMWARP_x = 0;
+ @GMWARP_y = 0;
+ end;
- if (.@e == 50) break; // FIXME: triggers a console warning
- .@x = rand(20, 20 + (.@e * 5));
- .@y = rand(20, 20 + (.@e * 5));
- ++.@e;
- }
+L_Failed:
+ message strcharinfo(0), .@n$+" : Impossible to attach to the target player. Did you try putting the name in \"quotation marks\"?";
+ end;
- slide_or_warp(.@map$, .@x, .@y);
- updateSpotlight();
+L_GM:
+ message strcharinfo(0), .@n$+" : GM command is level "+ if_then_else(@argv$[1] != "", CMD_CHARWARP, CMD_WARP) +", but you are level " + GM;
end;
OnInit:
- if (debug > 0)
- {
- bindatcmd("w", "@w::OnCall", 0, 20, 0);
- bindatcmd("go", "@w::OnCall", 0, 20, 0);
- bindatcmd("to", "@w::OnCall", 0, 20, 0);
- bindatcmd("warp", "@w::OnCall", 0, 20, 0);
- }
- else
- {
- bindatcmd("w", "@w::OnCall", 20, 60, 1);
- bindatcmd("go", "@w::OnCall", 20, 60, 1);
- bindatcmd("to", "@w::OnCall", 20, 60, 1);
- bindatcmd("warp", "@w::OnCall", 20, 60, 1);
- }
+ registercmd chr(ATCMD_SYMBOL) + "warp", strnpcinfo(0);
+ registercmd chr(ATCMD_SYMBOL) + "charwarp", strnpcinfo(0);
+ end;
}
diff --git a/npc/commands/zeny.txt b/npc/commands/zeny.txt
index 944c1bb9..de1013eb 100644..100755
--- a/npc/commands/zeny.txt
+++ b/npc/commands/zeny.txt
@@ -1,98 +1,78 @@
-// @esp atcommand
-// changes the number of Esperin
-//
-// group lv: 3
-// group char lv: 99
-// log: True
-//
-// usage:
-// @esp <delta>
-// #esp "char" <delta>
-//
-// example:
-// @esp +5
-// @esp -5
-// @esp +++
+- script @zeny NPC32767,{
+ callfunc "argv_splitter";
+ .@n$ = if_then_else(@argv$[1] != "", "char", "") + "Zeny";
+ if (GM < CMD_ZENY && GM < G_SYSOP) goto L_GM; // check if you can use it on self
+ .@target_id = BL_ID;
+ if (@argv$[1] != "") set .@target_id, getcharid(3, @argv$[1]);
+ if (@argv$[1] != "" && !(isloggedin(.@target_id))) goto L_Failed; // do NOT fallback to self
+ if (@argv$[1] != "" && GM < CMD_CHARZENY && GM < G_SYSOP) goto L_GM; // when target is not self, use charZeny permission
+ if (@argv$[0] == "--") goto L_Remove;
+ if (@argv$[0] == "---") goto L_RemoveAll;
+ if (@argv$[0] == "++") goto L_Max;
+ if (@argv$[0] == "+++") goto L_MaxAll;
+ set .@delta, @argv[0]; // ± Zeny
+ set .@Zeny, get(Zeny, .@target_id); // get the number of Zeny in char
+ set .@bank, get(#BankAccount, .@target_id); // get number of Zeny in (world) account
+ set .@new_Zeny, .@Zeny + .@delta; // new balance in char
+ if (.@new_Zeny < 0) goto L_MaybeRemoveBank; // Zeny would be below 0 so check if we can take from bank
+ if (.@new_Zeny > .max_Zeny) goto L_MaybeAddBank; // Zeny would be over the limit so check if we can store in bank
+ Zeny = (.@Zeny + .@delta), .@target_id;
+ goto L_Success;
-- script @esp 32767,{
+L_Remove:
+ Zeny = 0, .@target_id;
+ goto L_Success;
+
+L_RemoveAll:
+ Zeny = 0, .@target_id;
+ #BankAccount = 0, .@target_id;
+ goto L_Success;
+
+L_Max:
+ Zeny = .max_Zeny, .@target_id;
+ goto L_Success;
+
+L_MaxAll:
+ Zeny = .max_Zeny, .@target_id;
+ #BankAccount = .max_int, .@target_id;
+ goto L_Success;
+
+L_MaybeAddBank:
+ .@new_bank = (.@bank + (.@new_Zeny - .max_Zeny));
+ if (.@new_bank > .max_int || .@new_bank < 0) goto L_OutOfBounds;
+ Zeny = .max_Zeny, .@target_id;
+ #BankAccount = .@new_bank, .@target_id;
+ goto L_Success;
+
+L_MaybeRemoveBank:
+ if ((.@bank + .@new_Zeny) < 0) goto L_OutOfBounds;
+ Zeny = 0, .@target_id;
+ #BankAccount = (.@bank + .@new_Zeny), .@target_id;
+ goto L_Success;
+
+L_OutOfBounds:
+ // XXX: maybe we could also take from other chars from the same accout?
+ message strcharinfo(0), .@n$+" : Impossible to proceed! This would cause the player to have less than 0 Zeny or more than " + .max_int + ".";
end;
-OnCall:
- .@delta$ = .@atcmd_parameters$[0];
+L_Failed:
+ // XXX: should we allow GMs to change Zeny of users that are not logged in?
+ message strcharinfo(0), .@n$+" : Impossible to attach to the target player. Did you try putting the name in \"quotation marks\"?";
+ end;
- if (debug && startswith(.@delta$, "--"))
- {
- Zeny = 0;
- if (.@delta$ == "---")
- {
- BankVault = 0;
- }
- }
- else if (debug && (startswith(.@delta$, "++") || .@delta$ == ""))
- {
- Zeny = MAX_ZENY;
- if (.@delta$ == "+++")
- {
- BankVault = MAX_BANK_ZENY;
- }
- }
- else
- {
- .@d = atoi(.@delta$);
- if (.@d < 0)
- {
- .@a = Zeny + .@d; // The amount of zeny remaining after
- if (.@a < 0) // If we can't remove that much zeny, try removing from bank too
- {
- Zeny = 0;
- .@b = BankVault + .@a; // amount remaining in bank after
- if (.@b < 0)
- {
- BankVault = 0;
- }
- else
- {
- BankVault += .@a;
- }
- }
- else // We can remove that much zeny
- {
- Zeny += .@d;
- }
- }
- else
- {
- .@a = Zeny + .@d; // The amount of zeny after
- if (.@a < 0 || .@a >= MAX_ZENY) // If we can't add that much zeny, try adding to bank
- {
- .@c = .@d - (.@a - Zeny); // the amount to put in bank
- Zeny = MAX_ZENY;
- .@b = BankVault + .@c; // amout in bank after
- if (.@b < 0 || .@b == MAX_BANK_ZENY)
- {
- BankVault = MAX_BANK_ZENY;
- }
- else
- {
- BankVault += .@c;
- }
- }
- else // We can add that much zeny
- {
- Zeny += .@d;
- }
- }
- }
+L_Success:
+ gmlog "@Zeny " + @args$;
+ message strcharinfo(0), .@n$+" : The operation succeeded.";
end;
-OnInit:
- if (debug > 0)
- {
- bindatcmd "e", "@esp::OnCall", 0, 99, 0;
- bindatcmd "esp", "@esp::OnCall", 0, 99, 0;
- bindatcmd "money", "@esp::OnCall", 0, 99, 0;
- end;
- }
+L_GM:
+ message strcharinfo(0), .@n$+" : GM command is level "+ if_then_else(@argv$[1] != "", CMD_CHARZENY, CMD_ZENY) +", but you are level " + GM;
+ end;
- bindatcmd "esp", "@esp::OnCall", 99, 99, 1;
+OnInit:
+ set .max_Zeny, 1000000000; // hardcoded in tmwa
+ set .max_int, 2147483647; // max int32 value
+ registercmd chr(ATCMD_SYMBOL) + "Zeny", strnpcinfo(0);
+ registercmd chr(ATCMD_SYMBOL) + "charZeny", strnpcinfo(0);
+ end;
}