diff options
Diffstat (limited to 'npc/commands')
-rw-r--r-- | npc/commands/bodytype.txt | 53 | ||||
-rw-r--r-- | npc/commands/debug-look.txt | 83 | ||||
-rw-r--r-- | npc/commands/debug-preset.txt | 253 | ||||
-rw-r--r-- | npc/commands/debug-quest.txt | 217 | ||||
-rw-r--r-- | npc/commands/debug-skill.txt | 94 | ||||
-rw-r--r-- | npc/commands/debug.txt | 145 | ||||
-rw-r--r-- | npc/commands/event.txt | 57 | ||||
-rw-r--r-- | npc/commands/gm.txt | 41 | ||||
-rw-r--r-- | npc/commands/mobinfo.txt | 29 | ||||
-rw-r--r-- | npc/commands/motd.txt | 194 | ||||
-rw-r--r-- | npc/commands/music.txt | 75 | ||||
-rw-r--r-- | npc/commands/python.txt | 24 | ||||
-rw-r--r-- | npc/commands/rate-management.txt | 107 | ||||
-rw-r--r-- | npc/commands/resync.txt | 40 | ||||
-rw-r--r-- | npc/commands/scheduled-broadcasts.txt | 227 | ||||
-rw-r--r-- | npc/commands/super-menu.txt | 68 | ||||
-rw-r--r-- | npc/commands/warp.txt | 91 | ||||
-rw-r--r-- | npc/commands/zeny.txt | 98 |
18 files changed, 1896 insertions, 0 deletions
diff --git a/npc/commands/bodytype.txt b/npc/commands/bodytype.txt new file mode 100644 index 00000000..290c6fd6 --- /dev/null +++ b/npc/commands/bodytype.txt @@ -0,0 +1,53 @@ +// @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/debug-look.txt b/npc/commands/debug-look.txt new file mode 100644 index 00000000..0a4a953b --- /dev/null +++ b/npc/commands/debug-look.txt @@ -0,0 +1,83 @@ +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 new file mode 100644 index 00000000..1fbad520 --- /dev/null +++ b/npc/commands/debug-preset.txt @@ -0,0 +1,253 @@ +// 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 new file mode 100644 index 00000000..580173d0 --- /dev/null +++ b/npc/commands/debug-quest.txt @@ -0,0 +1,217 @@ +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 new file mode 100644 index 00000000..2a3ef551 --- /dev/null +++ b/npc/commands/debug-skill.txt @@ -0,0 +1,94 @@ +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 new file mode 100644 index 00000000..8cc1f1cd --- /dev/null +++ b/npc/commands/debug.txt @@ -0,0 +1,145 @@ +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); +} + + + +- script @debug 32767,{ + end; + +OnCall: + if (!debug && !is_admin()) + { + end; + } + GlobalDebugMenu; + closeclientdialog; + end; + +OnInit: + bindatcmd "debug", "@debug::OnCall", 0, 99, 0; + // TODO / FIXME: add a @test command that opens the help window for test-server +} diff --git a/npc/commands/event.txt b/npc/commands/event.txt new file mode 100644 index 00000000..3f0d61de --- /dev/null +++ b/npc/commands/event.txt @@ -0,0 +1,57 @@ +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 new file mode 100644 index 00000000..b402cda8 --- /dev/null +++ b/npc/commands/gm.txt @@ -0,0 +1,41 @@ +// @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/mobinfo.txt b/npc/commands/mobinfo.txt new file mode 100644 index 00000000..691bfb68 --- /dev/null +++ b/npc/commands/mobinfo.txt @@ -0,0 +1,29 @@ +// 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 new file mode 100644 index 00000000..2f6a5e2a --- /dev/null +++ b/npc/commands/motd.txt @@ -0,0 +1,194 @@ +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 new file mode 100644 index 00000000..b817b949 --- /dev/null +++ b/npc/commands/music.txt @@ -0,0 +1,75 @@ +// @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,{ + 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"; + } + end; + +OnMyself: + .@m$ = strtolower(.@atcmd_parameters$[0]); + .@key = array_exists($MUSIC_ARRAY$, .@m$); + + // TODO: Check if you have the music unlocked? Bitmask? Array? + + 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"; + } + end; + +OnInit: + bindatcmd "music", "@music::OnCall", 0, 99, 1; + bindatcmd "jukebox", "@music::OnMyself", 0, 50, 0; + end; +} diff --git a/npc/commands/python.txt b/npc/commands/python.txt new file mode 100644 index 00000000..e2fdc5bf --- /dev/null +++ b/npc/commands/python.txt @@ -0,0 +1,24 @@ +// 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 new file mode 100644 index 00000000..995ef940 --- /dev/null +++ b/npc/commands/rate-management.txt @@ -0,0 +1,107 @@ +- 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/resync.txt b/npc/commands/resync.txt new file mode 100644 index 00000000..a535a343 --- /dev/null +++ b/npc/commands/resync.txt @@ -0,0 +1,40 @@ +// 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 new file mode 100644 index 00000000..8699c581 --- /dev/null +++ b/npc/commands/scheduled-broadcasts.txt @@ -0,0 +1,227 @@ +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 new file mode 100644 index 00000000..5ed7ced3 --- /dev/null +++ b/npc/commands/super-menu.txt @@ -0,0 +1,68 @@ +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 new file mode 100644 index 00000000..22eeda39 --- /dev/null +++ b/npc/commands/warp.txt @@ -0,0 +1,91 @@ +// @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,{ + 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; + } + } + + 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 + + if (.@e == 50) break; // FIXME: triggers a console warning + .@x = rand(20, 20 + (.@e * 5)); + .@y = rand(20, 20 + (.@e * 5)); + ++.@e; + } + + slide_or_warp(.@map$, .@x, .@y); + updateSpotlight(); + 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); + } +} diff --git a/npc/commands/zeny.txt b/npc/commands/zeny.txt new file mode 100644 index 00000000..944c1bb9 --- /dev/null +++ b/npc/commands/zeny.txt @@ -0,0 +1,98 @@ +// @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 @esp 32767,{ + end; + +OnCall: + .@delta$ = .@atcmd_parameters$[0]; + + 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; + } + } + } + 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; + } + + bindatcmd "esp", "@esp::OnCall", 99, 99, 1; +} |