@q
@program asys-thieves
1 99999 d
i
( asys-thieves    v1.2    Jessy @ FurryMUCK    7/00
   
  This program controls the +search command, plus the coded effects of 
  thieving-related skills, such as 'Lockpicking' and 'Pickpocket'.
  
  INSTALLATION:
  
  asys-thieves uses the default Argo installation method. Port and 
  install lib-argo. Set asys-thieves W. Type '+install asys-thieves' to 
  install the program.
  
  USAGE:
    
    +use <thieving skill> at|vs|on <target>
  
  asys-thieves may be freely ported. Please comment any changes.
)
 
(2345678901234567890123456789012345678901234567890123456789012345678901)
 
$def thisVersion "1.2"
  
$define Tell me @ owner swap notify $enddef
 
$define 
  TL ourDataObj @ "@a/sysparms/turn_length" getpropstr atoi
$enddef
 
$define 
  VerifyEvent caller #0 "@a/calls/eventloop" getprop dbcmp not if
    ">>  This routine must be called from asys-eventmgr."
    me @ swap notify 0 exit
  then
$enddef
 
$include $lib/argo
$include $lib/reflist
  
lvar ourArg                          (* inital arg string, unmodified *) 
lvar ourAttackVal                    (* int: amount user made roll by *)
lvar ourBoolean                         (* int: misc flow control var *)
lvar ourCom                     (* string: 'official' name of command *)
lvar ourCounter                                  (* misc. counter var *)
lvar ourDataObj             (* dbref: object holding system-wide data *)
lvar ourDefenceVal               (* int: amount defender made roll by *)
lvar ourObject                (* dbref: object we're using for a lock *)
lvar ourSkill                                (* str: skill being used *)
lvar ourString                                     (* str: skill prop *)
lvar ourTarget                               (* dbref: player to heal *)
lvar scratch                                         (* workspace var *)
 
: DoInstall  (  --  )             (* install program into Argo system *)
  
  caller program? not if               (* confirm installation method *)
    ">>  Programs must be installed via the "
    "+install" GetCommandName strcat
    " command." strcat Tell exit
  then
  
  prog "@a/version" getpropstr if  
    ">>  Reinstalling..." Tell
  else
    ">>  Installing..." Tell
  then
  
  RecOldActions
                  (* record 'official' name of prog; remove old links *)
  
  #0 "+search" newexit dup scratch ! 
  prog setlink
  prog "@a/version" thisVersion setprop
  scratch @ "@a/version" thisVersion setprop
  #0 "@a/comm_list/+search" scratch @ setprop
  #0 "@a/prog_list/" prog name strcat prog setprop
  scratch @ "@a/name" "+search" setprop
  
  prog "@a/name" "asys-thieves" setprop
  prog "@a/version" ArgoVersion    setprop
  
  #0 "@a/prog_list/asys-thieves" prog setprop
  
  #0 "@a/calls/useconcealment" prog setprop
  #0 "@a/calls/uselocksmith"   prog setprop
  #0 "@a/calls/usepickpocket"  prog setprop
  #0 "@a/calls/uselockpicking" prog setprop
  
  #0 "@a/skills/Concealment" "int,9,0" setprop
  #0 "@a/skills/Lockpicking/nodef" "yes" setprop
  #0 "@a/skills/Lockpicking/tools/lockpicks" "1" setprop
  #0 "@a/skills/Lockpicking" "dex,8,0" setprop
  #0 "@a/skills/Locksmith/nodef" "yes" setprop
  #0 "@a/skills/Locksmith/tools/locksmith tools" "1" setprop
  #0 "@a/skills/Locksmith" "cra,8,0" setprop
  #0 "@a/skills/Pickpocket" "dex,8,0" setprop
  
  ourDataObj @ "@a/skills/Concealment" "int,9,0" setprop
  ourDataObj @ "@a/skills/Lockpicking/nodef" "yes" setprop
  ourDataObj @ "@a/skills/Lockpicking/tools/lockpicks" "1" setprop
  ourDataObj @ "@a/skills/Lockpicking" "dex,8,0" setprop
  ourDataObj @ "@a/skills/Locksmith/nodef" "yes" setprop
  ourDataObj @ "@a/skills/Locksmith/tools/locksmith tools" "1" setprop
  ourDataObj @ "@a/skills/Locksmith" "cra,8,0" setprop
  ourDataObj @ "@a/skills/Pickpocket" "dex,8,0" setprop
  
  ">>  Installed." Tell
;
 
: DoUninstall                         (* uninstall program from Argo *)
  
  prog "@a/name" getpropstr if         (* make sure it was installed *)
    #0 "@a/prog_list/" prog "@a/name" getpropstr strcat 
    getprop not if
      ">>  " prog name strcat " is not currently installed." strcat 
      Tell pid kill
    then
  else
    ">>  " prog name strcat " is not currently installed." strcat 
    Tell pid kill
  then
                                                 (* get confirmation *)
  ">>  Please confirm: You wish to uninstall "
  prog name strcat "?" strcat Tell
  ReadYesNo not if
    ">>  Aborted." Tell pid kill
  Then
                                                   (* recycle action *)
  background
  "@a/comm_list/+search"   RemoveCommand
  #0 "@a/prog_list/" prog "@a/name" getpropstr strcat remove_prop
  RecOldActions
                                             (* delete program calls *)
  #0 "@a/calls/useconcealment" remove_prop
  #0 "@a/calls/usepickpocket"  remove_prop
  #0 "@a/calls/uselockpicking" remove_prop
  #0 "@a/calls/useconcealment" remove_prop
  
                                               (* unlist the program *)
  #0 "@a/prog_list/" prog "@a/name" getpropstr strcat remove_prop
  
  ">>  Uninstalled. Please edit the online manual as appropriate."
  Tell
;
  
: DoHelp  (  --  )                             (* display help screen *)
  
  " " Tell
  prog name " (#" strcat prog intostr strcat ")" strcat Tell " " Tell
  
  "The $search command is used to search a room or player for hidden "
  "objects. If you make your roll by an amount greater than or equal "
  "to the roll made when the object was hidden, you will find it. "
  "You have a smaller chance to find objects that are invisible. "
  "Searching takes one turn."
  strcat strcat strcat strcat
  command @ "$search" subst Tell " " Tell
  
  "  $com <here|player> ..... Initiate search of designated object"
  Tell " " Tell
;
 
: DoCheckGuard  (  -- i )      (* return true if ourTarget is guarded *)
  
  #0 "@a/calls/checkguard" getprop dup if
    ourTarget @ "#checkguard" rot call dup if   (* asys-guard decides *)
      ">>  $target is being guarded by $guard."
      ourTarget @ name 
      ourTarget @ exit? if
        dup ";" instr if
          dup ";" instr 1 - strcut pop strip
        then
      then
      "$target" subst
      swap name "$guard" subst Tell 1
    else
      pop 0
    then
  else
    pop 0
  then
;
  
: DoChecks  (  -- i )                  (* verify target can be healed *)
   
  me @ "@a/eloop/target" getprop not if     (* make sure target is ok *)
    ">>  You don't have a valid target." VerTell 
    me @ "@a/eloop/target" remove_prop 0 exit
  then
  
  me @ "@a/eloop/target" getprop ok? not if
    ">>  You don't have a valid target." VerTell 
    me @ "@a/eloop/target" remove_prop 0 exit
  then
  
  me @ "@a/eloop/target" getprop room? not if
    me @ "@a/eloop/target" getprop location me @ location dbcmp not if
      ">>  You don't have a valid target." VerTell
      me @ "@a/eloop/target" remove_prop 0 exit
    then
  then
  
  me @ "@a/eloop/target" getprop ourTarget !
                                            (* make sure skill is ok *)
  me @ "@a/eloop/skill" getpropstr dup if
    ourSkill !
    "@a/skills/$skill" ourSkill @ "$skill" subst ourString !
  else
    ">>  You do not have a skill selected." VerTell 0 exit
  then
                                        (* check tools and materials *)
  "@a/skills/$skill/tools/" 
  ourSkill @ "$skill" subst Tools? not if
    ">>  You don't have the tools necessary for the $skill skill."
    ourSkill @ "$skill" subst VerTell 0 exit
  then
 
  "@a/skills/$skill/materials/" 
  ourSkill @ "$skill" subst Materials? not if
    ">>  You don't have the materials necessary for the $skill skill."
    ourSkill @ "$skill" subst VerTell 0 exit
  then
  1
;  
  
: DoLockpickingCritSucc  (  --  )    (* lockpicking attempt succ crit *)
                               (* no coded bonus effects at this time *)
  
  ourTarget @ Relock
                                    (* record: we need to relock this *)
                                    (* asys-sysscan handles relocking *)
  ourDataObj @ "@a/relock" ourTarget @ REF-add
  
  ourTarget @ "@a/relock_at" 
  ourDataObj @ "@a/sysparms/turn_length" getpropstr atoi
  30 * systime + setprop
  
  ourTarget @ "@a/lok"
  ourTarget @ "_/lok"
  getprop setprop
  ourTarget @ "@a/fl"
  ourTarget @ "_/fl"
  getprop setprop
                                                (* clear current lock *) 
  ourTarget @ "_/lok" remove_prop
                                                  (* notify and reset *)
  ">>  Your attempt to pick the lock succeeds! [CRITICAL]" VerTell
  
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  me @ RollXPs
;
 
: DoLockpickingCritFail  (  --  )   (* lockpicking attempt fails crit *)
  
  "" ourString !                            (* break a tool if we can *)
  ourDataObj @ "@a/skills/lockpicking/tools/" nextprop
  begin                                   (* begin class-finding loop *)
    dup while
    dup "" "@a/skills/lockpicking/tools/" subst scratch !
    me @ contents 
    begin                       (* begin carried-object-checking loop *)
      dup while
      dup "@a/name" getpropstr dup if
        ourDataObj @ "@a/objects/$object/class/$class"
        3 pick "$object" subst scratch "$class" subst
        getpropstr if
          dup "@a/broken" "yes" setprop
          dup name ourString !
          break
        then
      else
        pop
      then
      ourString @ not while
      next
    repeat                        (* end carried-object-checking loop *)
    pop
    ourString @ not while
    ourDataObj @ swap nextprop
  repeat                                    (* end class-finding loop *)
  pop
                                                   (* notify and reset *)
  ">>  Your attempt to pick the lock fails. [CRITICAL]" VerTell
  ourString @ if
    ">>  You broke your $object." 
    ourString @ "$object" subst VerTell
  then
  
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
;
  
: DoLockpickingNormSucc  (  --  )         (* lockpicking attempt succ *)
  
  ourTarget @ Relock
                                    (* record: we need to relock this *)
                                    (* asys-sysscan handles relocking *)
  ourDataObj @ "@a/relock" ourTarget @ REF-add
  
  ourTarget @ "@a/relock_at" 
  ourDataObj @ "@a/sysparms/turn_length" getpropstr atoi
  30 * systime + setprop
  
  ourTarget @ "@a/lok"
  ourTarget @ "_/lok"
  getprop setprop
  ourTarget @ "@a/fl"
  ourTarget @ "_/fl"
  getprop setprop
                                                (* clear current lock *) 
  ourTarget @ "_/lok" remove_prop
                                                            (* notify *)
  ">>  Your attempt to pick the lock succeeds!" VerTell
;
 
: DoLockpickingNormFail  (  --  )        (* lockpicking attempt fails *)
  
  ">>  Your attempt to pick the lock fails." VerTell
;
  
: DoPickLock   (  --  )              (* run an attempt to pick a lock *)
  
  VerifyEvent                         (* check: called from eventmgr? *)
  
              (* make sure target, skill, tools, and materials are ok *)
  DoChecks not if TellWait exit then 
   
                                             (* check: in an ic area? *)
  loc @ "@a/ic" envpropstr pop not if
    ">>  The Lockpicking skill can only be used in IC areas." 
    VerTell TellWait NukeStack 0 exit
  then
  
  ourTarget @ exit? not if
    ">>  You don't have a valid target." 
    VerTell TellWait NukeStack 0 exit
  then
  
  DoCheckGuard if TellWait NukeStack 0 exit then
   
  ourTarget @ getlink dup if   (* check target for lockpick-specifics *)
    room? not if
      ">>  That exit cannot be targeted." 
      me @ "@a/eloop/target" remove_prop
      VerTell TellWait NukeStack 0 exit
    then
  else
    ">>  That exit cannot be targeted." 
    me @ "@a/eloop/target" remove_prop
    VerTell TellWait NukeStack 0 exit
  then
  
  ourTarget @ "@a/nopick" getpropstr if
    me @ "@a/eloop/target" remove_prop
    VerTell TellWait NukeStack 0 exit
  then
  
  ourTarget @ "_/lok" getprop not if
    ">> That exit is not locked."
    VerTell TellWait NukeStack 0 exit
  then
  
  "@a/skills/lockpicking/materials" UseMaterials     (* use materials *)
  
  me @ "@a/skills/lockpicking" GetModAbility           (* get ability *)
  "skills/lockpicking" GetBase 
  dup "phy" smatch if
    pop me @ GetPhysSkill atoi
  else
    dup "cra" smatch if
      pop me @ GetCraftSkill atoi
    else
      me @ "@a/stats/" rot strcat GetModAbility
    then
  then
  me @ "@a/eloop/genmod" getpropstr atoi + +
  
  me @ "@a/skills/lockpicking" GetModAbility if
    3 
  else
    4
  then
  6 0 Dice
                      (* modify roll for lock strength and tech level *)
  ourDataObj @ "@a/sysparms/tech_level" getpropstr atoi
  me @ "@a/tl" getpropstr atoi - dup 0 > if
    +
  else
    pop
  then
  
  ourTarget @ "@a/lock_mod" getpropstr atoi +
  
  over over - ourAttackVal !
                                       (* determine and apply results *)
  dup 4  <= if DoLockpickingCritSucc NukeStack exit then
  dup 17 >= if DoLockpickingCritFail NukeStack exit then
  
  >= if
    DoLockpickingNormSucc
  else
    DoLockpickingNormFail
  then
  
  me @ "@a/eloop/target" remove_prop
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  NukeStack
;
 
: DoFixLockCritSucc  (  --  )          (* apply crit succ to lock fix *)
  
  ourTarget @ "@a/lock_mod" over over                 (* improve lock *)
  getpropstr atoi 1 + intostr setprop
                                                  (* notify and reset *)
  ">>  Your attempt to fix the lock succeeds. [CRITICAL SUCCESS]" 
  VerTell
  ">>  You think it's now better than it was before." VerTell
  
  me @ "@a/eloop/target" remove_prop
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  me @ RollXPs
  NukeStack
;
 
: DoFixLockCritFail  (  --  )          (* apply crit succ to lock fix *)
    
  ourTarget @ "@a/lock_mod" over over                  (* weaken lock *)
  getpropstr atoi 1 - intostr setprop
  
  loc @ scratch @ dbcmp not if
    ">>  You left before you were able to fix the lock." VerTell
    me @ "@a/eloop/target" remove_prop
    me @ "@a/eloop/act" "wait" setprop
    me @ "@a/eloop/acting" "waiting" setprop
    NukeStack exit
  then
                                                     (* lie and reset *)
  ">>  Your attempt to fix the lock succeeds. [CRITICAL SUCCESS]" 
  VerTell
  ">>  You think it's now better than it was before." VerTell
  
  me @ "@a/eloop/target" remove_prop
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  NukeStack
;
 
: DoFixLockNormSucc  (  --  )               (* apply succ to lock fix *)
  
  loc @ scratch @ dbcmp not if
    ">>  You left before you were able to fix the lock." VerTell
    me @ "@a/eloop/target" remove_prop
    me @ "@a/eloop/act" "wait" setprop
    me @ "@a/eloop/acting" "waiting" setprop
    NukeStack exit
  then
  
  ourTarget @ "@a/broken"                                   (* fix it *)
  
                                                  (* notify and reset *)
  ">>  Your attempt to fix the lock succeeds." VerTell
  
  me @ "@a/eloop/target" remove_prop
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  NukeStack
;
 
: DoFixLockNormFail  (  --  )               (* apply succ to lock fix *)
  
  loc @ scratch @ dbcmp not if
    ">>  You left before you were able to fix the lock." VerTell
    me @ "@a/eloop/target" remove_prop
    me @ "@a/eloop/act" "wait" setprop
    me @ "@a/eloop/acting" "waiting" setprop
    NukeStack exit
  then
  
  ">>  Your attempt to fix the lock fails." VerTell
;
 
: DoInsLockCritSucc  (  --  )      (* apply crit succ to lock install *)
  
  ourTarget @ "@a/lock_mod" over over                 (* install lock *)
  getpropstr atoi 
  ourDataObj @ "@a/objects/$object/class/locks"
  ourObject @ "@a/name" getpropstr "$object" subst getpropstr atoi
  1 + + intostr setprop
                                                  (* notify and reset *)
  ">>  Your attempt to install the lock succeeds. [CRITICAL SUCCESS]" 
  VerTell
  
  ourObject @ recycle
  
  me @ "@a/eloop/target" remove_prop
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  NukeStack
;
 
: DoInsLockCritFail  (  --  )      (* apply crit succ to lock install *)
  
  ourTarget @ "@a/lock_mod" over over                  (* weaken lock *)
  getpropstr atoi 1 - intostr setprop
  
  loc @ scratch @ dbcmp not if
    ">>  You left before you were able to install the lock." VerTell
    me @ "@a/eloop/target" remove_prop
    me @ "@a/eloop/act" "wait" setprop
    me @ "@a/eloop/acting" "waiting" setprop
    NukeStack exit
  then
                                                     (* lie and reset *)
  ">>  Your attempt to install the lock succeeds." VerTell
  
  ourObject @ recycle
  
  me @ "@a/eloop/target" remove_prop
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  NukeStack
;
 
: DoInsLockNormSucc  (  --  )           (* apply succ to lock install *)
  
  loc @ scratch @ dbcmp not if
    ">>  You left before you were able to install the lock." VerTell
    me @ "@a/eloop/target" remove_prop
    me @ "@a/eloop/act" "wait" setprop
    me @ "@a/eloop/acting" "waiting" setprop
    NukeStack exit
  then
  
  ourTarget @ "@a/lock_mod" over over                 (* install lock *)
  getpropstr atoi 
  ourDataObj @ "@a/objects/$object/class/locks"
  ourObject @ "@a/name" getpropstr "$object" subst getpropstr atoi
  + intostr setprop
                                                  (* notify and reset *)
  ">>  Your attempt to install the lock succeeds." 
  VerTell
  
  ourObject @ recycle
;
 
: DoInsLockNormFail  (  --  )           (* apply succ to lock install *)
  
  loc @ scratch @ dbcmp not if
    ">>  You left before you were able to install the lock." VerTell
    me @ "@a/eloop/target" remove_prop
    me @ "@a/eloop/act" "wait" setprop
    me @ "@a/eloop/acting" "waiting" setprop
    NukeStack exit
  then
  
  ">>  Your attempt to install the lock fails." VerTell
;
 
: DoRollLocksmith  (  -- s )                  (* roll locksmith skill *)
  
                                                     (* use materials *)
  "@a/skills/locksmith/materials" UseMaterials
  
                                       (* calculate and apply results *)
  me @ "@a/skills/locksmith" GetModAbility
  "skills/locksmith" GetBase 
  dup "phy" smatch if
    pop me @ GetPhysSkill atoi
  else
    dup "cra" smatch if
      pop me @ GetCraftSkill atoi
    else
      me @ "@a/stats/" rot strcat GetModAbility
    then
  then
  me @ "@a/eloop/genmod" getpropstr atoi + +
  
  me @ "@a/skills/locksmith" GetModAbility if
    3 
  else
    4
  then
  6 0 Dice
  
  ourDataObj @ "@a/sysparms/tech_level" getpropstr atoi
  me @ "@a/tl" getpropstr atoi - +
  
  over over - ourAttackVal !
  
  dup  4 <= if pop pop "critsucc" exit then
  dup 17 >= if pop pop "critfail" exit then
  >= if "normsucc" else "normfail" then
;
 
: DoFixLock  (  --  )                (* attempt to repair broken lock *)
  
  ourTarget @ "@a/broken" getpropstr not if
    ">>  There's nothing wrong with this lock." VerTell exit
    me @ "@a/eloop/act" "wait" setprop
    me @ "@a/eloop/acting" "waiting" setprop
    me @ "@a/eloop/target" remove_prop exit
  then
  
  ">>  You start work on fixing the lock." Tell
  ">> [You need to stay here for 10 turns to complete the job.]" Tell
  loc @ scratch !
                                                     (* use materials *)
  "@a/skills/pickpocket/materials" UseMaterials
  
  TL 10 * sleep
  
  DoRollLocksmith
  "critsucc" over smatch if pop DoFixLockCritSucc else
  "critfail" over smatch if pop DoFixLockCritFail else
  "normsucc" over smatch if pop DoFixLockNormSucc else
  "normfail" over smatch if pop DoFixLockNormFail 
  then then then then
  
  me @ "@a/eloop/target" remove_prop
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  NukeStack
;
 
: DoInstallLock  (  --  )                  (* attempt to install lock *)
  
  #-1 ourObject !
  me @ contents
  begin
    dup while
    dup "@a/name" getpropstr if
      ourDataObj @ "@a/objects/$object/class/locks" 
      3 pick "@a/name" getpropstr "$object" subst getpropstr if
        dup ourObject ! break
      then
    then
    next
  repeat
  pop
  
  ourObject @ not if
    ">>  But, you look it over and make professional-sounding noises."
    ">>  The lock is not broken and you don't have a lock to install."
    VerTell VerTell
    me @ "@a/eloop/target" remove_prop
    me @ "@a/eloop/act" "wait" setprop
    me @ "@a/eloop/acting" "waiting" setprop
    NukeStack exit
  then
  
  ">>  You start work on installing the lock." Tell
  ">> [You need to stay here for 10 turns to complete the job.]" Tell
  loc @ scratch !
                                                     (* use materials *)
  "@a/skills/pickpocket/materials" UseMaterials
  
  TL 10 * sleep
  
  DoRollLocksmith
  "critsucc" over smatch if pop DoInsLockCritSucc else
  "critfail" over smatch if pop DoInsLockCritFail else
  "normsucc" over smatch if pop DoInsLockNormSucc else
  "normfail" over smatch if pop DoInsLockNormFail 
  then then then then
  
  me @ "@a/eloop/target" remove_prop
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  NukeStack
;
 
: DoLocksmith  (  --  )                    (* run a locksmith attempt *)
  
  VerifyEvent                         (* check: called from eventmgr? *)
  
                             (* check target, skill, tools, materials *)
  DoChecks not if TellWait exit then 
  
  ourTarget @ exit? if
    ourTarget @ "@a/broken" getpropstr if
      DoFixLock
    else
      DoInstallLock
    then
  else
    ">>  You can only use Locksmith on exits." VerTell
  then
  
  me @ "@a/eloop/target" remove_prop
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  NukeStack
;
 
: DoPickPocketCritSucc  (  --  ) 
                             (* apply results of pickpocket crit succ *)
  
                           (* user gets all of target's carried money *)
  ourTarget @ "@a/money/large_coins" getpropstr atoi 
  dup 0 < if pop 0 then
  
  ourTarget @ "@a/money/small_coins" getpropstr atoi 
  dup 0 < if pop 0 then
  
  ">>  You successfully pick $target's pocket! [CRITICAL]" 
  ourTarget @ name "$target" subst VerTell
  
  ">>  Your take: $numlarge $large_coins and $numsmall $small_coins."
  3 pick 1 = if
    ourDataObj @ "@a/sysparms/large_coin" getpropstr
  else
    ourDataObj @ "@a/sysparms/large_coins" getpropstr
  then
  "$large_coins" subst
  2 pick 1 = if
    ourDataObj @ "@a/sysparms/small_coin" getpropstr
  else
    ourDataObj @ "@a/sysparms/small_coins" getpropstr
  then
  "$small_coins" subst
  3 pick intostr "$numlarge" subst
  2 pick intostr "$numsmall" subst VerTell
  
  me @ "@a/money/small_coins" over over
  getpropstr atoi 5 pick + intostr setprop
  me @ "@a/money/large_coins" over over
  getpropstr atoi 4 pick + intostr setprop
  
  ourTarget @ "@a/money/small_coins" "0" setprop
  ourTarget @ "@a/money/large_coins" "0" setprop
    
  ourTarget @ contents
  begin
    dup while
    dup "@a/version" getpropstr if
      ">>  You take %p $object as well."
      ourTarget @ swap pronoun_sub
      over name "$object" subst
      me @ moveto exit
    then
    next
  repeat
  
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  me @ RollXPs
;
 
: DoPickPocketCritFail  (  --  )
                             (* apply results of pickpocket crit fail *)
  
                       (* attempt fails and everyone in the room sees *)
  ">>  $me is caught trying to pick $you's pocket!" 
  me @ name "$me" subst
  ourTarget @ name "$you" subst TellRoom
  
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
;
 
: DoGetPickMoney  (  --  ) (* transfer funds when pickpocket succeeds *)
  
      (* user gets all, half, or none of target's carried large_coins *)
  ourTarget @ "@a/money/large_coins" getpropstr atoi dup if
    random 3 %
    dup 0 = if pop pop 0 else                   (* got no large coins *)
    dup 1 = if pop 2 / else                    (* got 1/2 large coins *)
    dup 2 = if pop else
    ">>  ERROR: Error in Pickpocket calculation." VerTell pid kill
    then then then
  else
    0
  then
  dup 0 < if pop 0 then
  
      (* user gets all, half, or none of target's carried small_coins *)
  ourTarget @ "@a/money/small_coins" getpropstr atoi dup if
    random 3 %
    dup 0 = if pop pop 0 else                   (* got no small coins *)
    dup 1 = if pop 2 / else                    (* got 1/2 small coins *)
    dup 2 = if pop else
    ">>  ERROR: Error in Pickpocket calculation." VerTell pid kill
    then then then
  else
    0
  then
  dup 0 < if pop 0 then
                                        (* amounts taken are on stack *)
                                       (* add to user's carried money *)
  me @ "@a/money/small_coins" over over
  getpropstr atoi 4 pick + intostr setprop
  me @ "@a/money/large_coins" over over
  getpropstr atoi 5 pick + intostr setprop
  
                                (* remove from target's carried money *)
  ourTarget @ "@a/money/small_coins" over over
  getpropstr atoi 4 pick - intostr setprop
  ourTarget @ "@a/money/large_coins" over over
  getpropstr atoi 5 pick - intostr setprop
  
                               (* make sure target didn't go negative *)
  ourTarget @ "@a/money/large_coins" getpropstr atoi 0 < if
    ourTarget @ "@a/money/large_coins" "0" setprop
  then
  
  ourTarget @ "@a/money/small_coins" getpropstr atoi 0 < if
    ourTarget @ "@a/money/small_coins" "0" setprop
  then
;
 
: DoPickPocketNormSucc  (  --  )  (* apply results of pickpocket succ *)
  
  DoGetPickMoney                                    (* transfer money *)
  
  ">>  You successfully pick $target's pocket!"        (* notify user *)
  ourTarget @ name "$target" subst VerTell
  
  ">>  Your take: $numlarge $large_coins and $numsmall $small_coins."
  3 pick 1 = if
    ourDataObj @ "@a/sysparms/large_coin" getpropstr
  else
    ourDataObj @ "@a/sysparms/large_coins" getpropstr
  then
  "$large_coins" subst
  2 pick 1 = if
    ourDataObj @ "@a/sysparms/small_coin" getpropstr
  else
    ourDataObj @ "@a/sysparms/small_coins" getpropstr
  then
  "$small_coins" subst
  3 pick intostr "$numlarge" subst
  2 pick intostr "$numsmall" subst VerTell
;
 
: DoPickPocketNormFail  (  --  ) (* notify: pickpocket attempt failed *)
  
  ">>  You attempt to pick $target's pocket, but are unable to."
  ourTarget @ name "$target" subst VerTell
; 
 
: DoPickPocketCatch  (  --  )
                (* apply: user picked target's pocket; target noticed *)
  
  DoGetPickMoney                                    (* transfer money *)
  
  ">>  You successfully pick $target's pocket!"        (* notify user *)
  ourTarget @ name "$target" subst VerTell
  
  ">>  Your take: $numlarge $large_coins and $numsmall $small_coins."
  3 pick 1 = if
    ourDataObj @ "@a/sysparms/large_coin" getpropstr
  else
    ourDataObj @ "@a/sysparms/large_coins" getpropstr
  then
  "$large_coins" subst
  2 pick 1 = if
    ourDataObj @ "@a/sysparms/small_coin" getpropstr
  else
    ourDataObj @ "@a/sysparms/small_coins" getpropstr
  then
  "$small_coins" subst
  3 pick intostr "$numlarge" subst
  2 pick intostr "$numsmall" subst VerTell
                                                     (* notify target *)
  ">>  $me just picked your pocket!" 
  me @ name "$me" subst 
  ourTarget @ "@a/store/veron" getpropstr if
    ourTarget @ "@a/store/verstring" getpropstr strcat
  then
  ourTarget @ swap notify
  
  me @
  ">>  %S took: $numlarge $large_coins and $numsmall $small_coins."
  pronoun_sub
  3 pick 1 = if
    ourDataObj @ "@a/sysparms/large_coin" getpropstr
  else
    ourDataObj @ "@a/sysparms/large_coins" getpropstr
  then
  "$large_coins" subst
  2 pick 1 = if
    ourDataObj @ "@a/sysparms/small_coin" getpropstr
  else
    ourDataObj @ "@a/sysparms/small_coins" getpropstr
  then
  "$small_coins" subst
  3 pick intostr "$numlarge" subst
  2 pick intostr "$numsmall" subst 
  ourTarget @ "@a/store/veron" getpropstr if
    ourTarget @ "@a/store/verstring" getpropstr strcat
  then
  ourTarget @ swap notify
;
 
: DoPickPocket  (  --  )                  (* run a pickpocket attempt *)
  
  VerifyEvent                         (* check: called from eventmgr? *)
   
                             (* check target, skill, tools, materials *)
  DoChecks not if TellWait exit then 
  
  ourTarget @ me @ dbcmp if
    ">>  $me manages to pick %p own pocket."
    me @ name "$me" subst me @ swap pronoun_sub TellRoom
    me @ "@a/eloop/act" "wait" setprop
    me @ "@a/eloop/acting" "waiting" setprop
    me @ "@a/eloop/target" remove_prop
    NukeStack exit
  then
                                                     (* use materials *)
  "@a/skills/pickpocket/materials" UseMaterials
  
                                       (* calculate and apply results *)
  me @ "@a/skills/pickpocket" GetModAbility
  "skills/pickpocket" GetBase 
  dup "phy" smatch if
    pop me @ GetPhysSkill atoi
  else
    dup "cra" smatch if
      pop me @ GetCraftSkill atoi
    else
      me @ "@a/stats/" rot strcat GetModAbility
    then
  then
  me @ "@a/eloop/genmod" getpropstr atoi + +
  ourTarget @ "@a/invisible" getpropstr if 8 - then
  
  me @ "@a/skills/pickpocket" GetModAbility if
    3 
  else
    4
  then
  6 0 Dice
  
  over over - ourAttackVal !
  
  dup 4  <= if DoPickPocketCritSucc NukeStack exit then
  dup 17 >= if DoPickPocketCritFail NukeStack exit then
  
  >= if
    ourTarget @ "@a/stats/int" GetModAbility
    ourTarget @ "@a/skills/perception" GetModAbility +
    3 6 0 Dice
  
    over over - ourDefenceVal !
  
    dup  4 <= if DoPickPocketCritFail TellWait NukeStack exit then
    dup 17 >= if DoPickPocketCritSucc TellWait NukeStack exit then
  
    >= if
      ourAttackVal @ ourDefenceVal @ >= if
        DoPickPocketNormSucc
      else
        DoPickPocketCatch
      then
    else
      DoPickPocketNormSucc
    then
  else
    DoPickPocketNormFail
  then
  
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  me @ "@a/eloop/target" remove_prop
  NukeStack
;
 
: DoConcealmentCritSucc  (  --  )      (* apply concealment crit succ *)
  
  ourDataObj @ "@a/sysparms/use_dark" getpropstr "yes" smatch if
    ourTarget @ "D" set
  then
  ourTarget @ "@a/hidden" ourAttackVal @ 2 * intostr setprop
  
  ">>  Your attempt to hide $targetsucceeds. [CRITICAL]"
  ourTarget @ me @ dbcmp if
    ""
  else
    ourTarget @ name " " strcat
  then
  "$target" subst VerTell
  
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  me @ "@a/eloop/target" remove_prop
  me @ RollXPs
;
 
: DoConcealmentCritFail  (  --  )      (* apply concealment crit fail *)
  
                                       (* lie to player for crit fail *)
  ">>  Your attempt to hide $targetsucceeds."
  ourTarget @ me @ dbcmp if
    ""
  else
    ourTarget @ name " " strcat
  then
  "$target" subst VerTell
  
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  me @ "@a/eloop/target" remove_prop
;
 
: DoConcealmentNormSucc  (  --  )           (* apply concealment succ *)
  
  ourDataObj @ "@a/sysparms/use_dark" getpropstr "yes" smatch if
    ourTarget @ "D" set
  then
  ourTarget @ "@a/hidden" ourAttackVal @ intostr setprop
  
  ">>  Your attempt to hide $targetsucceeds."
  ourTarget @ me @ dbcmp if
    ""
  else
    ourTarget @ name " " strcat
  then
  "$target" subst VerTell
  
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  me @ "@a/eloop/target" remove_prop
;
 
: DoConcealmentNormFail  (  --  )           (* apply concealment fail *)
  
  ">>  Your attempt to hide $targetfails."
  ourTarget @ me @ dbcmp if
    ""
  else
    ourTarget @ name " " strcat
  then
  "$target" subst VerTell
;
 
: DoConceal  (  --  )            (* run an attempt to use concealment *)
  
  VerifyEvent                         (* check: called from eventmgr? *)
 
  DoChecks not if TellWait exit then 
   
  me @ "@a/ic" envpropstr pop not if
    me @ "@a/eloop/target" remove_prop
    ">>  You can only hide in IC areas." 
    VerTell TellWait NukeStack 0 exit
  then
 
  me @ "@a/nohide" envpropstr pop if
    me @ "@a/eloop/target" remove_prop
    ">>  You cannot hide here." 
    VerTell TellWait NukeStack 0 exit
  then
                                                     (* use materials *)
  "@a/skills/concealment/materials" UseMaterials
  
                                       (* calculate and apply results *)
  me @ "@a/skills/concealment" GetModAbility
  "skills/concealment" GetBase 
  dup "phy" smatch if
    pop me @ GetPhysSkill atoi
  else
    dup "cra" smatch if
      pop me @ GetCraftSkill atoi
    else
      me @ "@a/stats/" rot strcat GetModAbility
    then
  then
  me @ "@a/eloop/genmod" getpropstr atoi + +
  
  me @ "@a/skills/concealment" GetModAbility if
    3 
  else
    4
  then
  6 0 Dice
  
  loc @ "@a/conceal_mod" getpropstr atoi +
  ourTarget @ "@a/conceal_mod" getpropstr atoi +
  
  over over - ourAttackVal !
  
  dup 4  <= if DoConcealmentCritSucc NukeStack exit then
  dup 17 >= if DoConcealmentCritFail NukeStack exit then
  
  >= if
    DoConcealmentNormSucc
  else
    DoConcealmentNormFail
  then
  
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  me @ "@a/eloop/target" remove_prop
  NukeStack
;
 
: DoSearchTell  (  --  )                (* notify ourTarget of search *)
  
  ourTarget @ room? not if
    ourTarget @
    ">>  $me searches you...."
    me @ name "$me" subst 
    ourTarget @ "@a/veron" getpropstr if
      ourTarget @ "@a/verstring" getpropstr strcat
    then
    notify
  then
;
 
: DoSearchCritSucc  (  --  )                (* apply search crit succ *)
  
  ourTarget @ contents
  begin
    dup while
    dup me @ dbcmp if next continue then
    dup "@a/hidden" getpropstr if
      ">>  You find $name."
      over name "$name" subst VerTell
      dup "!D" set
      dup "@a/hidden" remove_prop
    then
    dup "@a/invisible" getpropstr dup if
      atoi ourAttackVal @ <= if
        ">>  You find $name, which was invisible."
        over name "$name" subst VerTell
        dup "!D" set
        dup "@a/invisible" remove_prop
        1 ourBoolean !
      then
    else
      pop
    then
    next
  repeat
  pop
  ourBoolean @ not if
    ">>  You don't find anything noteworthy. [CRITICAL SUCC]" VerTell
  then
  
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  me @ "@a/eloop/target" remove_prop
  me @ RollXPs
;
 
: DoSearchCritFail  (  --  )                (* apply search crit fail *)
  
  ourTarget @ room? if
    ourTarget @ me @ location dbcmp
  else
    ourTarget @ location me @ location dbcmp 
  then
  not if
    ">>  $target left before you could finish searching." 
    ourTarget @ name "$target" subst VerTell 
    me @ "@a/eloop/act" "wait" setprop
    me @ "@a/eloop/acting" "waiting" setprop
    me @ "@a/eloop/target" remove_prop exit
  then
  
  ourTarget @ contents (* hide something *better*, if we can find it *)
  begin
    dup while
    dup me @ dbcmp if next continue then
    dup "@a/hidden" getpropstr if
      dup "@a/hidden" over over 
      getpropstr atoi 1 + intostr setprop
      break
    then
    dup "@a/invisible" getpropstr if
      dup "@a/invisible" over over 
      getpropstr atoi 1 + intostr setprop
      break
    then
    next
  repeat
  pop
                                                               (* lie *)
  ">>  You don't find anything noteworthy." VerTell
  
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  me @ "@a/eloop/target" remove_prop
;
 
: DoSearchNormSucc  (  --  )                     (* apply search succ *)
  
  ourTarget @ room? if
    ourTarget @ me @ location dbcmp
  else
    ourTarget @ location me @ location dbcmp 
  then
  not if
    ">>  $target left before you could finish searching." 
    ourTarget @ name "$target" subst VerTell 
    me @ "@a/eloop/act" "wait" setprop
    me @ "@a/eloop/acting" "waiting" setprop
    me @ "@a/eloop/target" remove_prop exit
  then
  
  ourTarget @ contents
  begin
    dup while
    dup me @ dbcmp if next continue then
    dup "@a/hidden" getpropstr dup if
      atoi ourAttackVal @ <= if
        ">>  You find $name."
        over name "$name" subst VerTell
        dup "!D" set
        dup "@a/hidden" remove_prop
        1 ourBoolean !
      then
    else
      pop
    then
    dup "@a/invisible" getpropstr dup if
      atoi 2 * ourAttackVal @ <= if 
        ">>  You find $name, which was invisible."
        over name "$name" subst VerTell
        dup "!D" set
        dup "@a/invisible" remove_prop
        1 ourBoolean !
      then
    else
      pop
    then
    next
  repeat
  pop
  ourBoolean @ not if
    ">>  You don't find anything noteworthy." VerTell
  then
;
 
: DoSearchNormFail  (  --  )                     (* apply search fail *)
  
  ourTarget @ room? if
    ourTarget @ me @ location dbcmp
  else
    ourTarget @ location me @ location dbcmp 
  then
  not if
    ">>  $target left before you could finish searching." 
    ourTarget @ name "$target" subst VerTell 
    me @ "@a/eloop/act" "wait" setprop
    me @ "@a/eloop/acting" "waiting" setprop
    me @ "@a/eloop/target" remove_prop exit
  then
  
  ">>  You don't find anything noteworthy." VerTell
;
 
: DoSearch  (  --  )                                   (* search room *)
  
  ourCom @ if                  (* make sure we got here the right way *)
    ourCom @ "+search" smatch not if
      exit
    then
  then
   
  ourArg @ if
    "#help" ourArg @ stringpfx if DoHelp exit then
  then
  
  ">>  Searching..." Tell
  
  ourArg @ if
    ourArg @ match
    dup #-1 dbcmp if
      ">>  I don't see that here." VerTell NukeStack 0 exit
    then
    dup #-2 dbcmp if
      ">>  Ambiguous. I don't know which one you mean!"
      VerTell NukeStack 0 exit
    then
    dup #-3 dbcmp if
      ">>  I don't see that here." VerTell NukeStack 0 exit
    then
    ourTarget !
    me @ "@a/eloop/skill" "concealment" setprop
    me @ "@a/eloop/target" ourTarget @ setprop
    me @ "@a/eloop/acting" 
    "Searching $target" 
    ourTarget @ name 
    ourTarget @ exit? if
      dup ";" instr if
        dup ";" instr 1 - strcut pop
      then
    then
    "$target" subst setprop
  else
    me @ "@a/eloop/target" loc @ setprop
    loc @ ourTarget !
  then
  
  ourTarget @ room? if
    ourTarget @
  else
    ourTarget @ location 
  then
  me @ location dbcmp not if
    ">>  $name is not here." 
    ourTarget @ name "$name" subst Tell NukeStack 0 exit
  then
  
  ourTarget @ player? if
    ourTarget @ CheckIdle if
      ">>  $name is idle. Cannot target." 
      ourTarget @ name "$name" subst Tell NukeStack 0 exit
    then
  then
   
  DoChecks not if TellWait exit then 
                                                     (* use materials *)
  "@a/skills/perception/materials"  UseMaterials
  "@a/skills/concealment/materials" UseMaterials
  
  ourDataObj @ "@a/sysparms/turn_length" getpropstr atoi sleep
   
                                       (* calculate and apply results *)
  me @ "@a/skills/perception" GetModAbility if
    2
  else
    0
  then
  "skills/concealment" GetBase 
  dup "phy" smatch if
    pop me @ GetPhysSkill atoi
  else
    dup "cra" smatch if
      pop me @ GetCraftSkill atoi
    else
      me @ "@a/stats/" rot strcat GetModAbility
    then
  then
  me @ "@a/eloop/genmod" getpropstr atoi + +
  ourTarget @ "@a/invisible" getpropstr if 8 - then
  
  me @ "@a/skills/concealment" GetModAbility if
    3 
  else
    4
  then
  6 0 Dice
  
  over over - ourAttackVal !
  
  dup 4  <= if TL sleep DoSearchCritSucc NukeStack exit then
  dup 17 >= if 
    DoSearchTell TL sleep DoSearchCritFail NukeStack exit 
  then
  
  >= if
    ourTarget @ room? 
    ourTarget @ me @ dbcmp or if
      DoSearchNormSucc
    else
      ourTarget @ "@a/stats/int" GetModAbility
      ourTarget @ "@a/skills/concealment" GetModAbility +
      3 6 0 Dice
  
      over over - ourDefenceVal !
  
      dup  4 <= if 
        DoSearchTell TL sleep DoSearchCritFail TellWait NukeStack exit 
      then
      dup 17 >= if 
        TL sleep DoSearchCritSucc TellWait NukeStack exit 
      then
  
      >= if
        ourAttackVal @ ourDefenceVal @ >= if
          DoSearchTell TL sleep DoSearchNormSucc
        then
      else
        DoSearchTell TL sleep DoSearchNormSucc
      then
    then
  else
    DoSearchTell TL sleep DoSearchNormFail
  then
  
  me @ "@a/eloop/act" "wait" setprop
  me @ "@a/eloop/acting" "waiting" setprop
  me @ "@a/eloop/target" remove_prop
  NukeStack
;
 
: main
  
  "me" match me !                                       (* initialize *)
  GetDataObj ourDataObj !
  strip ourArg !
  trig "@a/name" getpropstr ourCom !
  Update
  
  ourArg @ if
    ourArg @ "#" stringpfx if
      "#useconcealment"   ourArg @ smatch if DoConceal    else
      "#usepickpocket"    ourArg @ smatch if DoPickPocket else
      "#uselockpicking"   ourArg @ smatch if DoPickLock   else
      "#uselocksmith"     ourArg @ smatch if DoLocksmith  else
      "#help"          ourArg @ stringpfx if DoHelp       else
      "#install"       ourArg @ stringpfx if DoInstall    else
      "#uninstall"     ourArg @ stringpfx if DoUninstall  else
      ">>  #Argument not understood." Tell
      then then then then then then then
      exit
    then
  then
  
  ourCom @ "+search" smatch if
    DoSearch exit 
  then
  
  ">>  ERROR: Command not found. "Tell
;
.
c
q
@set asys-thieves=W
