File: robot.tcl

package info (click to toggle)
mmucl 1.5.1-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 648 kB
  • ctags: 303
  • sloc: tcl: 4,977; sh: 111; makefile: 97
file content (135 lines) | stat: -rw-r--r-- 3,311 bytes parent folder | download
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"
	    }
        }
    }
}