-
Notifications
You must be signed in to change notification settings - Fork 0
/
thing.rb
165 lines (143 loc) · 4.06 KB
/
thing.rb
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
require './sproc'
class Thing
attr_accessor :parent, :pmethods
def self.define_shortcut shortcut_name, &block
self.send :define_method, shortcut_name do |*args|
self.instance_eval do
@pmethods << [shortcut_name, :shortcut, args] if not @pmethods.select {|e| e[0] == shortcut_name }.any?
end
self.instance_exec(*args, &block)
end
define_singleton_method shortcut_name, &block
end
def self.define_instance_method name, &block
self.send :define_method, name, block
end
def define_instance_method name, &block
define_singleton_method name, block
end
alias :instance_method :method
define_shortcut(:reply_random) do |name,replies|
define_instance_method name do |user|
replies.sample
end
end
define_shortcut(:reply_one) do |name,reply|
define_instance_method name do |user|
reply
end
end
define_shortcut(:reply_list) do |name,replies|
define_instance_method name do |user|
@reply_list[name] ||= {}
@reply_list[name][user.hash] ||= -1
@reply_list[name][user.hash] += 1
replies[@reply_list[name][user.hash] < replies.length ? @reply_list[name][user.hash] : -1]
end
end
define_shortcut(:takeable) do
define_instance_method :take! do |user|
user.things << self
if [user.parent.delete(user,self)].flatten.compact.any?
@names -= [:north, :south, :east, :west]
@parent = user
user.parent.collate :whisper!, user, "Takes the " + names(user)[0].to_s
"You put the " + names(user)[0].to_s + " in your pocket"
else
"You cannot take the " + names(user)[0].to_s
end
end
define_instance_method :put! do |user|
if user.things.delete self
user.parent.things << self
@parent = user.parent
user.parent.collate :say!, user, "Puts down the " + names(user)[0].to_s
"You put the " + names(user)[0].to_s + " down"
else
"You don't have the " + names(user)[0].to_s
end
end
end
define_shortcut(:reply_var) do |name|
define_instance_method name do |user|
instance_variable_get ("@"+name.to_s).to_sym
end
end
def self.wrap name, &wrapper
wrapee = instance_method name
define_instance_method name do |user,*args|
self.instance_exec(user, args, proc do wrapee.bind(self).call(user,*args) end, &wrapper)
end
end
def wrap name, wrapper_s, record=true
wrapper = wrapper_s.respond_to?(:call) ? wrapper_s : SProc.new(wrapper_s)
if record
@pmethods << [name, :wrapping, wrapper]
end
wrapee = method name
define_instance_method name do |*args|
wrapper.call(user, args, proc do wrapee.call(user,*args) end)
end
end
def self.wrap_pass name
wrap name do |user,args,cb|
if args.any?
method_missing name, user, *args
else
cb.call
end
end
end
def wrap_pass name
wrap(name, %q{ |user,args,cb|
if args.any?
method_missing name, user, *args
else
cb.call
end
})
end
def define_method name, proc
aproc = proc.respond_to?(:call) ? proc : SProc.new(proc)
@pmethods << [name, :method, aproc]
define_instance_method name, &aproc
end
def initialize names, description, parent
@names = names.class == Array ? names : [names]
@description = description
@parent = parent
@pmethods = []
@reply_list = {}
@parent.things << self if @parent
end
def rebuild user=nil
@pmethods.each do |name,type,args|
case type
when :shortcut
send name, *args
when :method
define_instance_method name, &args
when :wrapping
wrap name, args, false
end
end
end
def names user
@names
end
def look! user
@description
end
def description! user
@description if visible? user
end
def method_missing verb, user, *args
"You cannot " + verb.to_s.chomp("!") + " the " + names(user)[0].to_s
end
def visible? user
true
end
def inspect
"<#{self.class} #{@names[0].to_s}>"
end
end