Dump of #82 (Generic Weapon)

@create #517 named generic weapon:generic weapon,weapon
"#82.("dodgable") => E_PERM (Permission denied)
"#82.("parryable") => E_PERM (Permission denied)
@prop #82."title" 0 r
@prop #82."oswing" "swings" r
@prop #82."swing" "swing" r
@prop #82."owield" "wields" r
@prop #82."wield" "wield" r
@prop #82."osheathe" "sheathes" r
@prop #82."sheathe" "sheathe" r
"#82.("slowness") => E_PERM (Permission denied)
@prop #82."length" 0 r
"#82.("parry") => E_PERM (Permission denied)
"#82.("attack") => E_PERM (Permission denied)
"#82.("pen") => E_PERM (Permission denied)
"#82.("dam") => E_PERM (Permission denied)
"#82.("skill") => E_PERM (Permission denied)
@prop #82."hands" 1 r
@prop #82."bully_msg" "%N %<%(oswing)> %p %t menacingly at %d." r
@prop #82."special_damage" 0 r
@prop #82."wooden" 0 r
@prop #82."blunt" 0 r
"#82.("pierce") => E_PERM (Permission denied)
@prop #82."con" 30 r
"#82.("max_str_bonus") => E_PERM (Permission denied)
@prop #82."disarmable" 1 r
@prop #82."materialize" 0 r
@prop #82."natural" 0 rc
"#82.("can_degrade") => E_PERM (Permission denied)
"#82.("track_usage") => E_PERM (Permission denied)
@prop #82."no_dub" 0 r
@prop #82."handles_death_msg" 0 r
;;#82.("worth") = -1
;;#82.("condition") = 100
;;#82.("odrop_failed_msg") = "%<tries> to drop %t but fails!"
;;#82.("odrop_succeeded_msg") = "%<drops> %t."
;;#82.("otake_succeeded_msg") = "%<picks> up %t."
"#82.("key") => E_PERM (Permission denied)
;;#82.("aliases") = {"generic weapon", "weapon"}
;;#82.("description") = "A generic implement of destruction."
;;#82.("object_size") = {49733, 1141286558}

@verb #82:"wield weild ready draw" this none none rxd
@program #82:wield
"wield weapon -- Wield the weapon, first making sure player has enough hands, or enough hands free.";
if (!(rpg = $local.rpg):trust($nothing, player))
  return E_PERM;
elseif (this.location != player)
  rpg:playertell(player, "You don't have ", this.name, ".");
  return;
elseif (!valid(doll = rpg:get_doll(player)))
  rpg:playertell(player, "It wouldn't do you much good, you don't know how to use it. Check out the Bovine Illuminati for some instruction.");
  return;
