Dump of #517 (Generic LRPG Thing)

@create $thing named Generic LRPG Thing:Generic LRPG Thing,thing
@prop #517."unique" 0 rc
@prop #517."encumbrance" 0 r
@prop #517."manufactured" 743932381 r
@prop #517."user_settable_messages" {} rc
;;#517.("user_settable_messages") = {"bully"}
"#517.("worth") => E_PERM (Permission denied)
@prop #517."keep_at_death" 0 r
@prop #517."condition" E_NONE r
@prop #517."claimed_by" #-1 r
@prop #517."glued" 0 rc
@prop #517."last_action" 0 r
@prop #517."use_spell_msg_db" 0 rc
;;#517.("odrop_failed_msg") = "%<tries> to drop %t but fails!"
;;#517.("odrop_succeeded_msg") = "%<drops> %t."
;;#517.("otake_succeeded_msg") = "%<picks> up %t."
"#517.("key") => E_PERM (Permission denied)
;;#517.("aliases") = {"Generic LRPG Thing", "thing"}
;;#517.("description") = "A tangible object for use in the LambdaMOO RPG."
;;#517.("object_size") = {35709, 1141286558}

@verb #517:"gi*ve ha*nd" this to any rxd
@program #517:give
"give -- Special RPG give makes sure the exchange is allowed.";
if ((iobj == $nothing) || (iobj == $failed_match))
  player:tell("Who do you want to give it to?");
elseif (iobj == $ambiguous_match)
  player:tell("I don't know which '", iobjstr, "' you mean.");
