Dump of #258 Dungeon @create #1610 named Generic Dungeon Room:Generic Dungeon Room,Dungeon Room @prop #258."transparency_support" 0 rc @prop #258."free_exit" 0 rc @prop #258."player_all_verbs" {} rc ;;#258.("player_all_verbs") = {"drop", "throw", "give", "hand", "wear", "remove", "wield", "unwield", "sheathe", "sling", "put", "insert"} @prop #258."room_all_verbs" {} rc ;;#258.("room_all_verbs") = {"get", "take"} @prop #258."gripe_recipients" {} rc ;;#258.("gripe_recipients") = {#4044} @prop #258."magic_effect" 0 r @prop #258."blessed_exit" 0 r @prop #258."accept_rpg_teleport" 0 rc "#258.("misc_notes") => E_PERM (Permission denied) "#258.("magic_effects") => E_PERM (Permission denied) "#258.("combat_effects") => E_PERM (Permission denied) "#258.("unannounced") => E_PERM (Permission denied) @prop #258."teleport_object" #-1 r @prop #258."teleport_task" 0 r @prop #258."forgiving" {} r "#258.("allowed_exits") => E_PERM (Permission denied) ;;#258.("dawn_msg") = "" ;;#258.("night_msg") = "" ;;#258.("dusk_msg") = "" ;;#258.("day_msg") = "" ;;#258.("free_entry") = 0 "#258.("entrances") => E_PERM (Permission denied) "#258.("exits") => E_PERM (Permission denied) ;;#258.("ctype") = 5 "#258.("key") => E_PERM (Permission denied) ;;#258.("aliases") = {"Generic Dungeon Room", "Dungeon Room"} ;;#258.("object_size") = {72473, 1141286558} @verb #258:"acceptable" this none this @program #258:acceptable {what} = args; {rpg, owner, loc} = {$local.rpg, what.owner, what.location}; if (rpg.player_start:is_banned(owner) || (!rpg.player_start:is_not_banned(what))) return 0; elseif (is_player(what)) if ((what != owner) && (!rpg.guests_allowed)) return 0; elseif ((loc in {$mail_editor, $note_editor}) && (this == loc.original[what in loc.active])) if (((valid(doll = rpg:get_doll(what)) && ((note = doll:read_misc_note("last_room")) != E_PROPNF)) && (note == this)) || (what in rpg.gms)) return 1; endif valid(doll) && rpg:log_error(tostr("Apparent hacked entry attempt by ", $string_utils:nn(what), " from ", $string_utils:nn(loc), " to ", $string_utils:nn(this), ". Callers: ", toliteral(callers(1)))); endif endif return ((pass(what) || (owner in rpg.gms)) || ($object_utils:contains(this, what) && ($object_utils:isa(what, rpg.thing) || rpg.object_db:is_monster(what)))) || ((what == this.teleport_object) && (task_id() == this.teleport_task)); "Removed my insertion of $local.rpg:trust(0) since it seems to allow all entries from any room with an :accept verb higher than this one."; "Mooshie (#106469) - Sun Oct 12 00:09:02 1997 PDT - Added teleport object/task check. Set by :bless_for_teleport "; "THX (#105941) - Thu Jan 27, 2000 - Allow players back in from $mail_editor and $note_editor."; "THX (#105941) - Sun Mar 18, 2001 - changed the is_rpg call to is_monster temporarily."; "THX (#105941) - Sun May 6, 2001 - Removed temporary acceptance of hacked $editor origins after catching a few exploiters. Now it just goes to pass(what)."; . @verb #258:"l*ook" any any any rxd @program #258:look "look [at] thing -- Take a gander at something."; rpg = $local.rpg; string = (prepstr == "at") ? iobjstr | dobjstr; what = string ? this:match(string) | this; if (valid(doll = rpg:get_doll(player)) && (msg = doll:cannot_see())) rpg:playertell(player, msg); elseif (!$command_utils:object_match_failed(what, string)) what:look_self(); if (valid(rpg:get_doll(what)) && is_player(what)) rpg:look_health(what); rpg:look_gear(what); endif endif "Quinn 01-AUG-93 0812-ET: Hacked to recognise 'at', and to use :object_match_failed."; "Profane (#30788) - Wed Feb 14, 2001 - support for cannot_see"; . @verb #258:"enterfunc" this none this @program #258:enterfunc if (!(rpg = $local.rpg):trusted_efunc()) return E_PERM; endif {thing} = args; pass(thing); if ((thing in rpg.pcs) && is_player(thing)) rpg.usage_meter:add_user(thing); endif theEntrance = this:identify_entrance(thing); this:notify_arrival(thing, theEntrance); if (valid(doll = (rpg = $local.rpg):get_doll(thing))) min = 999; for y in (doll.aggressor) if (valid(y) && (y.location == this)) else doll.aggressor = setremove(doll.aggressor, y); endif endfor for q in (setremove(thing.location.contents, thing)) if (valid(z = rpg:get_doll(q)) && ((poss = z.act) < min)) min = poss; endif endfor if (min < 999) doll.act = min; "fork (0)"; " doll:invite(doll:get_att(\"slowness\") / 2, {-1});"; "endfork"; else clear_property(doll, "act"); endif endif "New silent 'port detection:"; if ((theEntrance in this:entrances()) || ((thing == this.teleport_object) && (task_id() == this.teleport_task))) elseif ((((this:free_entry(thing) && (rpg.gm_lag < rpg.idle_threshold)) && (!(thing.owner in rpg.gms))) && valid(thing)) && (parent(thing) != $garbage)) task = task_id(); this.unannounced = setadd(this.unannounced, {task, thing}); fork (3) "Fork, because porting announces messages after the moveto; our code in announce* will remove the task from the .unannounced_property if it's not a silent port."; if (i = {task, thing} in this.unannounced) this:announce_all(thing.name, " teleports in, `silently.'"); (this.owner in rpg.gms) && this:exitshock(thing); this.unannounced = listdelete(this.unannounced, i); if (parent(this).unannounced == this.unannounced) clear_property(this, "unannounced"); endif endif endfork endif "Profane 5-OCT-97 -- new code for silent entry detection."; "Mooshie (#106469) - Fri Jan 2, 1998 - Added some security, a little de-ticking. Will de-tick much more later, this is a mess."; "Mooshie (#106469) - Sat Aug 28, 1999 - Added a call to the RPG usage meter."; . @verb #258:"forgive" any none none rxd @program #258:forgive rpg = $local.rpg; cp = caller_perms(); if (((cp != player) && valid(cp)) && (!rpg:trusted(cp))) return player:tell("See G_M about remote calls to the '", verb, "' verb."); elseif (!valid(doll = rpg:get_doll(player))) return player:tell("As a peaceful person, you hold no grudges."); elseif (valid(attempt = this:match(dobjstr))) dobj = attempt; elseif ($command_utils:object_match_failed(dobj, dobjstr)) return; endif if (!valid(fdoll = rpg:get_doll(dobj))) doll.aggressor = setremove(doll.aggressor, dobj); return player:tell(dobj.name, " is no threat to you."); endif for n in (this.forgiving) if ((n[1] == dobj) && (n[2] == player)) doll.aggressor = setremove(doll.aggressor, dobj); fdoll.aggressor = setremove(fdoll.aggressor, player); player:tell("You break off combat with ", dobj.name, "."); dobj:tell("You break off combat with ", player.name, "."); return rpg:rpg_announce_all_but(this, {player, dobj}, player.name, " and ", dobj.name, " break off combat with each other."); elseif (`(n[1].location != this) || (n[2].location != this) ! ANY => 1') this.forgiving = setremove(this.forgiving, n); endif endfor if (player in fdoll:aggressor()) this.forgiving = setadd(this.forgiving, {player, dobj}); is_player(dobj) ? dobj:tell(player.name, " forgives you and wishes to cease combat. If you wish to break off, type 'forgive ", player.name, "', and all will be forgiven.") | dobj:notify_forgive(player); player:tell("You offer to break off combat with ", dobj.name, "."); rpg:rpg_announce_all_but(this, {player, dobj}, player.name, " offers to break off the combat with ", dobj.name, "."); elseif (dobj in doll:aggressor()) doll.aggressor = setremove(doll.aggressor, dobj); player:tell("You break off combat with ", dobj.name, "."); is_player(dobj) ? dobj:tell(player.name, " breaks off combat with you.") | dobj:notify_forgive(player); rpg:rpg_announce_all_but(this, {player, dobj}, player.name, " breaks off combat with ", dobj.name, "."); else player:tell("There is no conflict between you and ", dobj.name, ". There is nothing to forgive."); endif . @verb #258:"hate" any none none rxd @program #258:hate rpg = $local.rpg; doll = rpg:get_doll(player); what = this:match(dobjstr); if ($match_utils:object_match_failed(what, dobjstr)) elseif (!valid(doll)) player:tell("As a peaceful person, you hold no grudges."); elseif (what == player) player:tell("If you hate yourself that much, why not MOOicide?"); elseif ((callers() && is_player(player)) && (!(caller_perms() in rpg.grand_masters))) rpg:log_error((((((("Player " + $string_utils:nn(player)) + " made to hate using +x nature of verb: ") + $string_utils:nn(caller)) + " owned by ") + tostr(`$string_utils:nn(caller.owner) ! ANY')) + " : ") + toliteral(callers())); elseif (!doll:legal_target(what)) return; elseif (!(what in rpg.pcs)) player:tell("You nurse your grudge against ", what.name, "."); else player:tell("You nurse your grudge against ", what.name, "."); (what in doll.aggressor) || doll:first_blood(player, what); (what.location == player.location) && (doll.aggressor = setadd(doll.aggressor, what)); endif "Hydros (#106189) Thu Aug 11, 2005 - Added a call to :legal_target."; . @verb #258:"tell_contents" this none this @program #258:tell_contents {contents, ctype} = args; if (this.dark) return; elseif (ctype != 5) pass(contents, ctype); return; endif pcs = (rpg = $local.rpg).pcs; people = things = {}; for q in (contents) if ((q in pcs) || is_player(q)) this:hide(q) || (people = listappend(people, q)); else things = listappend(things, q); endif endfor if (things) rpg:playershow(player, "You see ", $string_utils:english_list($list_utils:map_verb(things, "title")), " here."); endif if (people) rpg:playershow(player, $string_utils:english_list($list_utils:map_verb(people, "title")), (length(people) == 1) ? " is" | " are", " here."); endif "THX 13-Apr-1997 -- Scatter assignment and de-ticked. Should be nice and fast now."; . @verb #258:"exitfunc" this none this rx @program #258:exitfunc "Penalise for illegal exit, clear aggressor and action properties, and remove object from the aggressor lists of everyone still in the room."; {who} = args; if ((!(rpg = $local.rpg):trusted_efunc()) || ((caller != this) && (!$perm_utils:controls(caller_perms(), who)))) return E_PERM; elseif (valid(who) && (parent(who) != $garbage)) pass(who); else return; endif if (this:exit_ok(who)) "... they've left via a normal route ..."; else this:exitshock(who); endif odb = rpg.object_db; if (valid(doll = rpg:get_doll(who))) ("lighting" in this.room_data) && this:relight(doll, 0); ("tavern" in this.room_data) && odb.natweap_db:remove_natweap(doll, odb.pirate_brawling); clear_property(doll, "aggressor"); clear_property(doll, "act"); if (is_player(who)) doll:write_misc_note("last_room", this); if (valid(doll.duelee)) if ((ddoll = rpg:get_doll(doll.duelee)).duelee == who) "Fled a duel."; winner = doll.duelee; fork (0) for dude in ($set_utils:union(#15870:active_players(), {who, winner})) if (rpg.rpg_options:get(`rpg:get_doll(dude).rpg_options ! E_INVIND => {}', "APB")) rpg:playertell(dude, winner:titlec(), " has defeated ", who:title(), " in a duel to the death! ", who:title(), " has fled like a cowardly dog!"); endif endfor endfork clear_property(ddoll, "duelee"); endif clear_property(doll, "duelee"); endif endif endif for pair in (this.forgiving) if (who in pair) (this.forgiving = setremove(this.forgiving, pair)) || clear_property(this, "forgiving"); endif endfor (length(this.contents) < 33) && this:notify_exit(who, this:identify_exit(who, 0)); ((((!valid(loc = who.location)) || (odb:is_rpg_room(loc) || odb:is_rpg_room(loc.location))) || (parent(loc) == $generic_editor)) || (loc in {`who.home ! ANY => $nothing', rpg.player_start})) || ((who in rpg.pcs) && who:tell("You have just exited the LambdaRPG.")); "Profane (#30788) - Sat Nov 8 23:13:41 1997 PST - readded call to notify_exit, where'd it go?"; "Mooshie (#106469) - Fri Jan 2, 1998 - Moved the for loop that removes exiter from aggressor lists to :notify_exit, so we don't duplicate the for loop. Also replaced :secure_stack security with :trusted_efunc."; "THX (#105941) - Sat Nov 7, 1998 - Only call :notify_exit() if there are fewer than 50 objects in the room."; "THX (#105941) - Sat Mar 31, 2001 - Added a hack for the room lighting stuff."; "THX (#105941) - Mon Apr 30, 2001 - Added a misc_note that tracks the player's last RPG room location for validating a return from the kids of $generic_editor."; "THX (#105941) - Wed May 30, 2001 - Added a loop to clean out the .forgiving property."; "Profane (#30788) - Thu May 31, 2001 - announce fleeing of duels, reset duelee prop"; . @verb #258:"exits" this none this rxd #78 @program #258:exits if ((callers()[1][3] in #46.gms) || (callers()[1][1] == this)) return this.exits; else return {}; endif . @verb #258:"dests" this none this rxd #78 @program #258:dests if (callers()[1][3] in #46.gms) v = {}; for k in (this:exits()) z = k; while ($object_utils:isa(z, #566)) z = z.succ_exit; endwhile if ($object_utils:isa(z, $exit)) v = listappend(v, z.dest); endif endfor return v; else return {}; endif . @verb #258:"exit_ok" this none this @program #258:exit_ok "You can teleport from a room your owner owns, from one that's free_exit, or if you're a GM's object."; rpg = $local.rpg; {what} = args; theExit = this:identify_exit(what, 1); "this:notify_exit(what, theExit);"; if (((this:free_exit(what) || (theExit in this:exits())) || (what.owner == this.owner)) || (what.owner in rpg.gms)) return 1; elseif (`parent(theExit) ! E_INVARG' == $generic_editor) return 0; else ca = callers(); index = 0; while (ca[index = index + 1][1..2] == {this, "exitfunc"}) endwhile while (ca[index = index + 1][1..2] == {what, "moveto"}) endwhile for res in (ca[index..$]) if (res[3] in rpg.gms) return 1; elseif ((!res[3]) in rpg.exporters) return 0; endif endfor return 0; endif "Profane (#30788) - Fri Jan 2, 1998 - commented out call to notify_exit; since it should be done in exitfunc anyway."; "THX (#105941) - Thu Oct 7, 1999 - Tweaked this for speed and passed a 1 to this:identify_exit()."; . @verb #258:"same_time" this none this @program #258:same_time (rpg = $local.rpg):secure(); if (this.transparency_support) {dungeon, missile_exit, o_u} = {rpg.dungeon, rpg.object_DB.PARENT_missile_exit[1], $object_utils}; where = setadd(args, this); e = this:exits(); d = this:dests(); for k in [1..length(e)] if (o_u:isa(e[k], missile_exit) && (!(d[k] in where))) where = o_u:isa(d[k], dungeon) ? d[k]:same_time(@where) | {@where, d[k]}; endif endfor return where; else return {this}; endif . @verb #258:"announce_all_but" this none this @program #258:announce_all_but {exclude, @announce} = args; rpg = $local.rpg; for t in (this.contents) if (t in exclude) elseif (valid(doll = rpg:get_doll(t)) && doll:cannot_hear()) else try t:tell(@announce); except (ANY) "Ignore listener with bad :tell"; continue t; endtry endif endfor "New silent entry detection:"; if ((this.unannounced && (i = $list_utils:iassoc(task_id(), this.unannounced))) && index(tostr(@announce), this.unannounced[i][2].name)) this.unannounced = listdelete(this.unannounced, i); endif "Quinn 13-OCT-93 0116: Added .transparency_support check before all that ancestry snooping. Made one call to ancestors instead of several :isas. Changes should speed up :announce* calls and make tracebacks less frequent."; "Profane 5-OCT-97 -- new code for silent entry detection."; "THX (#105941) - Fri Jun 29, 2001 - Copied the old code to #258:announce_all_but(old) and removed the transparency support (which no-one was using apparently). Added exclusion of dolled objects that :cannot_hear(). Changed to the actual tells in this verb. Otherwise we just end up going through .contents all over again."; "Profane (#30788) - Fri Mar 8, 2002 - tighten up the detection, make them have their name in the message."; . @verb #258:"missile_dests" this none this @program #258:missile_dests if (!$local.rpg:trusted(caller_perms())) return E_PERM; endif who = args[1]; where = {this}; e = this:exits(); d = this:dests(); for k in [1..length(e)] if (($object_utils:isa(e[k], #16049) || $object_utils:isa(e[k], #16050)) && e[k]:is_missile_channel_for(who)) where = listappend(where, d[k]); endif endfor return where; . @verb #258:"moveto" this none this @program #258:moveto return ($local.rpg:trusted(caller_perms()) || (args[1] == $nothing)) && pass(@args); . @verb #258:"block" any any any @verb #258:"identify_exit" this none this @program #258:identify_exit {what, ?loc_if_no_exit = 0} = args; exits = this:exits(); for entry in (callers()[3..$]) if (entry[1] in exits) return entry[1]; endif endfor return loc_if_no_exit ? what.location | $nothing; . @verb #258:"identify_entrance" this none this @program #258:identify_entrance entrances = this:entrances(); for entry in (callers()[3..$]) if (entry[1] in entrances) return entry[1]; endif endfor return $nothing; "Mooshie (#106469) - Fri Jan 18, 2002 - This verb used to return callers()[$][1] - the 'this' of the last call. This really didn't make sense, and :identify_exit returns $nothing uniformly if no exit was used to leave. Changed it to return $nothing."; . @verb #258:"entrances" this none this rxd #78 @program #258:entrances if ((callers()[1][3] in #46.gms) || (callers()[1][1] == this)) return this.entrances; else return {}; endif . @verb #258:"contents" this none this @program #258:contents if ((contents = this.contents) && $list_utils:assoc("look_self", callers(), 2)) pcs = $local.rpg.pcs; for t in (contents) if (t in pcs) this:hide(t) && (contents = setremove(contents, t)); endif endfor endif return contents; . @verb #258:"old_missile_dests" this none this @program #258:old_missile_dests if (!$local.rpg:trust()) return E_PERM; endif who = args[1]; where = {this}; e = this:exits(); d = this:dests(); for k in [1..length(e)] if ($object_utils:isa(e[k], #16049) && e[k]:is_missile_channel_for(who)) where = listappend(where, d[k]); endif endfor return where; . @verb #258:"notify_arrival" this none this @program #258:notify_arrival ":notify_arrival(OBJ player, OBJ entrance_used)"; {who, entrance} = args; if (caller == this) rpg = $local.rpg; if (valid(doll = rpg:get_doll(who))) doll.valid_pkp_targets = doll.INvalid_pkp_targets = {}; for effobj in (doll.move_effects) if (`effobj.owner in rpg.gms ! ANY') fork (0) rpg:trusted_verb(effobj, "enter_effect") && effobj:enter_effect(who, this, entrance); endfork else doll:setremove_att("move_effects", effobj); endif endfor endif for object in (this.contents) rpg:s_i_f_i_n(); if (rpg:trusted_verb(object, verb)) object:(verb)(who, entrance); endif endfor endif return; "Irin -- Hardcode so that non-creature objects get notified."; "Passes to the Adventurer's Database (#46), which notifies each object in this location of the given event."; "Mooshie (#106469) - Fri Jan 18, 2002 - Added move effects support."; "Mooshie (#106469) - Fri Jan 18, 2002 - Changed this:contents() call to this.contents at the top of the :notify_arrival loop."; "#46:check_notification(this:contents(), verb, args);"; "Mooshie (#106469) - Fri Jan 18, 2002 - Commented out this call to :check_notification, which duplicates the for-loop above."; "Hydros (#106189) - Wed Jul 13, 2005 - As the RPG gets bigger, it gets tickier. Added forks in a couple of spots to avoid tick-outs we've been having."; "Hydros (#106189) - Tue, Aug 9, 2005 - Changed one of the forks to a suspending call. We were getting odd E_VERBNF tracebacks."; "Hydros (#106189) - Thu Sep 8, 2005 - Added a clearing of the .[IN]valid_pkp_targets props. Using these props helps to reduce ticks in $local.rpg.death_db.pkp_effect:check_for_pk()."; . @verb #258:"visible" this none this @program #258:visible "A more intelligent handling of `all' and `everything' matching."; "This version is tailored for the RPG, only returning kids of Adventure Gear (#517)."; objects = pass(@args); pcs = (rpg = $local.rpg).pcs; for q in (objects) if (q in pcs) this:invisible(q) && (objects = setremove(objects, q)); endif endfor if (!(dobjstr in {"all", "everything"})) return objects; endif q_u = rpg.user_utils.quinn; thing = rpg.thing; fvrb = q_u:cutr(callers(), 1)[1][2]; if (fvrb in this.room_all_verbs) objects = q_u:class_list(this.contents, thing); elseif (fvrb in this.player_all_verbs) objects = q_u:class_list((args ? args[1] | player).contents, thing); else objects = q_u:class_list(objects, thing); endif rpg:s_i_n(); return objects; . @verb #258:"@rpg-gripe" any from this @program #258:@rpg-gripe $mail_editor:invoke(this.gripe_recipients, "@rpg-gripe", "@gripe: " + tostr(args[1])); . @verb #258:"magic_effects" this none this @program #258:magic_effects ":magic_effects(OBJ caster doll, NUM spell quality, OBJ spell skill, OBJ target doll) => check the room for any mystickal effects that would influence casting."; "A non-numeric return value will stop the casting cold; a numeric return value will be subtracted from spell quality."; "Newly hacked to check .magic_effects for a list of extra effects that could be added to a room by gms who don't own the room."; rpg = $local.rpg; rpg:secure(); {caster, qual, spell, target} = args; effect = 0; for effobj in (this.magic_effects) if (rpg:trusted_verb(effobj, "magic_effect")) try e = effobj:magic_effect(@args); except x (ANY) this.magic_effects = setremove(this.magic_effects, effobj); e = 0; dude = $nothing; while ((!valid(dude)) && valid(parent(effobj))) if (info = `verb_info(effobj, "magic_effect") ! ANY') dude = info[1]; else effobj = parent(effobj); endif endwhile $mail_agent:send_message(this, effobj.owner, "Error reported", ($string_utils:from_value(x, 1, 5) + " ") + tostr(effobj)); endtry if (typeof(e) != NUM) return e; else effect = effect + e; endif else this.magic_effects = setremove(this.magic_effects, effobj); endif endfor "OK, add in the room's own effect:"; try e = this:magic_effect(@args); except x (ANY) this.magic_effects = setremove(this.magic_effects, this); e = 0; dude = $nothing; while ((!valid(dude)) && valid(parent(this))) if (info = `verb_info(this, "magic_effect") ! ANY') dude = info[1]; else this = parent(this); endif endwhile $mail_agent:send_message(this, this.owner, "Error reported", ($string_utils:from_value(x, 1, 5) + " ") + tostr(this)); endtry if (typeof(e) != NUM) return e; else effect = effect + e; endif return effect; "Mooshie (#106469) - Fri Oct 10 01:25:41 1997 PDT - moved typeof(e) check inside of :trusted_verb to avoid E_VARNF tbs."; . @verb #258:"set_value" this none this @program #258:set_value ":set_value(STR property_name, value) -- Sets this.(property_name) to `value'"; {att, val} = args; (rpg = $local.rpg):secure(); if ((caller_perms() in {this.owner, rpg.owner}) || (att in {"combat_effects", "magic_effects"})) return this.(att) = val; else return E_PERM; endif "Mooshie (#106469) - Mon Jan 19, 1998 - Re-wrote. Same thing, but faster."; "Profane (#30788) - Sun Aug 30, 1998 - what was the point of 2 perm checks?"; "THX (#105941) - Thu Jul 15, 1999 - The second check only allows other gamemasters to change magic_effects and combat_effects."; . @verb #258:"get_value" this none this @program #258:get_value $local.rpg:secure(); {att} = args; return this.(att); "Mooshie (#106469) - Mon Jan 19, 1998 - Re-wrote. Same thing, but faster."; . @verb #258:"obvious_exits" this none this rx @program #258:obvious_exits "Hacked to check for an :obvious verb as well as the standard property."; exits = {}; for exit in (this:exits()) if ($code_utils:verb_or_property(exit, "obvious")) exits = setadd(exits, exit); endif endfor return exits; "Quinn 10-AUG-93 0748: Added."; . @verb #258:"exitshock" this none this rx @program #258:exitshock ":exit_penalty(who) -- Penalise player for unauthorised teleport from an RPG room."; {who} = args; (rpg = $local.rpg):secure(); {owner, gms} = {this.owner, rpg.gms}; for what in ({who, @$object_utils:all_contents(who)}) rpg:s_i_f_i_n(); if ((valid(doll = rpg:get_doll(what)) && (is_player(what) || what.alive)) && (what.owner != owner)) aggressors = doll.aggressor; "These aggressors may not be in the same room ... e.g., archers."; clear_property(doll, "aggressor"); for t in (this.contents) (t in aggressors) || ((valid(tdoll = rpg:get_doll(t)) && (who in tdoll.aggressor)) && (aggressors = {@aggressors, t})); endfor compound = 1; deserted_players = {}; for t in (setremove(aggressors, who)) compound = compound + 1; if ((is_player(t) && (t in connected_players())) && (!(t in gms))) compound = compound + 1; deserted_players = {@deserted_players, t}; endif endfor rpg:playertell(what, "The inherent implausibility of your exit briefly distorts your consciousness."); if (!is_player(what)) doll:check_ins(10 + random(45 * compound)); else doll:check_ins(10 + random(45 * compound)); doll.last_attack = doll.last_attack + (4 + compound); doll:write_misc_note("teleport lag", doll.last_attack); doll:clear_good_spells(); deserted_players && this:exitslam(doll, deserted_players); endif endif endfor "THX1138 (#105941) - Mon Jun 15, 1998 - Added a splurge to time out beneficial spells if the player exits the LRPG using LambdaMOO teleportation."; "Hannibal (#104762) - Tue July 24, 2001 - Removed connected check for exitslam."; . @verb #258:"free_exit" this none this @program #258:free_exit return this.(verb); . @verb #258:"bless_exit" this none this @program #258:bless_exit ":bless_exit(what)"; "Bless exit from this room by the given object, during THIS task."; "A 'blessed' exit avoids the mental fatigue of other teleportation."; if ($local.rpg:trusted(caller_perms())) this.blessed_exit = {args[1], task_id()}; else return E_PERM; endif . @verb #258:"look_self" this none this @program #258:look_self "Temporary :look_effects() for showing storms active in the area."; pass(@args); rpg = $local.rpg; if (storms = rpg.magic_db:print_storms(this)) player:tell_lines(storms); endif melee = duels = {}; visible = this:contents(); for t in (this.contents) if (valid(doll = rpg:get_doll(t))) for r in (doll.view_effects) if (look = `r:look_msg(doll) ! E_VERBNF => ""') player:tell(look); endif endfor if ((valid(doll.duelee) && (`(ddoll = rpg:get_doll(doll.duelee)).duelee ! E_INVIND' == t)) && (!(t in $list_utils:flatten(duels)))) if (((doll.last_attack + 300) < time()) || ((`ddoll.last_attack ! E_INVIND => 0' + 300) < time())) "Duelist idled out."; rpg:tell_damage(t, "Your duel has timed out, and has been rendered null and void."); rpg:tell_damage(doll.duelee, "Your duel has timed out, and has been rendered null and void."); clear_property(doll, "duelee"); clear_property(ddoll, "duelee"); else duels = {@duels, {t, doll.duelee}}; endif elseif (doll.aggressor) (t in visible) && (melee = {@melee, t:title()}); endif endif endfor for pair in (duels) player:tell(pair[1]:titlec(), " and ", pair[2]:title(), " are engaged in a duel to the death!"); endfor (length(melee) > 1) && player:tell($string_utils:english_list(melee), " are engaged in ", {"fierce", "brutal", "vicious", "heated", "savage"}[random($)], " combat."); "Miles 26-Aug-1995 -- Added."; . @verb #258:"make_fertile" this none this @program #258:make_fertile ":make_fertile() -- Temporarily toggles the 'f' bit, allowing GMs (and not builders in general) to create a child of adventure gear. To be used as follows:"; ";;#equipment:make_fertile();return player:_create(#equipment)"; "Where '#equipment' is the number of the object you're wanting to create. The blank object returned will be your child. Congratulations, Mommy."; if ($local.rpg:trusted(caller_perms())) if (!this.f) this.f = 1; fork (0) this.f = 0; endfork endif return this.f; endif "Quinn 09-JUL-93 0343: Changed :trust call to :trusted(caller_perms()); Updated comment lines; eliminated check for ownership in first 'if'. Let it crash if a kid not owned by GM uses the parent; Now returns status of f-bit."; . @verb #258:"_eject" this none this @program #258:_eject ":_eject -- called from $local.rpg:die to eject loser players who have @refused moves from G_M"; {who} = args; $local.rpg:secure(); this:bless_exit(who); this:eject_basic(who); . @verb #258:"say" any any any rxd @program #258:say doll = (rpg = $local.rpg):get_doll(player); if (valid(doll) && (p = doll:cannot_talk())) return player:tell((typeof(p) == STR) ? p | "You're paralyzed and find it impossible to talk."); endif try if (is_player(player) || `player.yeller ! ANY => 0') player:tell("You say, \"", argstr, "\""); this:announce_all_but({player}, player.name, " ", $gender_utils:get_conj("says", player), ", \"", argstr, "\""); else player:tell("You say: \"", argstr, "\""); rpg:rpg_announce_all_but(this, {player}, player.name, " ", $gender_utils:get_conj("says", player), ", \"", argstr, "\""); endif except (ANY) "Don't really need to do anything but ignore the idiot who has a bad :tell"; endtry . @verb #258:"match_exit" this none this rx @program #258:match_exit rpg = $local.rpg; if (valid(p = pass(@args))) if ((caller == this) || (caller in rpg.object_db.walking_features)) if (this:sleeping(player)) rpg:playertell(player, "In your dreams, you yearn to travel."); kill_task(task_id()); elseif (this:resting(player)) this:stand(player); endif endif c = callers(); while (c[1][1..2] == {this, verb}) c = c[2..$]; endwhile "i.e. strip out any child versions of this verb"; if (((c[1][1] == this) && rpg:trusted(c[1][3])) && (m = (doll = rpg:get_doll(player)):cannot_walk())) "i.e. ONLY do the paralysis crap if match_exit is called by a trusted verb... let non-trusted verbs match_exits, because match_exit can be called non-VR, e.g. by FO's"; "Thus we prevent people from getting stamina checks via the overloaded combat effect by calling @rose, for example."; (length(callers()) < 7) && rpg:playertell(player, (typeof(m) == STR) ? m | "You're paralyzed. You aren't going to be doing much moving around."); return $failed_match; elseif (p in rpg.object_db.bad_exits) return $failed_match; endif endif return p; "Profane (#30788) - Mon Mar 5, 2001 - change security bits."; "THX (#105941) - Tue Apr 3, 2001 - Upgraded to do sleeping-refusal and auto-standing here rather than in #49444:east. Cleaned up quite a bit."; . @verb #258:"initialize" this none this @program #258:initialize owner = (rpg = $local.rpg).owner; if ((!(this.owner in rpg.gms)) && (!(parent(this) in rpg.object_DB.OBJ_player_ownable_room))) callers = callers(); fork (0) msg = {$string_utils:nn(player), toliteral(callers), ((($string_utils:nn(this) + " ") + $string_utils:nn(parent(this))) + " ") + ctime()}; $mail_agent:send_message(owner, {owner}, "Player has created child of #258", msg); endfork endif return pass(@args); . @verb #258:"sleep doze nap snooze rest sit crash slump collapse yawn snore search wake stand rise pray chant" none none none @program #258:sleep "A catch all verb that help the rpg room look smarter by not saying \"I don't understand that.\" all the time."; if (!((caller in {player, this, this.location}) && (player.location == this))) return E_PERM; endif if (verb in {"sleep", "doze", "nap", "snooze", "rest", "sit", "crash", "slump", "collapse"}) player:tell("You can't seem to get comfortable here."); elseif (verb == "yawn") player:tell("You yawn."); elseif (verb in {"snore", "wake"}) player:tell("You aren't sleeping here."); elseif (verb in {"stand", "rise"}) player:tell("You aren't resting here."); elseif (verb == "search") player:tell("You make a quick search of the room and find nothing hidden."); else player:tell("This isn't a good place to ", verb, "."); endif . @verb #258:"all_contents" this none this @program #258:all_contents "Copied from object utilities (#3669):all_contents by Hacker (#18105) Wed Jul 2 06:37:05 1997 PDT"; "all_contents(object)"; "Return a list of all objects contained (at some level) by object."; for y in (res = args[1].contents) y.contents && (res = {@res, @this:all_contents(y)}); endfor return res; . @verb #258:"read_misc_note" this none this @program #258:read_misc_note ":read_misc_note(name)"; "Much as the same verb on the voodoo doll. In fact, the same verb."; "View a miscellaneous note on the voodoo doll."; $local.rpg:secure(); {index} = args; for elm in (this.misc_notes) {elm1, elm2} = elm; if (elm1 == index) return elm2; endif endfor return E_PROPNF; . @verb #258:"write_misc_note" this none this @program #258:write_misc_note ":write_misc_note(name, value)"; "As per the vebr on #74"; if (!$local.rpg:trusted(caller_perms())) return E_PERM; elseif (length(args) != 2) return E_ARGS; endif notes = this.misc_notes; index = args[1]; for i in [1..length(notes)] if (notes[i][1] == index) this.misc_notes[i][2] = args[2]; return i; endif endfor this.misc_notes = listappend(notes, args); return length(notes) + 1; . @verb #258:"erase_misc_note" this none this @program #258:erase_misc_note ":erase_misc_note(name)"; "Remove a miscellaneous note from the room."; if (!$local.rpg:trusted(caller_perms())) return E_PERM; endif notes = this.misc_notes; index = args[1]; for i in [1..length(notes)] if (notes[i][1] == index) this.misc_notes = listdelete(notes, i); size = length(notes) - 1; if (size == 0) clear_property(this, "misc_notes"); endif return size; endif endfor return E_PROPNF; . @verb #258:"combat_effects" this none this @program #258:combat_effects ":combat_effect(DOLL by, DOLL target, OBJ weapon) => check the room for any wierd effects which would impede/assist the attacker."; "A non-numeric return value will stop the swing cold; a numeric return value will be subtracted from attack quality."; "Newly hacked to check .combat_effects for a list of extra effects that could be added to a room by gms who don't own the room."; rpg = $local.rpg; rpg:secure(); {by, target, weapon} = args; effect = 0; for effobj in (this.combat_effects) if (rpg:trusted_verb(effobj, "combat_effect")) try e = effobj:combat_effect(@args); except x (ANY) this.combat_effects = setremove(this.combat_effects, effobj); e = 0; dude = $nothing; while ((!valid(dude)) && valid(parent(effobj))) if (info = `verb_info(effobj, "combat_effect") ! ANY') dude = info[1]; else effobj = parent(effobj); endif endwhile $mail_agent:send_message(this, effobj.owner, "Error reported", ($string_utils:from_value(x, 1, 5) + " ") + tostr(effobj)); endtry else this.combat_effects = setremove(this.combat_effects, effobj); endif if (typeof(e) != NUM) return e; else effect = effect + e; endif endfor "OK, add in the room's own effect:"; try e = this:combat_effect(@args); except x (ANY) this.combat_effects = setremove(this.combat_effects, this); e = 0; dude = $nothing; while ((!valid(dude)) && valid(parent(this))) if (info = `verb_info(this, "combat_effect") ! ANY') dude = info[1]; else this = parent(this); endif endwhile $mail_agent:send_message(this, this.owner, "Error reported", ($string_utils:from_value(x, 1, 5) + " ") + tostr(this)); endtry if (typeof(e) != NUM) return e; else effect = effect + e; endif return effect; . @verb #258:"bless_for_teleport" this none this @program #258:bless_for_teleport "Usage: bless_for_teleport(OBJ thing)"; "Sets this room to allow the same task to teleport an object in."; if (!$local.rpg:trusted(caller_perms())) return E_PERM; endif {what} = args; this.teleport_object = what; this.teleport_task = task_id(); "Mooshie (#106469) - Sun Oct 12 00:06:40 1997 PDT - Added."; . @verb #258:"notify_exit" this none this @program #258:notify_exit "Passes to the Adventurer's Database (#46), which notifies each object in this location of the given event."; ":notify_exit(OBJ player, OBJ exit_used)"; {who, exit} = args; if (caller == this) gms = (rpg = $local.rpg).gms; if (valid(doll = rpg:get_doll(who))) for effobj in (doll.move_effects) if (`effobj.owner in gms ! ANY') fork (0) rpg:trusted_verb(effobj, "exit_effect") && effobj:exit_effect(who, this, exit); endfork else doll:setremove_att("move_effects", effobj); endif endfor endif for object in (this.contents) if (valid(doll = rpg:get_doll(object)) && doll.aggressor) doll.aggressor = setremove(doll.aggressor, who); doll.valid_pkp_targets = setremove(doll.valid_pkp_targets, who); doll.INvalid_pkp_targets = setremove(doll.INvalid_pkp_targets, who); endif if (rpg:trusted_verb(object, verb)) fork (0) object:(verb)(who, exit); endfork endif endfor endif return; "Profane (#30788) - Sat Dec 5, 1998 - error trap the calls."; "Mooshie (#106469) - Fri Jan 18, 2002 - Added move effects support."; "Hydros (#106189) - Wed Jul 13, 2005 - As the RPG gets bigger, it gets tickier. Added forks in a couple of spots to avoid tick-outs we've been having."; "Hydros (#106189) - Tue Oct 4, 2005 - Added clearing of .[IN]valid_pkp_targets props to aid the new PKProtection system."; . @verb #258:"att*ack hit ki*ll" any none none rxd @program #258:attack "attack "; "attack 's "; rpg = $local.rpg; if ((((!valid(cp = caller_perms())) || rpg:trusted(cp)) || ((caller == this) || (caller in rpg.vacuum.monsters))) || (!is_player(player))) if (parsed = $match_utils:parse_possessive_reference(dobjstr)) {dobjstr, where} = parsed; else where = ""; endif if (valid(doll = rpg:get_doll(player))) for t in (doll.aggressor) (t.location == this) || (doll.aggressor = setremove(doll.aggressor, t)); endfor if (dobjstr) "... do nothing ... "; elseif (agg = doll.aggressor) dobjstr = tostr(agg[random($)]); else rpg:playertell(player, "Who (or what) are you trying to hit?"); return; endif if (w = doll:wielding()) {first, @weaps} = w; return first:hit(dobjstr, "with", tostr(first), weaps, where); else rpg:playertell(player, "You are unarmed."); return E_INVIND; endif else rpg:playertell(player, "Your feeble attacks have no effect upon ", dobj.name, ". Perhaps you should consider being trained with the Bovine Illuminati."); return E_INVARG; endif else return E_PERM; endif . @verb #258:"he*al sl*ow re*call li*felink unl*ink mindp*robe de*press st*ealskill pa*cify unw*all fo*rcewall bar*kskin di*spel har*den hai*l ices*hell waterw*hip conj*ure sum*mon sto*rm sti*nkcloud pr*edict heat charm*foe hold*foe raven*fear bi*ting_cloud haste acidr*ain appr*aise poi*son tang*le gly*ph ca*lm minds*hock sha*tter mag*icfist rune reverse*missiles det*ect windw*all ench*ant rot fireb*olt viper*_bite unviper backf*ire unbar*k unbac*kfire petals wound drain compost triage beguile mergestorm stoneflesh blade*barrier unblade*barrier daggers*torm parch chill unreverse resurrect dirge fort*ify haw*thorn anim*ate" any any any rxd @program #258:heal "Copied from Generic Dungeon Room (#258):firebolt [verb author Grand_Master (#2693)] at Mon Sep 12 17:39:10 2005 PDT"; rpg = $local.rpg; mdb = rpg.magic_db; if (callers() && ((caller != this) && (!(caller in rpg.vacuum.monsters)))) rpg:secure(); endif "fiddle with the arguments given so they'll match."; test = $string_utils:parse_command((verb + " ") + argstr); true_dobjstr = dobjstr; if (!prepstr) test[6][2] = {@test[6][2], "with/using", "out of/from inside/from"}; endif "First, see short-circuit if the player is trying to call the exact verb on the exact object specified:"; if ((((dobj != this) && valid(dobj)) && $match_utils:match_verb(verb, dobj, args)) || (valid(iobj) && $match_utils:match_verb(verb, iobj, args))) "such was the case, so we can stop now."; return; endif "If a preposition isn't given, we just let the verb match `from' and `with' the prepositions used for casting from the focus directly."; "Iobj is always the focus, which we set down below."; "Dobj takes some more fiddling, and depends on the focus being used, so we fiddle it below."; "determine the full name of the verb we want:"; spells = verb_info(rpg.dungeon, verb)[3]; spells = " " + $string_utils:strip_chars(spells, "*"); match = match(spells, ("%<%(" + verb) + "%(%w%|_%)*%)%>"); try spell = substitute("%1", match); except (E_INVARG) "No match at all."; player:tell("The spellcasting shortcut verb can't seem to figure out which spell \"", verb, "\" refers to."); return; endtry "Now find what objects it's on."; doll = rpg:get_doll(player); stuff = valid(iobj) ? {iobj} | {}; "if the player gave an iobj (which will be a focus), we check that one first"; stuff = {@stuff, @`doll:wielding() ! ANY => {}', @`doll:wearing() ! ANY => {}'}; "then we check held/worn stuff."; "Now we see which of these things is a focus for the requested spell."; candidates = {}; wrong_prep = {}; for thingy in (stuff) if (verbloc = $object_utils:has_callable_verb(thingy, spell)) if (verb_args(verbloc[1], spell)[2] in test[6][2]) candidates = setadd(candidates, thingy); else "This bit is in case of failure, so we can explain syntax."; wrong_prep = setadd(wrong_prep, thingy); endif endif endfor "now try and call the spell verb"; for focus in (candidates) "$match_utils:match_verb needs iobjstr and prepstr set for it to work, so we set them here, per which focus we are trying."; iobjstr = tostr(iobj = focus); focus_args = verb_args($object_utils:has_callable_verb(focus, spell)[1], spell); prepstr = $code_utils:short_prep(focus_args[2]); "Fiddling with dobj is necessary for $match_utils:match_verb to call verbs with a `none' dobj argument."; if (!true_dobjstr) "Player did not specify a dobj, so we make some assumptions."; if (focus_args[1] != "none") if (spell in {@mdb.peaceful_spells, @mdb.self_default_spells}) "assume player as target for peaceful spells."; dobjstr = tostr(dobj = player); elseif (doll.aggressor) "Hostile spell, pick a random aggressor"; dobjstr = tostr(dobj = doll.aggressor[random($)]); else "Casting hostile spell with no aggressor. dork."; dobjstr = ""; dobj = $nothing; endif else "The player did not give us a dobj, but we might have set it in trying to match a verb without a `none' dobj argument, so unset it here."; dobjstr = ""; dobj = $nothing; endif elseif ((dobj == focus) && (focus_args[1] == "none")) dobjstr = ""; dobj = $nothing; endif if ($match_utils:match_verb(spell, focus, {})) "bingo, a match"; return; endif endfor "Ok, now try to explain the problem:"; if (wrong_prep) $command_utils:explain_syntax(wrong_prep[1], verb, args); else player:tell("You try to cast ", `rpg:match_skill(spell):title() ! E_INVIND => verb', ", but realize you lack the proper focus."); endif . @verb #258:"emote" any any any rxd @program #258:emote doll = (rpg = $local.rpg):get_doll(player); if (valid(doll) && (p = doll:cannot_emote())) return player:tell((typeof(p) == STR) ? p | "You're paralyzed and find it impossible to emote anything."); endif argstr = (argstr && (argstr[1] == ":")) ? argstr[2..$] | (" " + argstr); if (is_player(player)) " this:show_all_but({`this:sleeping() ! E_VERBNF'}, player.name, argstr)"; this:show_all_but(`this:sleeping() ! E_VERBNF', player.name, argstr); else player:tell("You emote: ", player.name, argstr); rpg:rpg_show_all_but(this, {player, @`this:sleeping() ! E_VERBNF => {}'}, player.name, argstr); endif . @verb #258:"exitclean" this none this @program #258:exitclean (rpg = $local.rpg):secure(); {doll} = args; n = 0; for t in (sch = doll.schedule) {what, effect, time, various} = t; n = n + 1; if (effect in {"unwind", "unwall", "unbark", "unstone"}) doll.schedule[n][3] = time(); elseif (effect == "unspeed") if (various[1] > doll.slowness) "They're hasted..."; doll.schedule[n][3] = time(); endif endif endfor . @verb #258:"notify_player" this none this rxd #58142 @program #258:notify_player if (caller == $local.rpg) {who, msg} = args; (who.location == this) && notify(who, msg); else return E_PERM; endif . @verb #258:"detect_magic_msg" this none this @program #258:detect_magic_msg "Returns messages displayed when a player successfully casts detect in this room."; {bydoll, qual} = args; (rpg = $local.rpg):secure(); msg = {}; for d in (setremove(this.magic_effects, this)) if ($object_utils:has_callable_verb(d, "detect_magic_msg")) msg = {@msg, @(typeof(f = d:detect_magic_msg(bydoll, qual)) == LIST) ? f | {f}}; endif endfor if (oset = (typeof(temp = this:read_misc_note("g&r")) == LIST) ? temp | {}) "revise the list, take out expired glyphs&runes etc."; grset = $list_utils:build_alist(oset, 3); for d in (grset) if (time() > d[3]) grset = setremove(grset, d); endif endfor if (!grset) rpg.magic_db.gr_combat_effect:remove_effect(this); return msg; endif if ((length(grset) * 3) != length(oset)) this:write_misc_note("g&r", $list_utils:flatten(grset)); endif gset = rset = {}; for d in (grset) if (d[2] < 0) gset = {@gset, d}; else rset = {@rset, d}; endif endfor if (qual > 100) "say what they are, their strength, when they expire."; msg = {@msg, "Your powerfully enhanced vision reveals much about the glowing magical energies upon the ground:"}; for d in (grset) f = abs(d[2]); if (f > 50) stren = "A pulsing and brightly throbbing "; elseif (f > 25) stren = "A solidly glowing "; else stren = "A flickering "; endif msg = {@msg, tostr(stren, d[1].name, (d[2] < 0) ? " glyph " | " rune ", "will expire in ", $time_utils:english_time(d[3] - time()), ".")}; endfor return msg; elseif (qual > 75) "say what the glyphs and runes are, and a qualifier indicating their strength"; nmsg = "Your enhanced vision reveals"; for d in (grset) f = abs(d[2]); if (f > 50) stren = "a pulsing and brightly throbbing "; elseif (f > 25) stren = "a solidly glowing "; else stren = "a flickering "; endif nmsg = nmsg + tostr(((d == grset[$]) && (length(grset) > 1)) ? " and " | " ", stren, d[1].name, (d[2] < 0) ? " glyph," | " rune,"); endfor nmsg[$] = " "; return {@msg, nmsg + "etched into the ground here."}; elseif (qual > 50) "say what the glyphs and runes are"; nmsg = "Your enhanced vision reveals"; for d in (grset) nmsg = nmsg + tostr(((d == grset[$]) && (length(grset) > 1)) ? " and " | " ", $string_utils:a_or_an(d[1].name), " ", d[1].name, (d[2] < 0) ? " glyph," | " rune,"); endfor nmsg[$] = " "; return {@msg, nmsg + "etched into the ground here."}; elseif (qual > 25) "say #glyphs and #runes"; return {@msg, tostr("Your enhanced vision reveals ", gset ? tostr($string_utils:english_number(length(gset)), " glyph", (length(gset) > 1) ? "s " | " ") | "", (gset && rset) ? "and " | "", rset ? tostr($string_utils:english_number(length(rset)), " rune", (length(gset) > 1) ? "s " | " ") | "", "etched into the ground here.")}; else "just say total # glyphs&runes"; return {@msg, tostr("Your enhanced vision reveals ", (length(grset) > 1) ? $string_utils:english_number(length(grset)) + " glyphs and/or runes" | "a glyph or rune", " etched into the ground here.")}; endif else return msg; endif "Dred 2-12-99: Created new spell result."; "Copied from Perceiving the Powers of Magic (#476):detect_magic_msg(room) by Dred (#49925) Tue Feb 16 06:13:51 1999 PST"; . @verb #258:"hide" this none this @program #258:hide {what} = args; if (valid(doll = $local.rpg:get_doll(what))) for t in (doll.view_effects) if (`t:hide_from_tell_contents(what) ! E_VERBNF') return 1; endif endfor endif return 0; . @verb #258:"disfunc" this none this rd @program #258:disfunc if ((((cp = caller_perms()) == player) || $perm_utils:controls(cp, player)) || (caller == this)) if (((player in $local.rpg.pcs) && (player == player.owner)) && (!(player in $local.rpg.gms))) this:announce_all_but({player}, $string_utils:pronoun_sub("%N % disconnected.", player)); else pass(@args); endif endif . @verb #258:"identify_exit(old)" this none this @program #258:identify_exit(old) lenc = length(ca = callers()); for entry in (ca[3..lenc]) if (entry[1] in this:exits()) return entry[1]; endif endfor return $nothing; return args[1].location; . @verb #258:"say(old)" any any any rxd @program #258:say(old) doll = $local.rpg:get_doll(player); if (valid(doll) && (p = doll:cannot_talk())) return player:tell((typeof(p) == STR) ? p | "You're paralyzed and find it impossible to talk."); endif try is_player(player) && player:tell("You say, \"", argstr, "\""); this:announce_all_but({player}, player.name, " ", $gender_utils:get_conj("says", player), ", \"", argstr, "\""); except (ANY) "Don't really need to do anything but ignore the idiot who has a bad :tell"; endtry . @verb #258:"emote(old)" any any any rxd @program #258:emote(old) doll = (rpg = $local.rpg):get_doll(player); if (valid(doll) && (p = doll:cannot_emote())) return player:tell((typeof(p) == STR) ? p | "You're paralyzed and find it impossible to emote anything."); endif argstr = (argstr && (argstr[1] == ":")) ? argstr[2..$] | (" " + argstr); if (is_player(player)) this:announce_all_but({}, player.name, argstr); else player:tell("You emote: ", player.name, argstr); rpg:rpg_announce_all_but(this, {player}, player.name, argstr); endif . @verb #258:"exitshock(old)" this none this rx @program #258:exitshock(old) ":exit_penalty(who) -- Penalise player for unauthorised teleport from an RPG room."; {who} = args; (rpg = $local.rpg):secure(); owner = this.owner; for what in ({who, @$object_utils:all_contents(who)}) rpg:time_stop(1); if ((valid(doll = rpg:get_doll(what)) && (is_player(what) || what.alive)) && (what.owner != owner)) aggressors = doll.aggressor; for t in (this.contents) (t in aggressors) || ((valid(tdoll = rpg:get_doll(t)) && (who in tdoll.aggressor)) && (aggressors = {@aggressors, t})); endfor compound = 1; for t in (aggressors) compound = (compound + 1) + is_player(t); endfor rpg:playertell(what, "The inherent implausibility of your exit briefly distorts your consciousness."); if ((connected = what in connected_players()) || (!is_player(what))) doll:check_ins(10 + random(45 * compound)); endif if (connected) doll.last_attack = (doll.last_attack + 4) + compound; doll:clear_good_spells(); endif clear_property(doll, "aggressor"); endif endfor "THX1138 (#105941) - Mon Jun 15, 1998 - Added a splurge to time out beneficial spells if the player exits the LRPG using LambdaMOO teleportation."; . @verb #258:"exitslam" this none this @program #258:exitslam {doll, mob} = args; if (`this.arena ! E_PROPNF => 0') "Combat Arena: fight is not to-the-death so don't penalize."; elseif (caller == this) rpg = $local.rpg; vowed = rpg.user_utils.ogwul:vowed(doll); if (((note = doll:read_misc_note("first_blood")) != E_PROPNF) || vowed) {char, puzzles, result} = {doll.character, rpg.puzzle_log, 0}; if (note) for t in (note) {who, time} = t; if ((who in mob) && (time > time())) puzzles:add_solved(char, verb); result = result + 1; endif endfor else puzzles:add_solved(char, verb); result = result + 1; endif if (result || vowed) {object_db, losses, su} = {rpg.object_db, {}, $string_utils}; hits = severity = puzzles:has_solved(char, verb); rpg.object_db.exitslam_effect:add(doll); doll:write_misc_note("exitslam", time() + (99 * severity)); contents = $object_utils:all_contents(char); severity = min(severity, length(contents)); for t in (contents) rpg:s_i_f_i_n(); if (((length(losses) < severity) && object_db:is_thing(t)) && (!t:keep_at_death(char))) losses = {@losses, t.name}; t:moveto(this); endif endfor rpg:rpg_announce_all_but(this, {char}, "In ", char.pp, " haste to leave, ", char.name, " teleports out without using LambdaRPG methods and leaves behind ", char.pp, " ", eng_list = su:english_list(losses), "!"); rpg:playertell(char, "In your haste to get away from ", su:english_list($list_utils:map_prop(mob, "name")), ", you become distracted while using teleportation techniques that aren't LambdaRPG methods and lose control of your ", eng_list, "!"); rpg:rpg_announce_all_but(this, {char}, char.name, "'s equipment clatters to the ground."); fork (0) $mail_agent:send_message(rpg.owner, rpg.object_db.confess, (su:nn(this) + ":") + verb, {((((su:nn(char) + " lost a ") + eng_list) + " whilst escaping from ") + su:nn(mob)) + " after initiating the combat (or having vowed to escape using only themely means).", ("This player has been affected " + tostr(hits)) + " times to date."}); endfork endif endif endif . @verb #258:"sc*ore health ht co*ndition" this none this @program #258:score "THX (#105941) - Thu Mar 16, 2000 - Interrupts the 'sc' on the Bovine FO to check sleeping players."; (rpg = $local.rpg):secure(); if (!dobjstr) dobj = player; elseif (valid(dobj)) "gotcha"; else dobj = player:my_match_object(dobjstr); endif dobj = toobj(dobj); if (valid(doll = rpg:get_doll(dobj))) for t in ({"inj", "ins", "fat"}) (doll.(t) < 0) && (doll.(t) = 0); endfor endif if (player in rpg.gms) elseif (`player.location:sleeping(player) ! ANY => 0') return player:tell(rpg.user_utils.thx1138:sleeping_score(dobj)); endif rpg.gm_feature.gm_utils:score(dobj); "THX (#105941) - Mon Dec 18, 2000 - Put an ugly bloody hack in to catch negative injury, fatigue, or sanity scores before continuing."; . @verb #258:"hidden_verbs" this none this @program #258:hidden_verbs {who} = args; prev = pass(who); generic = (rpg = $local.rpg).dungeon; if (!rpg:trusted(who)) prev = {@prev, {generic, verb_info(generic, "sleep")[3], {"none", "none", "none"}}}; prev = {@prev, {generic, verb_info(generic, "heal")[3], {"any", "any", "any"}}}; endif return prev; . @verb #258:"setadd_exit setremove_exit" this none this @program #258:setadd_exit ":setadd[remove]_exit(OBJ exit) -- Adds/removes and exit to/from an RPG room _if_ the exit is in the room's .allowed_exits property."; "If (room == exit.dest) then the exit is added/removed from room.entrances. If (room == exit.source) then the exit is added/removed from room.exits."; {exit} = args; (rpg = $local.rpg):secure(); if (`exit.source ! ANY => $nothing' == this) slot = "exits"; elseif (`exit.dest ! ANY => $nothing' == this) slot = "entrances"; else raise(E_INVARG); endif if ((this.owner in rpg.gms) && (exit in this.allowed_exits)) this.(slot) = index(verb, "add") ? setadd(this.(slot), exit) | setremove(this.(slot), exit); else raise(E_PERM); endif "THX (#105941) - Thu Mar 23, 2000 - Added."; . @verb #258:"invisible" this none this @program #258:invisible {what} = args; if (valid(doll = $local.rpg:get_doll(what))) for t in (doll.view_effects) if (`t:hide_from_visible(what) ! E_VERBNF') return 1; endif endfor endif return 0; . @verb #258:"match_exit(old)" this none this rx @program #258:match_exit(old) rpg = $local.rpg; c = callers(); while (c[1][1..2] == {this, verb}) c = c[2..$]; endwhile "i.e. strip out any child versions of this verb"; "if (caller == this || caller_perms() in rpg.gms)"; if (valid(p = pass(@args))) if (((c[1][1] == this) && rpg:trusted(c[1][3])) && (m = (doll = rpg:get_doll(player)):cannot_walk())) "i.e. ONLY do the paralysis crap if match_exit is called by a trusted verb... let non-trusted verbs match_exits, because match_exit can be called non-VR, e.g. by FO's"; "Thus we prevent people from getting stamina checks via the overloaded combat effect by calling @rose, for example."; (length(callers()) < 7) && player:tell((typeof(m) == STR) ? m | "You're paralyzed. You aren't going to be doing much moving around."); return $failed_match; elseif (p in rpg.object_db.bad_exits) return $failed_match; else return p; endif else return p; endif "else"; " return $failed_match;"; "endif"; "Profane (#30788) - Mon Mar 5, 2001 - change security bits."; . @verb #258:"_eject(old)" this none this @program #258:_eject(old) ":_eject -- called from #46:die to eject loser players who have @refused moves from G_M"; if ($local.rpg:trusted(caller_perms())) this:eject_basic(args[1]); endif . @verb #258:"duel" any any any @program #258:duel rpg = $local.rpg; if (player.location != this) rpg:playertell(player, "No remote dueling, sorry."); elseif (!valid(doll = rpg:get_doll(player))) rpg:playertell(player, "Duel how? You need to get illuminated first. Try #88."); elseif ($command_utils:object_match_failed(target = this:match(argstr), argstr)) elseif (target == player) rpg:playertell(player, "... Try the termination centre."); elseif (!is_player(target)) rpg:playertell(player, "You can only duel other players."); elseif (player.owner != player) rpg:playertell(player, "Duelling as a guest? What a pansy; get a real character first!"); elseif (target.owner != target) rpg:playertell(player, "Dueling guests? What fun is that? Forget it."); elseif (!valid(tdoll = rpg:get_doll(target))) rpg:playertell(player, target.name, " does not seem to be enlightened; therefore you cannot duel ", target.po, "."); elseif (player.location != target.location) rpg:playertell(player, "You're not in the same place as ", target.name, "."); elseif (valid(doll.duelee)) if (doll.duelee == target) if (tdoll.duelee == player) rpg:playertell(player, "Um, you and ", target.name, " are already dueling."); else rpg:playertell(player, "You have already challenged ", target.name, " to a duel to the death."); endif else if (`rpg:get_doll(doll.duelee).duelee ! E_INVIND' == player) rpg:playertell(player, "You're currently dueling ", doll.duelee.name, "; one duel at a time."); else rpg:playertell(player, "You've just challenged ", doll.duelee.name, " to a duel, finish that one first."); endif endif elseif ((valid(who = tdoll.duelee) && valid(`rpg:get_doll(tdoll.duelee).duelee ! E_INVIND => $nothing')) && (who != player)) rpg:playertell(player, target.name, " is currently engaged in a duel with ", who.name, "; wait until they've finished."); elseif (setremove(tdoll.aggressor, player)) rpg:playertell(player, target.name, " seems occupied with another combat at the moment. Maybe try again later, or ask them to break off all combat."); elseif (teammates = rpg.user_utils.quinn:class_list(doll.armour_effects, rpg.doll)) rpg:playertell(player, "You'll have to unteam with ", $string_utils:english_list($list_utils:map_prop($list_utils:map_prop(teammates, "character"), "name")), " before you can engage in a duel."); elseif (teammates = rpg.user_utils.quinn:class_list(tdoll.armour_effects, rpg.doll)) rpg:playertell(player, target.name, " will have to unteam with ", $string_utils:english_list($list_utils:map_prop($list_utils:map_prop(teammates, "character"), "name")), " before you can engage ", target.po, " in a duel."); elseif (tdoll.duelee == player) "Accepting duel."; doll.duelee = target; rpg:tell_damage(player, "You accept ", target.name, "'s duel to the death! FIGHT!"); rpg:tell_damage(target, player.name, " accepts your duel to the death! FIGHT!"); rpg.owner.duelers = {@rpg.owner.duelers, {player, target, time()}}; doll.last_attack = time(); tdoll.last_attack = time(); else "Initiating"; doll.duelee = target; rpg:tell_damage(player, "You have challenged ", target.name, " to a duel to the death!"); rpg:tell_damage(target, player.name, " has challenged you to a duel to the death! Type `duel ", player.name, "' to accept or `decline ", player.name, "' to refuse."); endif "Hydros (#106189) - Tue Nov 1, 2005 - Added check for target's location matching that of player."; . @verb #258:"decline" any any any @program #258:decline rpg = $local.rpg; "decline => declines a duel to the death that player has challenged you to."; if (player.location != this) rpg:playertell(player, "No remote dueling (or un-dueling), sorry."); elseif (!valid(doll = rpg:get_doll(player))) rpg:playertell(player, "Um dude, no one could duel you even if they wanted, stop being so paranoid."); elseif ($command_utils:object_match_failed(target = this:match(argstr), argstr)) elseif (!valid(tdoll = rpg:get_doll(target))) rpg:playertell(player, "Um, ", target.name, " couldn't duel you even if ", `target.ps ! ANY => "it"', " wanted to; stop being so paranoid."); elseif ((doll.duelee == target) && (tdoll.duelee == player)) rpg:playertell(player, "Hey, you already accepted the duel. No declining now."); elseif (tdoll.duelee != player) rpg:playertell(player, target.name, " has not offered to duel you, so you're safe."); else tdoll.duelee = $nothing; rpg:tell_damage(player, "You decline ", target.name, "'s duel to the death."); rpg:tell_damage(target, player.name, " has declined your offer to duel to the death."); endif . @verb #258:"announce_all_but(old)" this none this @program #258:announce_all_but(old) rpg = $local.rpg; if (this.transparency_support && (((rpg.thing in (anc = rpg:parents(caller))) || (rpg.doll in anc)) || (rpg.monster in anc))) for k in (this:same_time()) k:(verb)(@args); endfor else pass(@args); endif "New silent entry detection:"; if (i = $list_utils:iassoc(task_id(), this.unannounced)) this.unannounced = listdelete(this.unannounced, i); endif "Quinn 13-OCT-93 0116: Added .transparency_support check before all that ancestry snooping. Made one call to ancestors instead of several :isas. Changes should speed up :announce* calls and make tracebacks less frequent."; "Profane 5-OCT-97 -- new code for silent entry detection."; . @verb #258:"announce_all" this none this @program #258:announce_all this:announce_all_but({}, @args); "THX (#105941) - Fri Jun 29, 2001 - Added."; . @verb #258:"announce" this none this @program #258:announce this:announce_all_but({player}, @args); "THX (#105941) - Fri Jun 29, 2001 - Added."; . @verb #258:"show_all_but" this none this @program #258:show_all_but {exclude, @announce} = args; rpg = $local.rpg; for t in (this.contents) if (t in exclude) elseif (valid(doll = rpg:get_doll(t)) && doll:cannot_see()) else try t:tell(@announce); except (ANY) "Ignore listener with bad :tell"; continue t; endtry endif endfor "New silent entry detection:"; if (this.unannounced && (i = $list_utils:iassoc(task_id(), this.unannounced))) this.unannounced = listdelete(this.unannounced, i); endif "THX (#105941) - Fri Jun 29, 2001 - Added."; . @verb #258:"show" this none this @program #258:show this:show_all_but({player}, @args); "THX (#105941) - Fri Jun 29, 2001 - Added."; . @verb #258:"show_all" this none this @program #258:show_all this:show_all_but({}, @args); "THX (#105941) - Fri Jun 29, 2001 - Added."; . "***finished***