1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
# Turn a string like "one" into a digit.
proc todigit {str} {
set numbers {zero one two three four five six seven eight nine}
return [lsearch -exact $numbers [string tolower $str]]
}
# Walk sends each element of the list path, wrapping around when
# it reaches the end, to the mud with delay seconds between each
# write.
proc walk {args} {
global _walk
set syntax {
on {{+ path} {? delay 4}}
delay {{? delay}}
suspend {{? bool}}
off {}
}
switch -exact -- [check -opts walk $syntax $args] {
on {
if {[info exists _walk(id)]} {
error "walk already running"
} elseif {[catch {concat $arg(path)}]} {
error "path must be a list"
}
set _walk(path) $arg(path)
set _walk(suspend) 0
set _walk(delay) [expr {$arg(delay) * 1000}]
_walk_loop 0
} delay {
if {[info exists arg(delay)]} {
set _walk(delay) [expr {$arg(delay) * 1000}]
} else {
return $_walk(delay)
}
} suspend {
if {[info exists arg(bool)]} {
set _walk(suspend) [string is true $arg(bool)]
} else {
return $_walk(suspend)
}
} off {
catch {
after cancel $_walk(id)
unset _walk
}
}
}
return
}
proc _walk_loop {pos} {
global _walk
if {!$_walk(suspend)} {
write [lindex $_walk(path) $pos]
set pos [expr {[incr pos] % [llength $_walk(path)]}]
}
set _walk(id) [after $_walk(delay) _walk_loop $pos]
}
# This proc sets up actions to autometically kill defined monsters
# if you walk into a room with them in it. It handles multiple monsters
# of the same kind and will send a clean up command after combat.
# When combat starts it sets the global variable targ to the monster
# being attacked, suspends a walk if there is one, and sends
# "attack name" to the mud.
# When combat ends the cleanup command is sent and the walk,
# if there is one, resumes.
# mlist is a list of monster names to attack.
# It has to include all names from "name is here",
# "three names are here", and "you killed name".
# Example: auto_kill {man "militia man" "militia men"} hunt "bury all"
proc ak {args} {
global _ak
set syntax {
on {{+ mlist} {+ attack} {+ cleanup}}
off {}
}
set one_here_pat {^%s is here}
set many_here_pat {^%w %s are here}
set killed_pat {^You killed %s.}
switch -exact -- [check -opts ak $syntax $args] {
on {
set _ak(mlist) [string tolower $arg(mlist)]
set _ak(num) 0
set _ak(attack) $arg(attack)
set _ak(cleanup) $arg(cleanup)
action set $one_here_pat {_ak_event $1 1}
action set $many_here_pat {_ak_event $2 [todigit $1]}
action set $killed_pat {_ak_event $1 0}
} off {
catch {unset _ak}
action delete -exact -- $one_here_pat
action delete -exact -- $many_here_pat
action delete -exact -- $killed_pat
}
}
return
}
proc _ak_event {m num} {
global _ak targ
if {[lsearch -exact $_ak(mlist) [string tolower $m]] != -1} {
set targ $m
if {$num} {
set _ak(num) $num
write "$_ak(attack) $m"
walk suspend 1
} else {
if {[incr _ak(num) -1] < 1} {
write $_ak(cleanup)
walk suspend 0
} else {
write "$_ak(attack) $m"
}
}
}
}
|