elseif (`player.location:sleeping(player) ! E_VERBNF')
  return rpg:playertell(player, "You are snoozing.  Your weapons are 'unavailable for comment'.");
elseif (p = doll.paralyzed)
  return rpg:playertell(player, (typeof(p) == STR) ? p | "You're paralyzed.  It's hard to wield weapons in this state.");
elseif (rpg.magic_db.en_combat_effect in doll.combat_effects)
  return rpg:playertell(player, "The vines entangling you make that just a wee bit difficult.");
elseif (this in (wielding = doll.wielding))
  rpg:playertell(player, "You're already wielding it.");
  return;
elseif ((handsreq = this.hands) > doll.hands)
  rpg:playertell(player, "You don't have enough appendages to wield ", this.name, ".");
  return;
elseif (!this:may_wield(player))
  return;
elseif ((handsfree = doll:hands_free()) < handsreq)
  rpg:playertell(player, "Your hands are full.");
  for thing in ($list_utils:reverse(wielding))
    if (((handsfree < handsreq) && thing:may_unwield(player)) && thing.hands)
      "doll.wielding = setremove(doll.wielding, thing);";
      "thing:do_unwield(player);";
      "rpg:playertell(player, \"You \", thing.sheathe, \" your \", thing.name, \".\");";
      thing:_unwield(doll);
      handsfree = doll:hands_free();
      rpg:playertell(player, "You ", this.sheathe, " your ", thing:title(), ".");
      player.location:announce($string_utils:pronoun_sub(((("%n %<" + thing.osheathe) + "> %p ") + thing:title()) + "."));
    endif
  endfor
endif
if (doll:hands_free() >= handsreq)
  "doll.wielding = listappend(doll.wielding, this);";
  "this:do_wield(player);";
  "rpg:playertell(player, \"You \", this.wield, \" your \", this.name, \".\");";
  rpg:playertell(player, "You ", this.wield, " your ", this:title(), ".");
  "rpg:rpg_announce_all_but(player.location, {player}, $string_utils:pronoun_sub((\"%n %<\" + this.owield) + \"> %p %[tname].\"));";
  rpg:rpg_announce_all_but(player.location, {player}, $string_utils:pronoun_sub(((("%n %<" + this.owield) + "> %p ") + this:title()) + "."));
  this:_wield(doll);
endif
"Comment out this invite call, due to current lag conditions.";
"doll:invite((doll.slowness + weapon.slowness) / 3, {2, w});";
"Quinn 30-JUL-93 2219: Re-written and modified for dynamic unwielding when hands are full; added call to :look_gear after wielding; restored :invite call.";
"Quinn 10-AUG-93 0116: Fixed bug where someone without enough hands (doll.hands) could wield a weapon anyway.";
"Profane 15-AUG-96 1506PDT -- added dousing for light sources in auto-unwield.";
"Irin Sat Sep 28 12:04:07 1996 PDT -- Added call to :do_wield and :may_wield.  Removed dousing of light_sources, because it's in the light_source :do_unwield.";
"THX1138 28-Mar-1997 -- Changed the while-loop to a for-loop in the auto-unwield code.  Auto-unwield changed to go in the reverse of how the player originally wielded the stuff.  An additional check is then made for enough hands required before doing the listappend to doll.wielding.";
"Hydros (#106189) - Sun Jul 3, 2005 - Changed active messaging to use :title() instead of .name, to support Cervantes' new dual weapons. Old lines commented.";
"Hydros (#106189) - Tue Jul 5, 2005 - Nuts to that. Commented everything and moved the grunt work into this:_wield(). The same will be done for :unwield().";
"                                   - In the case of an already wielded weapon, turned the hard-coded unwielding into :_unwield().";
"Hydros(#106189) - Sat Jul 9, 2005 - Moved messaging from :_wield back into this verb. Not all wielding is voluntary.";
.

@verb #82:"sheathe unwield sling rem*ove" this none none rxd
@program #82:sheathe
if (!(rpg = $local.rpg):trust($nothing, player))
  return E_PERM;
elseif (this.location != player)
  rpg:playertell(player, "You're not carrying ", this.name, ".");
elseif (!valid(doll = rpg:get_doll(player)))
  rpg:playertell(player, "You fumble around with the ", this.name, " and realize you don't know what to do with it. Perhaps some training at the Bovine Illuminati would help.");
elseif (p = doll.paralyzed)
  rpg:playertell(player, (typeof(p) == STR) ? p | "It's hard to unwield weapons when you're paralyzed.");
elseif (rpg.magic_db.en_combat_effect in doll.combat_effects)
  return rpg:playertell(player, "The vines entangling you make that just a wee bit difficult.");
elseif (!this:may_unwield(player))
  return;
elseif (`player.location:sleeping(player) ! ANY => 0')
  return rpg:playertell(player, "You dream of unwielding your ", this.name, ".");
elseif (this in doll.wielding)
  "doll.wielding = setremove(doll.wielding, this);";
  "this:do_unwield(player);";
  "rpg:playertell(player, \"You \", this.sheathe, \" your \", this.name, \".\");";
  rpg:playertell(player, "You ", this.sheathe, " your ", this:title(), ".");
  "player.location:announce($string_utils:pronoun_sub((\"%n %<\" + this.osheathe) + \"> %p %[tname].\"));";
  player.location:announce($string_utils:pronoun_sub(((("%n %<" + this.osheathe) + "> %p ") + this:title()) + "."));
  this:_unwield(doll);
else
  rpg:playertell(player, "You aren't wielding your ", this.name, ".");
endif
"Hydros (#106189) - Sun Jul 3, 2005 - Changed active messaging to use :title() instead of .name, to support Cervantes' new dual weapons. Old lines commented.";
"Hydros (#106189) - Tue Jul 5, 2005 - Nuts to that. Commented everything and moved the grunt work into this:_unwield(). The same is done in :wield().";
"Hydros(#106189) - Sat Jul 9, 2005 - Moved messaging from :_unwield back into this verb. Not all unwielding is voluntary.";
.

@verb #82:"look_self" this none this
@program #82:look_self
{rpg, s_u} = {$local.rpg, $string_utils};
if (player in `player.location:sleeping() ! E_VERBNF => {}')
  return rpg:playertell(player, "You dream about examining some implement of destruction.");
endif
pass(@args);
if (typeof(this.title) == STR)
  rpg:playertell(player, "The name \"", this.title, "\" is written in ornate, flowing letters across the ", this.name, ".");
endif
if (!valid(doll = rpg:get_doll(this.location)))
  return;
endif
if (wloc = this in doll.wielding)
  mark = rpg.death_db.temple:mark(player);
  if (mark && (!this.blunt))
    rpg:playertell(player, "As you stare at the blade, you see the phantom ", (length(mark) > 1) ? "forms" | "form", " of ", s_u:nn(mark), ".");
  endif
endif
if (wloc == 1)
  if ((this.hands == 2) && (doll:hands_free() == 0))
    rpg:playertell(player, s_u:_cap_property(this, "name"), " is wielded with both hands.");
  else
    rpg:playertell(player, s_u:_cap_property(this, "name"), " is wielded in the primary hand.");
  endif
elseif (wloc == 2)
  rpg:playertell(player, s_u:_cap_property(this, "name"), " is wielded in the secondary hand.");
elseif (wloc)
  rpg:playertell(player, s_u:_cap_property(this, "name"), " is wielded.");
endif
"Ogwul:Mon Apr 25 18:29:16 MDT 1994:Capitalized the sentence stating handedness.";
"Ogwul:Mon Apr 25 18:38:50 MDT 1994:Added new message for two-handed weapons.";
.

@verb #82:"name christen dub entitle" this as any rxd
@program #82:name
"dub this as <title> -- Add the alias 'title' to this weapon, allowing the player to refer to multiple weapons of the same name.";
rpg = $local.rpg;
if ((valid(cp = caller_perms()) && (player != cp)) && (!rpg:is_monster(player)))
  return rpg:playertell(player, E_PERM);
elseif (this.location != player)
  rpg:playertell(player, "Wouldn't it be more dramatic if you were holding ", this.name, "?");
elseif (((this.no_dub || this.unique) || children(this)) && (!$perm_utils:controls(player, this)))
  rpg:playertell(player, "You are shocked by some mystic force.  The voice of what could only be the Sacred COW echoes in your naughty mind: \"MOO!\"  Well now you certainly won't try THAT again.");
elseif (iobjstr)
  this:set_aliases(setadd(setadd({@parent(this).aliases, @`this.crest ? {this.crest} | {} ! ANY => {}'}, this.title = iobjstr), this.name));
  rpg:playertell(player, this.name, " now bears the name \"", iobjstr, "\"");
else
  this:set_aliases(setremove(this.aliases, this.title));
  clear_property(this, "title");
  rpg:playertell(player, "You scratch off the title of ", this.name, ".");
endif
"Quinn 28-FEB-93: Must be holding weapon in order to dub it; fixed the screwy use of :set_name; clear property if !iobjstr.";
"Quinn 07-JUN-93: Hacked to disallow dubbing of unique weapons by nonowners.";
"Quinn 02-AUG-93: @chmod +x so players could take advantage of ordinal matching in the instance they'd most need it-- dubbing multiple weapons.";
"Quinn 21-NOV-93: Okay let's try this again.  Now just set aliases to {@parent(this).aliases, title}.";
"StarDancer 9-APR-96: Added :is_monster check so's monsters can dub weapons.";
"Irin Nuke Day '97 -- Dubbed objects now keep eir name in eir aliases.  They still lose any other special aliases.";
"Hydros (#106189) - Thu Apr 7, 2005 - When clearing a title, we also now remove the title from the aliases. (I can't believe my name has any place below these gods of LRPG lore.)";
.

@verb #82:"used" this none this
@program #82:used
":used(by, target)";
"Return a number modifying the attack, or a non-numeric value meaning the weapon is unusable.";
(rpg = $local.rpg):secure();
{by, target} = args;
if (valid(doll = rpg:get_doll(by)))
  if (($perm_utils:caller()[2] == "attack") && (z = this in doll.wielding))
    return 15 * (1 - z);
  endif
  "doll:check_fatigue(this.encumbrance);";
else
  return -200;
endif
"Profane 1/29/95 10:20 EST -- Changed reference to `this.location' to `by' in line 5.";
.

@verb #82:"title" this none this
@program #82:title
return this.title ? ((this.name + " named \"") + this.title) + "\"" | this.name;
.

@verb #82:"dodgable parryable slowness length skill hands special_damage con max_str_bonus disarmable" this none this
@program #82:dodgable
":(property)(by, targ) => Default returns the value of this weapon's `verb' property.";
"(both by and targ are characters, not dolls)";
"This hack will greatly enhance the versatility of the system, cleaning up the way hand/half weapons are handled, and allowing for things such as variable damages (pistol whipping, autofire), etcetera.";
"Explanations of each property follow. (Quinn 03-JAN-93)";
" dodgable  -- Modifier when dodging the weapon.";
" parryable -- Modifier when parrying against the weapon.";
" slowness  -- Speed of the weapon.  The lower the better.  Average is 10.";
" length    -- Length of weapon in ~5cm units, tho more a measure of bulk.";
" attack    -- Modifier when attacking with the weapon.";
" pen       -- Weapon's ability to penetrate armor. The lower the better.";
" dam       -- How much damage the weapon does.";
" skill     -- Object number of skill governing the weapon's use.";
" hands     -- How many hands required to wield the weapon.";
" special_damage -- Any damage that gets added directly to inj on a hit, for example, damage as a result of the weapon being poisoned.";
" pierce -- Ability of weapon to find holes in armour.  Daggers and other long narrow weapons should be > 0, clubs and blunt weapons < 0.";
" con    -- How good the weapon is at bashing through armour with the force of it's blows.  2 is a really good club.  3 is a mace.  4 for a heavy sword.  Use 1 only in exceptional circumstances.  5+ for most weapons.";
"max_str_bonus  -- How much damage the weapon would do if wielded by a person of high strength.  (i.e. str 25).  A person of str 12 would get half that bonus.  Clubs and such should have a low dam relative to this.  A dagger or rapier would have a very high dam, relative to this.";
return this.(verb);
"DR APR-24-94 -- Added special_damage.";
"Irin -- Wed Sep  4 21:37:48 1996 PDT added pierce.";
.

@verb #82:"intimidate bully impress threaten" any with this rxd
@program #82:intimidate
"intimidate any with this -- Show that you'll use that thing.";
"Set messages using normal pronoun subs (see 'help pronouns'), plus verb subs.";
"For example; if I type '@bully whip is \"%N %<cracks> %p whip at %d.\"' and then 'bully AcidHorse with whip', the following messages would be displayed:";
"to   me: You crack your whip at AcidHorse.";
"to   AH: Quinn cracks his whip at you.";
"to room: Quinn cracks his whip at AcidHorse.";
rpg = $local.rpg;
if (!rpg:trust($nothing, player))
  return E_PERM;
elseif (this.location != player)
  rpg:playertell(player, "You don't have ", this.name, ".");
elseif (!valid(doll = rpg:get_doll(player)))
  rpg:playertell(player, "Ha.  You think you'd know how to brandish that thing?  Maybe you should get some training so the bullies don't kick sand in your face anymore.  I hear Charles Atlas recommends the Bovine Illuminati 'Thug' plan.");
elseif (doll:cannot_attack(1))
elseif (dobj == $failed_match)
  player:tell("Bully *who*?");
elseif (!(this in doll:wielding()))
  rpg:playertell(player, "It's a bit difficult to intimidate ", dobj.name, " with a weapon you aren't even wielding.");
else
  rpg:say_action(strsub(this.bully_msg, "%(oswing)", this.oswing));
  if (rpg.object_db:is_monster(dobj))
    dobj:notify_bully(player, dobj, this);
  endif
endif
"Quinn 31-JUL-93 0243-ET: Added in conjunction with new :set_message.";
"Profane (#30788) - Sun Oct 19 14:44:05 1997 PDT - Added new call to monster's notify_bully.";
.

@verb #82:"critical_miss" this none this rx
@program #82:critical_miss
":critical_miss(OBJ attacker, OBJ target, NUM atk)";
"attacker -- who attacked";
"target -- who was hit.";
"atk    -- actual attack roll.";
"By default, do nothing.  Provided for possible special weapon effects.";
"Attacker is assumed to be the wielder of the weapon (this.location).";
"If a TRUE value is returned, the weapon is assumed to have done something.";
.

@verb #82:"critical_hit" this none this rx
@program #82:critical_hit
":critical_hit(OBJ attacker, OBJ target, NUM atk, OBJ loc, NUM dam)";
"Caller should always be the damaged doll.";
"attacker -- who attacked";
"target   -- who was hit.";
"loc      -- body area hit by the attack.";
"dam      -- damage applied to the character.";
"atk      -- actual attack roll.";
"By default, do nothing.  Provided for possible special weapon effects.";
"Attacker is assumed to be the wielder of the weapon (this.location).";
"If a TRUE value is returned, the weapon is assumed to have handled all damage effects.  :receive_damage will NOT be called.";
.

@verb #82:"notify_clang" this none this rx
@program #82:notify_clang
":notify_clang(OBJ attacker, OBJ victim, NUM hit_location, OBJ armour_hit, NUM quality)";
"Hook for weapons damage and other special combat effects.  Called when armour and weapon contact without any damage being done to the victim (armour absorbed the hit).";
"Quality is the final attack roll, some indication of the quality of the hit.";
{attacker, victim, loc, armour, qual} = args;
$local.rpg:secure();
this:check_degrade(attacker, victim, loc, armour, qual);
`armour:check_degrade(attacker, victim, loc, this, qual) ! ANY';
"Profane 2-17-95 00:13EST - Added check for weapon degrading.";
"THX (#105941) - Tue Dec 21, 1999 - Re-introducing armour degradation.";
.

@verb #82:"has_own_hit" this none this
@program #82:has_own_hit
":has_own_hit() => returns 1 iff the weapon has its own ''hit kill'' verb defined.";
return ({x} = $object_utils:has_callable_verb(this, "hit")) && (x != $local.rpg.weapon);
.

@verb #82:"notify_parry" this none this
@program #82:notify_parry
":notify_parry(OBJ attacker, OBJ victim, STR hit_location, OBJ weapon_doing_the_parrying, NUM quality, NUM try_of_parry)";
"Hook for weapons damage and other special combat effects. Called on the ``attacking'' weapon when the defender manages to parry the attack.";
"Quality is the final attack roll, some indication of the quality of the hit.";
"Try is the `attack' roll made by the defender when parrying.";
$local.rpg:secure();
this:check_degrade(@args);
"Profane 2-13-95 20:52EST - Added.";
"Profane 2-18-95 00:08EST - Added check for weapon degrading.";
.

@verb #82:"dam" this none this rx
@program #82:dam
":dam(by, targ) => NUM modified damage of weapon due to its condition.";
{by, targ} = args;
dam = this.dam;
cond = this:condition(by, targ) || 100;
mod = (100 - cond) / 10;
"if (cond <= 100)";
"  mod = (100 - cond) / 10;";
"else";
"  mod = -toint(tofloat(cond) ^ (1.0 / 1.1) / 10.0);";
"endif";
mod = this.blunt ? mod / 2 | mod;
return max(dam - mod, dam / 2);
"Profane 2/17/95 23:14EST - Added.";
.

@verb #82:"pen" this none this rx
@program #82:pen
":pen(by, targ) => NUM modified penetration of weapon due to its condition.";
{?by = player, ?targ = player} = args;
pen = this.pen;
if (this.blunt || (pen < 2))
elseif ((typeof(cond = this:condition(by, targ)) == 3) || (cond < 101))
  pen = max(pen + ((100 - (this:condition(by, targ) || 100)) / 5), 2);
else
  pen = max((pen * 100) / this:condition(by, targ), 2);
endif
return pen;
"Profane 2/17/95 23:14EST - Added.";
"dalton (#116601) - Sun Oct  6, 2002 - added separate computation for condition over 100.";
.

@verb #82:"attack" this none this rx
@program #82:attack
":attack(by, targ) => NUM modified attack modifier of weapon due to its condition.";
{by, targ} = args;
att = this.attack;
cond = this:condition(by, targ) || 100;
if (att < 0)
  return att * ((cond <= 0) ? abs(cond) + 100 | (100 / cond));
elseif (att == 0)
  return att + ((cond - 100) / 10);
endif
return (att * cond) / 100;
"Profane 2/17/95 23:14EST - Added.";
"THX (#105941) - Mon Jan 22, 2001 - Check special case of attack < 0.";
"Profane (#30788) - Fri Mar  2, 2001 - now weapons with a default 0 bonus get an effect.";
"dalton (#116601) - Wed Sep 11, 2002 - added check for negative condition to handle unique weapons.";
.

@verb #82:"check_degrade" this none this
@program #82:check_degrade
":check_degrade(OBJ attacker, OBJ victim, location, OBJ other weapon/armour, NUM qual of attack, NUM try of parry)";
{attacker, victim, location, anvil, qual, ?parry_qual = 0} = args;
if ((typeof(condition = this.condition) == NUM) && ((!valid(anvil)) || `anvil:can_degrade(this) ! ANY => 1'))
  if (this.unique || children(this))
    return;
  endif
  "Chance of breaking: 1% for every 5 condition points we are below 50. e.g. .condition 40 == 2% chance of breaking.";
  break_chance = max((50 - condition) / 5, 0);
  if (random(100) <= break_chance)
    $local.rpg:secure();
    this:("break")();
    kill_task(task_id());
  else
    if (callers()[1][2] == "announce_parry")
      by = victim;
      target = attacker;
    else
      by = attacker;
      target = victim;
    endif
    chance = (5 + (5 * this.wooden)) + (qual / 100);
    "Chance of degrading = .5%, 1% if this is a blunt weapon. Modified by the quality of the attack expressed as a percentage. For yer average attack, this works out to be ~ .8% (1.3% for blunt weapons).";
    if (random(499) <= chance)
      "Alright, real simple formula since old one was tick-intensive and people whined it did too much damage.";
      amt = (5 * qual) / 100;
      amt = random(max(amt, 1));
      (rpg = $local.rpg):secure();
      this.condition = max(condition - amt, 0);
      rpg:playertell(by, "Your ", this.name, " seems a little worse for wear.");
    endif
  endif
endif
"Profane 2-17-95 23:33EST - Added.";
"THX (#105941) 18-FEB-1997 - Scatter assignments <incl. accounting for different numbers of args from notify_clang and notify_parry>.";
"THX (#105941) - Tue Dec 21, 1999 - Put security in place _only_ if the weapon degrades or breaks.";
"Hydros (#106189) - Mon Oct 17, 2005 - subst /999/499/23. 2% chance of degrade instead of 1%.";
.

@verb #82:"break" this none this
@program #82:break
":break() -- Make the weapon break. Instead of recycling it, we just move it to the cemetary and let the regular reaping take care of it.";
if (!(rpg = $local.rpg):trusted(caller_perms()))
  return E_PERM;
  "elseif (this.owner != rpg.owner || this.unique || typeof(condition = this.condition) != NUM || children(this))";
  "rpg:rpg_announce(this.location.location, this:titlec(), \" resists the final dissolution!\");";
  "return E_NACC;";
else
  if (valid(doll = rpg:get_doll(who = this.location)) && (this in doll.wielding))
    rpg:playertell(who, "Your ", this.name, " shatters from the abuse it has taken!");
    this:room_announce_all_but({who}, who.name, "'s ", this.name, " shatters from the abuse it has taken!");
    doll.wielding = setremove(doll.wielding, this);
  else
    this:room_announce_all(this:titlec(), " shatters into slivers!");
  endif
  this:unclaim_for(this.claimed_by);
  this:moveto(rpg.cemetery);
endif
"Profane 2-17-95 23:42EST - Added.";
"Profane 6-AUG-96 1607PDT -- commented out E_NACC check-- since this check is done by the reap task anyway, and the point of this verb is to remove the weapon from a person/place.";
.

@verb #82:"set_title" this none this
@program #82:set_title
":set_title(STR) => STR title -- Set the .title of the object.";
if (!$local.rpg:trusted(caller_perms()))
  return E_PERM;
elseif (children(this))
  return E_NACC;
elseif (typeof(title = args[1]) != STR)
  return E_INVARG;
else
  return this:set_aliases(setadd(parent(this).aliases, this.title = title));
endif
.

@verb #82:"pierce" this none this
@program #82:pierce
"qual = (length(args) > 2) ? args[3] | 0;";
{attacker, me, ?qual = 0} = args;
return (this.pierce * (100 + qual)) / 100;
"THX1138 18-FEB-1997 - Scatter assignment to reduce ticks.  Commented old code.";
.

@verb #82:"may_wield" this none this
@program #82:may_wield
":may_wield(who) => Who is allowed to wield this.  Verb for additional checks of wielding being allowed.";
{who} = args;
"if ((is_player(who) && (!index($string_utils.alphabet, who.name[$]))) && ($string_utils:match_player(who.name[1..$ - 1]) != who))";
"  who:tell(\"Grand_Master does not support the use of aliases which consist of another player's name with a non-alphabetic alphanumeric character on the end.  Social reform through coercion.  Wow.\");";
if (valid(doll = (rpg = $local.rpg):get_doll(who)))
  if (msg = doll:immobilized())
    rpg:playertell(player, msg);
    return 0;
  endif
  return 1;
endif
return 0;
.

@verb #82:"do_wield" this none this
@program #82:do_wield
":do_wield(who) => Perform whatever tasks need to be done when weapon is wielded.";
rpg = $local.rpg;
if ((!(this.owner in rpg.gms)) && `verb_info(this, "0") ! E_VERBNF')
  {who} = args;
  `rpg:get_doll(who):setremove_att("wielding", this) ! ANY';
  (this.owner in rpg.ex_gms) ? kill_task(task_id()) | raise(E_PERM, "Sorry, but non-gms may not own weapon objects.  Thanks for playing.");
else
  this.last_action && this:do_update();
  return 1;
endif
.

@verb #82:"may_unwield" this none this
@program #82:may_unwield
":may_unwield(who) => Determine if anything would prevent them from unwielding the item.";
{who} = args;
if (valid(doll = (rpg = $local.rpg):get_doll(who)))
  if (msg = doll:cannot_move(1))
    "rpg:playertell(who, msg);";
    return 0;
  endif
  return 1;
else
  return 0;
endif
.

@verb #82:"do_move" this none this
@program #82:do_move
":do_move(oldloc, newloc) => Remove this from oldloc.wielding.";
(rpg = $local.rpg):secure();
{oldloc, newloc} = args;
"if (valid(doll = rpg:get_doll(oldloc)))";
if (valid(doll = rpg:get_doll(oldloc)) && (this in (wielding = doll.wielding)))
  "doll.wielding = setremove(doll.wielding, this);";
  doll.wielding = setremove(wielding, this);
  this:do_unwield(oldloc);
endif
pass(oldloc, newloc);
"Hydros (#106189) - Fri Mar 4, 2005 - Commented out the old check for valid doll, and re-added it with a check to see if this is even being wielded before unwielding it.";
.

@verb #82:"parry" this none this
@program #82:parry
":parry(by, targ, weapon) => how good is the weapon at parrying.";
"Irin -- moved this off from the other verbs, to add a weapon check.";
return this.(verb);
.

@verb #82:"announce_swing" this none this rx
@program #82:announce_swing
":announce_swing(attacker, target)";
"Announce that `attacker' has swung at `target' with this weapon.";
{who, target} = args;
(rpg = $local.rpg):playertell(who, "You ", this.swing, " your ", weapon = this.name, " at ", tname = target.name, ".");
rpg:playertell(target, @string = {who.name, " ", this.oswing, " ", who.pp, " ", weapon, " at "}, "you.");
rpg:rpg_announce_all_but(who.location, {who, target}, @string, tname, ".");
"THX1138 2-15-97 2:00EST - Version 1.8.0 update.  De-ticked.";
.

@verb #82:"announce_parry" this none this rx
@program #82:announce_parry
":announce_parry(attacker, defender, location-string, weapon, qual of attack, quality of parry)";
"Announce that `defender' has used this weapon to parry an attack by `attacker' with `weapon' aimed at `location-string'.";
{attacker, who, locstr, weapon, qual, best} = args;
(rpg = $local.rpg):playertell(who, "You parry with your ", this.name, ".");
rpg:rpg_announce_all_but(who.location, {who}, who.name, " parries with ", who.pp, " ", this.name, ".");
"this:check_degrade(@args)";
"StarDancer 11-19-95 comment out the degrade check, 'cause we're *always* runnin outa ticks.";
"Profane 2-18-95 00:18EST - Added weapon degrading check.";
"THX1138 2-15-97 2:00EST - Version 1.8.0 update.  De-ticked.";
.

@verb #82:"announce_kill" this none this rx
@program #82:announce_kill
":announce_kill(attacker, target, location-string)";
"Announce that `attacker' has killed `target' with a blow to the `location-string' from this weapon.";
{by, dead, locstr} = args;
(rpg = $local.rpg):playertell(dead, by.name, " has killed you! Your soul is returned to the cycle of transmigrations.");
rpg:rpg_announce_all_but(dead.location, {dead}, dead.name, " is slain by a blow to the ", locstr, ".");
"THX1138 2-15-97 2:00EST - Version 1.8.0 update.  De-ticked.";
.

@verb #82:"announce_miss" this none this rx
@program #82:announce_miss
":announce_miss(attacker, target, quality of attack)";
"Announce that `attacker' has missed `target' with this weapon.";
{by, target, qual} = args;
(rpg = $local.rpg):playertell(by, "You miss.");
rpg:rpg_announce_all_but(by.location, {by}, by.psc, " misses.");
"THX1138 2-15-97 2:00EST - Version 1.8.0 update.  De-ticked.";
.

@verb #82:"announce_hit" this none this rx
@program #82:announce_hit
":announce_hit(attacker, target, location-string, severity-string, stunned)";
"'location-string' is a string describing where the target was hit.  For example; `left arm' or `left arm and right shoulder'.";
"'severity-string' is probably one of `scratched', `slightly wounded', `hit', `seriously wounded'.  See :announce_kill for death messages.";
"'stunned' is true if the target was stunned by the attack.";
{by, who, locstr, severity, stun} = args;
subargs = {by, who, locstr, severity, this};
stunned = stun ? " and stunned." | ".";
msg = (rpg = $local.rpg):combat_sub("You are %b in the %w", @subargs);
omsg = rpg:combat_sub(who.name + " is %b in the %w", @subargs);
rpg:tell_damage(who, msg, stunned);
rpg:rpg_announce_all_but(who.location, {who}, omsg, stunned);
"THX1138 2-15-97 2:00EST - Version 1.8.0 update.  De-ticked.";
"Profane (#30788) - Sat Dec 27, 1997 - check new option package for filter";
"Mooshie (#106469) - Mon Dec 28, 1998 - Got rid of hard-coded highlighting. Go through $local.rpg:tell_damage.";
.

@verb #82:"announce_dodge" this none this rx
@program #82:announce_dodge
":announce_dodge(attacker, target, location-string)";
"Announce that `target' has dodged a blow by `attacker' wielding this weapon aimed for `location-string'.";
{attacker, who, locstr} = args;
(rpg = $local.rpg):playertell(who, "You dodge.");
rpg:rpg_announce_all_but(who.location, {who}, who.name, " dodges.");
"THX1138 2-15-97 2:00EST - Version 1.8.0 update.  De-ticked.";
.

@verb #82:"used_title" this none this
@program #82:used_title
return this.name;
.

@verb #82:"contract" this none this
@program #82:contract
(rpg = $local.rpg):secure();
if ((!this.blunt) && (mark = rpg.death_db.temple:mark(player)))
  rpg:playertell(player, "As you stare at the blade, you see the phantom ", (length(mark) > 1) ? "forms" | "form", " of ", $string_utils:nn(mark), ".");
endif
.

@verb #82:"stare gaze" none to this
@program #82:stare
rpg = $local.rpg;
if (this.location != player)
  return rpg:playertell(player, "You aren't close enough to stare at the ", this.name, ".");
endif
if (this.blunt)
  rpg:playertell(player, "You don't notice anything unusual about the ", this.name, ".");
elseif ((mark = rpg.death_db.temple:mark(player)) && (mark != $nothing))
  marx = {};
  for t in (mark)
    marx = setadd(marx, t.name);
  endfor
  rpg:playertell(player, "You see the phantom ", (length(marx) > 1) ? "forms" | "form", " of ", $string_utils:english_list(marx), ".");
elseif (rpg:exp(player) > 5000)
  rpg:playertell(player, "You feel repulsed by random images of brutal murder and a jackal-headed demon.");
else
  rpg:playertell(player, "You feel vaguely uneasy about something, but you aren't sure what.");
endif
.

@verb #82:"do_unwield" this none this
@program #82:do_unwield
":do_unwield(who) => perform tasks needed to unwield the item.";
this.last_action && this:do_update();
return 1;
.

@verb #82:"hit_special_effect" this none this
@program #82:hit_special_effect
this.last_action && this:do_update();
return 1;
.

@verb #82:"hit kill" any with this rxd
@program #82:hit
rpg = $local.rpg;
if (rpg:trusted(valid(cp = caller_perms()) ? cp | this.owner) || (caller in rpg.vacuum.monsters))
  "if (rpg:trusted(valid(cp = caller_perms()) ? cp | this.owner) || (caller in {$match_utils, @rpg.vacuum.monsters}))";
  {whatstr, prep, weapstr, ?weaps = {}, ?where = ""} = args;
  target = (ploc = player.location):match(whatstr);
  if (valid(doll = rpg:get_doll(player)))
    if (target == $failed_match)
      rpg:playertell(player, "I can't see \"", whatstr, "\" anywhere.");
      return target;
    elseif (target == $ambiguous_match)
      rpg:playertell(player, "I don't know which \"", whatstr, "\" you mean.");
      return target;
    elseif (`target.location ! E_INVIND' != ploc)
      rpg:playertell(player, "I can't see \"", whatstr, "\" here.");
      return $nothing;
    elseif (is_player(player) && (`idle_seconds(player) ! ANY => 301' > 300))
      raise(E_NACC, "You're comatose.  Try attacking while you're actually at the keyboard.");
    else
      if (this in doll:wielding())
        if (rpg:trusted_verb(ploc, "attack"))
          if (doll:long_enough())
            send = {target, {this, @weaps}};
            if (where && valid(tdoll = rpg:get_doll(target)))
              if (valid(area = tdoll:match_body_area(where)))
                send = {@send, area:attack_mod(target, player, this), area};
                rpg:playertell(player, "You take aim for ", target.name, "'s ", where, ".");
              elseif (area == $ambiguous_match)
                rpg:playertell(player, target.name, " has more than one ", where, ".  You'll have to be more specific.");
                return area;
              else
                rpg:playertell(player, "You can't find anything resembling a \"", where, "\" on ", target.name, ".");
                return area;
              endif
            endif
            if (rpg.rpg_options:get(doll.rpg_options, "defend"))
              rpg.option_feature:set_rpg_option(doll, "defend", 0);
              rpg:playertell(player, "You actively choose to swing your weapon at the enemy again.");
            endif
            doll.last_attack = time();
            {target, weapons, ?bmods = 0, ?barea = 0, ?no_invite = `ploc.peaceful ! ANY => 0'} = send;
            doll:attack(target, weapons, bmods, barea, no_invite);
          else
            rpg:playertell(player, "You'll need at least ", tostr(max(1, (doll.last_attack - time()) + rpg.gm_lag)), " seconds to recover from your last attack.");
            return E_NACC;
          endif
        else
          rpg:playertell(player, "Are you kidding?  These are horrible fighting conditions.  Go to a real battleground.");
          return E_RECMOVE;
        endif
      else
        rpg:playertell(player, "It's still ", index(this.name, "sword") ? "in the scabbard" | "packed away", ", you'd better wield it first.");
        return E_INVIND;
      endif
    endif
  else
    rpg:playertell(player, "You flail ineffectively about with your ", this.name, ". Perhaps some training at the Bovine Illuminati is in order.");
    return E_INVARG;
  endif
else
  raise(E_PERM);
endif
.

@verb #82:"is_natural" this none this
@program #82:is_natural
"Usage: is_natural() => Boolean true/false.";
"Natural weapons should be ones in which the user does not actually have to be carrying the weapon-object to use it. Such as with fists.";
return this.natural;
.

@verb #82:"condition" this none this
@program #82:condition
{?by = player, ?who = player} = args;
if ((is_player(by) && is_player(who)) && `(callers()[2][4] == $local.rpg.doll) && (callers()[2][2] in {"attack", "respond"}) ! ANY')
  return min(100, pass(by, who) || 0);
else
  return pass(by, who);
endif
.

@verb #82:"hidden_verbs" this none this
@program #82:hidden_verbs
{who} = args;
prev = pass(who);
weapon = (rpg = $local.rpg).weapon;
if (((!valid(doll = rpg:get_doll(who))) || (this in doll.wielding)) || (who != this.location))
  prev = {@prev, {weapon, "wield weild", {"this", "none", "none"}}};
endif
if (((!valid(doll)) || (!(this in doll.wielding))) || (who != this.location))
  prev = {@prev, {weapon, "sheathe unwield sling rem*ove", {"this", "none", "none"}}};
  prev = {@prev, {weapon, "hit kill", {"any", "with/using", "this"}}};
  prev = {@prev, {weapon, "intimidate bully impress threaten", {"any", "with/using", "this"}}};
endif
if (who != this.location)
  prev = {@prev, {weapon, "name christen dub entitle", {"this", "as", "any"}}};
endif
if (this.blunt || (!rpg.death_db.temple:mark(who)))
  prev = {@prev, {weapon, "stare gaze", {"none", "at/to", "this"}}};
endif
return prev;
.

@verb #82:"hit(old)" any with this rxd
@program #82:hit(old)
rpg = $local.rpg;
if (rpg:trusted(valid(cp = caller_perms()) ? cp | this.owner) || (caller in rpg.vacuum.monsters))
  {whatstr, prep, weapstr, ?weaps = {}, ?where = ""} = args;
  target = (ploc = player.location):match(whatstr);
  if (valid(doll = rpg:get_doll(player)))
    if (target == $failed_match)
      rpg:playertell(player, "I can't see \"", whatstr, "\" anywhere.");
      return target;
    elseif (target == $ambiguous_match)
      rpg:playertell(player, "I don't know which \"", whatstr, "\" you mean.");
      return target;
    elseif (`target.location ! E_INVIND' != ploc)
      rpg:playertell(player, "I can't see \"", whatstr, "\" here.");
      return $nothing;
    elseif (is_player(player) && (`idle_seconds(player) ! ANY => 301' > 300))
      raise(E_NACC, "You're comatose.  Try attacking while you're actually at the keyboard.");
    else
      if (this in doll:wielding())
        if (rpg:trusted_verb(ploc, "attack"))
          if (doll:long_enough())
            send = {target, {this, @weaps}};
            if (where && valid(tdoll = rpg:get_doll(target)))
              if (valid(area = tdoll:match_body_area(where)))
                send = {@send, area:attack_mod(target, player, this), area};
                rpg:playertell(player, "You take aim for ", target.name, "'s ", where, ".");
              elseif (area == $ambiguous_match)
                rpg:playertell(player, target.name, " has more than one ", where, ".  You'll have to be more specific.");
                return area;
              else
                rpg:playertell(player, "You can't find anything resembling a \"", where, "\" on ", target.name, ".");
                return area;
              endif
            endif
            if (rpg.rpg_options:get(doll.rpg_options, "defend"))
              rpg.option_feature:set_rpg_option(doll, "defend", 0);
              rpg:playertell(player, "You actively choose to swing your weapon at the enemy again.");
            endif
            doll.last_attack = time();
            doll:attack(@send);
          else
            rpg:playertell(player, "You'll need at least ", tostr(max(1, (doll.last_attack - time()) + rpg.gm_lag)), " seconds to recover from your last attack.");
            return E_NACC;
          endif
        else
          rpg:playertell(player, "Are you kidding?  These are horrible fighting conditions.  Go to a real battleground.");
          return E_RECMOVE;
        endif
      else
        rpg:playertell(player, "It's still ", index(this.name, "sword") ? "in the scabbard" | "packed away", ", you'd better wield it first.");
        return E_INVIND;
      endif
    endif
  else
    rpg:playertell(player, "You flail ineffectively about with your ", this.name, ". Perhaps some training at the Bovine Illuminati is in order.");
    return E_INVARG;
  endif
else
  raise(E_PERM);
endif
.

@verb #82:"can_degrade" this none this
@program #82:can_degrade
return this.(verb);
.

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

@verb #82:"track_usage" this none this
@program #82:track_usage
if ((prop = this.(verb)) && (parent(caller) == $local.rpg.doll))
  {indx} = args;
  prop[indx] = prop[indx] + 1;
  prop[$].(verb) = prop;
endif
"The property holds {swings, parries, dodges, strikes, kills, weapon} where weapon is the parent object held responsible.";
"THX (#105941) - Mon Feb  5, 2001 - Added";
.

@verb #82:"_wield" this none this
@program #82:_wield
"This handles the grunt work of :wield.";
(rpg = $local.rpg):secure();
{doll} = args;
who = doll.character;
doll.wielding = listappend(doll.wielding, this);
this:do_wield(who);
for eq in (setremove({@doll.wielding, @doll.wearing}, this))
  fork (0)
    `rpg:trusted_verb(eq, "notify_equip") ! E_VERBNF => 0' && eq:notify_equip(doll, this);
  endfork
endfor
"Hydros (#106189) - Tue Jul 5, 2005 - Added, including a check of all your current equipment for :notify_equip.";
"Hydros(#106189) - Sat Jul 9, 2005 - Moved messaging back into :wield. Not all wielding is voluntary.";
.

@verb #82:"_unwield" this none this
@program #82:_unwield
"This does the grunt work of :unwield.";
(rpg = $local.rpg):secure();
{doll} = args;
who = doll.character;
doll.wielding = setremove(doll.wielding, this);
this:do_unwield(who);
for eq in (setremove({@doll.wielding, @doll.wearing}, this))
  fork (0)
    `rpg:trusted_verb(eq, "notify_unequip") ! E_VERBNF => 0' && eq:notify_unequip(doll, this);
  endfork
endfor
"Hydros (#106189) - Tue Jul 5, 2005 - Added, including a check of all your current equipment for :notify_unequip.";
"Hydros(#106189) - Sat Jul 9, 2005 - Moved messaging back into :unwield. Not all unwielding is voluntary.";
.

"***finished***