From 59f2b8b864f69acb67df24724e843b2eec6fb6ab Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Sun, 27 Jun 2021 14:59:42 -0300 Subject: Replace Hurnscald Tree. --- npc/annuals/tree_beard.txt | 1035 +++++++++++++++++++++++++++++++--- npc/functions/confused-tree-dict.txt | 515 +++++++++++++++++ npc/scripts.conf | 1 + 3 files changed, 1486 insertions(+), 65 deletions(-) create mode 100644 npc/functions/confused-tree-dict.txt diff --git a/npc/annuals/tree_beard.txt b/npc/annuals/tree_beard.txt index a7866f2b..e0a4d1b2 100644 --- a/npc/annuals/tree_beard.txt +++ b/npc/annuals/tree_beard.txt @@ -1,60 +1,21 @@ -020-1,90,78,0 script #GhostTreeOne NPC133,{ - callfunc "HalloweenTree"; - close; -} - -020-1,90,78,0 script #Tree NPC380,{ - end; -} - -020-1,90,78,0 script #XmasTree NPC379,{ - end; -} - 020-1,90,79,0 script Present#1 NPC386,{ callfunc "XmasStates"; callfunc "XmasMainItemReward"; close; } -009-1,54,38,0 script #GhostTreeTwo NPC133,{ - callfunc "HalloweenTree"; - close; -} - -009-1,54,38,0 script #TreeNoSnow NPC394,{ - end; -} - -009-1,54,38,0 script #XmasTreeNoSnow NPC381,{ - end; -} - 009-1,54,39,0 script Present#2 NPC386,{ callfunc "XmasStates"; callfunc "XmasMainItemReward"; close; } -001-1,57,75,0 script #GhostTreeThree NPC133,{ - callfunc "HalloweenTree"; - close; -} - -001-1,58,75,0 script #PalmTree NPC384,{ - end; -} - 001-1,58,76,0 script Present#3 NPC386,{ callfunc "XmasStates"; callfunc "XmasMainItemReward"; close; } -001-1,58,75,0 script #XmasPalmTree NPC383,{ - end; -} - function script SpawnMobs { donpcevent "XmasSpawnManager::OnCommandSpawnStart"; return; @@ -82,40 +43,984 @@ L_Return: } function script ReplaceTrees { - disablenpc "#Tree"; - disablenpc "#TreeNoSnow"; - disablenpc "#PalmTree"; - disablenpc "#GhostTreeOne"; - disablenpc "#GhostTreeTwo"; - disablenpc "#GhostTreeThree"; - disablenpc "#XmasTree"; - disablenpc "#XmasTreeNoSnow"; - disablenpc "#XmasPalmTree"; - if ($@xmas_time) goto L_XmasTree; if ($@halloween_time) goto L_HalloweenLive; - goto L_Tree; + + setnpcdisplay("#ConfusedTree", NPC394); + setnpcdisplay("#ConfusedIcedTree", NPC380); + setnpcdisplay("#ConfusedPalmTree", NPC384); + return; L_XmasTree: - enablenpc "#XmasTree"; - enablenpc "#XmasTreeNoSnow"; - enablenpc "#XmasPalmTree"; - goto L_Return; + setnpcdisplay("#ConfusedTree", NPC381); + setnpcdisplay("#ConfusedIcedTree", NPC379); + setnpcdisplay("#ConfusedPalmTree", NPC383); + return; L_HalloweenLive: - enablenpc "#GhostTreeOne"; - enablenpc "#GhostTreeTwo"; - enablenpc "#GhostTreeThree"; - goto L_Return; + setnpcdisplay("#ConfusedTree", NPC133); + setnpcdisplay("#ConfusedIcedTree", NPC133); + setnpcdisplay("#ConfusedPalmTree", NPC133); + return; +} -L_Tree: - enablenpc "#Tree"; - enablenpc "#TreeNoSnow"; - enablenpc "#PalmTree"; - goto L_Return; +// Evol scripts. +// Author: +// gumi +// Based on CrazyTree, originally made by: +// gumi +// pclouds +// veryape +// wushin +// Description: +// emulated confused tree prototype -L_Return: - return; +// ~t lowercase hot word regex + +009-1,54,38,0 script #ConfusedTree NPC394,14,14,{ + + function tree_panel { + if (is_trusted() == false && #Tree_Trusted == false) + { + narrator(l("You see a tree.")); + if (getq(HurnscaldQuests_Inspector) == 2) + { + select( + l("Have you seen anything strange lately?"), + l("Do you know anything about the recent robberies?")); + + narrator(S_FIRST_BLANK_LINE, + l("..."), + l("It doesn't reply.")); + } + close; + } + + function clear_db { + clear(); + mes(l("##BWARNING:##b you are about to permanently empty the quote database.")); + next(); + mes(l("Do you want to continue?")); + + select( + l("Abort!"), + l("Empty the quote DB")); + + if (@menu == 2) + { + .@sentence$ = "I am an idiot"; + mes(l("Please write the following sentence:")); + mes(""); + mesf(" ##B%s.", .@sentence$); + input(.@confirm$); + + if (!startswith(strtoupper(.@confirm$), strtoupper(.@sentence$))) { + mes(l("Invalid!")); + close; + } + + query_sql("TRUNCATE TABLE tree_quotes;"); + mes(l("Database erased.")); + next(); + } + + return; + } + + function list_commands { + clear(); + mes(l("To grab a quote:")); + mes(col(" ~grab ##Bplayer name##b", 7)); + next(); + mes(l("To get a quote:")); + mes(col(" ~quote anyone", 7)); + mes(col(" ~quote ##Bplayer name##b", 7)); + mes(col(" ~quote ##B#number##b", 7)); + next(); + mes(l("To remove a quote:")); + mes(col(" ~remove quote ##B#number##b", 7)); + mes(col(" ~remove last quote", 7)); + next(); + mes(l("Last seen:")); + mes(col(" ~seen ##Bplayer name##b", 7)); + next(); + mes(l("To ignore a player:")); + mes(col(" ~ignore ##Bplayer name##b", 7)); + next(); + mes(l("To unignore a player:")); + mes(col(" ~unignore ##Bplayer name##b", 7)); + next(); + + if (is_admin()) + { + mes(l("To trust a player:")); + mes(col(" ~trust ##Bplayer name##b", 7)); + next(); + mes(l("To de-trust a player:")); + mes(col(" ~untrust ##Bplayer name##b", 7)); + next(); + } + return; + } + + do + { + clear(); + setnpcdialogtitle(l("Tree Control Panel")); + mes(l("Oh noes! You found my secret backdoor!")); + next(); + mes(l("Please select an option:")); + + select( + l("List the commands"), + rif(is_admin(), l("Empty the quote DB")), + l("Dance for me")); + + switch (@menu) + { + case 1: list_commands(); break; + case 2: clear_db(); break; + default: speech(l("Too lazy.")); close; + } + + } while (true); + + end; + } + + // utility functions below + + function check_is_ignored { + .@val = htget(.ignore_ht, strcharinfo(PC_NAME), 0); + + if (.@val > gettimetick(2)) + { + ++.ignored_times; + end; + } + + else if (.@val > 0) + { + htput(.ignore_ht, strcharinfo(PC_NAME), 0); // remove expired entries + } + + return; + } + + function special_name { + .@name$ = strcharinfo(PC_NAME); + .@low$ = strtolower(.@name$); + + if (rand(.sname_rate) == 0) + { + for (.@i = 0; .@i < .alias; .@i += 2) + { + if (.@low$ ~= .alias$[.@i]) + { + explode(.@aliases$, .alias$[.@i+1], "`"); + .@name$ = .@aliases$[rand(getarraysize(.@aliases$))]; + break; + } + } + } + + return .@name$; + } + + function face { + if (gettimetick(2) - .last_emote < .emote_rate) + { + ++.ignored_times; + return; + } + + .last_emote = gettimetick(2); + return emotion(getarg(0, E_SURPRISE)); + } + + function rp { + // used for queries + return replacestr(getarg(0,""), "~t", strtolower("(?:" + .name$ + "|" + .hotwords$ + ")")); + } + + function format_reply { + // used for replies + .@str$ = getarg(0, ""); + + // search for {{mustaches}} + while (.@str$ ~= "{{([^}]+)}}") + { + .@sub$ = replacestr($@regexmatch$[1], " ", ""); // remove whitespaces + .@sub$ = strtolower(.@sub$); // always lowercase the var name + .@capitalize = .@titlecase = .@allcaps = false; + + if (charat(.@sub$, 0) == "^") + { + .@capitalize = true; + .@sub$ = substr(.@sub$, 1, getstrlen(.@sub$) - 1); // strip first char + } + + else if (charat(.@sub$, 0) == "+") + { + .@titlecase = true; + .@sub$ = substr(.@sub$, 1, getstrlen(.@sub$) - 1); // strip first char + } + + else if (charat(.@sub$, 0) == "!") + { + .@allcaps = true; + .@sub$ = substr(.@sub$, 1, getstrlen(.@sub$) - 1); // strip first char + } + + if (compare(.@sub$, ",")) { + .@var$ = sprintf(".H%s$", substr(md5(.@sub$), 0, 25)); + + if (getelementofarray(getd(.@var$), 1) == "") { + explode(.@sub2$, .@sub$, ","); + .@size = 1; + + for (.@i = 0; .@i < getarraysize(.@sub2$); ++.@i) { + .@subsize = getd(sprintf(".D_%s", .@sub2$)); + copyarray(getelementofarray(getd(.@var$), .@size), getd(sprintf(".D_%s$[1]", .@sub2$)), .@subsize); + .@size += .@subsize; + } + } + } else { + .@var$ = sprintf(".D_%s$", .@sub$); + } + + .@rep$ = relative_array_random(getd(.@var$)); + + if (.@capitalize) .@rep$ = capitalize(.@rep$); + else if (.@titlecase) .@rep$ = titlecase(.@rep$); + else if (.@allcaps) .@rep$ = strtoupper(.@rep$); + + .@str$ = replacestr(.@str$, $@regexmatch$[0], .@rep$); // remove the mustache, replace by value + } + + // search for emotes + if (.@str$ ~= "%%([^ ])") + { + // only handling a few of them + switch (ord($@regexmatch$[1])) + { + case 73: face(any(E_WINK, E_ANGEL)); break; + case 83: face(any(E_SAD, E_CRYING)); break; + case 85: face(E_SURPRISE); break; + case 93: face(any(E_HEARTEYE, E_HEART)); break; + case 94: face(E_DISGUST); break; + case 99: face(E_DEAD); break; + case 105: face(E_CRYING); break; + case 106: + case 91: face(any(E_SPEECH, E_BLAH)); break; + case 107: face(E_INSULTBUBBLE); break; + default: .@unhandled = true; + } + + if (.@unhandled != true) + { + if (.@str$ == $@regexmatch$[0]) end; // don't send handled, emote-only messages + .@str$ = replacestr(.@str$, " "+ $@regexmatch$[0], ""); // otherwise strip the emote + } + } + + // built-in variables + .@str$ = replacestr(.@str$, "~n", .name$); // npc name + .@str$ = replacestr(.@str$, "~p", special_name()); // player name or special name + .@str$ = replacestr(.@str$, "~P", strcharinfo(PC_NAME)); // unaltered player name + + return rp(.@str$); + } + + function strip_colors { + .@str$ = replacestr(getarg(0, ""), "##0", ""); + .@str$ = replacestr(.@str$, "##1", ""); + .@str$ = replacestr(.@str$, "##2", ""); + .@str$ = replacestr(.@str$, "##3", ""); + .@str$ = replacestr(.@str$, "##4", ""); + .@str$ = replacestr(.@str$, "##5", ""); + .@str$ = replacestr(.@str$, "##6", ""); + .@str$ = replacestr(.@str$, "##7", ""); + .@str$ = replacestr(.@str$, "##8", ""); + .@str$ = replacestr(.@str$, "##9", ""); + return replacestr(.@str$, "##a", ""); + } + + function strip_formatting { + .@str$ = strip_colors(getarg(0, "")); + .@str$ = replacestr(.@str$, "##B", ""); + return replacestr(.@str$, "##b", ""); + } + + function delayed_reply { + ++.answered_times; + @tree_reply$ = getarg(0, ""); + addtimer(.delay_reply, .name$ + "::OnDoReply"); + return; + } + + function reply { + .@reply$ = format_reply(getarg(0, "")); + getmapxy(.@pc_map$, .@pc_x, .@pc_y, UNITTYPE_PC); // get char location + + if (((.@reply$ == .last_reply$ && gettimetick(2) - .last_reply < .repeat_rate) + || gettimetick(2) - .last_reply < .talk_rate + || (gettimetick(2) - .blocked < .block_time && is_trusted() == false) + || .@pc_map$ != .map$ + || distance(.x, .y, .@pc_x, .@pc_y) > .distance + || .@reply$ == "") + && is_dev() == false) + { + ++.ignored_times; + return; + } + + .last_reply = gettimetick(2); + .last_reply$= .@reply$; + + delayed_reply(.@reply$); + return; + } + + function seen_me { + if (playerattached() > 0 && htexists(.seen_ht)) + { + htput(.seen_ht, strcharinfo(PC_NAME), gettimetick(2)); + } + return; + } + + function have_you_seen { + .@player$ = getarg(0, ""); + .@player = getcharid(CHAR_ID_ACCOUNT, .@player$); + + if (.@player > 0) + { + // nested if, because they don't short-circuit + if (checkoption(Option_Invisible, .@player) == false) { + delayed_reply(sprintf("Player `%s` is currently online.", .@player$)); + end; + } + } + + .@time = htget(.seen_ht, .@player$, 0); + + if (.@time < 1) + delayed_reply(sprintf("I haven't seen player `%s` today.", .@player$)); + + else + delayed_reply(sprintf("Player `%s` was last seen %s.", .@player$, FuzzyTime(.@time, 0, 99))); + + end; + } + + function special_drops { + .@drop$ = relative_array_random(.drops$); + .@name$ = strcharinfo(PC_NAME); + .@low$ = strtolower(.@name$); + + if (rand(.sdrop_rate) == 0) + { + for (.@i = 0; .@i < .sdrops; .@i += 2) + { + if (.@low$ ~= .sdrops$[.@i]) + { + explode(.@d$, .sdrops$[.@i+1], "`"); + .@drop$ = .@d$[rand(getarraysize(.@d$))]; + break; + } + } + } + + return .@drop$; + } + + function roll_dice { + .@dices = max(min(getarg(0, 1), 8), 1); // 1..8 + .@sides = max((getarg(1, 6) < 1 ? 6 : getarg(1, 6)), 1); // 1..MAX_INT + + .@result$ = sprintf("*rolls the dice%s: %d", + rif(.@dices > 1, "s"), rand(1, .@sides)); // first dice + + for (.@d = 1; .@d < .@dices; ++.@d) + { + .@result$ += ", " + rand(1, .@sides); + } + + return .@result$ + ".*"; + } + + function flip_coin { + .@coins = getarg(0, 1); + + .@result$ = sprintf("*flips the coin%s: %s", + rif(.@coins > 1, "s"), (rand(2) == 1 ? "heads" : "tails")); // first coin + + for (.@c = 1; .@c < .@coins; ++.@c) + { + .@result$ += ", " + (rand(2) == 1 ? "heads" : "tails"); + } + + return .@result$ + ".*"; + } + + function roulette { + if (.roulette == 1) + { + npctalk("*pulls the trigger: *##BBANG##b*.*"); + delayed_reply("*reloads and spins the chambers.*"); + .roulette = rand(1, 7); // the Nagant_M1895 has 7 chambers + + // now the fun part + nude(); + percentheal(-100, 0); + } + + else + { + delayed_reply("*pulls the trigger: *click*.*"); + .roulette = (.roulette == 7 ? 1 : .roulette + 1); + } + + end; + } + + function monologue_player { + return sprintf("Your current monologue is at least %d line%s long.", + @monologue, rif(@monologue != 1, "s")); + } + + function who_player { + return sprintf("You seem to be ##B~P##b [%i:%i].", + getcharid(CHAR_ID_ACCOUNT), getcharid(CHAR_ID_CHAR)); + } + + function make_quote_table { + // Do not modify this + query_sql("CREATE TABLE IF NOT EXISTS `tree_quotes` (" + " `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT," + " `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0'," + " `grabber` INT(11) UNSIGNED NOT NULL DEFAULT '0'," + " `timestamp` INT(10) UNSIGNED NOT NULL DEFAULT '0'," + " `message` VARCHAR(150) NOT NULL DEFAULT ''," + " PRIMARY KEY (`id`)," + " KEY `char_id` (`char_id`)," + " KEY `grabber` (`grabber`)" + ") ENGINE=MyISAM;"); + + .last_query = gettimetick(2); + return; + } + + function grab_quote { + .@name$ = getarg(0, ""); + + if (gettimetick(2) - .last_query < (is_trusted() ? .qpoll_rate : .qpoll_rate2)) + { + ++.ignored_times; + end; + } + + if (.@name$ == strcharinfo(PC_NAME)) + { + delayed_reply("##BError: You may not grab yourself."); + end; + } + + explode(.@tmp$[0], htget(.msg_ht, .@name$, ""), ":"); // get last message, if any + htput(.msg_ht, .@name$, ""); // ensure you can't grab twice the same message + + .@char_id = atoi(.@tmp$[0]); // grab the char id part + + if (.@char_id < 1) + { + delayed_reply(sprintf("##BError: I couldn't find anything to grab from player `%s`.", .@name$)); + end; + } + + .@msg$ = implode(.@tmp$, ":"); // put it back together + .@start = getstrlen(.@tmp$[0]) + getstrlen(.@tmp$[1]) + 2; // char:time:msg <= we just want the msg part + .@msg$ = escape_sql(strip_formatting(substr(.@msg$, .@start, getstrlen(.@msg$) - 1))); // sanitize + + if (.@msg$ == "") + { + delayed_reply("##BError: Message is empty or malformed. It cannot be grabbed."); + end; + } + + else if (.@msg$ ~= "^[!#~@]?(?:grab)?shield(?:ed)?(?:[:.!]? .*)?$") + { + delayed_reply("##BError: Message is shielded."); + end; + } + + query_sql(sprintf("INSERT INTO tree_quotes (char_id,grabber,timestamp,message) VALUES (%i,%i,%i,'%s');", + .@char_id, getcharid(CHAR_ID_CHAR), gettimetick(2), .@msg$)); + + query_sql("SELECT MAX(id) FROM tree_quotes;", .q_last_id); // get the last quote id + + .last_query = gettimetick(2); + + delayed_reply(sprintf("Success: Quote grabbed. (#%i)", .q_last_id)); + end; + } + + function remove_quote { + .@tmp = getarg(0, 0); + + if (gettimetick(2) - .last_query < (is_trusted() ? .qpoll_rate : .qpoll_rate2)) + { + ++.ignored_times; + end; + } + + query_sql(sprintf("SELECT id FROM tree_quotes WHERE id = %i ORDER BY id DESC LIMIT 1;", .@tmp), .@id); // check if it exists + + if (.@id < 1) + { + delayed_reply(sprintf("##BError: I couldn't find quote #%i in the database.", .@tmp)); + end; + } + + query_sql(sprintf("DELETE FROM tree_quotes WHERE id = %i ORDER BY id DESC LIMIT 1;", .@id)); + + .last_query = gettimetick(2); + + delayed_reply(sprintf("Success: Quote removed. (#%i)", .@id)); + end; + } + + function cite_quote { + .@id = getarg(0,0); + + if (gettimetick(2) - .last_query < (is_trusted() ? .qpoll_rate : .qpoll_rate2)) + { + ++.ignored_times; + end; + } + + query_sql(sprintf("SELECT t.id, c.name AS grabee, d.name AS grabber, t.timestamp, t.message " + "FROM `tree_quotes` t " + "JOIN `char` c ON t.char_id = c.char_id " + "JOIN `char` d ON t.grabber = d.char_id " + "WHERE t.id=%i ORDER BY t.id DESC LIMIT 1;", + .@id), + .@nid[0], .@grabee$[0], .@grabber$[0], .@time[0], .@msg$[0]); + + .last_query = gettimetick(2); + + if (.@nid[0] < 1) + { + delayed_reply(sprintf("##BError: I couldn't find quote #%i in the database.", .@id)); + end; + } + + delayed_reply(sprintf("<%s> ##B%s##b ##a— grabbed by %s %s.", + .@grabee$[0], .@msg$[0], .@grabber$[0], FuzzyTime(.@time[0],0,1))); + end; + } + + function random_quote { + .@name$ = escape_sql(getarg(0, "")); + + if (gettimetick(2) - .last_query < (is_trusted() ? .qpoll_rate : .qpoll_rate2)) + { + ++.ignored_times; + end; + } + + query_sql("SELECT t.id, c.name AS grabee, d.name AS grabber, t.timestamp, t.message " + "FROM `char` c " + "JOIN `tree_quotes` t ON t.char_id = c.char_id " + "JOIN `char` d ON d.char_id = t.grabber " + + rif(.@name$ != "", sprintf("WHERE c.name='%s' ", .@name$)) + + "ORDER BY RAND() LIMIT 1;", + .@nid[0], .@grabee$[0], .@grabber$[0], .@time[0], .@msg$[0]); + + .last_query = gettimetick(2); + + if (.@nid[0] < 1) + { + if (.@name$ != "") + delayed_reply(sprintf("##BError: I couldn't find any quote from `%s` in the database.", getarg(0, ""))); + else + delayed_reply("##BError: The quote database is empty."); + end; + } + + delayed_reply(sprintf("<%s> ##B%s##b ##a— grabbed by %s %s. (#%i)", + .@grabee$[0], .@msg$[0], .@grabber$[0], FuzzyTime(.@time[0],0,1), .@nid[0])); + end; + } + + function trigger_hotword { + .@o$ = getarg(0, ""); // original lowercase + .@m$ = replacestr(.@o$, "*", ""); // original lowercase clean + + + if (.@m$ ~= "(?:^| )tell(?: (?:me|him|her|us|them))? a(?:n ?other| lame| bad| boring)? joke") + reply(relative_array_random(.jokes$)); + + else if (.@m$ ~= "(?:^| )heal me(?:$|[^a-z])") + reply(relative_array_random(.healing$)); + // XXX: maybe actually heal the player once in a while + + else if (.@m$ ~= "(?:^| )(?:what|who) are you") + reply(relative_array_random(.whoami$)); + + else if (.@m$ ~= rp("(?:^| )(?:hi+|hello|heya?|hiya|good (?:morning|afternoon))[^a-z]* .*~t|~t.* (?:hi+|hello|heya?|hiya)")) + { + .blocked = 0; + .@rpl$ = relative_array_random(.greetings$); + reply(.@rpl$); + } + + else if (.@o$ ~= rp("(?:^[*]| )(?:kicks?|shakes?) .*~t")) + reply(special_drops()); + + else if (.@o$ ~= rp("(?:^[*]| )(?:cuts?|nukes?|kills?|chops? down|saws?|hews?|murders?) .*~t")) + reply(relative_array_random(.kill$)); + + else if (.@o$ ~= rp("(?:^[*]| )pokes? .*~t")) + reply(relative_array_random(.poke$)); + + else if (.@o$ ~= rp("(?:^[*]| )(?:waters?|pees?|licks?) .*~t")) + reply(relative_array_random(.disgusting$)); + + else if (compare(.@m$, " answer ") && .@m$ ~= "(?:life|universe|everything)(?:$|[^a-z])") + reply(relative_array_random(.answer$)); + + else if (.@o$ ~= rp("(?:^[*]| )(?:burns?|incinerates?|ignites?) .*~t")) + reply(relative_array_random(.burning$)); + // XXX: maybe here send a fire particle effect + + else if (.@m$ ~= rp("(?:^| )die ~t")) + reply(relative_array_random(.die$)); + + else if (.@o$ ~= rp("(?:^[*]| )bites? .*~t|(?:^[*]| )drops? .* on ~t")) + reply(relative_array_random(.silly$)); + + else if (.@m$ ~= rp("(?:^| )(?:loves?|hugs?|kiss(es)?) .*~t|~t.* love(?:$|[^a-z])")) + reply(relative_array_random(.love$)); + + else if (.@m$ ~= rp("(?:^| )dance .*~t|~t.* dance(?:$|[^a-z])")) + reply(relative_array_random(.dance$)); + + else if (.@m$ ~= rp("(?:^| )hates? .*~t")) + reply(relative_array_random(.hate$)); + + else if (.@o$ ~= rp("(?:^[*]| )(?:eats?|shoots?|plucks?|tortures?|slaps?|slaps?|poisons?|breaks?|stabs?|throws?|punch(?:es)?) .*~t")) + reply(relative_array_random(.pain$)); + + else if (.@o$ ~= rp("(?:^[*]| )(?:climbs?|rides?|mounts?) .*~t")) + reply(relative_array_random(.climb$)); + + else if (.@m$ ~= "(?:^| )(?:see y(?:a|ou)|good night|(?:bye)?bye+)(?:$|[^a-z])") + reply(relative_array_random(.bye$)); + + else if (.@m$ ~= rp("(?:^| )bad ~t")) + reply(relative_array_random(.bad$)); + + else if (.@m$ ~= "(?:^| )(?:how old are you|uptime)(?:$|[^a-z])") + reply("%%B Server uptime: " + FuzzyTime(.uptime, 1, 99) + "."); + + else if (.@m$ ~= "(?:^| )how chatty are you(?:$|[^a-z])") + reply("%%B Answered " + .answered_times + " times, ignored " + .ignored_times + " times."); + + else if (.@m$ ~= "(?:^| )what.* version(?:$|[^a-z])") + reply("%%B ~n, version " + .version + "."); // XXX: maybe return Hercules version and serverdata commit instead + + else if (.@m$ ~= "(?:^| )(?:(?:8|eight)[ -]?ball|(?:should|would|will|do|does) (?:i|you|he|she|it|we|they))(?:$|[^a-z])") + reply(relative_array_random(.eightball$)); + + else if (.@m$ ~= "(?:^| )roll(?: a| the)? dice(?:$|[^a-z])") + reply(roll_dice(1, 6)); + + else if (.@m$ ~= "(?:^| )roll(?: a)? ([1-8])d((?:[1-9][0-9]{0,10})?)(?:$|[^0-9a-z])") + reply(roll_dice(atoi($@regexmatch$[1]), atoi($@regexmatch$[2]))); + + else if (.@m$ ~= "(?:^| )roll ([1-8]) dices?(?:$|[^a-z])") + reply(roll_dice(atoi($@regexmatch$[1]), 6)); + + else if (.@m$ ~= "(?:^| )(?:flip|toss)(?: a| the)? coin(?:$|[^a-z])") + reply(flip_coin(1)); + + else if (.@m$ ~= "(?:^| )(?:flip|toss) ([1-8]) coins?(?:$|[^a-z])") + reply(flip_coin(atoi($@regexmatch$[1]))); + + else if (.@m$ ~= "(?:^| )(?:press|pull)(?: the)? trigger(?:$|[^a-z])") + roulette(); + + else if (.@m$ ~= "(?:^| )(?:how long|what) is(?: my)? monologue(?:$|[^a-z])") + reply(monologue_player()); + + else if (.@m$ ~= "(?:^| )who am i(?:$|[^a-z])") + reply(who_player()); + + else if (.@m$ ~= "(?:^| )shut up(?:$|[^a-z])") + { + reply(relative_array_random(.shut_up$)); + .blocked = gettimetick(2); + } + + else if (rand(.dunno_rate) == 0) + reply(relative_array_random(.no_idea$)); + + else + ++.ignored_times; + + end; + } + + function trigger_hiall { + if (rand(.hiall_rate) == 0) + reply(relative_array_random(.greetings$)); + + else + ++.ignored_times; + + end; + } + +OnClick: + //if ($@xmas_time) + // goto L_XmasTree; + if ($@halloween_time) + callfunc "HalloweenTree"; + tree_panel(); + end; + + +OnTalkNearby: + .@no_nick$ = strip(strip_formatting(substr($@p0$, getstrlen(strcharinfo(PC_NAME)) + 3, getstrlen($@p0$) - 1))); // not very obvious stuff + .@no_nick_lower$ = strtolower(.@no_nick$); // FIXME: hercules doesn't have a way to do case insensitive regex yet + .@no_nick_clean$ = replacestr(.@no_nick_lower$, "*", ""); + + htput(.msg_ht, strcharinfo(PC_NAME), getcharid(CHAR_ID_CHAR) + ":" + gettimetick(2) + ":" + .@no_nick$); // log last message, for quotegrabs + .lastsender = getcharid(CHAR_ID_CHAR); // for monologue + + .last_activity = gettimetick(2); // for the auto-janitor + + if ((is_trusted() || #Tree_Trusted) && charat(.@no_nick$, 0) == .symbol$) + { + if (.@no_nick$ ~= "^.grab \"?([^#:@\"]{4,23})\"?$") + reply(grab_quote($@regexmatch$[1])); + + else if (.@no_nick$ ~= "^.(?:ungrab|remove|delete)(?: quote)? #([0-9]+)$") + reply(remove_quote(atoi($@regexmatch$[1]))); + + else if (.@no_nick$ ~= "^.(?:ungrab|remove|delete)(?: last(?: quote)?)?$") + reply(remove_quote(.q_last_id)); + + else if (.@no_nick$ ~= "^.(?:quote|cite) #([0-9]+)$") + reply(cite_quote(atoi($@regexmatch$[1]))); + + else if (.@no_nick$ ~= "^.(?:(?:random )?quote|cite)(?: anyone| someone| random)?$") + reply(random_quote()); + + else if (.@no_nick$ ~= "^.(?:quote|cite) \"?([^#:@\"]{4,23})\"?$") + reply(random_quote($@regexmatch$[1])); + + else if (.@no_nick$ ~= "^.seen \"?([^#:@\"]{4,23})\"?$") + reply(have_you_seen($@regexmatch$[1])); + + // to allow trusted testers to reboot without knowing the exit code + else if (debug && .@no_nick$ ~= "^.re(?:boot|load|start)(?:(?: the)? server)?$") + { + announce("The server is rebooting. This may take a couple minutes.", bc_all); + sleep2(1000); + atcommand("@serverexit 104"); + } + + // exit, pull all, clean, build, reboot + else if (debug && .@no_nick$ ~= "^.re-?build(?:(?: the)? server)?$") + { + announce("The server is rebuilding. This will take several minutes.", bc_all); + sleep2(1000); + atcommand("@serverexit 108"); + } + + else if (.@no_nick$ ~= "^.(?:add )?ignored? \"?([^#:@\"]{4,23})\"?$") + { + .@chr = getcharid(CHAR_ID_ACCOUNT, $@regexmatch$[1]); + if (.@chr < 1) + { + reply("##BError: Player not found or not online."); + end; + } + htput(.ignore_ht, strcharinfo(PC_NAME, .@chr), gettimetick(2) + 3600); + reply(sprintf("Success: Player `%s` is now ignored for 1 hour.", + strcharinfo(PC_NAME, .@chr))); + } + + else if (.@no_nick$ ~= "^.(?:un|de-?|remove )ignored? \"?([^#:@\"]{4,23})\"?$") + { + .@chr = getcharid(CHAR_ID_ACCOUNT, $@regexmatch$[1]); + if (.@chr < 1) + { + reply("##BError: Player not found or not online."); + end; + } + htput(.ignore_ht, strcharinfo(PC_NAME, .@chr), 0); + reply(sprintf("Success: Player `%s` is no longer ignored.", + strcharinfo(PC_NAME, .@chr))); + } + + else if (is_admin() && .@no_nick$ ~= "^.(?:add )?trust(?:ed)? \"?([^#:@\"]{4,23})\"?$") + { + .@chr = getcharid(CHAR_ID_ACCOUNT, $@regexmatch$[1]); + if (.@chr < 1) + { + reply("##BError: Player not found or not online."); + end; + } + set(getvariableofpc(#Tree_Trusted, .@chr), true); + reply(sprintf("Success: Player `%s` can now use restricted commands.", + strcharinfo(PC_NAME, .@chr))); + } + + else if (is_admin() && .@no_nick$ ~= "^.(?:un|de-?|remove )trust(?:ed)? \"?([^#:@\"]{4,23})\"?$") + { + .@chr = getcharid(CHAR_ID_ACCOUNT, $@regexmatch$[1]); + if (.@chr < 1) + { + reply("##BError: Player not found or not online."); + end; + } + set(getvariableofpc(#Tree_Trusted, .@chr), false); + reply(sprintf("Success: Player `%s` can no longer use restricted commands.", + strcharinfo(PC_NAME, .@chr))); + } + + else + reply("##BError: Command not found or invalid syntax."); + } + + else if (.@no_nick_lower$ ~= rp("^(~t[^a-z ]* .*|(?:.* (?:~t[^a-z ]* .*|~t[^ a-z]*)))$")) + { + check_is_ignored(); + trigger_hotword($@regexmatch$[1]); + } + + else if (.@no_nick_clean$ ~= "^(hi(ya)?|hello|heya?) (all|friends|every(one|body))") + { + check_is_ignored(); + trigger_hiall(); + } + + else + { + if (.lastsender == getcharid(CHAR_ID_CHAR)) + @monologue++; + + else + @monologue = 1; + } + + // TODO: eliza mode, whisper eliza mode + end; + +OnTouch: + if (rand(.touch_rate) == 0) { + face(); + } + end; + +OnDoReply: + if (@tree_reply$ != "") { + npctalk(@tree_reply$); + @tree_reply$ = ""; + } + end; + +OnPCLogoutEvent: + seen_me(); + end; + +OnTimer3600000: + // scheduled janitor + .@now = gettimetick(2); + initnpctimer(); // schedule next + + if (.last_activity > (.@now - 3600)) { + end; // last activity is too recent + } + + // cleanup routine below + .lastsender = 0; + .last_activity = 0; + .last_reply = 0; + .last_emote = 0; + .last_query = 0; + .blocked = 0; + .enable_janitor = 0; + + htclear(.msg_ht); // empty the message table (quotegrabs) + htclear(.ignore_ht); // empty the ignore table + + .@it = htiterator(.seen_ht); // allocate new iterator + for (.@key$ = htinextkey(.@it); hticheck(.@it); .@key$ = htinextkey(.@it)) { + if (.@key$ == "") { + continue; + } + + if (htget(.seen_ht, .@key$, 0) < (.@now - 86400)) { + htput(.seen_ht, .@key$, 0); // remove from hash table if older than 24h + } + } + htidelete(.@it); // free the iterator + + face(); // do an emote (because why not) + end; + + +OnInit: + // config below + .hotwords$ = "tree"; // what hot words the npc should listen to, besides its own name (regex) + .distance = 14; // the npc will only listen to player within X tiles + //.dir = season_direction(); // sprite direction according to the season + .talk_rate = 1; // min number of seconds to wait between replies + .repeat_rate = 1; // min number of seconds to wait before sending the same message twice in a row + .block_time = 600; // how long to stay quiet after someone says shut up, in seconds + .emote_rate = 3; // min number of seconds to wait between emotes + .sdrop_rate = 8; // 1 in X chances to get a special drop + .sname_rate = 8; // 1 in X chances to get a special name + .dunno_rate = 2; // 1 in X chances to get a reply when the command is not found + .hiall_rate = 2; // 1 in X chances to reply to a "hi everyone" + .touch_rate = 4; // 1 in X chances to trigger the OnTouch action + .qpoll_rate = 1; // min number of seconds to wait before calling the sql db again for GMs + .qpoll_rate2 = 5; // min number of seconds to wait before calling the sql db again for non-GMs (currently unused) + .delay_reply = 250; // number of ms to wait to reply + .enable_janitor = true; // automatically free memory when idle + .symbol$ = "~"; // symbol for GM-only commands + + // register some arrays + callfunc("TREE_dictionaries"); + + // do random stuff + make_quote_table(); + face(); + + // boring stuff below + .version[0] = 21; // increase this when you make a change + .version[1] = 1; + .uptime = gettimetick(2); + .alwaysVisible = true; // the NPC doesn't de-spawn when moving away + .pid = 1; // regex pattern id + .msg_ht = htnew(); // hashtable id for message history + .seen_ht = htnew(); // hashtable id for seen log + .ignore_ht = htnew(); // hashtable id for ignored players + .roulette = rand(1, 7); // spin the chambers + defpattern(.pid, "^(.*)$", "OnTalkNearby"); + activatepset(.pid); + if (.enable_janitor) { + initnpctimer(); + } } + +// Duplicates below +001-1,57,75,0 duplicate(#ConfusedTree) #ConfusedPalmTree NPC384,14,14 +020-1,90,78,0 duplicate(#ConfusedTree) #ConfusedIcedTree NPC380,14,14 + diff --git a/npc/functions/confused-tree-dict.txt b/npc/functions/confused-tree-dict.txt new file mode 100644 index 00000000..e1c0f555 --- /dev/null +++ b/npc/functions/confused-tree-dict.txt @@ -0,0 +1,515 @@ +// Evol scripts. +// Author: +// gumi +// rein +// Based on CrazyTree, originally made by: +// gumi +// pclouds +// veryape +// wushin +// Description: +// dictionaries for confused tree + +// Built-in variables: +// ~t lowercase hot word regex +// ~n npc name +// ~p player name or special name +// ~P player name only +// +// Custom variables: +// {{var}} random from array .D_var$ +// {{^var}} same but capitalize +// {{+var}} same but title case +// {{!var}} same but all caps +// You can also specify multiple variables, separated by a comma (,) +// +// Example: +// "*drops a {{! size }} {{ color }} {{^ sizeable object, someone }} on ~p's head*" + +function script TREE_dictionaries { + .npc$ = strnpcinfo(0); + + // special aliases below (regex of lowercase char names) + // the substitutions are an array separated by backticks (`) + // XXX: this could become a hashtable at some point if it gets too big + + setarray(getvariableofnpc(.alias$[0], .npc$), + "^veryape(?:gm)?$", "hairyape", + + "^wu-?shin$", "Dwarven Princess`" + "She-Ra", + + "^reid$", "Mistress`" + "Milady`" + "R'eid", + + "^(?:slicer|madcamel)$", "Camel Toe", + + "^4144(?:4d494e)?$", "NPC", + + "^omatt$", "@@https://youtu.be/S2qiZoqH9OY|omatt@@`" + "o'matt", + + "^prsm$", "Refractor`" + "Overlord"); + set(getvariableofnpc(.alias, .npc$), getarraysize(getvariableofnpc(.alias$, .npc$))); + + + + // special drops below (regex of lowercase char names) + // the substitutions are an array of standard replies separated by backticks (`) + // and allow {{variables}} + // XXX: this could become a hashtable at some point if it gets too big + + setarray(getvariableofnpc(.sdrops$[0], .npc$), + "^reid$", "*drops an empty jar of Nutella on ~p*", + "^omatt$", "*drops Elisabeth Granneman on ~p*"); + set(getvariableofnpc(.sdrops, .npc$), getarraysize(getvariableofnpc(.sdrops$, .npc$))); + + + // variables below + + setarray(getvariableofnpc(.D_size$[1], .npc$), // {{size}} + "tiny", 1, + "small", 1, + "perfectly sized", 1, + "large", 1, + "huge", 1, + "humongous", 1, + "ginormous", 1); + set(getvariableofnpc(.D_size, .npc$), getarraysize(getvariableofnpc(.D_size$, .npc$))); + + setarray(getvariableofnpc(.D_color$[1], .npc$), // {{color}} + "red", 1, + "orange", 1, + "yellow", 1, + "pink", 1, + "aqua", 1, + "cyan", 1, + "blue", 1, + "indigo", 1, + "violet", 1, + "purple", 1, + "magenta", 1, + "pink", 1, + "black", 1, + "white", 1, + "grey", 1, + "greyscale", 1, + "brown", 1, + "maroon", 1, + "turquoise", 1, + "lime", 1, + "sky blue", 1, + "invisible", 1); + set(getvariableofnpc(.D_color, .npc$), getarraysize(getvariableofnpc(.D_color$, .npc$))); + + setarray(getvariableofnpc(.D_violentadverb$[1], .npc$), // {{violent adverb}} + "violently", 1, + "repeatedly", 1, + "casually", 1, + "forcefully", 1, + "slowly", 1, + "carefully", 1, + "hopefully", 1, + "dangerously", 1, + "shockingly", 1, + "religiously", 1); + set(getvariableofnpc(.D_violentadverb, .npc$), getarraysize(getvariableofnpc(.D_violentadverb$, .npc$))); + + setarray(getvariableofnpc(.D_hello$[1], .npc$), // {{hello}} + "hi", 4, + "hey", 3, + "yo", 2, + "hello", 10, + "howdy", 1, + "bonjour", 1); + set(getvariableofnpc(.D_hello, .npc$), getarraysize(getvariableofnpc(.D_hello$, .npc$))); + + setarray(getvariableofnpc(.D_violentverb$[1], .npc$), // {{violent verb}} + "slaps", 5, + "hits", 1, + "pummels", 1, + "beats", 1, + "flattens", 1, + "taunts", 1, + "liquidates", 1, + "spanks", 1, + "affronts", 1, + "tranquilizes", 1, + "atomizes", 1, + "impales", 1, + "dismembers", 1); + set(getvariableofnpc(.D_violentverb, .npc$), getarraysize(getvariableofnpc(.D_violentverb$, .npc$))); + + // FIXME: Is this even used anywhere? + setarray(getvariableofnpc(.D_location$[1], .npc$), // {{location}} + "Artis", 1, + "Hurnscald", 1, + "Tulimshar", 1, + "Nivalis", 1, + "Candor", 1, + "Drasil", 1); + set(getvariableofnpc(.D_location, .npc$), getarraysize(getvariableofnpc(.D_location$, .npc$))); + + setarray(getvariableofnpc(.D_sizeableobject$[1], .npc$), // {{sizeable object}} + "trout", 1, + "whale", 1, + "space whale", 1, + "penguin", 1, + "coelacanth", 1, + "squid", 1, + "shrimp", 1, + "crab", 1, + "tentacle", 1, + "dictionary", 1, + "grammar book", 1, + "textbook", 1, + "dinosaur", 1, + "t-rex", 1, + "star-nosed mole", 1, + "chimpanzee", 1, + "mermaid", 1, + "merman", 1, + "piano", 1, + "prince", 1, + "princess", 1, + "pinkie", 1, + "squirrel", 1, + "mouboo", 1, + "wet mop", 1, + "drunken pirate", 1, + "cake", 1, + "cookie", 1, + "chocobo", 1, + "restraining order", 1, + "freight train", 1, + "carnival hammer", 1, + "crate", 1, + "bomb", 1, + "bowl of petinuas", 1, + "box", 1, + "platypus", 1, + "magic eightball", 1, + "vase", 1); + set(getvariableofnpc(.D_sizeableobject, .npc$), getarraysize(getvariableofnpc(.D_sizeableobject$, .npc$))); + + setarray(getvariableofnpc(.D_nsizeableobject$[1], .npc$), // {{n sizeable object}} + "octopus", 1, + "elephant", 1, + "angry cat", 1, + "anvil", 1, + "encyclopedia set", 1); + set(getvariableofnpc(.D_nsizeableobject, .npc$), getarraysize(getvariableofnpc(.D_nsizeableobject$, .npc$))); + + setarray(getvariableofnpc(.D_someone$[1], .npc$), // {{someone}} + "Voldemort", 1, + "Cthulhu", 1, + "Platyna", 1, + "Hitler", 1, + "Luvia", 1, + "General Krukan", 1, + "Borg Queen", 1, + "Freeyorp", 1, + "MadCamel", 1); + set(getvariableofnpc(.D_someone, .npc$), getarraysize(getvariableofnpc(.D_someone$, .npc$))); + + // replies below + + setarray(getvariableofnpc(.greetings$[1], .npc$), + "{{^ hello }} ~p!", 4, + "{{^ hello }} ~p.", 6, + "{{^ hello }} ~p, what's up?", 1, + "{{^ hello }} ~p, anything new?", 1, + "{{^ hello }} ~p, how are you?", 1, + "~p!!!!", 1, + "~p!!!", 1, + "~p!!", 1, + "{{^ hello }} ~p! You are looking lovely today!", 1, + "Welcome back, ~p.", 3, + "~p is back!!", 1, + "Hello and welcome to the Aperture Science computer-aided enrichment center.", 1, + "Greetings ~p.", 1, + "What's up ~p?", 2, + "How are you ~p?", 1); + set(getvariableofnpc(.greetings, .npc$), getarraysize(getvariableofnpc(.greetings$, .npc$))); + + setarray(getvariableofnpc(.jokes$[1], .npc$), + "How did the tree get drunk? On root beer.", 1, + "Do you think I'm lazy?", 1, + "I miss CrazyTree %%S.", 1, + "I miss LazyTree %%S.", 1, + "I'm not telling you!", 1, + "*sighs.*", 1, + "If I do it for you, then I have to do it for everybody.", 1, + "What did the beaver say to the tree? It's been nice gnawing you.", 1, + "What did the little tree say to the big tree? Leaf me alone.", 1, + "What did the tree wear to the pool party? Swimming trunks.", 1, + "What do trees give to their dogs? Treets.", 1, + "What do you call a tree that only eats meat? Carniforous.", 1, + "What do you call a tree who's always envious? Evergreen.", 1, + "What is the tree's least favourite month? Sep-timber!", 1, + "What kind of tree can fit into your hand? A palm-tree.", 1, + "What was the tree's favorite subject in school? Chemistree.", 1, + "Why did the leaf go to the doctor? It was feeling green.", 1, + "Why doesn't the tree need sudo? Because it has root.", 1, + "Why was the cat afraid of the tree? Because of its bark.", 1, + "Why was the tree executed? For treeson.", 1, + "How do trees get on the internet? They log in.", 1, + "Why did the pine tree get into trouble? Because it was being knotty.", 1, + "Did you hear the one about the oak tree? It's a corn-y one!", 1, + "What do you call a blonde in a tree with a briefcase? Branch Manager.", 1, + "How is an apple like a lawyer? They both look good hanging from a tree.", 1, + "Why did the sheriff arrest the tree? Because its leaves rustled.", 1, + "I'm too tired, ask someone else.", 1, + "If you are trying to get me to tell jokes you are barking up the wrong tree!", 1, + "You wooden think they were funny anyhow. Leaf me alone!", 1, + "What is brown and sticky? A stick.", 1, + "What's the best way to carve wood? Whittle by whittle.", 1, + "What did the tree do when the bank closed? It started its own branch.", 1, + "Do you want a brief explanation of an acorn? In a nutshell, it’s an oak tree.", 1, + "A snare drum and a crash cymbal fell out of a tree. *BA-DUM TSSSHH*", 1, + "How do you properly identify a dogwood tree? By the bark!", 1, + "Where do saplings go to learn? Elementree school.", 1, + "Why do trees make great thieves? Sticky fingers.", 1, + "What is green, has leaves, and a trunk? A houseplant going on vacation.", 1, + "Where can Adansonia trees go for a quick trim? To the baobarber.", 1, + "What looks like half a spruce tree? The other half.", 1, + "What do you give to a sick citrus tree? Lemon aid.", 1, + "What did the tree say to the drill? You bore me.", 1, + "What happened to the wooden car with wooden wheels and a wooden engine? It wooden go.", 1, + "How do trees keep you in suspense? I'll tell you tomorrow.", 1, + "Where do birch trees keep their valuables? In a river bank.", 1, + "What kind of stories do giant sequoia trees tell? Tall tales.", 1, + "What is the most frustrating thing about being a tree? Having so many limbs and not being able to walk.", 1, + "What's black, highly dangerous, and lives in a tree? A crow with a machine gun.", 1, + "What kind of wood doesn't float? Natalie Wood.", 1, + "Two men passed a sign while looking for work. It was for tree fellers. They said: “what a shame, there are only two of us”.", 1); + set(getvariableofnpc(.jokes, .npc$), getarraysize(getvariableofnpc(.jokes$, .npc$))); + + setarray(getvariableofnpc(.healing$[1], .npc$), + "Eat an apple, they're good for you.", 1, + "If I do it for you, then I have to do it for everybody.", 1, + "Oh, go drink a potion or something.", 1, + "Whoops! I lost my spellbook.", 1, + "No mana.", 1); + set(getvariableofnpc(.healing, .npc$), getarraysize(getvariableofnpc(.healing$, .npc$))); + + setarray(getvariableofnpc(.whoami$[1], .npc$), + "An undercover GM.", 1, + "An exiled GM.", 1, + "I'm not telling you!", 1, + "I'm a bot! I'll be level 99 one day! Mwahahahaaha!!!111!", 1, + "Somebody said I'm a Chinese copy of CrazyTree.", 1, + "I am your evil twin.", 1, + "I don't remember anything after I woke up! What happened to me?", 1, + "I don't know. Why am I here??", 1, + "Who are you?", 1, + "On the 8th day, God was bored and said 'There will be bots'. So here I am.", 1, + "♪ I'm your hell, I'm your dream, I'm nothing in between ♪♪", 1, + "♪♪ Aperture Science. We do what we must, because... we can ♪", 1, + "I'm just a reincarnation of a copy.", 1); + set(getvariableofnpc(.whoami, .npc$), getarraysize(getvariableofnpc(.whoami$, .npc$))); + + setarray(getvariableofnpc(.drops$[1], .npc$), + "*drops a {{ sizeable object }} on ~p's head.*", 8, + "*drops an {{ n sizeable object }} on ~p's head.*", 2, + "*drops {{ someone }} on ~p's head.*", 1, + "*drops a coin on ~p's head.*", 1, + "*drops a fruit on ~p's head.*", 1, + "*drops an apple on ~p's head.*", 1, + "*drops an iten on ~p's head.*", 1, + "*drops a GM on ~p.*", 1, + "*drops a piece of moon rock on ~p's head.*", 1, + "*drops a pin on ~p's head.*", 1, + "*drops a rock on ~p's head.*", 1, + "*drops a tub of paint on ~p's head.*", 1, + "*drops a sandworm on ~p.*", 1, + "*drops an idea in ~p's head.*", 1, + "*drops The Hitchhiker's Guide to the Galaxy on ~p's head.*", 1, + "Ouch.", 1, + "Ouchy.", 1, + "*drops dead.*", 1, + "*sighs.*", 1, + "Leaf me alone.", 1, + "Stop it! I don't drop branches, try the Druid tree for once!", 1); + set(getvariableofnpc(.drops, .npc$), getarraysize(getvariableofnpc(.drops$, .npc$))); + + setarray(getvariableofnpc(.die$[1], .npc$), + "*drops an iten on ~p's head.*", 1, + "*drops a piece of moon rock on ~p's head.*", 1, + "*drops {{ someone }} on ~p's head.*", 1, + "*drops a {{ sizeable object }} on ~p's head.*", 3, + "*drops an {{ n sizeable object }} on ~p's head.*", 1, + "*drops a {{ size }} {{ sizeable object, n sizeable object }} on ~p's head.*", 1, + "*drops a {{ size }} {{ color }} {{ sizeable object, n sizeable object }} on ~p's head.*", 1, + "*{{ violent adverb }} {{ violent verb }} ~p.*", 1, + "*drops dead.*", 1, + "*sighs.*", 1, + "Avada Kedavra!", 1, + "Make me!", 1, + "Never!!", 1, + "You die, ~p!", 4, + "No!", 1, + "In a minute.", 1, + "Suuure... I'll get right on it...", 1); + set(getvariableofnpc(.die, .npc$), getarraysize(getvariableofnpc(.die$, .npc$))); + + setarray(getvariableofnpc(.poke$[1], .npc$), + "*tickles.*", 1); + set(getvariableofnpc(.poke, .npc$), getarraysize(getvariableofnpc(.poke$, .npc$))); + + setarray(getvariableofnpc(.disgusting$[1], .npc$), + "Ewwwww %%^.", 1); + set(getvariableofnpc(.disgusting, .npc$), getarraysize(getvariableofnpc(.disgusting$, .npc$))); + + setarray(getvariableofnpc(.answer$[1], .npc$), + "42.", 1, + "Kittens.", 1); + set(getvariableofnpc(.answer, .npc$), getarraysize(getvariableofnpc(.answer$, .npc$))); + + setarray(getvariableofnpc(.burning$[1], .npc$), + "*curses ~p and dies %%c.*", 1, + "Help! I'm on fire!", 1, + "Oh hot.. hot hot!", 1, + "*is glowing.*", 1, + "*is flaming.*", 1, + "Ehemm. Where are firefighters? I need them now!", 1, + "*is so hot!.*", 1, + "*slowly catches fire.*", 1, + "*trembles with trepidation.*", 1, + "*is immune to fire.*", 1); + set(getvariableofnpc(.burning, .npc$), getarraysize(getvariableofnpc(.burning$, .npc$))); + + setarray(getvariableofnpc(.kill$[1], .npc$), + "*curses ~p and dies %%c.*", 1); + set(getvariableofnpc(.kill, .npc$), getarraysize(getvariableofnpc(.kill$, .npc$))); + + setarray(getvariableofnpc(.silly$[1], .npc$), + "Hahaha, good one!", 1); + set(getvariableofnpc(.silly, .npc$), getarraysize(getvariableofnpc(.silly$, .npc$))); + + setarray(getvariableofnpc(.love$[1], .npc$), + "♪♪ and IIII.. will alwayyyys loooovvve youuuuu. ♪♪ %%]", 1, + "♪♪ nothing's gonna change my love for you, you oughta know by now how much I love you.. ♪ %%]", 1, + "♪ ..and then I go and spoil it all, by saying something stupid like: “I love you.” ♪", 1, + "♪ ..won't you find a place for me? somewhere in your heart... ♪♪", 1, + "Thank you.", 1, + "♪♪ ..I can't love another when my heart is somewhere far away.. ♪", 1, + "%%]", 1); + set(getvariableofnpc(.love, .npc$), getarraysize(getvariableofnpc(.love$, .npc$))); + + setarray(getvariableofnpc(.dance$[1], .npc$), + "I would but I am rooted to the ground.", 1, + "Have you ever seen a tree dance before?", 1, + "Hahaha, good one!", 1); + set(getvariableofnpc(.dance, .npc$), getarraysize(getvariableofnpc(.dance$, .npc$))); + + setarray(getvariableofnpc(.hate$[1], .npc$), + "Right back at you!", 1, + "Ok...", 1, + "*pats ~p, let it go...*", 1, + "Hu hu hu, ~p hates me.", 1); + set(getvariableofnpc(.hate, .npc$), getarraysize(getvariableofnpc(.hate$, .npc$))); + + setarray(getvariableofnpc(.bye$[1], .npc$), + "*waves goodbye to ~p in tears, come back soon!*", 1); + set(getvariableofnpc(.bye, .npc$), getarraysize(getvariableofnpc(.bye$, .npc$))); + + setarray(getvariableofnpc(.pain$[1], .npc$), + "Ouch.", 1, + "Ouchy.", 1, + "Argh.", 1, + "Eek.", 1, + "*howls.*", 1, + "*screams.*", 1, + "*groans.*", 1, + "*cries.*", 1, + "*faints.*", 1, + "*shrieks.*", 1, + "*hides behind itself.*", 1, + "%%k", 1, + "Why, what did I do to you? %%i", 1); + set(getvariableofnpc(.pain, .npc$), getarraysize(getvariableofnpc(.pain$, .npc$))); + + setarray(getvariableofnpc(.eightball$[1], .npc$), + "It is possible.", 1, + "Yes!", 1, + "Of course.", 1, + "Naturally.", 1, + "Obviously.", 1, + "It shall be.", 1, + "The outlook is good.", 1, + "It is so.", 1, + "One would be wise to think so.", 1, + "The answer is certainly yes.", 1, + "In your dreams.", 1, + "I doubt it very much.", 1, + "No chance.", 1, + "The outlook is very poor.", 1, + "Unlikely.", 1, + "About as likely as pigs flying.", 1, + "You're kidding, right?", 1, + "NO!", 1, + "NO.", 1, + "No.", 1, + "Maybe...", 1, + "No clue.", 1, + "I don't know.", 1, + "The outlook is hazy, please ask again later.", 1, + "What are you asking me for?", 1, + "Come again?", 1, + "You know the answer better than I.", 1, + "The answer is def-- oooh! shiny thing!", 1, + "No idea.", 1, + "Perhaps.", 1, + "I think it is better not to tell you.", 1, + "Error 417: Expectation failed.", 1); + set(getvariableofnpc(.eightball, .npc$), getarraysize(getvariableofnpc(.eightball$, .npc$))); + + setarray(getvariableofnpc(.bad$[1], .npc$), + "I'm not bad! You are bad!", 1, + "OK, I'm bad.", 1, + "I'm just a littttle bad.", 1, + "Not as bad as the people that made me.", 1); + set(getvariableofnpc(.bad, .npc$), getarraysize(getvariableofnpc(.bad$, .npc$))); + + setarray(getvariableofnpc(.no_idea$[1], .npc$), + "What?", 2, + "What??", 1, + "Whatever.", 1, + "Hmm...", 2, + "Huh?", 1, + "*yawns.*", 1, + "Wait a minute...", 1, + "What are you talking about?", 1, + "Who are you?", 1, + "What about me?", 1, + "I don't know what you are talking about", 1, + "Excuse me?", 1, + "Very interesting.", 1, + "Really?", 1, + "Go on...", 1, + "*scratches its leafy head.*", 1, + "*feels a disturbance in the force.*", 1, + "%%j", 1, + "*senses a disturbance in the force.*", 1, + "I'm bored...", 1, + "%%U", 1, + "%%[", 1); + set(getvariableofnpc(.no_idea, .npc$), getarraysize(getvariableofnpc(.no_idea$, .npc$))); + + setarray(getvariableofnpc(.shut_up$[1], .npc$), + "*goes hide in a corner %%S.*", 1); + set(getvariableofnpc(.shut_up, .npc$), getarraysize(getvariableofnpc(.shut_up$, .npc$))); + + setarray(getvariableofnpc(.climb$[1], .npc$), + "*sways violently.*", 1, + "*bends all the way to the ground.*", 1, + "*creaks and bends.*", 1, + "*welcomes those who come to play %%I.*", 1, + "*beams with pride.*", 1); + set(getvariableofnpc(.climb, .npc$), getarraysize(getvariableofnpc(.climb$, .npc$))); + + return; +} diff --git a/npc/scripts.conf b/npc/scripts.conf index 6ad4e69b..cddf86da 100644 --- a/npc/scripts.conf +++ b/npc/scripts.conf @@ -107,6 +107,7 @@ // Events "npc/functions/gm_island.txt", +"npc/functions/confused-tree-dict.txt", "npc/annuals/fathertime.txt", "npc/annuals/check_time.txt", "npc/annuals/tree_beard.txt", -- cgit v1.2.3-60-g2f50