diff options
Diffstat (limited to 'npc/commands')
-rw-r--r-- | npc/commands/debug-quest.txt | 102 | ||||
-rw-r--r-- | npc/commands/debug.txt | 688 | ||||
-rw-r--r-- | npc/commands/force-rename.txt | 46 | ||||
-rw-r--r-- | npc/commands/gm.txt | 41 | ||||
-rw-r--r-- | npc/commands/ipcheck.txt | 71 | ||||
-rw-r--r-- | npc/commands/kami.txt | 86 | ||||
-rw-r--r-- | npc/commands/language.txt | 60 | ||||
-rw-r--r-- | npc/commands/numa.txt | 100 | ||||
-rw-r--r-- | npc/commands/python.txt | 27 | ||||
-rw-r--r-- | npc/commands/rate-management.txt | 231 | ||||
-rw-r--r-- | npc/commands/resync.txt | 45 | ||||
-rw-r--r-- | npc/commands/scheduled-broadcasts.txt | 227 | ||||
-rw-r--r-- | npc/commands/warp.txt | 86 |
13 files changed, 1810 insertions, 0 deletions
diff --git a/npc/commands/debug-quest.txt b/npc/commands/debug-quest.txt new file mode 100644 index 00000000..24363e09 --- /dev/null +++ b/npc/commands/debug-quest.txt @@ -0,0 +1,102 @@ +// Evol Script +// Author: Gumi, Jesusalva + +// TODO: This script must be auto-generated from db/quests.conf to be of any use +function script GlobalQuestDebug { + 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, + l("Custom"), -136; + + switch (@menuret) + { + case -1: return; + case -136: + mes "Determine the quest number, as stated in db/quests.conf"; + input .@quest; + if (!.@quest) return; + mes ""; + mes l("DEBUG: Changing @@, Values: (@@, @@, @@).", getquestlink(.@quest), getq(.@quest), getq2(.@quest), getq3(.@quest)); + select + "set 1", + "set 2", + "set 3", + "reset"; + mes l("DEBUG: Changing @@ field @@ to something else.", getquestlink(.@quest), @menu); + mes ""; + mes "Determine the new value (numeric only)"; + input .@value; + if (.@value < 0) return; + if (@menu == 1) + setq1 .@quest, .@value; + if (@menu == 2) + setq2 .@quest, .@value; + if (@menu == 3) + setq3 .@quest, .@value; + if (@menu == 4) + setq .@quest, .@value, 0, 0; + + return; + default: return; + } + } while (1); + return; +} + + + +- script @qdebug 32767,{ + end; + +OnCall: + if (!is_gm()) { + end; + } + GlobalQuestDebug; + closedialog; + end; + +OnSetq: + if (.@atcmd_numparameters < 1) { + dispbottom "setq called with invalid arguments (min. 2)"; + dispbottom "GM Command syntax: @setq <quest_id> <val1> <val2> <val3>"; + end; + } + .@q=atoi(.@atcmd_parameters$[0]); + if (.@atcmd_numparameters < 2) { + if (!is_trusted()) + charcommand sprintf("@request Quest %d count: %d / %d / %d", .@q, + getq(.@q), getq2(.@q), getq3(.@q)); + else + dispbottom sprintf("%s Quest count: %d / %d / %d", getquestlink(.@q), + getq(.@q), getq2(.@q), getq3(.@q)); + end; + } + 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 @@ modified by GM", getquestlink(.@q)); + specialeffect 50, 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", 99, 99, 1; + bindatcmd "setq", "@qdebug::OnSetq", 99, 99, 1; +} diff --git a/npc/commands/debug.txt b/npc/commands/debug.txt new file mode 100644 index 00000000..f62b4a97 --- /dev/null +++ b/npc/commands/debug.txt @@ -0,0 +1,688 @@ + +function script Debug { + goto L_Begin; + +L_Begin: + mes "What do you want to do?"; + mes "Your range: "+readbattleparam(getcharid(3), UDT_ATKRANGE); + mes "Bow range: "+getiteminfo(Bow, ITEMINFO_RANGE); + menu + "Reset stat points.", L_ResetStatusPoints, + "Change my level.", L_Level, + "Change other stuff.", L_Stats, + "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_Stats: + mesc l("Stats: %s", col(b("@str/@agi/@vit/@int/@dex/@luk/@allstats"),3)); + mesc l("GP: %s", col(b("@zeny"),3)); + mesc l("Items: %s", col(b("/createitems"),3)); + mesc l("Hide from monsters: %s", col(b("@monsterignore or @safe"),3)); + mesc l("Reset Stats: %s", col(b("@streset"),3)); + next; + goto L_Begin; + +L_Level: + mes "What level do you want to be (min: 1 - max: 140)?"; + input @lvl; + if (@lvl < 1) + goto L_LevelTooLow; + if (@lvl > 140) + 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 140."; + next; + goto L_Begin; + +L_SameLevel: + mes "You already are level " + @lvl + "."; + resetstatus; + next; + goto L_Begin; + +L_ResetStatusPoints: + resetstatus; + mes "Stats successfully resetted."; + next; + goto L_Begin; + +L_BasicSkills: + adddefaultskills(); + goto L_Begin; + +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); + + 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; + mes ""; + mes l("Focus list:"); + mesc l("%s : %s", l("Mallard's Eye"), + (isfocused(SKILL_MALLARDS_EYE) ? l("Yes") : l("No"))); + mesc l("%s : %s", l("Brawling"), + (isfocused(SKILL_BRAWLING) ? l("Yes") : l("No"))); + mesc l("%s : %s", l("Speed"), + (isfocused(SKILL_SPEED) ? l("Yes") : l("No"))); + mesc l("%s : %s", l("Resist Ailment"), + (isfocused(SKILL_RESIST_POISON) ? l("Yes") : l("No"))); + mesc l("%s : %s", l("Astral Soul"), + (isfocused(SKILL_ASTRAL_SOUL) ? l("Yes") : l("No"))); + mesc l("%s : %s", l("Raging"), + (isfocused(SKILL_RAGING) ? l("Yes") : l("No"))); + .@t=getactivatedpoolskilllist(); + menuint + l("Back"), -3, + l("Focus Skill +"), -2, + rif(getskilllv(SKILL_POOL), l("Focus Skill -")), -1, + l("Add all focus skills"), 0, + l("Remove all focus skills"), -4, + ("Toggle Focus - Mallards Eye"), SKILL_MALLARDS_EYE, + ("Toggle Focus - Brawling"), SKILL_BRAWLING, + ("Toggle Focus - Speed"), SKILL_SPEED, + ("Toggle Focus - Resist Ailment"), SKILL_RESIST_POISON, + ("Toggle Focus - Astral Soul"), SKILL_ASTRAL_SOUL, + ("Toggle Focus - Raging"), SKILL_RAGING; + mes ""; + switch (@menuret) { + case -3: goto L_Begin; + case -2: + skill SKILL_POOL, @pool+1, 0; break; + case -1: + skill SKILL_POOL, max(0, @pool-1), 0; break; + case 0: + updateskill SKILL_MALLARDS_EYE, 9; + updateskill SKILL_BRAWLING, 9; + updateskill SKILL_SPEED, 9; + updateskill SKILL_RESIST_POISON, 9; + updateskill SKILL_ASTRAL_SOUL, 9; + updateskill SKILL_RAGING, 9; + break; + case -4: + skill SKILL_POOL, 0, 0; break; + updateskill SKILL_MALLARDS_EYE, 0; + updateskill SKILL_BRAWLING, 0; + updateskill SKILL_SPEED, 0; + updateskill SKILL_RESIST_POISON, 0; + updateskill SKILL_ASTRAL_SOUL, 0; + updateskill SKILL_RAGING, 0; + break; + default: + if (FOCUSING & getpoolskillFID(@menuret)) { + unpoolskill(@menuret); + mesc "Focus removed", 1; + } else { + .@s = poolskill(@menuret); + if (.@s) + mesc "Focus added", 2; + else + mesc sprintf("Impossible to focus. You can only focus %d skills at a time.", .@t), 1; + } + } + 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 exp is "+MAGIC_EXP; + 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 " + MAGIC_EXP + "."; + 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: 65535)."; + input @value; + if (@value < 0 || @value > 65535) + goto L_WrongMagicExperience; + MAGIC_EXP = @value; + mes "You now have " + MAGIC_EXP + " 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) + updateskill SKILL_MAGIC, 0; + mes "General Magic skill changed to level 0."; + next; + goto L_MagicSkills; + +L_ChangeGeneralMagicSkill1: + updateskill SKILL_MAGIC, 1; + mes "General Magic skill changed to level 1."; + next; + goto L_MagicSkills; + +L_ChangeGeneralMagicSkill2: + updateskill SKILL_MAGIC, 2; + if (MAGIC_EXP < 100) + MAGIC_EXP = 100; + 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) + updateskill SKILL_MAGIC_LIFE, 0; + mes "Life Magic skill changed to level 0."; + next; + goto L_MagicSkills; + +L_ChangeLifeMagicSkill1: + updateskill SKILL_MAGIC_LIFE, 1; + mes "Life Magic skill changed to level 1."; + next; + goto L_MagicSkills; + +L_ChangeLifeMagicSkill2: + updateskill SKILL_MAGIC_LIFE, 2; + if (MAGIC_EXP < 100) + MAGIC_EXP = 100; + 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) + updateskill SKILL_MAGIC_WAR, 0; + mes "War Magic skill changed to level 0."; + next; + goto L_MagicSkills; + +L_ChangeWarMagicSkill1: + updateskill SKILL_MAGIC_WAR, 1; + mes "War Magic skill changed to level 1."; + next; + goto L_MagicSkills; + +L_ChangeWarMagicSkill2: + updateskill SKILL_MAGIC_WAR, 2; + if (MAGIC_EXP < 100) + MAGIC_EXP = 100; + 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) + updateskill SKILL_MAGIC_TRANSMUTE, 0; + mes "Transmutation Magic skill changed to level 0."; + next; + goto L_MagicSkills; + +L_ChangeTransmutationMagicSkill1: + updateskill SKILL_MAGIC_TRANSMUTE, 1; + mes "Transmutation Magic skill changed to level 1."; + next; + goto L_MagicSkills; + +L_ChangeTransmutationMagicSkill2: + updateskill SKILL_MAGIC_TRANSMUTE, 2; + if (MAGIC_EXP < 100) + MAGIC_EXP = 100; + 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) + updateskill SKILL_MAGIC_NATURE, 0; + mes "Nature Magic skill changed to level 0."; + next; + goto L_MagicSkills; + +L_ChangeNatureMagicSkill1: + updateskill SKILL_MAGIC_NATURE, 1; + mes "Nature Magic skill changed to level 1."; + next; + goto L_MagicSkills; + +L_ChangeNatureMagicSkill2: + updateskill SKILL_MAGIC_NATURE, 2; + if (MAGIC_EXP < 100) + MAGIC_EXP = 100; + 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) + updateskill SKILL_MAGIC_ASTAL, 0; + mes "Astral Magic skill changed to level 0."; + next; + goto L_MagicSkills; + +L_ChangeAstralMagicSkill1: + updateskill SKILL_MAGIC_ASTRAL, 1; + mes "Astral Magic skill changed to level 1."; + next; + goto L_MagicSkills; + +L_ChangeAstralMagicSkill2: + updateskill SKILL_MAGIC_ASTRAL, 2; + if (MAGIC_EXP < 100) + MAGIC_EXP = 100; + 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) + updateskill SKILL_MAGIC_DARK, 0; + mes "Dark Magic skill changed to level 0."; + next; + goto L_MagicSkills; + +L_ChangeDarkMagicSkill1: + updateskill SKILL_MAGIC_DARK, 1; + mes "Dark Magic skill changed to level 1."; + next; + goto L_MagicSkills; + +L_ChangeDarkMagicSkill2: + updateskill SKILL_MAGIC_DARK, 2; + if (MAGIC_EXP < 100) + MAGIC_EXP = 100; + mes "Dark Magic skill changed to level 2."; + next; + goto L_MagicSkills; + +L_GetAllMagic: + updateskill SKILL_MAGIC, 5; + updateskill SKILL_MAGIC_LIFE, 5; + updateskill SKILL_MAGIC_WAR, 5; + updateskill SKILL_MAGIC_TRANSMUTE, 5; + updateskill SKILL_MAGIC_NATURE, 5; + updateskill SKILL_MAGIC_ASTRAL, 5; + updateskill SKILL_MAGIC_DARK, 5; + mes "Magic skills added."; + next; + goto L_MagicSkills; + +L_ResetMagicSkills: + updateskill SKILL_MAGIC, 0; + updateskill SKILL_MAGIC_LIFE, 0; + updateskill SKILL_MAGIC_WAR, 0; + updateskill SKILL_MAGIC_TRANSMUTE, 0; + updateskill SKILL_MAGIC_NATURE, 0; + updateskill SKILL_MAGIC_ASTRAL, 0; + updateskill SKILL_MAGIC_DARK, 0; + mes "Magic skills removed."; + next; + goto L_MagicSkills; + +L_AddAll: + adddefaultskills(); + updateskill SKILL_POOL, 1; + updateskill SKILL_MALLARDS_EYE, 9; + updateskill SKILL_BRAWLING, 9; + updateskill SKILL_SPEED, 9; + updateskill SKILL_RESIST_POISON, 9; + updateskill SKILL_ASTRAL_SOUL, 9; + updateskill SKILL_RAGING, 9; + updateskill SKILL_MAGIC, 5; + updateskill SKILL_MAGIC_LIFE, 5; + updateskill SKILL_MAGIC_WAR, 5; + updateskill SKILL_MAGIC_TRANSMUTE, 5; + updateskill SKILL_MAGIC_NATURE, 5; + updateskill SKILL_MAGIC_ASTRAL, 5; + updateskill SKILL_MAGIC_DARK, 5; + + // Real skills + learnskill SKILL_CONFRINGO, 1; + learnskill SKILL_ABIZIT, 1; + learnskill SKILL_MONSTERINFO, 1; + learnskill EVOL_AREA_PROVOKE, 1; + learnskill SKILL_FLAR, 1; + learnskill SKILL_CHIZA, 1; + learnskill SKILL_MODRIPHOO, 1; + learnskill SKILL_MODRISUMP, 1; + learnskill SKILL_MODRIYIKAM, 1; + learnskill SKILL_MODRILAX, 1; + learnskill SKILL_LUM, 1; + learnskill SKILL_PARUM, 1; + learnskill SKILL_GOLE, 1; + learnskill SKILL_KALAKARENK, 1; + learnskill SKILL_KALBOO, 1; + learnskill SKILL_KALGINA, 1; + learnskill SKILL_KALRENK, 1; + learnskill SKILL_HALHISS, 1; + learnskill SKILL_HELORP, 1; + learnskill SKILL_KAFLOSH, 1; + learnskill SKILL_BETSANC, 1; + learnskill SKILL_ASORM, 1; + learnskill SKILL_INGRAV, 1; + learnskill SKILL_UPMARMU, 1; + learnskill SKILL_PHLEX, 1; + learnskill SKILL_KULARZUFRILL, 1; + learnskill SKILL_ZUKMINBIRF, 1; + learnskill SKILL_PATMUPLOO, 1; + learnskill SKILL_PATVILOREE, 1; + learnskill SKILL_PATLOREE, 1; + learnskill SKILL_MANPAHIL, 1; + resetstatus; + BaseLevel = 99; + mes "All skills added to their maximum level."; + mes "Maximum number of Legacy Magic Experience points."; + mes "You are now level " + BaseLevel + "."; + next; + goto L_Begin; + +L_ResetAll: + //adddefaultskills(); + updateskill SKILL_POOL, 0; + updateskill SKILL_MALLARDS_EYE, 0; + updateskill SKILL_BRAWLING, 0; + updateskill SKILL_SPEED, 0; + updateskill SKILL_RESIST_POISON, 0; + updateskill SKILL_ASTRAL_SOUL, 0; + updateskill SKILL_RAGING, 0; + updateskill SKILL_MAGIC, 0; + updateskill SKILL_MAGIC_LIFE, 0; + updateskill SKILL_MAGIC_WAR, 0; + updateskill SKILL_MAGIC_TRANSMUTE, 0; + updateskill SKILL_MAGIC_NATURE, 0; + updateskill SKILL_MAGIC_ASTRAL, 0; + updateskill SKILL_MAGIC_DARK, 0; + + // Real skills + updateskill SKILL_CONFRINGO, 0; + updateskill SKILL_ABIZIT, 0; + updateskill SKILL_MONSTERINFO, 0; + updateskill EVOL_AREA_PROVOKE, 0; + updateskill SKILL_FLAR, 0; + updateskill SKILL_CHIZA, 0; + updateskill SKILL_MODRIPHOO, 0; + updateskill SKILL_MODRISUMP, 0; + updateskill SKILL_MODRIYIKAM, 0; + updateskill SKILL_MODRILAX, 0; + updateskill SKILL_LUM, 0; + updateskill SKILL_PARUM, 0; + updateskill SKILL_GOLE, 0; + updateskill SKILL_KALAKARENK, 0; + updateskill SKILL_KALBOO, 0; + updateskill SKILL_KALGINA, 0; + updateskill SKILL_KALRENK, 0; + updateskill SKILL_HALHISS, 0; + updateskill SKILL_HELORP, 0; + updateskill SKILL_KAFLOSH, 0; + updateskill SKILL_BETSANC, 0; + updateskill SKILL_ASORM, 0; + updateskill SKILL_INGRAV, 0; + updateskill SKILL_UPMARMU, 0; + updateskill SKILL_PHLEX, 0; + updateskill SKILL_KULARZUFRILL, 0; + updateskill SKILL_ZUKMINBIRF, 0; + updateskill SKILL_PATMUPLOO, 0; + updateskill SKILL_PATVILOREE, 0; + updateskill SKILL_PATLOREE, 0; + updateskill SKILL_MANPAHIL, 0; + MAGIC_EXP = 0; + resetstatus; + BaseLevel = 1; + mes "All skills removed."; + mes "Magic experience reset."; + mes "You are now level " + BaseLevel + "."; + next; + goto L_Begin; + +L_close: + closeclientdialog; + return; +} + +- script Debug Spell NPC32767,{ + end; + +OnDebug: + if (!debug && getgmlevel() < CMD_DEBUG) end; + callfunc "Debug"; + end; + +OnSetVar: + if (getarraysize(.@atcmd_parameters$) != 3) + Exception("Usage: @set-var VARIABLE INDEX VALUE", RB_DISPBOTTOM|RB_ISFATAL); + + .@cmd$=array_shift(.@atcmd_parameters$); + .@idx=atoi(array_shift(.@atcmd_parameters$)); + if (charat(.@atcmd_parameters$[0], + getstrlen(.@atcmd_parameters$[0])-1) == "$") + .@str=true; + + if (.@str) + .@val$=array_shift(.@atcmd_parameters$); + else + .@val=array_shift(.@atcmd_parameters$); + + if (.@str) + setd(sprintf("%s[%d]", .@cmd$, .@idx), .@val$); + else + setd(sprintf("%s[%d]", .@cmd$, .@idx), .@val); + + .@msg$=sprintf("%s[%d] is now: %s", .@cmd$, .@idx, + getd(sprintf("%s[%d]", .@cmd$, .@idx))); + + if (!is_trusted()) + charcommand("@request System Information: "+.@msg$); + else + dispbottom(.@msg$); + end; + +// If the char is not a staff member, it'll be sent to GM Log instead +OnGetVar: + if (getarraysize(.@atcmd_parameters$) != 2) + Exception("Usage: @get-var VARIABLE INDEX", RB_DISPBOTTOM|RB_ISFATAL); + + .@cmd$=array_shift(.@atcmd_parameters$); + .@idx=atoi(array_shift(.@atcmd_parameters$)); + + .@mg$=sprintf("%s[%d] == %s", .@cmd$, .@idx, + getd(sprintf("%s[%d]", .@cmd$, .@idx))); + + if (!is_trusted()) + charcommand("@request System Information: "+.@mg$); + else + dispbottom(.@mg$); + end; + +OnSClear: + sc_end SC_ALL; + sc_end SC_DAILYSENDMAILCNT; + dispbottom l("Status Condition Cleared"); + end; + +OnAllPerms: + if (@allperms) end; + charcommand("@addperm all_skill"); + charcommand("@addperm all_equipment"); + charcommand("@addperm skill_unconditional"); + charcommand("@addperm join_chat"); + charcommand("@addperm hide_session"); + charcommand("@addperm any_warp"); + charcommand("@addperm view_hpmeter"); + charcommand("@addperm view_equipment"); + charcommand("@addperm receive_requests"); + charcommand("@addperm can_trade_bound"); + charcommand("@addperm bypass_nostorage"); + @allperms=true; + end; + +OnInit: + registercmd "@debug", "Debug Spell::OnDebug"; + bindatcmd "getvar", "Debug Spell::OnGetVar", 99, 99, 1; + bindatcmd "get-var", "Debug Spell::OnGetVar", 99, 99, 1; + bindatcmd "setvar", "Debug Spell::OnSetVar", 99, 99, 1; + bindatcmd "set-var", "Debug Spell::OnSetVar", 99, 99, 1; + bindatcmd "sclear", "Debug Spell::OnSClear", 99, 99, 1; + bindatcmd "allperms", "Debug Spell::OnAllPerms", 99, 100, 1; + end; +} + +029-2,30,26,0 script Debug#0 NPC154,{ + @debug_npc = 1; + callfunc "Debug"; + end; +OnInit: + if (!debug) + disablenpc "Debug#0"; + end; +} + +001-1,53,47,0 script Debug#1 NPC154,{ + @debug_npc = 1; + callfunc "Debug"; + end; +OnInit: + if (!debug) + disablenpc "Debug#1"; + end; +} + +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: + if (!debug) + disablenpc "Debug#3"; + end; +} + diff --git a/npc/commands/force-rename.txt b/npc/commands/force-rename.txt new file mode 100644 index 00000000..6535ea22 --- /dev/null +++ b/npc/commands/force-rename.txt @@ -0,0 +1,46 @@ +// @charrename/@forcerename atcommand +// FORCEFULLY renames a char. Collision is handled by SQL. +// +// group lv: 80+ +// group char lv: 80+ +// log: True +// +// usage: npc/commands/force-rename.txt +// @charrename New Nickname +// #forcerename "char" <Nickname> +// + +- script @charrename 32767,{ + end; + +OnRename: + // array size validation + if (getarraysize(.@atcmd_parameters$) <= 0) { + dispbottom("Syntax requires argument between 3 and 30 chars long."); + end; + } + // Set new nickname + .@nickname$ += implode(.@atcmd_parameters$, " "); + .@nickname$ = strip(.@nickname$); + // Empty nickname + if (.@nickname$ == "" || .@nickname$ == "NULL") + end; + // Too long or too short nickname + if (getstrlen(.@nickname$) > 30 || getstrlen(.@nickname$) < 3) + end; + // Attempt to rename. If name is taken, will fail at SQL query + dispbottom l("Your nickname has been redefined by GM Team."); + .@id=getcharid(3); + .@n$=strcharinfo(0); + detachrid(); + kick(.@id, 12); // 12 = Pay changed. + sleep(25); + query_sql(sprintf("UPDATE `char` SET `name`='%s' WHERE `name`='%s'", escape_sql(.@nickname$), escape_sql(.@n$))); + debugmes "[SUCCESS] char %s renamed to %s", .@n$, .@nickname$; + end; + +OnInit: + bindatcmd "charrename", "@charrename::OnRename", 80, 80, 1; + bindatcmd "forcerename", "@charrename::OnRename", 80, 80, 1; + end; +} 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/ipcheck.txt b/npc/commands/ipcheck.txt new file mode 100644 index 00000000..a241d3c0 --- /dev/null +++ b/npc/commands/ipcheck.txt @@ -0,0 +1,71 @@ +// TMW2 script +// Author: Jesusalva <admin@tmw2.org> +// +// @ipcheck <player_name> +// #ipcheck <player_name> +// +// Returns user IP + + +- script @ipcheck 32767,{ + end; + +OnCall: + if (.@atcmd_numparameters == 0) + .@request$ = strcharinfo(0); + else + .@request$ = implode(.@atcmd_parameters$, " "); + dispbottom strip(.@request$)+": IP "+getcharip(.@request$); + //dispbottom strcharinfo(0)+": IP "+getcharip(.@request$); + end; + +OnBan: + if (.@atcmd_numparameters == 0) { + dispbottom col("Syntax: #ipban <reason>", 1); + } + // Do not allow banning high-level staff + if (is_admin() || is_gm()) + end; + .@target$=strcharinfo(0); + .@reason$ = implode(.@atcmd_parameters$, " "); + dispbottom col(l("You were permanently banned by the GM Team."), 1); + sleep2(200); + query_sql "INSERT INTO ipbanlist (list,btime,rtime,reason) VALUES ('"+getcharip(.@target$)+"','"+gettime(7)+"-"+gettime(6)+"-"+gettime(5)+" "+gettime(3)+":"+gettime(2)+":"+gettime(1)+"','2037-01-01 00:00:00','"+.@reason$+"')"; + logmes("was IP-Blocked, and will not connect again."), LOGMES_ATCOMMAND; + sleep2(2000); + charcommand("@kick "+.@target$); + end; + +OnInit: + bindatcmd "ipcheck", "@ipcheck::OnCall", 60, 100, 0; + bindatcmd "ipban", "@ipcheck::OnBan", 99, 100, 1; + end; +} + +// TMW2 script +// Author: Jesusalva <admin@tmw2.org> +// +// @checkidle <player_name> +// #checkidle <player_name> +// +// Returns user idle time in seconds. +// Useful when the game prohibits warping to player. + + +- script @checkidle 32767,{ + end; + +OnCall: + if (.@atcmd_numparameters == 0) + .@request$ = strcharinfo(0); + else + .@request$ = implode(.@atcmd_parameters$, " "); + dispbottom strip(.@request$)+" idle time: "+checkidle(.@request$); + //dispbottom strcharinfo(0)+": IP "+getcharip(.@request$); + end; + +OnInit: + bindatcmd "checkidle", "@checkidle::OnCall", 60, 80, 0; + end; +} + diff --git a/npc/commands/kami.txt b/npc/commands/kami.txt new file mode 100644 index 00000000..1211fae0 --- /dev/null +++ b/npc/commands/kami.txt @@ -0,0 +1,86 @@ +// TMW2 Script +// +// @k <message> +// Broadcast, and broadcast to #world too +// +// @servmsg <message> +// Experimental, uses servicemessage() - requires up to date server + +- script @k 32767,{ + end; + +OnCall: + .@request$ = strcharinfo(0)+": "; + .@request$ += implode(.@atcmd_parameters$, " "); + channelmes("#world", .@request$); + announce l(.@request$), bc_all|bc_npc; + end; + +OnServMsg: + .@request$ = strcharinfo(0)+": "; + .@request$ += implode(.@atcmd_parameters$, " "); + // This can be slow, beware + .@c = getunits(BL_PC, .@players, MAX_CYCLE_PC); + for (.@i = 0; .@i < .@c; .@i++) { + message(.@players[.@i], .@request$); + } + end; + +OnBuff: + // Disabled command, used for debug purposes + .@c = getunits(BL_PC, .@players, MAX_CYCLE_PC); + for (.@i = 0; .@i < .@c; .@i++) { + attachrid(.@players[.@i]); + sc_start SC_INCMHPRATE, 300000, 100; + sc_start SC_INCMSPRATE, 300000, 100; + sc_start SC_INCFLEERATE, 300000, 100; + sc_start SC_INCHITRATE, 300000, 100; + sc_start SC_WALKSPEED, 300000, 150; + sc_start SC_ATTHASTE_POTION3, 300000, 50; + percentheal 100, 100; + dispbottom l("YOU WERE BLESSED BY JESUSALVA"); + dispbottom l("YOU CAN FEEL THE POWER FLOWING TROUGH YOU."); + detachrid(); + } + end; + +OnInstDestroy: + .@request = implode(.@atcmd_parameters$, " "); + if (.@request != 0) + instance_destroy(.@request); + end; + +OnInstCheck: + .@request$ = implode(.@atcmd_parameters$, " "); + dispbottom has_instance2(.@request$); + end; + +OnInit: + bindatcmd "k", "@k::OnCall", 60, 80, 1; + bindatcmd "servmsg", "@k::OnServMsg", 80, 99, 1; + + bindatcmd "blessing", "@k::OnBuff", 99, 100, 1; + bindatcmd "instcheck", "@k::OnInstCheck", 99, 100, 1; + bindatcmd "instdestr", "@k::OnInstDestroy", 99, 100, 1; + end; +} + +// kamibroadcast( message{, sender} ) +function script kamibroadcast { + .@msg$=getarg(0); + .@snd$=getarg(1, ""); + + // Send to #world + if (.@snd$ == "") + channelmes("#world", " "+.@msg$); + else + channelmes("#world", "[ "+.@snd$+" ] : "+.@msg$); + + // Make an announce + if (.@snd$ == "") + announce .@msg$, bc_all|bc_npc; + else + announce .@snd$+" : "+.@msg$, bc_all|bc_npc; + + return; +} diff --git a/npc/commands/language.txt b/npc/commands/language.txt new file mode 100644 index 00000000..ce7122f5 --- /dev/null +++ b/npc/commands/language.txt @@ -0,0 +1,60 @@ +// TMW2 Script +// Author: Jesusalva +// With code parts from Julia (Evol) + +// @lang atcommand +// Changes Language +// +// group lv: 0 +// group char lv: 0 +// log: False +// +// usage: +// @lang +// + +function script CMD_lang { + callfunc "checkclientversion"; + mesq l("Which language do you speak?"); + next; + asklanguage(LANG_IN_SHIP); + mes ""; + mesn; + mesq l("Ok, done."); + return; +} + +- script @lang 32767,{ + end; + +OnCall: + CMD_lang(); + close; + +OnTranslate: + // Implode, using a slash at whitespaces + .@request$ = implode(.@atcmd_parameters$, "%2F"); + // No NPC provided? + if (.@request$ == "") { + dispbottom l("Usage: @translate <npc file>"); + dispbottom l("Example: @translate Nard"); + dispbottom l("Example: @translate Elmo"); + dispbottom l("Example: @translate npc/002-1/arpan"); + dispbottom l("PS. Doesn't always work. You need an account at %s and to be at ManaPlus Team.", "@@https://www.transifex.com/arctic-games|Transifex@@"); + end; + } + // Add .txt extension of needed + if (!compare(.@request$, ".txt")) + .@request$ += ".txt"; + // Fix stuff for URL format + .@request$ = replacestr(.@request$, "/", "%2F"); + .@request$ = strtolower(.@request$); + // Give your translation link + dispbottom "@@https://www.transifex.com/arctic-games/moubootaur-legends/translate/#"+languagecode()+"/serverdata?q=occurrence%3A"+.@request$+"|Translate with Transifex@@"; + close; + +OnInit: + bindatcmd "lang", "@lang::OnCall", 0, 60, 0; + bindatcmd "translate", "@lang::OnTranslate", 0, 60, 0; + end; +} diff --git a/npc/commands/numa.txt b/npc/commands/numa.txt new file mode 100644 index 00000000..3fc544eb --- /dev/null +++ b/npc/commands/numa.txt @@ -0,0 +1,100 @@ + +- 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; + +// FIXME +L_XmasDebug: + gmlog strcharinfo(0) + " accessed the Xmas debug."; + callfunc "XmasDebug"; + goto L_close; + +// FIXME +L_HalloweenDebug: + gmlog strcharinfo(0) + " accessed the Halloween debug."; + callfunc "HalloweenDebug"; + goto L_close; + +// FIXME +L_EasterDebug: + gmlog strcharinfo(0) + " accessed the Easter debug."; + callfunc "Easter Debug"; + goto L_close; + +// FIXME +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 "StoneBoard"; + goto L_close; + +// FIXME? +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 "GlobalQuestDebug"; + goto L_close; + +L_close: + close; + +OnInit: + registercmd "numa", strnpcinfo(0); + registercmd "superdebug", strnpcinfo(0); + end; +} + +017-9,39,31,0 duplicate(SuperDebug) Numa NPC393 + + diff --git a/npc/commands/python.txt b/npc/commands/python.txt new file mode 100644 index 00000000..3d198f82 --- /dev/null +++ b/npc/commands/python.txt @@ -0,0 +1,27 @@ +// The Mana World script +// Author: Gumi <gumi@themanaworld.org> +// Author: Jesusalva <jesusalva@themanaworld.org> +// +// Stomp stomp stomp (use with caution) + +- script @python 32767,{ + end; + +OnCall: + specialeffect(69, AREA, playerattached()); + .@zone$=getmapinfo(MAPINFO_ZONE, .@mapa$); + if (.@zone$ == "MMO") + end; + sc_start SC_CASH_DEATHPENALTY, 1000, 1; + addtimer 380, .name$+"::OnKill"; + end; + +OnKill: + percentheal -100, -100; + //dispbottom l("Oh look, it is Cupid!"); + end; + +OnInit: + bindatcmd "python", "@python::OnCall", 60, 60, 1; + end; +} diff --git a/npc/commands/rate-management.txt b/npc/commands/rate-management.txt new file mode 100644 index 00000000..273ce9ba --- /dev/null +++ b/npc/commands/rate-management.txt @@ -0,0 +1,231 @@ +// Authors: Gumi, Jesusalva +- 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_job_rate = getbattleflag("base_job_rate"); + //.original_pk_mode = getbattleflag("pk_mode"); + //.original_death_penalty = getbattleflag("death_penalty_type"); + end; +} + + +///////////////////////////////////////////////////////////////////////////////// +- script @droprate 32767,{ + end; + + function dropRateReal { + return 100; // getbattleflag("item_rate_common") ? + } + + function dropRecalc { + .@val=getarg(0); + return .@val; + } + + function rateCleanUp { + stopnpctimer; + .hours = 0; + .max_hours = 0; + .current_rate = getbattleflag("item_rate_common"); + setbattleflag("item_rate_common", dropRateReal()); + setbattleflag("item_rate_common_boss", dropRateReal()); + setbattleflag("item_rate_heal", dropRateReal()); + setbattleflag("item_rate_heal_boss", dropRateReal()); + setbattleflag("item_rate_use", dropRateReal()); + setbattleflag("item_rate_use_boss", dropRateReal()); + setbattleflag("item_rate_equip", dropRateReal()); + setbattleflag("item_rate_equip_boss", dropRateReal()); + setbattleflag("item_rate_card", dropRateReal()); + setbattleflag("item_rate_card_boss", dropRateReal()); + charcommand("@reloadmobdb"); // this is on purpose (callable without RID) - no idea what is the purpose + channelmes("#world", "The Drop Rate Bonus is now over."); + } + + 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("item_rate_common", dropRecalc(.@new_rate)); + setbattleflag("item_rate_common_boss", dropRecalc(.@new_rate)); + setbattleflag("item_rate_heal", dropRecalc(.@new_rate)); + setbattleflag("item_rate_heal_boss", dropRecalc(.@new_rate)); + setbattleflag("item_rate_use", dropRecalc(.@new_rate)); + setbattleflag("item_rate_use_boss", dropRecalc(.@new_rate)); + setbattleflag("item_rate_equip", dropRecalc(.@new_rate)); + setbattleflag("item_rate_equip_boss", dropRecalc(.@new_rate)); + setbattleflag("item_rate_card", dropRecalc(.@new_rate)); + setbattleflag("item_rate_card_boss", dropRecalc(.@new_rate)); + charcommand("@reloadmobdb"); + initnpctimer; // start counting + + .@msg$=strcharinfo(0)+" modified drop rates to "+str(.@new_rate)+"%. It will only last "+str(FuzzyTime(time_from_hours(.max_hours), 2, 2))+"!"; + + announce .@msg$, bc_all; + channelmes("#world", .@msg$); + + //dispbottom l("You successfully set the drop rate to @@%. It will reset to @@% (default value) in @@.", + // .@new_rate, dropRateReal(), FuzzyTime(time_from_hours(.max_hours), 2, 2)); + dispbottom l("You can also manually stop it at any time with: @droprate default"); + } else if (.@new_rate == 0 && .@special$ == "") { + // get current exp rate + if (.current_rate == dropRateReal()) { + atcommand("@rates"); + dispbottom col(l("Usage of @exprate without argument is deprecated, please use \"@rates\" instead."), 1); + } else { + dispbottom l("Current drop rate is set to @@%, and will reset to @@% (default value) in @@.", + .current_rate, dropRateReal(), remainingTime()); + dispbottom l("If you meant to reset the drop rate to its default value: @droprate default"); + } + } + + else + { + // reset + rateCleanUp; + dispbottom l("Drop rate has been reset to @@% (default value).", + dropRateReal()); + } + + end; + +OnTimer3600000: + // runs every hour + if (++.hours == .max_hours) { + rateCleanUp; + end; + } + initnpctimer; + end; + +OnPCLoginEvent: + if (.max_hours > 0) { + dispbottom col(l("Drop rate is set to @@% for the next @@.", + .current_rate, remainingTime()), 6); + } + end; + +OnInit: + bindatcmd "droprate", "@droprate::OnCall", 80, 80, 1; // change drop rate + + // WARNING: using @reloadscript will change the "original" value, use @reloadbattleconf before! + .current_rate = getbattleflag("item_rate_common"); + //force_refreshall(); + end; +} diff --git a/npc/commands/resync.txt b/npc/commands/resync.txt new file mode 100644 index 00000000..246bfa88 --- /dev/null +++ b/npc/commands/resync.txt @@ -0,0 +1,45 @@ +// TMW2 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 +// +// This also introduces @resyncall +// Which is an alias for @refresh and causes client to reload the whole map, +// Including yourself and monsters. + +- script @resync 32767,{ + end; + +// Soft Resync +OnCall: + if (ispcdead()) { + dispbottom l("Impossible to resync: You are dead."); + end; + } + if (@rsync_delay > gettimetick(2)) { + dispbottom l("Not resync'ing to prevent flood."); + end; + } + getmapxy(.@m$, .@x, .@y, 0); + slide .@x, .@y; + @rsync_delay=gettimetick(2)+rand2(3,5); + end; + +// Hard Resync +OnCallRefresh: + if (@rsync_delay > gettimetick(2)) { + dispbottom l("Not resync'ing to prevent flood."); + end; + } + @rsync_delay=gettimetick(2)+rand2(3,5); + atcommand("@refresh"); + end; + +OnInit: + bindatcmd "resync", "@resync::OnCall", 0, 60, 0; + bindatcmd "resyncall", "@resync::OnCallRefresh", 0, 60, 0; + end; +} diff --git a/npc/commands/scheduled-broadcasts.txt b/npc/commands/scheduled-broadcasts.txt new file mode 100644 index 00000000..1801663a --- /dev/null +++ b/npc/commands/scheduled-broadcasts.txt @@ -0,0 +1,227 @@ +// Evol Script +// Authors: Gumi +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; + } + logmes "Scheduled Broadcast: A new broadcast was added", LOGMES_ATCOMMAND; + 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))); + } + 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_gm()) + { + end; + } + + StoneBoard; + closedialog; + end; + +OnInit: + bindatcmd "sched", "@sched::OnCall", 80, 99, 1; +} + +function script StoneBoardRead { + if ($@SCHED_Opt[0] && $@SCHED_Msg$ != "") + { + announce $@SCHED_Msg$, bc_self; + } + return; +} diff --git a/npc/commands/warp.txt b/npc/commands/warp.txt new file mode 100644 index 00000000..ddd0449d --- /dev/null +++ b/npc/commands/warp.txt @@ -0,0 +1,86 @@ +// @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 (getmapinfo(MAPINFO_ID, .@map$) < 0) + { + if (getmapinfo(MAPINFO_ID, .@atcmd_parameters$[0]) >= 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; + } + + warp(.@map$, .@x, .@y); + end; + +OnInit: + if (debug) { + bindatcmd("w", "@w::OnCall", 0, 20, 0); + bindatcmd("go", "@w::OnCall", 0, 20, 0); + bindatcmd("to", "@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); + } + end; +} |