***A dump of the Adventurers Database (#46) on March 6th @create $room named Adventurers Database:Adventurers,Database,rpg @prop #46."recycler" #4489 rc @prop #46."seconds_min" 1 rc @prop #46."ticks_min" 5000 rc @prop #46."exporters" {} rc @prop #46."sheet_level" {} rc ;;#46.("sheet_level") = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 0, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 0, 1, 1, 2, 2, 1, 2, 2, 1, 2, 2, 2} @prop #46."sheet_atts" {} rc ;;#46.("sheet_atts") = {#19148, #19184, #19226, #19230, #19231, #19235, #19243, #19316, #19343, #19804, #107205, #57444, #5781, #75899, #25257, #5784, #9080, #7565, #7144, #7096, #6232, #32762, #6175, #10590, #6178, #6176, #95126, #29862, #75056, #6499, #6451, #6357, #7689, #32774, #32783, #105206, #1587, #40790, #19988, #19989, #83399, #60852, #76229, #7790, #87015, #7607, #32775, #6531, #32761, #32781, #32755, #9064, #9092, #67571, #29441, #18671, #46377, #10887, #7127, #86906, #80069, #41175, #37142, #60016, #53375, #112382, #14725, #104445, #12289, #74835, #65756, #101109, #74932, #87759, #66624, #74393, #9097, #101146, #78716, #89057, #32773, #54026, #79154, #6564, #108033, #98619, #18688, #104447, #59643, #17251, #11401, #68846, #108598, #62036, #6275, #32771, #41289, #70784, #81055, #9903, #10923, #69062, #73102, #117341, #85976, #99395, #102024, #55012, #45809, #20936, #16045, #57478, #75817, #93140, #83431, #34688, #97757, #71258, #8108, #22707, #52130, #56377, #109701, #49020, #110969, #14497, #71490, #24840, #19856, #19835, #32039, #24330, #17076, #4649, #24346, #34155, #81749, #67393, #89199, #24345, #25664, #50023, #66562, #4631, #2763, #4728, #32776, #32779, #32780, #32778} @prop #46."gms" {} rc ;;#46.("gms") = {#2693, #34876, #43860, #21077, #19845, #37972, #58456, #49397, #61219, #93228, #47818, #106488, #77500, #105941, #106469, #106487, #104762, #46102, #98232, #82267, #87516, #45216, #49925, #68, #7003, #3118, #540, #14, #89395, #63546, #50222, #31829, #1449, #100806, #108850, #117389, #100337, #116601, #119377, #30788, #106189, #50367, #102427, #112369, #114701} @prop #46."costs" {} rc ;;#46.("costs") = {1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8, 9, 10, 11, 13, 15, 17, 20, 24, 29, 35, 42, 50, 999999} @prop #46."dolls" {} rc ;;#46.("dolls") = {#1390, #3734, #3787, #4004, #4052, #4320, #8078, #18659, #23825, #18806, #31931, #41833, #41849, #32854, #28038, #29022, #51009, #26184, #51775, #17620, #16403, #52611, #24130, #51988, #53172, #20523, #26738, #29404, #13502, #31489, #49887, #52310, #54064, #29919, #29454, #24620, #47855, #57735, #41153, #27441, #55068, #37347, #34390, #50892, #56269, #55824, #48060, #21835, #3741, #16735, #31791, #51744, #61229, #35881, #62807, #44094, #67379, #73513, #71231, #73510, #32602, #55763, #3345, #69302, #68814, #4144, #72773, #4515, #72786, #65369, #65060, #84167, #12424, #61774, #13011, #89508, #75264, #88792, #80245, #56639, #90355, #97224, #97238, #97252, #97312, #28961, #97049, #9742, #66136, #58410, #100848, #52999, #51620, #70640, #71119, #91803, #8384, #3259, #33402, #5048, #2058, #71253, #69416, #57870, #8986, #10173, #52437, #8355, #76993, #93782, #87663, #60721, #13007, #60793, #28617, #96270, #11776, #43431, #76087, #97067, #93189, #47568, #101475, #88576, #92765, #82789, #98895, #23270, #49937, #58286, #7384, #79705, #61532, #94754, #67546, #68745, #5830, #62033, #27734, #81317, #48400, #96845, #67302, #55891, #14643, #3018, #56519, #95273, #75107, #84951, #102052, #58764, #77749, #16177, #11573, #70513, #86454, #70577, #71689, #81184, #89210, #70665, #97793, #60332, #103196, #11390, #100994, #64275, #106869, #104279, #54518, #10967, #64372, #7252, #35371, #77636, #90875, #84464, #5285, #46616, #79618, #94369, #7016, #2209, #51123, #92230, #3358, #30279, #100360, #5779, #30459, #107885, #96550, #73705, #48507, #70680, #64213, #111936, #22572, #55147, #5481, #59247, #61608, #57116, #103345, #9667, #13399, #91479, #92788, #17078, #101379, #112995, #96378, #1774, #81683, #90308, #16131, #100567, #21336, #13268, #72274, #102501, #45276, #20943, #55357, #2451, #2968, #75149, #27411, #11013, #100451, #50965, #74106, #113709, #90364, #54015, #87720, #79702, #62888, #94490, #108023, #113734, #109951, #34523, #72092, #111137, #74217, #24275, #90345, #88834, #56196, #79809, #24128, #82014, #69378, #91346, #14632, #74421, #59917, #91199, #105335, #53073, #24997, #49788, #115292, #95432, #28881, #70317, #90064, #45671, #86258, #6081, #59886, #69599, #8133, #94127, #95797, #36083, #87587, #98130, #90278, #67703, #110533, #104471, #111301, #17205, #98551, #103275, #104097, #19373, #108585, #113324, #81738, #14838, #75010, #110106, #38031, #4983, #115206, #96826, #63856, #83645, #91704, #86628, #10665, #49440, #61244, #55074, #53506, #74171, #102229, #4639, #63496, #78129, #90245, #81004, #66939, #50103, #106063, #89890, #89586, #45020, #101620, #108070, #45811, #42571, #112392, #109476, #71435, #75337, #72443, #67261, #114815, #67054, #11881, #81613, #73519, #55237, #107040, #68208, #18661, #98202, #112144, #87184, #69325, #115783, #111669, #99985, #4483, #2196, #82434, #43655, #14872, #10979, #96002, #94749, #89957, #17158, #10575, #102797, #104858, #118737, #23337, #99442, #103917, #22747, #97414, #107893, #106110, #109650, #116641, #66998, #33188, #106922, #53362, #92393, #16934, #94986, #91987, #78355, #55692, #93739, #54636, #72766, #112030, #62438, #54350, #52180, #113398, #44125, #16987, #114998, #116651, #2372, #69105, #84307, #51599, #38771, #44228, #68157, #114841, #106644, #58013, #101796, #100826, #54097, #51681, #33090, #54696, #93524, #118953, #55854, #68010, #58066, #115296, #55743, #88022, #15784, #57440, #52320, #68798, #71789, #17717, #53195, #81299, #55604, #89543, #80521, #118571, #82542, #91963, #9717, #113883, #111442, #59409, #97819, #8316, #94875, #51734, #94539, #4527, #68957, #102921, #115158, #3563, #112537, #14455, #92158, #51008, #94516, #63401, #16854, #86550, #103069, #46615, #9672, #11018, #113478, #56037, #61118, #90708, #95535, #108341, #66475, #12479, #74840, #88091, #59230, #64608, #116141, #50663, #65583, #77575, #121683, #107937, #66179, #96670, #75154, #84499, #3287, #32357, #11576, #83138, #121608, #105308, #15518, #74538, #12683, #40508, #69004, #60716, #57485, #14477, #76745, #59743, #81052, #37054, #51551, #13510, #16030, #114345, #114057, #59143, #58642, #95925, #118662, #64397, #119861, #11627, #60300, #72869, #103087, #113891, #47803, #87403, #114568, #66655, #72891, #117227, #104892, #59405, #31779, #120441, #43634, #72919, #96467, #15459, #109749, #51438, #98444, #16091, #52573, #10683, #108779, #81028, #86117, #65990, #43906, #117434, #113951, #97838, #85215, #70184, #102058, #39780, #14719, #71780, #112148, #56573, #121552, #8138, #105311, #30397, #60227, #76286, #71226, #103636, #4861, #9482, #73621, #54553, #56827, #111764, #54073, #111037, #114949, #117103, #72339, #58323, #26020, #80566, #120726, #91855, #58884, #57419, #95226, #119842, #23545, #65069, #15514, #116092, #110222} @prop #46."attdeps" {} rc ;;#46.("attdeps") = {{{}, {"ohswd"}}, {{"agl", "agl", "agl", "pcn", "agl"}, {}}, {{"end", "end", "end", "wil", "end"}, {}}, {{}, {"melee"}}, {{"agl", "str", "agl"}, {}}, {{}, {"ohhfw"}}, {{}, {"melee"}}, {{}, {"melee"}}, {{}, {"thhft"}}, {{}, {"ohswd"}}, {{}, {"melee"}}, {{}, {"melee"}}, {{"melee", "agl", "pcn", "str"}, {}}, {{}, {"shield"}}, {{"int", "wil", "int"}, {}}, {{}, {"magic"}}, {{}, {"fire"}}, {{}, {"thhft"}}, {{"agl", "str", "wil", "agl", "str"}, {}}, {{"wil", "wil", "int", "wil", "pcn"}, {}}, {{"str", "agl", "end", "str"}, {}}, {{}, {"thhft"}}, {{}, {}}, {{}, {}}, {{}, {}}, {{}, {}}, {{}, {}}, {{}, {}}, {{}, {}}, {{}, {}}, {{}, {}}, {{}, {"ecto"}}, {{}, {"gadget"}}, {{"dex", "int", "pcn"}, {}}, {{}, {"ecto"}}, {{"agl", "str", "pcn"}, {}}, {{}, {"throw"}}, {{}, {"climb"}}, {{}, {"ohswd"}}, {{}, {"melee"}}, {{}, {"natweap"}}, {{}, {"natweap"}}, {{}, {"natweap"}}, {{"ohswd"}, {"kat"}}, {{"thswd"}, {"kat"}}, {{}, {"climb"}}, {{}, {}}, {{}, {"knives"}}, {{}, {"magic"}}, {{}, {"time"}}, {{}, {"magic"}}, {{}, {"force"}}, {{}, {"melee"}}, {{"ohhfw"}, {"baxe"}}, {{"thhft"}, {"baxe"}}, {{"dex", "pcn", "dex", "int"}, {}}, {{}, {"drive"}}, {{}, {"bike"}}, {{}, {"fire"}}, {{}, {"magic"}}, {{}, {"life"}}, {{}, {"knives", "melee"}}, {{}, {"longarms"}}, {{}, {"missiles"}}, {{"dex", "pcn", "dex"}, {}}, {{}, {"missiles"}}, {{}, {"drawbow"}}, {{}, {}}, {{}, {"spear"}}, {{}, {"javelin", "throw"}}, {{}, {"javelin", "melee"}}, {{}, {"missiles"}}, {{}, {"handguns"}}, {{"pcn", "wil", "pcn"}, {}}, {{}, {"observe"}}, {{}, {"observe"}}, {{}, {"throw"}}, {{"app", "wil", "emp"}, {}}, {{}, {"convince"}}, {{}, {"convince"}}, {{}, {"trick"}}, {{}, {"dagger", "throw"}}, {{}, {"dagger", "melee"}}, {{}, {"ohswd"}}, {{}, {"thhft"}}, {{}, {"fire"}}, {{}, {"gadget"}}, {{"dex", "emp", "wil"}, {}}} @prop #46."atts" {} rc ;;#46.("atts") = {"brswd", "dodge", "shock", "ohswd", "melee", "club", "ohhfw", "thhft", "tclub", "rap", "kat", "thswd", "shield", "kites", "magic", "fire", "firebolt", "staff", "climb", "sanity", "swim", "scyth", "str", "end", "dex", "agl", "int", "emp", "wil", "pcn", "app", "gadget", "throw", "furn", "wclim", "scim", "natweap", "claw", "tenta", "teeth", "kat1", "kat2", "tclimb", "knives", "dagger", "time", "slow", "force", "forcewall", "baxe", "baxe1", "baxe2", "drive", "heat", "life", "heal", "sai", "crossbow", "longarms", "missiles", "drawbow", "longbow", "spear", "javelin", "javelin_throw", "javelin_melee", "handguns", "revolver", "observe", "notice", "search", "star", "convince", "persuade", "trick", "pray", "dagger_throw", "dagger_melee", "machete", "pick", "storm", "lockpick", "spellsing", "thieving", "teleport", "charm", "recall", "pacify", "stamina", "brawl", "moofu", "magic_theory", "creo", "intellego", "muto", "perdo", "rego", "corporem", "ignem", "vim", "animalem", "mentem", "aquam", "herbam", "imagonem", "terram", "depress", "calm_winds", "shatter", "windwall", "stinkcloud", "predict", "whip", "harden", "enchant", "biting_cloud", "barkskin", "hail", "lifelink", "stealskill", "mindprobe", "waterwhip", "iceshell", "dispel", "claim", "auram", "shocking_grasp", "unarmed", "greatsword", "summon"} @prop #46."pcs" {} rc ;;#46.("pcs") = {#1381, #3730, #3777, #4002, #4048, #1214, #8077, #17777, #19044, #4418, #13573, #4981, #10249, #16104, #21598, #15458, #7057, #5632, #26608, #35896, #52165, #40259, #2955, #42381, #53178, #53798, #45991, #31020, #45622, #40379, #40890, #51765, #51082, #44015, #55272, #6527, #8953, #50841, #36198, #20474, #48474, #22224, #7686, #39500, #16410, #53941, #53978, #22055, #51809, #57159, #56543, #61004, #9096, #102, #62858, #56299, #33020, #73468, #73054, #71798, #73373, #72883, #32401, #79574, #79214, #4142, #8954, #8952, #85990, #4677, #29929, #4375, #4186, #74798, #77819, #83797, #33931, #1383, #93374, #67730, #7151, #94799, #41501, #26450, #21252, #97587, #95558, #90796, #61620, #63670, #66635, #365, #819, #820, #1453, #2805, #2992, #3048, #3094, #3098, #3764, #3032, #3760, #3956, #4049, #4050, #7965, #10441, #11966, #2230, #15844, #15907, #15908, #15990, #12689, #86696, #103632, #73404, #58625, #87886, #88892, #83242, #8891, #1112, #20800, #1092, #69439, #66341, #104015, #98531, #1285, #1298, #1355, #1338, #1348, #1091, #1011, #76667, #87453, #1798, #1251, #9799, #9365, #7744, #75947, #52869, #4713, #1742, #6113, #5003, #4688, #12763, #1178, #1179, #79322, #1987, #2705, #2605, #41330, #15884, #63530, #52868, #6 >> Network buffer overflow: 993 lines of output to you have been lost << else wielding_msg = s_u:pronoun_sub((" %S % wielding " + s_u:title_list(wielding)) + ".", who); endif player:tell(wearing_msg + wielding_msg); if (special) player:tell(s_u:from_list(special, " ")); endif "Quinn 31-JUL-93 2247-ET: Re-written to use modern core verbs; minor changes to variable choice; inclusion of ALL things wielded if more than 2"; "Quinn 10-AUG-93 0226-ET: Hacked to print 'only' hand instead of 'primary' if the character has only one hand."; "Quinn 12-AUG-94 1418-ET: Check :hide_from_look_gear returning true, and do not show weapon if so. Messages now support verb conj/plural players, and are more informative, including support for natural weapons. Remove !rpg_thing equipment."; "Quinn 12-AUG-94 1554-ET: Added :look_gear_msg verb check for special display of certain equipment."; "Quinn 26-SEP-94 0938-ET: Stuck .crest in shield:look_gear_msg. Items MUST define a :hide_from_look_gear returning true if they wish to be excluded from the mundane listing, even if they define a :look_gear_msg."; "StarDancer 10-NOV-94 0035-ET: Added a `armed with' msg for monsters who's .animal prop is set 'cause most animals don have hands."; "Profane 22-JUN-96 0018EST -- Added hook for custom verb on monsters"; . @verb #46:"approve_att_change" this none this rx @program #46:approve_att_change ":log_att_change(player, {doll, attribute, new_value}, callers)"; "Return E_PERM if the given attribute change should not be permitted."; "(Right now this is used only to log stat changes. Set 'logging_att_changes' to the log length desired.)"; if (caller_perms() == this.owner) {who, info, stack} = args; {doll, att, val} = info; if (is_player(char = doll.character) && ((char in this.fishy) || ((abs(val - doll.(att)) > 20) && (att != "inj")))) if ((att in this.no_log_atts) || ((who in this.gms) && (char in this.gms))) "... do nothing ..."; "Since practically every time ya move, .act gets set, let's filter it out."; elseif ((len = this.logging_att_changes) > 1) log = listinsert(this.att_change_log, {time(), who, info, stack ? stack | callers()}, 1); log = log[1..min($, len)]; this.att_change_log = log; endif endif {prog, object} = stack[1][3..4]; if (((prog in this.probation) || (object in this.banned_from_mod)) || (att in this.unsettable_values)) return E_PERM; endif return 1; else return E_PERM; endif . @verb #46:"view_att_log" this none this @program #46:view_att_log if (!(caller_perms() in {@this.grand_masters, @this.spies})) return E_PERM; else return {this.fishy, this.att_change_log}; endif . @verb #46:"add_doll" this none this @program #46:add_doll " add_doll(OBJ character, OBJ doll) -> BOOLEAN success may suspend"; "Adds doll to this.dolls and character to this.pcs, associated with"; "each other. The character may not have another doll already registered."; if (!this:trusted(caller_perms())) return E_PERM; endif character = args[1]; doll = args[2]; if (((!$object_utils:isa(doll, this.doll)) || (doll.character != character)) || (character in this.pcs)) return E_INVARG; endif $command_utils:suspend_if_needed(this.gm_lag); this.pcs = {@this.pcs, character}; this.dolls = {@this.dolls, doll}; return 1; "June 28, 1995 -- Slither, first version"; . @verb #46:"rm_pc" this none this @program #46:rm_pc " rm_pc(OBJ pc) => OBJ doll may suspend"; "Removes the (pc/doll) pair from this.pcs/this.dolls lists. Returns"; "the removed doll."; if ((caller == this) || this:trusted(caller_perms())) this:s_i_n(); pos = args[1] in this.pcs; if (pos) dolls = this.dolls; this.pcs = listdelete(this.pcs, pos); this.dolls = listdelete(dolls, pos); return dolls[pos]; else return E_INVARG; endif else return E_PERM; endif "June 28, 1995 -- Slither, first version"; . @verb #46:"rm_doll" this none this @program #46:rm_doll " rm_doll(OBJ doll) => OBJ pc may suspend"; "Removes the (pc/doll) pair from this.pcs/this.dolls lists. Returns"; "the removed RPG character."; {doll} = args; this:secure(); this:s_i_n(); pos = doll in this.dolls; if (!pos) return $object_utils:isa(doll, this.doll) ? 1 | E_INVARG; endif pcs = this.pcs; this.dolls = listdelete(this.dolls, pos); this.pcs = listdelete(pcs, pos); return pcs[pos]; "June 28, 1995 -- Slither, first version"; . @verb #46:"reap_protect_pc" this none this @program #46:reap_protect_pc " :reap_protect_pc(OBJ pc, NUM time, OBJ gm, STR comment) => BOOL changed"; "Keeps the player `pc' from having their doll reaped until after `time'."; "`gm' should be the gm to contact about this, and `comment' allows one"; "to explain any unusual circumstances. If the player is already protected,"; "then this call will replace the previous data."; if (!this:trusted(caller_perms())) return E_PERM; endif pc = args[1]; time = args[2]; if (((length(args) != 4) || (!is_player(pc))) || (time < time())) return E_INVARG; endif olddata = this.reap_protected_pcs; pos = pc in olddata[1]; if (pos) newpcs = olddata[1]; newpcdata = olddata[2]; newpcdata[pos] = listdelete(args, 1); else newpcs = {@olddata[1], pc}; newpcdata = {@olddata[2], listdelete(args, 1)}; endif this.reap_protected_pcs = {newpcs, newpcdata}; return 1; "July 31/95 Slither -- first version"; . @verb #46:"unreap_protect_pc" this none this @program #46:unreap_protect_pc " :unreap_protect_pc(OBJ pc)"; "Removes any RPG reap protection for pc"; if (!this:trusted(caller_perms())) return E_PERM; endif pc = args[1]; data = this.reap_protected_pcs; pos = pc in data[1]; if (pos) newpcs = listdelete(data[1], pos); newpcdata = listdelete(data[2], pos); this.reap_protected_pcs = {newpcs, newpcdata}; endif "July 31/95 Slither -- first version"; . @verb #46:"is_reap_protected" this none this @program #46:is_reap_protected " :is_reap_protected(OBJ pc) => LIST data "; "If pc is protected from the RPG reap, returns {time, gm, comment},"; "otherwise returns {}. 'time' is the time the pc is protected until,"; "and 'gm' is the gm to talk to about this, and 'comment' is any"; "comment that was provided about protecting this player."; pc = args[1]; pos = pc in this.reap_protected_pcs[1]; if (pos) data = this.reap_protected_pcs[2][pos]; if (data[1] < time()) this:unreap_protect_pc(pc); return {}; else return data; endif else return {}; endif "July 31/95 Slither -- first version"; . @verb #46:"cleanse_reap_protected_pcs" this none this @program #46:cleanse_reap_protected_pcs " :cleanse_reap_protected_pcs() may suspend"; "removes any invalid or useless entries from this.reap_protected_pcs"; for pc in (this.reap_protected_pcs[1]) $command_utils:suspend_if_needed(10); if (!is_player(pc)) "pc isn't a player anymore!"; this:unreap_protect_pc(pc); else rpp = this.reap_protected_pcs; pos = pc in rpp[1]; if (pos && (rpp[2][pos][1] < time())) "protection expired"; this:unreap_protect_pc(pc); endif endif endfor return 1; "July 31/95 Slither -- first version"; . @verb #46:"reap_protected_pcs" this none this @program #46:reap_protected_pcs " :reap_protected_pcs() => {LIST pcs, LIST pcdata} may suspend"; "returns data on all the pcs that are protected from the RPG reap."; "The data is in the following format:"; " pcs is a list of all the protected pcs"; " pcdata is a list such that pcdata[i] is the data about pcs[i],"; " and pcdata[i] is in the format {time, gm, comment}, where"; " time is the time the protection expires"; " gm is the gm who is listed as being the person to ask about this,"; " comment is any comment they made about this protection"; this:cleanse_reap_protected_pcs(); return this.reap_protected_pcs; "July 31/95 Slither -- first version"; . @verb #46:"rpg_announce*_all" this none this @program #46:rpg_announce_all ":rpg_announce(, ) -> As a regular room:announce for location, but only spews to non-sleeping players."; {where, @string} = args; this:secure(); this:rpg_announce_all_but(where, (verb == "rpg_announce") ? {player} | {}, @string); "THX1138 (#105941) - Sun Apr 19, 1998 - Changed code to send to this:rpg_announce_all_but() to save on maintaining identical code."; . @verb #46:"rpg_announce_all(older)" this none this @program #46:rpg_announce_all(older) ":rpg_announce_all(, ) -> As a regular room:announce for location, but only spews to non-sleeping players."; {where, @string} = args; this:rpg_announce_all_but(where, {}, @string); "THX1138 (#105941) - Sun Apr 19, 1998 - Changed code to send to this:rpg_announce_all_but() to save on maintaining identical code."; . @verb #46:"is_rpg_room" this none this @program #46:is_rpg_room return this.object_db:(verb)(@args); . @verb #46:"is_monster" this none this @program #46:is_monster return this.object_db:(verb)(@args); . @verb #46:"rate_skill skill_rate" this none this @program #46:rate_skill ":rate_skill(NUM score, NUM max possible score) => STR word rating of score compared with max"; {score, max} = args; if ((score < 0) || (max < 1)) return "subhuman"; else names = this.rate_words; point_spread = max / (length(names) - 3); if (point_spread) score = score / point_spread; score = score ? score | 1; else excess = (length(names) - max) - 3; names = names[1..($ - 3) - (excess - (excess / 2))]; names = names[(excess / 2) || 1..$]; endif score = (score > length(names)) ? length(names) | score; score = score ? score | 1; return names[score]; endif . @verb #46:"gmlist" this none this @program #46:gmlist rpg_helpers = #58390:group_members(); help_names = {}; for who in (rpg_helpers) help_names = (valid(who) && is_player(who)) ? {@help_names, $string_utils:nn(who)} | help_names; endfor return $string_utils:columnize(help_names, 3); . @verb #46:"rpg_lag" this none this @program #46:rpg_lag ":rpg_lag() => How much are we delaying RPG actions to control lag?"; return this.gm_lag; "THX July 23, 1998 - Bypass this dog's breakfast of Irin's code that uses scads of ticks."; try if (q = queued_tasks()) n = 1; while ((n <= length(q)) && (q[n][2] <= (time() - 1000000))) n = n + 1; endwhile a = q[n][2]; if (a == 0) return this.min_command_interval; endif lag = min(time() - a, 3600); return max(this.min_command_interval, (10 * lag) / this.lag_standard); else return this.min_command_interval; endif except x (ANY) return this.min_command_interval; endtry . @verb #46:"restore_pc" this none this @program #46:restore_pc ":restore_pc(who, doll) => restores doll to who, saving their other doll."; {who, newdoll} = args; this:secure(); {rpg_doll, player_start, death_db} = {this.doll, this.player_start, this.death_db}; if ((!is_player(who)) || (!$object_utils:isa(newdoll, rpg_doll))) return E_NACC; endif if (newdoll.character != who) return E_INVARG; endif if (n = newdoll in this.dolls) return E_NONE; endif if (n = who in this.pcs) this:save_doll(this.dolls[n]); elseif ((!(caller in {this.magic_db, this.object_db.hack_db})) && player_start:is_banned(who)) player:tell("Have the player to be restored go the the Initiation Chamber first."); return E_INVIND; endif if ((who in this.macro_users) && (caller_perms() != this.owner)) return player:tell("Only Grand_Master can restore an indicted macro user."); endif banned = player_start.banned_for_life; for t in (this.saved_dolls) if ((parent(t) != rpg_doll) || (t.character in banned)) this.saved_dolls = setremove(this.saved_dolls, t); endif endfor this.pcs = {@this.pcs, who}; this.dolls = {@this.dolls, newdoll}; this.saved_dolls = setremove(this.saved_dolls, newdoll); this.object_db.CAP_corrector:correct_doll(newdoll); death_db.corpse_dolls = setremove(death_db.corpse_dolls, newdoll); this.guild_db:restore_guilds(newdoll); this.puzzle_log:restore_puzzles(newdoll); for x in (newdoll.natural_weapons) this.object_db.natweap_db:remove_natweap(newdoll, x); endfor newdoll.resurrected = time(); return newdoll; "THX 27-Mar-1997 -- Added splurge to remove newdoll from this.saved_dolls ... to save time for manually restoring PCs when searching through the list."; "Profane 8-APR-97 1618PST -- return newdoll"; "Mooshie (#106469) - Tue Jan 13, 1998 - guild DB and puzzle log hook."; "THX (#105941) - Mon Jan 26, 1998 - Added a blurb to clean out this.saved_dolls which needs to be done only occasionally."; "THX (#105941) - Wed Feb 18, 1998 - Added a requirement that the player to be restored must already have a voodoo doll. This will prevent banned players from using registered seconds."; "THX (#105941) - Mon Nov 1, 1999 - Added a call to the CAP_corrector upon rebirth."; "THX (#105941) - Fri Jun 1, 2001 - Allow hack_db to resurrect as well as magic_db."; "Hannibal (#104762) - Wed July 25, 2001 - Set newdoll.resurrected to time()."; "Hydros (#106189) - Tue Mar 15, 2005 - Removed all natural weapons that might be lingering on the doll--because mailed fists were sticking around."; . @verb #46:"check_notification" this none this @program #46:check_notification this:secure(); return this.notifier:check_notification(@args); "Route to RPG notifier."; ":check_notification(OBJ|LIST to_be_notified, STR notify_verb, LIST args)"; "The verb now accepts a list as an arg, no longer checks :get_doll, and justspews the data, ignoring whether its a valid doll OR object."; if (!this:trusted(caller_perms())) return E_PERM; endif {x, verbname, argslist} = args; if (verbname[1..7] != "notify_") return E_PERM; endif for object in ((typeof(x) == LIST) ? x | {x}) if (this:is_monster(object)) value = `object:(verbname)(@argslist) ! ANY'; endif endfor "New check_notification hacked by Quinn 03-JAN-93."; "Profane 13-APR-95 14:20EST - Added :trusted_verb check, thus adding 46 ticks per notify call.."; "THX 13-FEB-97: Version 1.8.0 update, de-ticked and removed Profane's grudging :trusted_verb check in favour of an is_monster check."; . @verb #46:"trusted_verb trusted_property" this none this rxd #58016 @program #46:trusted_verb ":trusted_verb/property(OBJ object, STR verbname | STR propname)"; "Return true if the indicated verb/property is owned by a player in $local.rpg.gms. Return 0 if it is not, or an error if the arguments are invalid."; "--WIZARDLY--"; {object, name} = args; if (verb == "trusted_property") if ($object_utils:has_property(object, name)) where = object; else return E_PROPNF; endif else if (`{where} = $object_utils:has_callable_verb(object, name) ! ANY => 0') "... do nothing ... "; else return E_VERBNF; endif endif try {info, @extra} = (verb == "trusted_verb") ? verb_info(where, name) | property_info(where, name); return info in this.gms; except error (ANY) return error[1]; endtry "Copied from Grand_Master (#2693):trusted_verb Sun Oct 9 10:00:39 1994 PDT"; "Copied from Quinn (#19845):trusted_verb Sun Feb 6 16:02:53 1994 PST"; "Isagi 100894 11:00P Fixed feature that caused E_VERBNF to be returned if there was no verb, but there was a property."; "THX1138 02-16-97 10:00EST - Got rid of needless assignments and handled everything with scatter assignments to improve readability and to reduce _indexing_ into lists that were _created_ a few lines previously."; . @verb #46:"secure" this none this @program #46:secure ":secure() => raise E_PERM if we don't like the look of whoever called your verb (i.e., a builtin, or non-GM permed verb called you.)"; if (callers()[2][3] in this.gms) return; endif (caller_perms() in this.ex_gms) ? kill_task(task_id()) | raise(E_PERM, "RPG Security Violation!"); "Profane 1-APR-97 1708PST -- added bit for command-line verbs"; "Irin Thu Apr 3 12:33:06 1997 PST -- Unceremoniously sent the code for command-line verbs to #46:secure_x(). Thus saving 1 tick."; "THX (#105941) - Fri Mar 23, 2001 - Added ex_gm check IFF the verb's about to raise an error."; . @verb #46:"secure_stack" this none this @program #46:secure_stack ":secure_stack([trust builtin at end]) => Check if all calling verbs up to and incuding the first verb not of the same name and location are GM permed. the optional argument, if true, means that we would trust a builtin to be the first caller in this."; "The idea with this verb is to make just one security check for a whole bunch of callers. Put the security check on the root verb (example, #258:enterfunc). Then, all the other enterfuncs which call #258:enterfunc (example: #9505:enterfunc) can just 'pass(@args)' first. We reach the root of the secure stack, make the security check, raise an error if it failed, otherwise all the code in the stack is secure. Cool, huh?"; {?trust_builtin = 0} = args; gms = this.gms; callers = callers(); calling_object = callers[1][1]; calling_verb = callers[1][2]; for caller in (callers[2..$]) if ((caller[1] == calling_object) && (caller[2] == calling_verb)) if (caller[3] in gms) else raise(E_PERM, "RPG Security Violation. Insecure stack verb."); endif elseif ((caller[3] in gms) || (((trust_builtin && caller[2]) && (caller[3] == #-1)) && (caller[4] == #-1))) return; else raise(E_PERM, "RPG Security Violation. Insecure stack caller."); endif endfor . @verb #46:"merge_dolls" this none this @program #46:merge_dolls ":merge_dolls(new, old) => Merge stats on 'old' with 'new'. Recycle 'old'."; this:secure(); {new, old, ?numer = 2} = args; doll = this.doll; if ((((((parent(new) != doll) || (parent(old) != doll)) || (new.character != old.character)) || (!(old in this.saved_dolls))) || (!(new in this.dolls))) || (numer < 1)) "Checking that all dolls and doll.characters are properly aligned, and that the mixing ratio is at least 1:1."; return E_INVARG; endif denom = numer + 1; for skill in ($object_utils:descendants_suspended(this.skill_object)) sk = skill.aliases[1]; try hi = max(old.(sk), new.(sk)); lo = min(old.(sk), new.(sk)); new.(sk) = ((numer * hi) + lo) / denom; except (ANY) "darn. Somebody made a skillobject without a prop on the doll. Owell."; endtry $command_utils:suspend_if_needed(this.gm_lag); endfor this.guild_db:restore_guilds(old); this.puzzle_log:restore_puzzles(old); this.saved_dolls = setremove(this.saved_dolls, old); return 1; "Mooshie (#106469) - Tue Jan 13, 1998 - Restore old guild/puzzle info."; . @verb #46:"secure_x" this none this @program #46:secure_x ":secure() => raise E_PERM if we don't like the look of whoever caller your verb (i.e., a builtin, or non-GM permed verb called you."; if (`callers()[2][3] ! E_RANGE => player' in this.gms) return; endif raise(E_PERM, "RPG Security Violation!"); "Profane 1-APR-97 1708PST -- added bit for command-line verbs"; . @verb #46:"sheet_text" this none this @program #46:sheet_text ":sheet_text(OBJ doll, [NUM type of sheet]) -> LIST text containing info on who's skills and whatnot."; "Types: 1 = Basic (words, left column only); 2 = Intermediate (words, no zeros), 3 = Advanced (words, all), 4 = Arcane (numbers, all)"; this:secure(); {doll, ?type = 1} = args; if (parent(doll) != this.doll) raise(E_INVARG, "Error: Non-doll passed to :sheet_text"); endif who = doll.character; {su, cu} = {$string_utils, $command_utils}; atts = this.sheet_atts; lev = this.sheet_level; text = {}; len = length(atts); sec = su:space((type < 4) ? 12 | 25); loc = 0; q = 1; fit = (type < 4) ? 12 | 3; while (q <= len) cu:suspend_if_needed(lag = this.gm_lag, "Suspending the generation of ", who.name, "'s statistics. Will resume shortly. [approx. ", lag, " seconds]"); line = ""; att = atts[q]; val = doll.(att.aliases[1]); i = lev[q]; if (((i == 0) || (type > 2)) || (val && (type > 1))) for x in [1..i] line = line + sec; endfor sum = doll:total(att); valword = (type < 4) ? this:rate_skill(val, 25) | tostr(val); sumword = (type < 4) ? this:rate_skill(sum, doll:potential_total(att)) | tostr(sum); line = ((((line + su:left((length(att.name) < 15) ? att.name | att.name[1..14], 15)) + (val ? su:right(valword, fit) | su:space(fit))) + " (") + su:right(sumword, fit)) + ") "; endif q = q + 1; if (line) text = {@text, line}; endif endwhile return text; "Profane 15-APR-97 1112PST -- hacked up old verb to create different versions."; . @verb #46:"slip_text" this none this @program #46:slip_text ":slip_text(OBJ chracter) -> return list of text for a slip of parchment"; {who, ?type = 1} = args; if (!this:trusted(caller_perms())) return E_PERM; elseif (!this:trusted(caller.owner)) caller.owner:tell("You may as well recycle ", $string_utils:nn(caller), ". You ain't gonna get anything out of it."); return E_PERM; elseif (!valid(doll = this:get_doll(who))) return {"NO INFORMATION FOUND ON SUBJECT"}; elseif ((player in this.gms) || (this.gm_lag < this.idle_threshold)) text = {tostr("Agent : ", crypt(caller.name), "--", caller), tostr("Date : ", who:ctime() || ctime()), tostr("Player: ", who.name, " (", who, ") Doll: ", doll, (who in this.gms) ? " *** GameMaster ***" | ""), ""}; text = {@text, @this:sheet_text(doll, type)}; return text; else return player:tell("The MOO is too busy to generate sheet stats at the moment. Try when LambdaMOO is less lagged."); endif . @verb #46:"get_att" none none none rxd @program #46:get_att {att} = args; if (caller_perms() in this.gms) return (att in this.no_view) ? (caller_perms() in this.grand_masters) ? this.(att) | {} | `this.(att) ! ANY => {}'; else return E_PERM; endif . @verb #46:"sample_lag" this none this @program #46:sample_lag if (!(caller_perms() in this.grand_masters)) return E_PERM; endif lag = (time() - this.last_lag_sample) - 15; this.lag_samples = {lag, @this.lag_samples[1..3]}; "Now compute the current lag and store it in a property, instead of computing it in :current_lag, which is called a hundred times a second."; thislag = max(0, (time() - this.last_lag_sample) - this.lag_sample_interval); if (thislag > 3600) "more than an hour, probably the lag sampler stopped"; this.current_lag = 0; else samples = this.lag_samples; sum = 0; cnt = 0; for x in (listdelete(samples, 1)) sum = sum + x; cnt = cnt + 1; endfor this.current_lag = max(thislag, samples[1], samples[2], sum / cnt); endif fork (15) this:sample_lag(); endfork this.last_lag_sample = time(); lag_samples = setremove(this.lag_samples, max(@this.lag_samples)); this.gm_lag = $login.checkpoint_in_progress + (min(240, max(@lag_samples, $login.current_lag / 2) / 4) * this.object_db.lag_beast.alive); "THX 17-Jun-1997 -- Ripped this code offa $login and reconfigured for G_M's usage."; "THX (#105941) - Tue Nov 17, 1998 - Added a line to truncate the largest of G_M's lag samples ... let's try to ignore transient spikes. Also truncate the lag at 240 seconds which is backing off enough for bloody well anyone."; "THX (#105941) - Wed Dec 20, 2000 - Added $login.checkpoint_in_progress straight in ... so His Eminence will back off an additional second during checkpoint."; . @verb #46:"gm_lag" this none this @program #46:gm_lag return this.gm_lag; . @verb #46:"check_doll" this none this @program #46:check_doll "Usage: check_doll(OBJ doll [, INT hands needed [, boolean sleeping ok? [, boolean resting ok? [, STR sleep msg [, STR rest msg [, STR not-enough hands msg ]]]]])"; {doll, ?hands = 0, ?sleeping = 0, ?resting = 0, ?sleep_msg = "You dream of doing great things.", ?rest_msg = "You should probably get off your can before trying that.", ?hand_msg = "You seem to have run out of hands necessary for that."} = args; who = doll.character; if (sleeping) if (resting) if (doll:long_enough()) if (msg = doll.paralyzed) who:tell((typeof(msg) == STR) ? msg | "You're paralyzed. Knock it off."); elseif (is_player(who) && (`idle_seconds(who) ! ANY => 301' > 300)) who:tell("Try doing that when you're actually at the keyboard, eh?"); endif else who:tell("It will take at least ", tostr((doll.last_attack - time()) + rpg:rpg_lag()), " seconds to recover."); endif elseif (`who.location:resting() ! E_VERBNF => 0') who:tell(rest_msg); endif elseif (`who.location:sleeping() ! E_VERBNF => 0') who:tell(sleep_msg); endif . @verb #46:"trusted_efunc" this none this @program #46:trusted_efunc "Usage: trusted_efunc()"; "Called from an :exitfunc or :enterfunc to make sure that it's either a) being called legitimately from something moving in or out of the room, or b) being called by GM perms."; if (length(calls = callers()) > 1) {it, name, prog, @rest} = calls[2]; return ((it == caller) || (prog in this.gms)) || ((!valid(it)) && (name in {"move", "recycle"})); endif return 0; . @verb #46:"initiate_pc" this none this rxd #2487 @program #46:initiate_pc "Check the bloodline of the player. If E is ok, call this:def_pc()."; if (caller == (start = #88)) {pc} = args; if ((pc in connected_players()) && (pc.location == start)) banned = {@start.banned_for_life, @$list_utils:slice(start.banned, 1)}; cr = $local.second_char_registry; all_chars = cr:is_shared_char(pc) ? cr:shared_owners(pc) | cr:all_chars(pc); for t in (all_chars) if (t in banned) if (pos = pc in this.pcs) this.pcs = listdelete(this.pcs, pos); this.dolls = listdelete(this.dolls, pos); endif return; endif endfor (pc in this.pcs) || this:def_pc(pc); endif else return E_PERM; endif "Wizard permissions required."; "THX1138 (#105941) - Mon Jan 26, 1998 - Added this code to prevent secondary characters of LRPG-banned characters from getting new dolls."; "THX1138 (#105941) - Thu May 21, 1998 - subst /this.player_start/#88/ to prevent any chance of hacking the caller here."; . @verb #46:"trusted_fefunc" this none this @program #46:trusted_fefunc "Usage: trusted_fefunc()"; "Stands for trusted fertile efunc. Does the same thing as #332:secure_efunc, but is for use when called by a fertile room parent. It needs to check for :enterfunc/:exitfunc verbs defined on children, which adds ticks."; if ((len = length(calls = callers())) > 2) original = callers[1][1]; for call in (calls) {it, name, prog, @rest} = call; if ((prog in gms) || ((!valid(it)) && (name in {"move", "recycle"}))) return 1; elseif (it != original) return 0; endif endfor endif return 0; . @verb #46:"log_error" this none this @program #46:log_error "Snagged from Irin (#106049):log_error Wed Mar 11 21:22:49 1998 PST"; "RPG:log_error(STR/LIST error) => Report some sort of funky error to appropriate parties."; this:secure(); {error} = args; error = (typeof(error) == LIST) ? error | {error}; error = {ctime(), $string_utils:nn(caller), $string_utils:nn(caller_perms()), @error}; this.errors = listappend(this.errors, error); return; if (length(this.errors) > 10) msg = {}; for n in (this.errors) msg = {@msg, @n, ""}; endfor $mail_agent:send_message(this, this.owner, "Some errors.", msg); this.errors = {}; endif . @verb #46:"fixpos" this none this @program #46:fixpos "$local.rpg version of ... $you:fixpos(string, pronoun)"; "This is horribly dwimmy. E.g. %x's gets turned into your, %X's gets turned into Your, and %X'S gets turned into YOUR. --Nosredna"; {string, pronoun} = args; if (!index(string, "'s")) return string; endif {prefix, letter} = {pronoun[1..$ - 1], pronoun[$]}; {lowercase, uppercase} = {"abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"}; upper = prefix + uppercase[index(lowercase, letter)]; allupper = upper + "'S"; upper = upper + "'s"; lower = (prefix + lowercase[index(lowercase, letter)]) + "'s"; return strsub(strsub(strsub(string, lower, "your", 1), upper, "Your", 1), allupper, "YOUR", 1); "THX (#105941) - Thu Oct 12, 2000 - Copied this from Brack's (#90845) version of $you."; . @verb #46:"clean*_player_prop" this none this @program #46:clean_player_prop "Copied from THX_utils (#99799):clean by THX1138 (#105941) Wed May 20 11:17:02 1998 PDT"; "Verb cleans out props containing lists of players. Doll-less and invalid objects are removed."; "To get this to work for you, you need to copy this verb to your utilities."; {object, property} = args; if ((caller_perms() != (owner = this.owner)) || (property in {"dolls", "pcs"})) return E_PERM; "... special check to protect this.dolls and this.pcs from accidents ..."; endif current = object.(property); newlist = {}; for t in (current) if (valid(this:get_doll(t))) newlist = setadd(newlist, t); else owner:tell($string_utils:nn(t), " has no doll."); endif endfor object.(property) = newlist; . @verb #46:"pronoun_sub" this none this @program #46:pronoun_sub "Pronoun (and other things) substitution. See 'help pronouns' for details."; "syntax: $string_utils:pronoun_sub(text[,who[,thing[,location[,dobj[,iobj]]]]])"; "%s,%o,%p,%q,%r => 's pronouns. defaults to player."; "%n,%d,%i,%t,%l,%% => , dobj, iobj, , location and %"; " defaults to caller; defaults to who.location"; "%S,%O,%P,%Q,%R, %N,%D,%I,%T,%L have corresponding capitalized substitutions."; " %[#n], %[#d], ... => , dobj, etc.'s object number"; "%(foo) => .foo and %(Foo) => .foo capitalized. %[dfoo] => dobj.foo, etc.."; "% -> whatever does when normal people foo. This is determined by calling :verb_sub() on the ."; "% -> whatever does when normal people foo."; {string, ?who = player, ?thing = caller, ?where = $nothing, ?dobject = dobj, ?iobject = iobj} = args; "if (caller != this)"; " return E_PERM;"; "endif"; this:secure(); where = valid(where) ? where | (valid(who) ? who.location | where); "set_task_perms($no_one);"; if (typeof(string) == LIST) plines = {}; for line in (string) plines = {@plines, this:(verb)(line, who, thing, where)}; endfor return plines; endif old = tostr(string); new = ""; objspec = "nditl"; objects = {who, dobject, iobject, thing, where}; prnspec = "sopqrSOPQR"; prprops = {"ps", "po", "pp", "pq", "pr", "Ps", "Po", "Pp", "Pq", "Pr"}; oldlen = length(old); while ((prcnt = index(old, "%")) && (prcnt < oldlen)) s = old[k = prcnt + 1]; if ((s == "<") && (gt = index(old[k + 2..$], ">"))) "handling % "; gt = (gt + k) + 1; vb = old[k + 1..gt - 1]; vbs = who; if ((length(vb) > 2) && (vb[2] == ":")) " %"; vbs = objects[index(objspec, vb[1]) || 1]; vb = vb[3..$]; endif vb = $object_utils:has_verb(vbs, "verb_sub") ? vbs:verb_sub(vb) | this:(verb)(vb, vbs); new = (new + old[1..prcnt - 1]) + vb; k = gt; else cp_args = {}; if (brace = index("([", s)) if (!(w = index(old[k + 1..oldlen], ")]"[brace]))) return new + old; else p = old[prcnt + 2..(k = k + w) - 1]; if (brace == 1) "%(property)"; cp_args = {who, p}; elseif (p[1] == "#") "%[#n] => object number"; s = (o = index(objspec, p[2])) ? tostr(objects[o]) | (("[" + p) + "]"); elseif (!(o = index(objspec, p[1]))) s = ("[" + p) + "]"; else " %[dproperty] "; cp_args = {objects[o], p[2..w - 1], strcmp(p[1], "a") < 0}; endif endif elseif (o = index(objspec, s)) passed = is_player(objects[o]) ? "name" | ""; cp_args = {objects[o], passed, strcmp(s, "a") < 0}; elseif (w = index(prnspec, s, 1)) cp_args = {who, prprops[w]}; elseif (s == "#") s = tostr(who); elseif (s != "%") s = "%" + s; endif new = (new + old[1..prcnt - 1]) + ((!cp_args) ? s | ((typeof(sub = $string_utils:_cap_property(@cp_args)) != ERR) ? sub | (("%(" + tostr(sub)) + ")"))); endif old = old[k + 1..oldlen]; oldlen = oldlen - k; endwhile return new + old; . @verb #46:"say_action" this none this rx @program #46:say_action "$local.rpg:say_action(message [,who, thing, where, excluding whom, highlight whom])"; "announce 'message' with pronoun substitution as if it were just "; " $local.rpg:rpg_announce_all($string_utils:pronoun_sub(message, who, thing, where)); "; "except that who (player), dobj, and iobj get modified messages, with the appropriate use of 'you' instead of their name."; "who default player"; "thing default object that called this verb"; "where default who.location"; "excluding default {}"; "highlighting default nobody (otherwise the argument given will see eir messages with `damage highlighting')"; "(This differs from $you:say_action in that only bystanding non-sleeping players will get messages.)"; {msg, ?who = player, ?thing = caller, ?where = who.location, ?excluding = {}, ?highlight = 0} = args; if (where in this.silent_rooms) return; endif this:secure(); {s_u, you} = {$string_utils, $you}; if (typeof(msg) == LIST) tell = ""; for x in (msg) tell = tell + ((typeof(x) == STR) ? x | x[random($)]); endfor else tell = msg; endif spew = {tell, tell, tell}; if (i = highlight in {who, dobj, iobj}) doll = this:get_doll(highlight); options = this.rpg_options; {start, finish} = options:get(doll.rpg_options, "highlighting") ? options:get(doll.rpg_options, "highlights") || options.highlights_default | {"", ""}; spew[i] = tostr(start, tell, finish); endif this:playershow(who, this:pronoun_sub(this:fixpos(spew[1], "%n"), you, thing, where)); exclude = {dobj, who, iobj, @excluding}; for t in (where.contents) if ((t in exclude) || (!valid(tdoll = this:get_doll(t)))) elseif (tdoll:cannot_see()) exclude = {@exclude, t}; elseif (tdoll:cannot_resolve()) exclude = {@exclude, t}; hazy = {@hazy, t}; endif endfor this:s_i_n(); this:rpg_show_all_but(where, exclude, this:pronoun_sub(tell, who, thing, where)); if (hazy) {dstow, istow} = {dobj, iobj}; ((dobj in this.pcs) || is_player(dobj)) && (dobj = this.somebody); this:rpg_show_all_but(where, $set_utils:diff(where.contents, hazy), this:pronoun_sub(tell, this.someone, thing, where)); {dobj, iobj} = {dstow, istow}; endif if ((`is_player(dobj) ! E_TYPE, E_INVIND' && (!(dobj in {who, @excluding}))) && (dobj.location == where)) ddoll = this:get_doll(dobj); {dstow, istow} = {dobj, iobj}; if (valid(ddoll) && ddoll:cannot_resolve()) active = this.someone; ((iobj in this.pcs) || is_player(iobj)) && (iobj = this.somebody); else active = who; endif dobj = you; this:playershow(dstow, this:pronoun_sub(this:fixpos(spew[2], "%d"), active, thing, where)); {dobj, iobj} = {dstow, istow}; endif if ((`is_player(iobj) ! E_TYPE, E_INVIND' && (!(iobj in {who, dobj, @excluding}))) && (iobj.location == where)) idoll = this:get_doll(iobj); {dstow, istow} = {dobj, iobj}; if (valid(idoll) && idoll:cannot_resolve()) active = this.someone; ((dobj in this.pcs) || is_player(dobj)) && (dobj = this.somebody); else active = who; endif iobj = you; this:playershow(istow, this:pronoun_sub(this:fixpos(spew[3], "%i"), active, thing, where)); {dobj, iobj} = {dstow, istow}; endif "Profane (#30788) - Tue Dec 30, 1997 - only do tells to dobj/iobj if they're players."; "Mooshie (#106469) - Tue Jan 6, 1998 - Added `excluded' option. An update from $you."; "THX (#105941) - Fri Jun 12, 1998 - Changed call from s_u:pronoun_sub to this:pronoun_sub everywhere and commented out old ugly hack for . This calls player.name instead of player:title which should save a few ticks and improve readability."; "Profane (#30788) - Sat Jun 20, 1998 - hack for damage highlighting"; "Profane (#30788) - Sun Jun 4, 2000 - insert `yadda/location = where' conditions for spewing messages to iobj, dobj"; "THX (#105941) - Mon Jun 25, 2001 - Changed to exclude those who cannot see and alter the messages to those who cannot_resolve to Someone and Somebody Else."; . @verb #46:"rate*_weapon" this none this @program #46:rate_weapon "$local.rpg:rate*_weapon(OBJ weapon, [LIST {attacker, defender}])"; "=> rating"; "Rate an rpg weapon based on certain mathematical criteria."; this:secure(); x = this.pcs[$]; {weap, ?foes = {x, x}} = args; if (!$object_utils:isa(weap, this.weapon)) return E_INVARG; endif {x, y} = foes; boost = 20 - (10 * weap.hands); if ($object_utils:has_verb(weap, "critical_hit") != {this.weapon}) boost = boost + 15; endif if ($object_utils:has_verb(weap, "critical_miss") != {this.weapon}) boost = boost - 7; endif basic = `(((min(weap:attack(x, y), 50) + max(-25, weap:parry(x, y, weap) / 3)) - max(-25, weap:dodgable(x, y))) - max(-25, weap:parryable(x, y))) - weap:slowness(x, y) ! ANY => 25'; expert = `(((weap:dam(x, y) + weap:special_damage(x, y)) + max(-5, weap:pierce(x, y))) - max(0, weap:pen(x, y))) + (30 / max(1, weap:con(x, y))) ! ANY => 25' + boost; return abs(expert) * (expert + basic); "@Moved from spiderknight (#348):rate by THX1138 (#105941) Mon Jul 13 08:25:54 1998 PDT"; . @verb #46:"compare_opponents" this none this @program #46:compare_opponents this:secure(); {protag, antag} = args; if (valid(pdoll = this:get_doll(protag)) && valid(adoll = this:get_doll(antag))) return {this:rank_pc(pdoll, protag, antag), this:rank_pc(adoll, antag, protag)}; else player:tell("Both arguments must be LambdaRPG participants."); endif . @verb #46:"rank_pc" this none this @program #46:rank_pc if (caller == this) {doll, who, whoelse} = args; rank = weapon = 0; look_thru = doll.wielding ? doll.wielding | doll.natural_weapons; for t in (look_thru) temp = rank; rank = max(rank, max(1, this:rate_weapon(t, {who, whoelse}) / 55) * doll:total(t.skill)); weapon = (temp == rank) ? weapon | t; endfor return {rank, weapon}; else return E_PERM; endif . @verb #46:"has_saved_doll" this none this @program #46:has_saved_doll {?who = $nothing} = args; doll = this.doll; dolls = pcs = {}; for t in (this.saved_dolls) if (((valid(t) && (parent(t) == doll)) && `is_player(t.character) ! E_TYPE') && ((time() - t.last_action) < 2000000)) dolls = {@dolls, t}; pcs = {@pcs, t.character}; else this.saved_dolls = setremove(this.saved_dolls, t); endif endfor return valid(who) ? (who in pcs) ? dolls[who in pcs] | $nothing | pcs; . @verb #46:"tell_damage" this none this @program #46:tell_damage "Usage: tell_damage(OBJ who, @STR damage strings)"; "Will highlight the damage string before sending it to the recipient--as appropriate."; {who, @msg} = args; if (valid(doll = this:get_doll(who))) this:secure(); options = this.rpg_options; {start, finish} = options:get(doll.rpg_options, "highlighting") ? options:get(doll.rpg_options, "highlights") || options.highlights_default | {"", ""}; this:playertell(who, start, @msg, finish); endif "THX (#105941) - Mon Jun 5, 2000 - Check that the doll is valid since improvement checks call this code too."; . @verb #46:"s_i_n" this none this rx @program #46:s_i_n if ((ticks_left() < 7500) || (seconds_left() < 2)) {?long = this.gm_lag} = args; (caller_perms() == this.owner) && suspend(long); endif "suspends if ticks left is under 6000 or if secs left is under 2"; "THX (#105941) - Fri Jan 1, 1999 - This is G_M's version of $command_utils:suspend_if_needed(). NB: Use rpg:s_i_f_i_n() when doing conditional suspends in for-loops."; . @verb #46:"doll_exp" this none this @program #46:doll_exp ":doll_exp(doll) -> Numeric representation of doll's overall LRPG experience."; this:secure(); {doll, ?augment = 0} = args; exp = 0; if (valid(doll) && (parent(doll) == this.doll)) skills = this.skills.contents; attributes = this.attributes; for skill in (skills) if (!(skill in attributes)) exp = exp + (doll.(skill.aliases[1]) * skill.learn); endif endfor if (augment) exp = (exp * 2) * max(doll.magic_theory, doll.melee); endif endif return exp; . @verb #46:"s_i_f_i_n suspend_in_for_if_needed" this none this rx @program #46:s_i_f_i_n if ((ticks_left() < 2400) || (seconds_left() == 1)) (caller_perms() == this.owner) && suspend(0); endif "suspends if ticks left is under 3600 or if secs left is under 1."; "THX (#105941) - Fri Jan 1, 1999 - This version of :suspend_if_needed(0) is to be used in for-loops in the core if the effects required are fairly immediate. In other words, this is a quick and dirty way of gaining some more ticks and seconds."; . @verb #46:"save_doll" this none this @program #46:save_doll this:secure(); {doll} = args; if ((is_player(who = doll.character) && (who == who.owner)) && (parent(doll) == this.doll)) saved = who in $list_utils:map_prop(this.saved_dolls, "character"); if (saved) s_d = this.saved_dolls[saved]; current = (this:doll_exp(doll) + (5 * doll.pot)) + (99 * $math_utils:sum($list_utils:map_arg(doll, "get_att", $list_utils:slice($list_utils:map_prop(this.attributes, "aliases"), 1)))); test = (this:doll_exp(s_d) + (5 * s_d.pot)) + (99 * $math_utils:sum($list_utils:map_arg(s_d, "get_att", $list_utils:slice($list_utils:map_prop(this.attributes, "aliases"), 1)))); if (current > test) this.saved_dolls[saved]:moveto(this.cemetery); this.saved_dolls = listdelete(this.saved_dolls, saved); "Only save ONE DOLL PER PLAYER, thank you drive through."; "Only save a new doll if it has more exp than the old one. Yes, this does not take into account basic stat fluctuations. deal."; saved = 0; endif endif else return E_INVARG; endif this:s_i_n(); for weapon in (doll.wielding) weapon:do_unwield(who); endfor for armour in (doll.wearing) armour:do_remove(who); endfor doll.wielding = doll.wearing = {}; for item in (doll.schedule) if (item in doll.schedule) doll.schedule = setremove(doll.schedule, item); {q1, q2, time, q4} = item; this.toady:call_verb(q1, q2, {doll, @q4}); endif endfor for item in (doll.claimed_objects) valid(`item.claimed_by ! ANY => $nothing') && item:unclaim_for(item.claimed_by); endfor doll.paralyzed = 0; if (n = doll in this.dolls) this.dolls = listdelete(this.dolls, n); this.pcs = listdelete(this.pcs, n); endif doll:write_misc_note("Guilds", (guildb = this.guild_db):guilds_for(who)); guildb:reset_for(who); puzzles = (puzzle_log = this.puzzle_log):solved(who); times = {}; for puzzle in (puzzles) this:s_i_n(); times = {@times, puzzle_log:has_solved(who, puzzle)}; endfor doll:write_misc_note("Puzzles", {puzzles, times}); puzzle_log:reset_for(who); if (doll == this.object_db.suit_doll) return; elseif (saved) this.saved_dolls = {@this.saved_dolls, doll}; this.death_db.corpse_dolls = setadd(this.death_db.corpse_dolls, doll); else (who == this.owner) || (this.saved_dolls = listappend(setremove(this.saved_dolls, doll), doll)); this.saved_dolls = {@this.saved_dolls[max(1, $ - 80)..$]}; endif ((doll in this.dolls) || (doll in this.saved_dolls)) || doll:moveto(this.cemetery); "THX (#105941) - Sat Mar 21, 1998 - Still save macro users' dolls. Prevent all but G_M from restoring in restore_pc instead. Stop G_M from getting a doll saved .... waste of quota"; "Profane (#30788) - Mon Jan 11, 1999 - consider pot and att totals when deciding which doll to save."; "THX (#105941) - Tue Nov 2, 1999 - Changed to temporarily save the doll associated with a corpse. This doll will be removed by player_corpse:rot() if the player isn't resurrected first."; "THX (#105941) - Mon Apr 16, 2001 - Put a hack in so that the doll associated with the suit of armour doesn't get into saved_dolls."; . @verb #46:"rpg_announce_all_but" this none this @program #46:rpg_announce_all_but ":rpg_announce_all_but(, , ) -> As a regular room:announce_all_but for location, but only spews to non-sleeping players who are not in the exclude list."; {where, exclude, @text} = args; if (where in this.silent_rooms) return; endif this:secure(); "New silent entry detection:"; "if (i = `$list_utils:iassoc_new(task_id(), where.unannounced) ! ANY')"; " where.unannounced = listdelete(where.unannounced, i);"; "endif"; text = (typeof(text) == LIST) ? text | {text}; exclude = {@exclude, @this.silent_players}; for dude in (where.contents) if (dude in connected_players()) (dude in exclude) || this:playertell(dude, @text); elseif ((mon = `dude.tell_forward ! E_PROPNF => {}') && (dude.owner in this.gms)) exclude = (valid(doll = dude.doll) && doll:cannot_hear()) ? setadd(exclude, dude) | exclude; for t in (mon) (dude in exclude) || t:tell(" (", dude.name, ") ", @text); endfor endif endfor "THX (#105941) - Mon Feb 15, 1999 - Changed call to where:notify_player() if caller_perms() are trusted."; "THX (#105941) - Mon Jun 25, 2001 - Added a check for monitored monsters who cannot hear."; . @verb #46:"new_sheet" this none this @program #46:new_sheet ":sheet(who, [about_what]) -- tell player numerical info about WHO's LRPG stats."; if (!this:trust()) return E_PERM; endif {who, ?what = 0} = args; doll = this:get_doll(who); if (doll == $nothing) player:tell("No such adventurer."); return; endif sheet = {}; sheet = {tostr("Player: ", who.name, " (", who, ") Doll: ", doll, (who in this.gms) ? " *** GameMaster ***" | "")}; sheet = {@sheet, ""}; suff = ""; s = " "; atts = this.sheet_atts; h = this.sheet_level; if (what == "combat") atts = atts[1..55]; h = h[1..55]; elseif (what == "magic") atts = atts[56..100]; h = h[56..100]; elseif (what == "miscl") atts = atts[101..$]; h = h[101..$]; endif for q in [1..length(atts)] this:time_stop(); z = doll.(atts[q].aliases[1]); if (z) zs = $string_utils:right(tostr(z), 2); else zs = " "; endif if (suff == "") for k in [1..h[q]] suff = suff + s; endfor endif skill = this:match_skill(atts[q]); if (what == "magic") suff = ((((suff + $string_utils:left((length(skill.aliases[1]) < 13) ? skill.aliases[1] | skill.aliases[1][1..12], 13)) + zs) + " (") + $string_utils:right(tostr(doll:total(atts[q])), 3)) + ") "; else suff = ((((suff + $string_utils:left((length(skill.name) < 13) ? skill.name | skill.name[1..12], 13)) + zs) + " (") + $string_utils:right(tostr(doll:total(atts[q])), 3)) + ") "; endif if (q == length(atts)) sheet = {@sheet, suff, ""}; elseif ((h[q] == -2) && (h[q + 1] == 0)) sheet = {@sheet, suff, ""}; suff = ""; elseif (h[q] != (h[q + 1] - 1)) sheet = {@sheet, suff}; suff = ""; endif endfor sheet = {@sheet, tostr(who.name, " hates ", $string_utils:english_list($list_utils:map_prop(doll.aggressor, "name")), ". ", who.psc, " is in ", who.location.name, " (", who.location, ").")}; sheet = {@sheet, tostr("Physical Damage: ", doll.inj, " Psychic Damage: ", doll.ins, " Experience: ", this:exp(who), (doll.size == 10) ? "" | (" Size: " + tostr(doll.size)))}; player:tell_lines_suspended(sheet); . @verb #46:"parents" this none this @program #46:parents {what} = args; ret = {}; while (valid(what = parent(what))) ret = {@ret, what}; endwhile return ret; "THX (#105941) - Wed Feb 24, 1999 - This is a bit speedier than $object_utils:ancestors() ... only for one object though."; . @verb #46:"is_fast_room" this none this @program #46:is_fast_room return $object_utils:isoneof(args[1], this.fast_rooms); . @verb #46:"rpg_announce_all_but(old)" this none this @program #46:rpg_announce_all_but(old) ":rpg_announce_all_but(, , <@(LIST of STRs)/STR args to pass to tell>) -> As a regular room:announce_all_but for location, but only spews to non-sleeping players who are not in the exclude list."; {where, exclude, @text} = args; if (where in this.silent_rooms) return; endif text = (typeof(text) == LIST) ? text | {text}; exclude = {@exclude, @this.silent_players}; for dude in (where.contents) if (dude in connected_players()) (dude in exclude) || dude:tell(@text); elseif ((mon = `dude.tell_forward ! E_PROPNF => {}') && (dude.owner in this.gms)) for t in (mon) (dude in exclude) || t:tell(" (", dude.name, ") ", @text); endfor endif endfor for room in (`where.tell_forward ! E_PROPNF => {}') for dude in (room.contents) if (dude in connected_players()) (dude in exclude) || dude:tell(" (from ", where.name, ") ", @text); endif endfor endfor "Profane 1-DEC-96 1229PST - s/is_player/connected_players, move exclusion check to conditional, added comment"; "THX (#105941) - Mon Apr 27, 1998 - Commented the Silent 'port stuff. Let room:announce() handle it. This verb is for speed."; . @verb #46:"playertell_lines" this none this @program #46:playertell_lines "Usage: playertell_lines(OBJ player, LIST|STR line(s) of text)"; "Sends all provided lines through this:playertell (to consolidate line-wrapping code and the like)."; this:secure(); {who, lines} = args; (typeof(lines) != LIST) && (lines = {lines}); for line in (lines) this:playertell(who, line); endfor . @verb #46:"train(old)" this none this @program #46:train(old) ":train(player, attribute-list)"; "Attempt to improve each of player's attributes in 'attribute-list'."; "=> E_NONE if player isn't an Illuminatus."; "=> E_QUOTA if player has no potential."; "=> n where 'n' is the number of courses completed."; this:secure(); {pc, atts} = args; if (!valid(doll = this:get_doll(pc))) return E_NONE; elseif (!(pot = doll.pot)) return E_QUOTA; endif total = 0; for attnam in (atts) "oldatt = doll.(attnam);"; oldatt = doll:get_unmod_att(attnam); cost = this.costs[oldatt + 1]; if ((!pot) || (cost > pot)) return total; else doll.(attnam) = oldatt + 1; doll.pot = pot = doll.pot - cost; total = total + 1; endif endfor return total; "Quinn 11-AUG-93 0645: Re-written w/comments; removed messages; return meaningful values; see Academy Room (#146@LMOO) for example interpretation of results."; "THX 20-FEB-1997 -- Scatter assignment. Whee."; "Profane (#30788) - Wed May 19, 1999 - Use :unmod_att"; . @verb #46:"fixpos(old)" this none this @program #46:fixpos(old) "Copied from Irin (#106049):fixpos Thu Mar 12 11:34:15 1998 PST"; {string, fix} = args; up = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; down = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}; allupper = ""; upper = ""; lower = ""; for n in [1..length(fix)] if ((i = fix[n] in up) || (i = fix[n] in up)) upper = upper + up[i]; lower = lower + down[i]; else upper = upper + fix[n]; lower = lower + fix[n]; endif endfor allupper = upper + "'S"; upper = upper + "'s"; lower = lower + "'s"; return strsub(strsub(strsub(string, lower, "your", 1), upper, "Your", 1), allupper, "YOUR", 1); . @verb #46:"rm_doll(old)" this none this @program #46:rm_doll(old) " rm_doll(OBJ doll) => OBJ pc may suspend"; "Removes the (pc/doll) pair from this.pcs/this.dolls lists. Returns"; "the removed RPG character."; if (!this:trusted(caller_perms())) return E_PERM; endif doll = args[1]; $command_utils:suspend_if_needed(this.gm_lag); pos = doll in this.dolls; if (!pos) return $object_utils:isa(doll, this.doll) ? 1 | E_INVARG; endif pcs = this.pcs; this.dolls = listdelete(this.dolls, pos); this.pcs = listdelete(pcs, pos); return pcs[pos]; "June 28, 1995 -- Slither, first version"; . @verb #46:"do_reset" this none this @program #46:do_reset "Kill that guest's RPG doll, as appropriate."; if (parent(caller) != $local.guest) return E_PERM; elseif (valid(gdoll = this:get_doll(caller))) {odb, cemetery, loc} = {this.object_db, this.cemetery, caller.location}; is_rpg = odb:is_rpg(loc); "drop RPG items only in dungeons. Nice and tidy"; for item in (caller.contents) if (odb:is_corpse(item)) item:moveto(this.cinder); elseif (odb:is_thing(item)) dest = (is_rpg && loc:acceptable(item)) ? loc | cemetery; item:moveto(dest); endif this:s_i_f_i_n(); endfor for person in ({@gdoll.aggressor, @valid(loc) ? loc.contents | {}}) "clear aggressor lists"; if (valid(pdoll = this:get_doll(person))) pdoll.aggressor = setremove(pdoll.aggressor, caller); endif this:s_i_f_i_n(); endfor "kill the doll"; this.recycler:_recycle(gdoll); endif "THX (#105941) - Mon Nov 27, 2000 - Added to replace the code on $local.guest:do_reset() that was antiquated."; . @verb #46:"secure(old)" this none this @program #46:secure(old) ":secure() => raise E_PERM if we don't like the look of whoever called your verb (i.e., a builtin, or non-GM permed verb called you.)"; if (callers()[2][3] in this.gms) return; "if (callers()[$][4] == #1)"; " \"verb has gone thru huh processing; feature verb.\";"; " if ($set_utils:intersection($list_utils:slice(callers(), 3), setremove($list_utils:slice($local.rpg.player_start.banned, 1), $local.rpg.owner)))"; " \"Certain banned people like to make cheating/macro FOs. Sorry.\";"; " raise(E_PERM, \"RPG Security Violation!\");"; " endif"; "endif"; endif raise(E_PERM, "RPG Security Violation!"); "Profane 1-APR-97 1708PST -- added bit for command-line verbs"; "Irin Thu Apr 3 12:33:06 1997 PST -- Unceremoniously sent the code for command-line verbs to #46:secure_x(). Thus saving 1 tick."; . @verb #46:"is_alive" this none this rx @program #46:is_alive {doll} = args; if (is_player(char = doll.character)) return char in this.pcs; endif return char.alive; . @verb #46:"say_audio" this none this rx @program #46:say_audio "$local.rpg:say_audio(message [,who, thing, where, excluding whom, highlight whom])"; "announce 'message' with pronoun substitution as if it were just "; " $local.rpg:rpg_announce_all($string_utils:pronoun_sub(message, who, thing, where)); "; "except that who (player), dobj, and iobj get modified messages, with the appropriate use of 'you' instead of their name."; "who default player"; "thing default object that called this verb"; "where default who.location"; "excluding default {}"; "highlighting default nobody (otherwise the argument given will see eir messages with `damage highlighting')"; "(This differs from $you:say_action in that only bystanding non-sleeping players will get messages. This version added to handle audible messages ... blindness or deafness can now be a factor.)"; {msg, ?who = player, ?thing = caller, ?where = who.location, ?excluding = {}, ?highlight = 0} = args; if (where in this.silent_rooms) return; endif this:secure(); {s_u, you} = {$string_utils, $you}; if (typeof(msg) == LIST) tell = ""; for x in (msg) tell = tell + ((typeof(x) == STR) ? x | x[random($)]); endfor else tell = msg; endif spew = {tell, tell, tell}; if (i = highlight in {who, dobj, iobj}) doll = this:get_doll(highlight); options = this.rpg_options; {start, finish} = options:get(doll.rpg_options, "highlighting") ? options:get(doll.rpg_options, "highlights") || options.highlights_default | {"", ""}; spew[i] = tostr(start, tell, finish); endif this:playertell(who, this:pronoun_sub(this:fixpos(spew[1], "%n"), you, thing, where)); exclude = {dobj, who, iobj, @excluding}; for t in (where.contents) if ((t in exclude) || (!valid(tdoll = this:get_doll(t)))) elseif (tdoll:cannot_hear()) exclude = {@exclude, t}; elseif (tdoll:cannot_see() || tdoll:cannot_resolve()) exclude = {@exclude, t}; blind = {@blind, t}; endif endfor this:rpg_announce_all_but(where, exclude, this:pronoun_sub(tell, who, thing, where)); if (blind) {dstow, istow} = {dobj, iobj}; ((dobj in this.pcs) || is_player(dobj)) && (dobj = this.somebody); this:rpg_announce_all_but(where, $set_utils:diff(where.contents, blind), this:pronoun_sub(tell, this.someone, thing, where)); {dobj, iobj} = {dstow, istow}; endif if ((`(dobj in this.pcs) || is_player(dobj) ! E_TYPE, E_INVIND' && (!(dobj in {who, @excluding}))) && (dobj.location == where)) ddoll = this:get_doll(dobj); if (valid(ddoll) && ddoll:cannot_hear()) else {dstow, istow} = {dobj, iobj}; if (valid(ddoll) && (ddoll:cannot_see() || ddoll:cannot_resolve())) active = this.someone; ((iobj in this.pcs) || is_player(iobj)) && (iobj = this.somebody); else active = who; endif dobj = you; this:playertell(dstow, this:pronoun_sub(this:fixpos(spew[2], "%d"), active, thing, where)); {dobj, iobj} = {dstow, istow}; endif endif if ((`is_player(iobj) ! E_TYPE, E_INVIND' && (!(iobj in {who, dobj, @excluding}))) && (iobj.location == where)) idoll = this:get_doll(iobj); if (valid(idoll) && idoll:cannot_hear()) else {dstow, istow} = {dobj, iobj}; if (valid(idoll) && (idoll:cannot_see() || idoll:cannot_resolve())) active = this.someone; ((dobj in this.pcs) || is_player(dobj)) && (dobj = this.somebody); else active = who; endif iobj = you; this:playertell(istow, this:pronoun_sub(this:fixpos(spew[3], "%i"), active, thing, where)); {dobj, iobj} = {dstow, istow}; endif endif "THX (#105941) - Tue Jun 5, 2001 - Added."; . @verb #46:"playershow" this none this @program #46:playershow ":playershow(OBJ who, STR or STRs @msg) - calls notify(who, tostr(@msg)) if who is a player and if who is in a descendant of $local.rpg.dungeon."; (caller == this) || this:secure(); {who, @msg} = args; where = who.location; if (valid(doll = this:get_doll(who)) && doll:cannot_see()) return; elseif (is_player(who) && this:is_fast_room(where)) msg = strsub(tostr(@msg), "xch_mudtext", "xch mudtext"); if ((ll = who.linelen) > 0) for line in ($player:linesplit(msg, ll)) where:notify_player(who, line); endfor else where:notify_player(who, msg); endif else who:tell(@msg); endif "Mooshie (#106469) - Sat Oct 9, 1999 - Checking if 'caller == this' first should save indexing ticks for the many calls routed through :rpg_announce* verbs and :playertell_lines."; . @verb #46:"playertell" this none this @program #46:playertell ":playertell(OBJ who, STR or STRs @msg) - calls notify(who, tostr(@msg)) if who is a player and if who is in a descendant of $local.rpg.dungeon."; (caller == this) || this:secure(); {who, @msg} = args; where = who.location; if (is_player(who) && this:is_fast_room(where)) msg = strsub(tostr(@msg), "xch_mudtext", "xch mudtext"); if ((ll = who.linelen) > 0) for line in ($player:linesplit(msg, ll)) where:notify_player(who, line); endfor else where:notify_player(who, msg); endif else who:tell(@msg); endif "Mooshie (#106469) - Sat Oct 9, 1999 - Checking if 'caller == this' first should save indexing ticks for the many calls routed through :rpg_announce* verbs and :playertell_lines."; . @verb #46:"rpg_show_all_but" this none this @program #46:rpg_show_all_but ":rpg_announce_all_but(, , ) -> As a regular room:announce_all_but for location, but only spews to non-sleeping players who are not in the exclude list."; {where, exclude, @text} = args; if (where in this.silent_rooms) return; endif this:secure(); "New silent entry detection:"; "if (i = `$list_utils:iassoc_new(task_id(), where.unannounced) ! ANY')"; " where.unannounced = listdelete(where.unannounced, i);"; "endif"; text = (typeof(text) == LIST) ? text | {text}; exclude = {@exclude, @this.silent_players}; for dude in (where.contents) if (dude in connected_players()) (dude in exclude) || this:playertell(dude, @text); elseif ((mon = `dude.tell_forward ! E_PROPNF => {}') && (dude.owner in this.gms)) exclude = (valid(doll = dude.doll) && doll:cannot_see()) ? setadd(exclude, dude) | exclude; for t in (mon) (dude in exclude) || t:tell(" (", dude.name, ") ", @text); endfor endif endfor "THX (#105941) - Mon Feb 15, 1999 - Changed call to where:notify_player() if caller_perms() are trusted."; "THX (#105941) - Mon Jun 25, 2001 - Added a check for monitored monsters who cannot see."; . @verb #46:"rpg_show*_all" this none this @program #46:rpg_show_all ":rpg_show(, ) -> As a regular room:show for location, but only spews to non-sleeping players."; {where, @string} = args; this:secure(); this:rpg_show_all_but(where, (verb == "rpg_show") ? {player} | {}, @string); "THX (#105941) - Sun Jun 24, 2001 - Changed code to send to this:rpg_show_all_but() to save on maintaining identical code."; . @verb #46:"playerannounce" this none this @program #46:playerannounce ":playerannounce(OBJ who, STR or STRs @msg) - calls notify(who, tostr(@msg)) if who is a player and if who is in a descendant of $local.rpg.dungeon. Checks doll:cannot_hear() before proceeding."; (caller == this) || this:secure(); {who, @msg} = args; where = who.location; if (valid(doll = this:get_doll(who)) && doll:cannot_hear()) return; elseif (is_player(who) && this:is_fast_room(where)) msg = strsub(tostr(@msg), "xch_mudtext", "xch mudtext"); if ((ll = who.linelen) > 0) for line in ($player:linesplit(msg, ll)) where:notify_player(who, line); endfor else where:notify_player(who, msg); endif else who:tell(@msg); endif "THX (#105941) - Mon Jul 2, 2001 - Added."; . @verb #46:"erase_all_saved_dolls_for" this none this @program #46:erase_all_saved_dolls_for "Removed all the back up voodoo dolls of `who' from this.saved_dolls."; "Yeah, yeah, this scenario is rare, but possible."; (rpg = $local.rpg):secure(); if (!(caller_perms() in this.grand_masters)) return E_PERM; else {who} = args; for x in (this.saved_dolls) rpg:s_i_f_i_n(); if (`x.character ! E_PROPNF => $nothing' == who) this.saved_dolls = setremove(this.saved_dolls, x); this.dolls = setremove(this.dolls, x); "We also recycle the doll(s)."; x:moveto(this.cemetery); endif endfor endif "Hydros (#106189) - Mon Mar 7, 2005 - Added. Currently for use with Alaria (#35896):restore."; . @verb #46:"wizmove" this none this rxd #2487 @program #46:wizmove "Copied from Hydros (#106189):wmove at Tue Apr 12 12:11:30 2005 PDT"; "A wizardly move for His Eminence's RPG. Only specific objects, and specific verbs on those objects, are approved to call this, and these should be rare."; "NOTE to GameMasters: to access this verb, contact Grand_Master, (or an incarnation thereof). This wizardly code is not to be taken lightly and His Eminence frowns on abuse of forced movement code--i.e., you taste crunchy with ketchup."; "NB: If the teleported object is a player, e will receive RPG exitshock unless, after the move, you :announce eir name to the room, (e.g. ` teleports in.')."; (rpg = $local.rpg):secure(); {moved, newloc} = args; if (!rpg.object_db:is_rpg_room(moved.location)) "Only callable while `moved' target is within the RPG."; return E_PERM; else "Only specific verbs on specific objects can call this movement into play."; if ((x = $list_utils:assoc(caller, rpg.approved_wizmoves, 1)) && (callers()[1][2] == x[2])) "If move() fails for any reason, we simply eject them from the RPG (:eject_basic() being owned by Heathcliff somewhere down the line.)"; `move(moved, newloc) ! E_RECMOVE, E_NACC => moved.location:_eject(moved)'; else return E_PERM; endif endif "Hydros (#106189) - Tue Apr 12, 2005 - Added, soon to be owned by Nosredna (#2487)."; . @verb #46:"respawn_non_pkp_pc" this none this @program #46:respawn_non_pkp_pc "Instantly respawn a non-PKP PC in eir .home. A perk for volunteering into the playerkilling realm."; this:secure(); {doll} = args; who = doll.character; loc = who.location; for item in ({@doll.aggressor, @valid(loc) ? loc.contents | {}}) this:s_i_f_i_n(); if (valid(them = this:get_doll(item))) them.aggressor = setremove(them.aggressor, who); endif endfor for t in (doll.armour_effects) if (parent(t) == this.doll) doll:remove_teammate(t); t:remove_teammate(doll); endif endfor doll.inj = 50 + random(25); doll.ins = 50 + random(25); doll.fat = 50 + random(25); tot = 0; costs = this.costs; for att in (this.attributes) val = doll.(att.aliases[1]); for n in [1..min(val, 25)] tot = tot + costs[n]; endfor endfor {lop, pop} = {600, 2}; if (tot > lop) for att in (this.attributes) a = att.aliases[1]; if ((tot > (2 * lop)) || (random(pop) == 2)) doll.(a) = min(max(doll.(a) - 1, 12 + random(5)), doll.(a)); endif endfor endif if (doll.app > 11) doll.app = doll.app - 1; endif count = 0; countlist = {}; for x in ($list_utils:randomly_permute(who.contents)) if (this.object_db:is_thing(x)) count = count + 1; if (`who.location:acceptable(x) ! ANY => 0') `x:moveto(who.location) ! ANY'; countlist = setadd(countlist, x.name); endif if (count >= 3) break; endif endif endfor this.magic_db:teleport(doll, who.home, (rpcm = this.death_db.respawn_pc_msgs)[1], rpcm[2], rpcm[3], rpcm[4]); if (countlist != {}) who:tell(("You dropped your " + $string_utils:english_list(countlist)) + " where you died."); endif "Copied from Hydros (#106189):respawn_non_pkp_pc at Sun Oct 16 14:18:30 2005 PDT"; . "***finished***