elseif ($object_utils:isa(player.location, #5400))
  player:tell("We'll have none of that now.");
elseif (this.location != player)
  player:tell("You don't have that!");
elseif (iobj.location != player.location)
  player:tell("I don't see that person here.");
elseif (!iobj:acceptable(dobj))
  msg = `iobj:unacceptable_msg(player, dobj) ! E_VERBNF => tostr(iobj.name, " does not want that item.")';
  player:tell(msg);
elseif (this:ok_exchange(player, iobj))
  this:moveto(iobj);
  if (this.location == iobj)
    player:tell("You hand ", this.name, " to ", iobj.name, ".");
    iobj:tell(player.name, " hands you ", this.name, ".");
    player:room_announce_all_but({player, iobj}, player:title(), " hands ", this:title(), " to ", iobj:title(), ".");
  else
    player:tell("You can't give ", this:title(), " to ", iobj.name, ".");
  endif
endif
.

@verb #517:"stat*istics" this none none r
@program #517:statistics
if ($local.rpg:trusted(valid(cp = caller_perms()) ? cp | player))
  a = listinsert($object_utils:ancestors(this), this);
  a = a[1..#517 in a];
  for y in (a)
    if ((y.owner == #517.owner) || y.r)
      for z in (properties(y))
        player:tell($string_utils:left(z, 20), $string_utils:from_value(this.(z)));
      endfor
    endif
  endfor
else
  player:tell("No permission to examine ", this.name, ".");
endif
.

@verb #517:"encumbrance" this none this
@program #517:encumbrance
return this.encumbrance;
.

@verb #517:"get_value" this none this
@program #517:get_value
if ($local.rpg:trusted(caller_perms()))
  return this.(args[1]);
else
  return E_PERM;
endif
.

@verb #517:"location" this none this
@program #517:location
return this.location;
.

@verb #517:"set_value" this none this
@program #517:set_value
":set_value(STR property_name, value) -- Sets this.(property_name) to `value'";
{prop, value} = args;
rpg = $local.rpg;
if (rpg:trusted(cp = caller_perms()) && ((cp in {this.owner, rpg.thing.owner}) || (caller == this)))
  if (prop == "claimed_by")
    rpg:log_error((("Unclaim oddity ( Player: " + $string_utils:nn(player)) + " ):") + toliteral(callers()));
  endif
  return this.(prop) = value;
else
  return E_PERM;
endif
.

@verb #517:"recycle" this none this rx
@program #517:recycle
"Added to remove invalid equipment from wielding/wearing.  Quinn (02-MAR-93)";
if ((caller == this) || $perm_utils:controls(caller_perms(), this))
  vacuum = (rpg = $local.rpg).vacuum;
  if (valid(doll = rpg:get_doll(this.location)))
    doll.wielding = setremove(doll.wielding, this);
    doll.wearing = setremove(doll.wearing, this);
    doll.magic_effects = setremove(doll.magic_effects, this);
  endif
  who = this:claimed_by();
  if (valid(who))
    this:unclaim_for(who);
  endif
  vacuum.doomed = setremove(vacuum.doomed, this);
  if (this in (disp = rpg.dispenser).dispenses)
    disp:rem_dispensed(this);
  endif
  return pass();
else
  return E_PERM;
endif
"Mooshie (#106469) - Sun Feb  1, 1998 - Remove recycled dispenser objects.";
"THX (#105941) - Thu Jun 29, 2000 - Remove from .magic_effects too, since Isagi's amphora neglect this step.";
.

@verb #517:"initialize" this none this
@program #517:initialize
if ((caller == this) || $perm_utils:controls(caller_perms(), this))
  pass(@args);
  this:set_name(parent(this).name);
  this:set_aliases(parent(this).aliases);
  this.manufactured = time();
  valid(this.claimed_by) && this:unclaim_for(this.claimed_by);
  $quota_utils:object_bytes(this);
else
  return E_PERM;
endif
"Quinn 11-MAR-93 xxxx-ET: Hacked to install default names/aliases of the parent, helpful for GMs who must create from eval. ";
"Quinn 29-JUL-93 0136-ET: Manufactured stamp added to aid in determining weapon depreciation in the form of rust, dullness.";
"Quinn 16-DEC-93 1300-ET: $quota_utils:object_size.";
"Slither 2-June-95 Added initialization of .claimed_by";
.

@verb #517:"#517:set_message(old)" this none this
@program #517:#517:set_message(old)
":set_message(msgname, newvalue)";
"Allow adventurers to set certain messages on their equipment.";
msgname = args[1];
who = caller_perms();
if ((caller == this) || $perm_utils:controls(who, this))
  "... No questions asked.";
  return pass(@args);
elseif (!(msgname in (settable = this.user_settable_messages)))
  return tostr("Sorry, but you aren't allowed to set that message.  You may set the following: ", $string_utils:english_list(settable), ".");
elseif (this.unique || children(this))
  return tostr($string_utils:nn(this), " is a unique artifact!  It'd be a crime to alter it.");
elseif (this.location != who)
  "... Only allow em to set the message if e's holding the item.";
  return tostr("You must be holding ", this:title(), " in order to set its messages.");
elseif (args[2])
  return pass(@args);
else
  "... If empty string, we'll clear the message.  Note this will crash if Grand_Master doesn't own the property.  Temp until I petition for a clearing protocol in $root_class:set_message.";
  clear_property(this, msgname + "_msg");
  return 0;
endif
"Quinn 31-JUL-93 0244-ET: Added to facilitate customisation by players.";
.

@verb #517:"ok_exchange" this none this
@program #517:ok_exchange
":ok_exchange(origin, destination)";
"Is it okay to move this from 'origin' to 'destination'?";
"Usually called from thing:give and :get.";
(rpg = $local.rpg):secure();
{origin, dest} = args;
if (!valid(origin))
  player:tell("I don't understand that.");
  return 0;
elseif (glued = this:glued(dest))
  glued = (typeof(glued) == STR) ? glued | "The %n appears to be fixed in place.";
  player:tell(strsub(glued, "%n", this.name));
  return 0;
elseif (valid(doll = rpg:get_doll(dest)))
  "... Although we can hack the :get verb, we cannot hack the :give, so may as well put the check here.  (and :tell, since we can't leave it a mystery why the object didn't move)";
  if (!is_player(who = doll.character))
    "... Don't bother checking monsters?  The problem is that they can't think freely, and thus adjust their inventory.  Incongruous, yes; but necessary for the time being.  Auto-adjustment would mean extra code, extra ticks, and extra hassle.";
  elseif (doll:cannot_take(1))
    return 0;
  elseif ((!doll:hands_free()) && (length(doll.wielding) >= doll.hands))
    "Allow players wielding 2-handed weapons to use 1 hand to pick things up.";
    if (player == who)
      player:tell("You juggle your inventory in vain, unable to pick up ", this.name, ".  Try emptying your hands.");
    else
      player:tell("Sorry, but ", who.name, " has ", who.pp, " hands full.");
      who:tell(player.name, " tries to give you ", this.name, " but your hands are full.");
    endif
    return 0;
  elseif ((0 && (!(player in $object_utils:contains(player, this)))) && (doll:encumbrance() > 10))
    "... Removed for now because of very high tick usage and unprofitable reality margin.";
    "... Too encumbered to carry anything more.";
    if (player == who)
      player:tell(tostr("You try to pick up ", this.name, " but the load is too great.  Try dropping something."));
    else
      player:tell(tostr("Sorry, but ", who.name, " is carrying too much already."));
      who:tell(tostr(player.name, " tries to give you ", this.name, " but you can't bear the extra burden."));
    endif
    return 0;
  endif
  "Quinn 29-JUL-93 0134-ET: Added to :moveto().";
  "Quinn 31-JUL-93 2210-ET: Code removed from :moveto(), placed in this verb, called by :give and :get.";
endif
return 1;
"THX1138 23-MAR-1997 -- Scatter assignment, s /db/rpg/g 1-$, and cleaned up a bit.";
.

@verb #517:"g*et t*ake" this none none rxd
@program #517:get
"get/take -- Special RPG get/take makes sure the exchange is allowed.";
loc = this.location;
if (loc == player)
  player:tell("You already have that!");
elseif ((!valid(loc)) || (loc != player.location))
  player:tell("I don't see that here.");
elseif (((loc in $local.rpg.pcs) || $object_utils:isa(loc, $local.puppet)) && (!((valid(cp = caller_perms()) ? cp | player) in $local.rpg.gms)))
  player:tell("You can't take that.");
elseif (this:ok_exchange(loc, player))
  this:moveto(player);
  if (this.location == player)
    player:tell(this:take_succeeded_msg() || tostr("You take ", this.name, "."));
    if (msg = this:otake_succeeded_msg())
      player.location:announce(player.name, " ", msg);
    endif
    this:do_get(loc, player);
  else
    player:tell(this:take_failed_msg() || "You can't pick that up.");
    if (msg = this:otake_failed_msg())
      player.location:announce(player.name, " ", msg);
    endif
  endif
endif
"Profane 12-1-95 1216EST Added Validity check line 4";
"Mooshie (#106469) - Fri Nov  7 19:44:23 1997 PST - Added check to see if we're on a being (RPG or puppet) so things can't port into said being and just pick us up.";
.

@verb #517:"condition" this none this
@program #517:condition
":condition() => Return the condition of this object as a percentage of its original 'potency'.  Defaults to 100%.  Leave it to the owner/programmer to hack depreciation.";
"Probably used most often for purposes of approximating worth.  A basic equation for this would be:";
"  worth = item:worth() * item:condition() / 100";
"Provided in consideration of all the math-morons out there.  (Like me!)";
return this.condition;
"Quinn 22-AUG-93 1751: Added.";
"Quinn 30-NOV-93 0429: Return .condition instead of the default 100.";
.

@verb #517:"keep_at_death" this none this
@program #517:keep_at_death
":keep_at_death([killer])";
"False if the item be dropped at death.";
"True if it is a 'natural' weapon, or otherwise shouldn't be left as loot.";
"The killer is sent, if eir identity is known.";
return this.keep_at_death;
.

@verb #517:"tell_condition" this none this
@program #517:tell_condition
":tell_condition([condition]) -- Tell player the condition of this item.";
c = args ? args[1] | this:condition(player, player);
if (typeof(c) != NUM)
  return;
endif
if (c > 110)
  player:tell("It is a perfect specimen of its type.");
elseif (c > 99)
  player:tell("It is practically new.");
elseif (c > 90)
  player:tell("It is in excellent shape.");
elseif (c > 80)
  player:tell("It is in very good condition.");
elseif (c > 60)
  player:tell("It is in pretty good shape.");
elseif (c > 40)
  player:tell("It isn't in terrible shape, but shows obvious signs of wear.");
elseif (c > 25)
  player:tell("It has seen quite a lot of use, and it shows.");
elseif (c > 15)
  player:tell("It's old and neglected and in pretty bad shape.");
else
  player:tell("It's in really bad shape, but you might be able to sell it for scrap.");
endif
"Quinn 01-DEC-93 0230: Provided for condition being non-numeric, in which case nothing is printed.";
.

@verb #517:"look_self" this none this
@program #517:look_self
":look_self() -- Show condition of an RPG item.";
pass(@args);
this:tell_condition();
this:tell_claimed();
.

@verb #517:"hide_from_look_gear" this none this
@program #517:hide_from_look_gear
":hide_from_look_gear(doll)";
"Return true if this equipment (when used by the given voodoo doll's character) should not show up in :look_gear displays.";
return 0;
.

@verb #517:"look_gear_msg" this none this
@program #517:look_gear_msg
":look_gear_msg(doll)";
"A special message to be displayed in the :look_gear output when this equipment is being used by the given voodoo doll's character.";
"Should be a string which, if given, will be the only mention of the item in the :look_gear display.";
.

@verb #517:"claimed_by" this none this rx
@program #517:claimed_by
":claimed_by()";
"Return who claims this object.  If the property contains a player who no longer has an RPG doll, then return $nothing.";
if (valid(who = this.claimed_by))
  if (valid(doll = $local.rpg:get_doll(who)))
    "if (!(this in doll:claimed_objects()))";
    "if (doll:add_claimed_object(this) == E_QUOTA)";
    "this.claimed_by = $nothing;";
    "endif";
    "endif";
  else
    this.claimed_by = $nothing;
  endif
endif
return this.claimed_by;
"Profane 11-APR-95 23:38EST - Rewrote. Add objects to doll's list if they somehow aren't on 'em.";
"Slither 6/7/95 -- commented out code to add object to doll's list.";
"  There shouldn't be any such leaks, and if there is, I want to know!";
.

@verb #517:"claim_for" this none this
@program #517:claim_for
":claim_for(who[, ignore_quota])";
"-> E_PERM,   caller is not a GM.";
"-> E_NONE,   this is already claimed by given person.";
"-> E_NACC,   claimed by someone else who won't let it go.";
"-> E_INVARG, who is not illuminated.";
"-> E_TYPE,   the object simply cannot be claimed (usable for a gm's custom objects).";
"If ignore_quota is given and true, the E_QUOTA condition will not occur.";
"-> E_QUOTA,  who has claimed eir max amount of objects.";
who = args[1];
rpg = $local.rpg;
if (!rpg:trusted(caller_perms()))
  return E_PERM;
elseif (valid(old = this:claimed_by()))
  if (old == who)
    return E_NONE;
  else
    this:unclaim_for(old);
  endif
endif
if (valid(this:claimed_by()))
  return E_NACC;
elseif (!valid(doll = rpg:get_doll(who)))
  return E_INVARG;
endif
ignore_quota = (length(args) > 1) && args[2];
if (!(result = doll:add_claimed_object(this, ignore_quota)))
  return result;
else
  this.claimed_by = who;
  return 1;
endif
.

@verb #517:"claim" this none none rxd
@program #517:claim
"claim <item>";
"Claim this item as your own, preventing it from being swept.";
"One may only claim as many objects as their doll's max_claims allows.";
rpg = $local.rpg;
who = valid(cp = caller_perms()) ? rpg:trusted(cp) ? player | cp | player;
if (this.location != who)
  who:tell("You aren't holding ", this.name, ".");
  return E_RANGE;
endif
if (children(this))
  "Keep players from claiming items that have kids.";
  return player:tell("this is a generic ", this.name, " and shouldn't be claimed. Please report to a GM or G_M how you got it, because these items should not be out of the vault.");
endif
result = this:claim_for(who);
if (result == E_NONE)
  who:tell("You already hold a claim to ", this.name, ".");
elseif (result == E_INVARG)
  who:tell("You have no need for such an item.  Perhaps if you were involved in ancient bovine cult...");
elseif (result == E_QUOTA)
  who:tell("No more claims can be accepted until you revoke some of your earlier ones.  Go to the Department of Environmental Protection for more info.");
elseif (result == E_NACC)
  old = this.claimed_by;
  who:tell(old:titlec(), " won't give up ", old.pp, " claim.");
elseif (result == E_TYPE)
  who:tell("Such an item is not claimable.");
elseif (this.claimed_by == who)
  who:tell("You stake your claim to ", this:title(), ".");
else
  who:tell("You can't seem to claim that object.  Please contact a GM.");
endif
return result;
.

@verb #517:"unclaim_for" this none this
@program #517:unclaim_for
":unclaim_for(who)";
"-> E_PERM,   caller is not a GM.";
"-> E_NONE,   this is not currently claimed by the given person.";
{who} = args;
(rpg = $local.rpg):secure();
if (this.claimed_by != who)
  return E_NONE;
elseif (valid(doll = rpg:get_doll(who)))
  doll:remove_claimed_object(this);
endif
if (parent(this).claimed_by == $nothing)
  clear_property(this, "claimed_by");
else
  this.claimed_by = $nothing;
endif
return 1;
.

@verb #517:"unclaim" this none none rxd
@program #517:unclaim
"unclaim <item>";
"Remove all claims you have to the object, freeing it to be claimed by someone else, or swept up.";
rpg = $local.rpg;
if (valid(cp = caller_perms()))
  who = rpg:trusted(cp) ? player | cp;
else
  who = player;
endif
result = this:unclaim_for(who);
if (result == E_NONE)
  who:tell("You don't hold any claim to that.");
elseif (this.claimed_by != who)
  who:tell("You revoke your claim to ", this:title(), ".");
else
  who:tell("You can't seem to revoke your claim to that object.  Please contact a GM.");
endif
return result;
.

@verb #517:"set_cond*ition" this none this
@program #517:set_condition
":set_condition(NUM) => NUM condition -- Set the .condition of the object.";
{cond} = args;
rpg = $local.rpg;
if (!rpg:trusted(caller_perms()))
  return E_PERM;
elseif (this in rpg.dispenser.dispenses)
  return E_TYPE;
elseif (children(this))
  return E_NACC;
elseif (typeof(this.condition) != NUM)
  return E_INVIND;
elseif (typeof(cond) != NUM)
  return E_INVARG;
else
  (cond > 245) && rpg:log_error(tostr("RPG item condition exceeds 245 (", cond, ").   Player: ", $string_utils:nn(player), "   Doll: ", $string_utils:nn(rpg:get_doll(player)), "    Room Effects: ", $string_utils:nn(`player.location.magic_effects ! ANY => $nothing'), "   Callers(): ") + toliteral(callers(1)));
  this.last_action && this:do_update();
  return this.condition = cond;
endif
.

@verb #517:"destroy" this none none rxd
@program #517:destroy
if (!(rpg = $local.rpg):trusted(callers() ? caller_perms() | player))
  player:tell("How do you plan to do that?");
  return E_PERM;
elseif (!rpg.vacuum:killable(this))
  if (!callers())
    player:tell("Whoa pal, that's a little too valuable to just destroy off-handedly.");
  endif
else
  this:room_announce_all(this:titlec(), " wavers and then vanishes into the aether.");
  this:moveto($nothing);
  rpg.recycler:_recycle(this);
endif
"Profane 5-AUG-96 1714PDT - Added";
.

@verb #517:"do_move" this none this
@program #517:do_move
":do_move(oldloc, newloc) => Do whatever would be appropriate if the item moved from oldloc to newloc.";
{oldloc, newloc} = args;
(rpg = $local.rpg):secure();
for location in ({newloc, oldloc})
  where = location;
  while (where != $nothing)
    if (valid(doll = rpg:get_doll(where)))
      doll.weight = $nothing;
    endif
    where = where.location;
  endwhile
endfor
"if (rpg.object_db:is_money(this) && (!this.quantity))";
"((newloc == #10555) || (callers()[3][2] == \"get_collective\")) || rpg:log_error(\"$0 money moved. \" + toliteral(callers(1)))";
"endif";
if (valid(doll = rpg:get_doll(newloc)))
  doll:misc_effects("notify_move", this, oldloc, newloc);
  rpg.object_db.magnetic_object_heart:heartbeat();
endif
if (!valid(newloc))
elseif (((newloc.owner in rpg.gms) || (newloc in rpg.pcs)) || (!`this:no_hoarding(newloc) ! E_VERBNF'))
  (this.last_action || ((`is_player(newloc) ! ANY' && (this.owner == rpg.owner)) && (!(newloc in rpg.gms)))) && this:do_update();
else
  this:moveto(rpg.cemetery);
endif
"THX - 25-Apr-1997 -- Updated security and used args instead of {args[1], args[2]} for tick reasons.";
"Profane (#30788) - Sun May  2, 1999 - new hook for backfire spell effect";
"Profane (#30788) - Fri Dec 29, 2000 - call _misc_effects and move backfire shiznit off into a misc_effect call";
"Profane (#30788) - Mon Apr 16, 2001 - New paradigm for magnetic object checking- call when someone picks some stuff up.";
.

@verb #517:"tell_claimed" this none this
@program #517:tell_claimed
if (valid(who = this:claimed_by()))
  player:tell(who:titlec(), " has scratched ", who.pp, " crude insignia onto the object.");
endif
.

@verb #517:"set_worth" this none this rxd #90864
@program #517:set_worth
"item:set_worth(cost)";
if (!(caller_perms() in {this.owner, $code_utils:verb_loc().owner, @$local.rpg.grand_masters}))
  return E_PERM;
elseif (length(args) < 1)
  return E_INVARG;
else
  return this.worth = args[1];
endif
.

@verb #517:"get_worth worth" this none this rxd #90864
@program #517:get_worth
"item:get_worth() - returns the .worth of an object.";
$local.rpg:secure();
return this.worth;
.

@verb #517:"glued" this none this
@program #517:glued
":glued(OBJ dest) => 0 or 1  Is the object \"glued\" down if we try to move it to dest?";
return this.(verb);
.

@verb #517:"hidden_verbs" this none this
@program #517:hidden_verbs
{who} = args;
prev = pass(who);
thing = (rpg = $local.rpg).thing;
if (this.location == who)
  prev = {@prev, {thing, "g*et t*ake", {"this", "none", "none"}}};
  prev = {@prev, {$thing, "g*et t*ake", {"this", "none", "none"}}};
else
  prev = {@prev, {thing, "gi*ve ha*nd", {"this", "at/to", "any"}}};
  prev = {@prev, {$thing, "gi*ve ha*nd", {"this", "at/to", "any"}}};
  prev = {@prev, {$thing, "d*rop th*row", {"this", "none", "none"}}};
endif
if (!rpg:trusted(who))
  prev = {@prev, {thing, "stat*istics", {"this", "none", "none"}}};
  prev = {@prev, {thing, "destroy", {"this", "none", "none"}}};
endif
if (!valid(this.claimed_by))
  prev = {@prev, {thing, "unclaim", {"this", "none", "none"}}};
else
  prev = {@prev, {thing, "claim", {"this", "none", "none"}}};
endif
return prev;
.

@verb #517:"moveto" this none this
@program #517:moveto
"Usage: moveto(OBJ new location)";
"Some quick hacks to make sure this isn't being moved by the wrong people.";
if (`caller.dest ! ANY' in {E_PROPNF, E_INVIND})
elseif (caller != this)
  $local.rpg:log_error((((("Attempt to move object via exit " + $string_utils:nn(caller)) + " owned by ") + tostr(`$string_utils:nn(caller.owner) ! ANY')) + "  :  ") + toliteral(callers()));
  return E_PERM;
endif
cp = (caller_perms() in (rpg = $local.rpg).probation) ? $no_one | caller_perms();
{dest} = args;
if (valid(dest) || (cp in rpg.gms))
elseif (caller != this)
  for t in (callers())
    if (index(t[2], "eject") && t[3].wizard)
      rpg.vacuum:back_in_play(this);
    endif
  endfor
endif
doll = rpg:get_doll(place = this.location);
if (this:glued(dest) || (((valid(doll) && valid(dest)) && (dest.location == place)) && (!(dest.owner in rpg.gms))))
  return 0;
endif
if (cp in rpg.gms)
  pass(dest);
elseif ((((caller == place) || ((caller == this) && (caller_perms() == place))) && valid(dest)) && ((dest in {place.location, place}) || (dest.location == place)))
  pass(dest);
elseif (cp.wizard)
  (callers()[1][2] == "eject") || rpg:log_error((((("Wizard-permed move via " + $string_utils:nn(caller)) + " owned by ") + tostr(`$string_utils:nn(caller.owner) ! ANY')) + "  :  ") + toliteral(callers()));
  pass(dest);
else
  return 0;
endif
if (((place != this.location) && valid(this)) && (parent(this) != $garbage))
  this:do_move(place, this.location);
endif
return 0;
"Don't allow move if:";
" - this.owner doesn't want it moved (i.e. :glued)";
" - or, calling perms are in rpg.probation";
" - or, a non-GM object is trying to get it from a location with a doll";
"";
"Otherwise, allow move if:";
" - calling perms are in rpg.gms";
" - we're being moved by a wizard";
" - our location is moving us to a) something else in our location, or b) our location's location";
"";
"NOTE: Do *NOT* allow rpg.exporters to move. This allows pretty much everyone to be able to move anything.";
"Mooshie (#106469) - Tue Dec 30, 1997 - Completely re-wrote this puppy.";
"THX (#105941) - Wed Jan 14, 1998 - Added no-extra-tick code to allow movement by .wizards.  s /@args/dest/ to save a tick.  La!";
"Irin - Sat May 23 13:44:16 1998 PDT - exits may not move RPG objects.";
"THX (#105941) - Fri Dec  4, 1998 - Turn probated gamemaster perms into $no_one's.";
"Mooshie (#106469) - Tue Jan 12, 1999 - Stopped allow the move if 'caller == this,' since stuff like $thing:drop can be hacked.";
"Profane (#30788) - Tue Jan 12, 1999 - I dunno what mooshie did, but it screwed up dropping, so I did s/caller == place/caller in {place, this}/20";
"Mooshie (#106469) - Wed Jan 13, 1999 - Ok, changed the line 20 check again so that, if caller == this, then caller_perms() has to be the current location. This should work (I hope!) since $thing:drop and the like do set_task_perms().";
.

@verb #517:"do_get" this none this
@program #517:do_get
{oldloc, newloc} = args;
.

@verb #517:"do_update" this none this
@program #517:do_update
if (this == $local.rpg.thing)
  "... do nothing to the generic ...";
elseif (caller == this)
  {?amount = time() + 2500000} = args;
  this.last_action = max(amount, this.last_action);
else
  return E_PERM;
endif
.

@verb #517:"make_fertile" this none this
@program #517:make_fertile
"Usage: make_fertile()  => Makes this temporarily fertile if permitted.";
"       make_fertile(1) => Resets this to unfertile.";
$local.rpg:secure();
if (args)
  this.f = 0;
elseif (this.f)
else
  this.f = 1;
  fork (0)
    this.f = 0;
  endfork
endif
.

@verb #517:"force_update" this none this
@program #517:force_update
$local.rpg:secure();
this:do_update(@args);
.

@verb #517:"description" this none this
@program #517:description
rpg = $local.rpg;
if (index(callers()[$][2], "@exam") && (!(player in {@rpg.gms, @rpg.wannabees})))
  player:tell("Use 'examine' rather than '@examine' to look at LambdaRPG equipment.");
  kill_task(task_id());
endif
return pass(@args);
.

@verb #517:"break" this none this
@program #517:break
":break() -- Make the weapon break. Instead of recycling it, we just move it to the cemetery and let the regular reaping take care of it.";
{?announce = 1} = args;
(rpg = $local.rpg):secure();
dumpdest = (((loc = this.location) in rpg.pcs) || is_player(loc)) ? loc.location | loc;
announce && rpg:rpg_announce_all_but(dumpdest, {}, this:titlec(), " falls apart into nothingness!");
this:unclaim_for(this.claimed_by);
(announce && this.contents) && rpg:rpg_announce_all_but(dumpdest, {}, "A ", $string_utils:english_list($list_utils:map_prop(this.contents, "name")), (length(this.contents) > 1) ? " spill" | " spills", " out of the remains of the ", this:title(), "!");
for t in (this.contents)
  t:moveto(dumpdest);
endfor
this:moveto(rpg.cemetery);
"THX (#105941) - Wed Mar 22, 2000 - Added a splurge for dumping out the contents first and added an optional argument for suppressing the announcements.";
.

@verb #517:"use_spell_msg_db" this none this
@program #517:use_spell_msg_db
":use_spell_msg_db(STR message to set)";
"Determines if a spellcast message may be player-set. The STR is in the form of 'SPELL_cast' or 'SPELL_cast_self'.";
return this.(verb);
.

@verb #517:"set_message" this none this
@program #517:set_message
":set_message(msgname, newvalue)";
"Allow adventurers to set certain messages on their equipment.";
{msgname, value} = args;
who = caller_perms();
if ((caller == this) || $perm_utils:controls(who, this))
  "... No questions asked.";
  return pass(@args);
elseif (this.unique || children(this))
  return tostr($string_utils:nn(this), " is a unique artifact!  It'd be a crime to alter it.");
elseif (this.location != who)
  "... Only allow em to set the message if e's holding the item.";
  return tostr("You must be holding ", this:title(), " in order to set its messages.");
elseif (!(msgname in (settable = this.user_settable_messages)))
  if (!this:use_spell_msg_db(msgname))
    return tostr("Sorry, but you aren't allowed to set that message.  You may set the following: ", $string_utils:english_list(settable), ".");
  elseif ((!value) || (value == `parent(this).(msgname) ! ANY => !value'))
    "Clear the message!";
    value = 0;
  elseif ((!(all = $local.rpg.magic_db.spell_msg_db:find_exact(msgname))) || (!(value in all)))
    "If the message isn't vetted....";
    return tostr("Sorry, but that is an invalid value for that message. Consult ", $string_utils:nn($local.rpg.magic_db.spell_msg_db.chalkboard), " for acceptable values.");
  endif
endif
if (value)
  return pass(@args);
else
  "... If empty string, we'll clear the message.  Note this will crash if Grand_Master doesn't own the property.  Temp until I petition for a clearing protocol in $root_class:set_message.";
  clear_property(this, msgname + "_msg");
  return 0;
endif
.

"***finished***