Class: Grueserve::Client
Defined Under Namespace
Classes: Command, CommandSet, Location
Constant Summary
Constants included
from Debuggable
Debuggable::LEVELS
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from Rated
#max_rate_of
Methods included from Debuggable
format, level, level=, #method_missing, output, #report, #report_for, #reset, #reset_for, source_part, #time
Constructor Details
#initialize(options) ⇒ Client
Returns a new instance of Client.
60
61
62
63
64
65
66
67
68
|
# File 'lib/grueserve/client.rb', line 60
def initialize(options)
self.socket = options.delete(:socket)
@application = options.delete(:application)
raise "Unknown options to #{self.class}.new: #{options.inspect}" unless options.empty?
self.map = @application.map
self.team = map.smallest_team
@last_start_point = @application.map.start_point(self.team)
@client_threads = Set.new
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
in the class Grueserve::Debuggable
Instance Attribute Details
#application ⇒ Object
Returns the value of attribute application.
58
59
60
|
# File 'lib/grueserve/client.rb', line 58
def application
@application
end
|
#client_threads ⇒ Object
Returns the value of attribute client_threads.
58
59
60
|
# File 'lib/grueserve/client.rb', line 58
def client_threads
@client_threads
end
|
#last_start_point ⇒ Object
Returns the value of attribute last_start_point.
58
59
60
|
# File 'lib/grueserve/client.rb', line 58
def last_start_point
@last_start_point
end
|
#ready ⇒ Object
Returns the value of attribute ready.
58
59
60
|
# File 'lib/grueserve/client.rb', line 58
def ready
@ready
end
|
Instance Method Details
#adjusted_damage(dmg) ⇒ Object
265
266
267
|
# File 'lib/grueserve/client.rb', line 265
def adjusted_damage(dmg)
return dmg
end
|
#broadcast_message(m) ⇒ Object
198
199
200
201
202
|
# File 'lib/grueserve/client.rb', line 198
def broadcast_message(m)
self.map.each_client do |client|
client.send_message(m)
end
end
|
#broadcast_noise(sound, source) ⇒ Object
190
191
192
193
194
195
196
|
# File 'lib/grueserve/client.rb', line 190
def broadcast_noise(sound, source)
self.map.each_client do |client|
noise_line = client.body.origo.to(source)
noise_damp = application.map.noise_damp(noise_line)
client.send_noise(sound, noise_damp, (noise_line.abs > 0 ? noise_line.angle : nil))
end
end
|
#calculate_bullet_effects(bullet_line) ⇒ Object
144
145
146
147
148
149
150
151
152
153
154
155
|
# File 'lib/grueserve/client.rb', line 144
def calculate_bullet_effects(bullet_line)
viewers = map.viewers_of(bullet_line.p1) + map.viewers_of(bullet_line.p2)
viewers.each do |viewer|
viewer.send_bullet(bullet_line)
end
broadcast_noise("shot", bullet_line.p1);
Set.new(map.body_parts.intersections(bullet_line)).each do |intersection|
unless (victim = map[intersection.last]) == self
victim.shot_at(self, bullet_line)
end
end
end
|
#damage ⇒ Object
311
312
313
|
# File 'lib/grueserve/client.rb', line 311
def damage
0.0
end
|
#dead_time ⇒ Object
315
316
317
|
# File 'lib/grueserve/client.rb', line 315
def dead_time
5
end
|
#fire_bullet(angle) ⇒ Object
137
138
139
140
141
142
|
# File 'lib/grueserve/client.rb', line 137
def fire_bullet(angle)
bullet_line = body.origo.to(1000,0)
bullet_line.angle = angle
bullet_line.p2 = application.map.bullet_intersection(bullet_line)
calculate_bullet_effects(bullet_line)
end
|
#fuzz ⇒ Object
Uses the Box-Muller transform to generate a bit of normal distribution with variance 1
225
226
227
|
# File 'lib/grueserve/client.rb', line 225
def fuzz
Math.sqrt(-2 * Math.log(rand)) * Math.cos(2 * Math::PI * rand)
end
|
#handle_helo(node) ⇒ Object
120
121
122
123
124
|
# File 'lib/grueserve/client.rb', line 120
def handle_helo(node)
self.nickname = node["nickname"]
self.nickname = "Anonymous" if self.nickname.empty?
application.map.send_binaries(self)
end
|
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
|
# File 'lib/grueserve/client.rb', line 229
def handle_input(message)
case message.root.name
when "MESSAGE"
message.root.each_child do |child|
case child.name
when "HELO"
extend(Soldier)
handle_helo(child)
when "READY"
handle_ready
when "COMMAND"
self.current_command = CommandSet.new(child)
when "PING"
handle_ping
end
end
else
log_warn("Got unknown message: #{message.to_s}")
end
end
|
#handle_ping ⇒ Object
250
251
252
|
# File 'lib/grueserve/client.rb', line 250
def handle_ping
self.ping!
end
|
#handle_policy_request ⇒ Object
109
110
111
112
113
114
115
116
117
118
|
# File 'lib/grueserve/client.rb', line 109
def handle_policy_request
msg = XML::Document.new
root = XML::Node.new("cross-domain-policy")
access = XML::Node.new("allow-access-from")
access["domain"] = "*"
access["to-port"] = "*"
root << access
msg.root = root
send_xml(msg.to_s)
end
|
#handle_ready ⇒ Object
101
102
103
104
105
106
107
|
# File 'lib/grueserve/client.rb', line 101
def handle_ready
self.body.relocate(last_start_point)
refill
self.register!
broadcast_message("#{nickname} connected")
update_viewing
end
|
#hit_me?(bullet_line) ⇒ Boolean
281
282
283
|
# File 'lib/grueserve/client.rb', line 281
def hit_me?(bullet_line)
return !Map.blocks?(bullet_line.p1.to(body.origo).abs, 1.0 - profile)
end
|
#killed(client) ⇒ Object
285
286
287
288
289
290
291
292
293
294
|
# File 'lib/grueserve/client.rb', line 285
def killed(client)
self.kills += 1
if client.team == self.team
broadcast_message("#{nickname} teamkilled #{client.nickname}")
self.score -= 2
else
broadcast_message("#{nickname} killed #{client.nickname}")
self.score += 2
end
end
|
#killed_by(client) ⇒ Object
254
255
256
257
258
259
260
261
262
263
|
# File 'lib/grueserve/client.rb', line 254
def killed_by(client)
self.score -= 1
self.deaths += 1
set_position(body.origo, :dead)
broadcast_noise("scream", body.origo)
thread_with_rescue do
sleep(dead_time)
revive
end
end
|
#max_hitpoints ⇒ Object
319
320
321
|
# File 'lib/grueserve/client.rb', line 319
def max_hitpoints
10
end
|
#new_message ⇒ Object
70
71
72
73
74
75
|
# File 'lib/grueserve/client.rb', line 70
def new_message
msg = XML::Document.new
root = XML::Node.new("MESSAGE")
msg.root = root
return msg
end
|
#profile ⇒ Object
330
331
332
333
334
335
|
# File 'lib/grueserve/client.rb', line 330
def profile
rval = standing_profile
rval /= 3.0 if state == :dodging
rval *= application.map.protection_factor(body.origo)
return rval
end
|
#refill ⇒ Object
303
304
305
|
# File 'lib/grueserve/client.rb', line 303
def refill
self.hitpoints = max_hitpoints
end
|
#revive ⇒ Object
296
297
298
299
300
301
|
# File 'lib/grueserve/client.rb', line 296
def revive
new_position = application.map.start_point(self.team, self.last_start_point)
set_position(new_position, :standing)
self.last_start_point = new_position
refill
end
|
#send_aim(x, y, radius) ⇒ Object
157
158
159
160
161
162
163
164
165
|
# File 'lib/grueserve/client.rb', line 157
def send_aim(x, y, radius)
msg = new_message
aim = XML::Node.new("AIM")
aim["x"] = x.to_i.to_s
aim["y"] = y.to_i.to_s
aim["radius"] = radius.to_i.to_s
msg.root << aim
send_xml(msg.to_s)
end
|
#send_bin(key, val) ⇒ Object
126
127
128
129
130
|
# File 'lib/grueserve/client.rb', line 126
def send_bin(key, val)
log_debug("Going to send bin to #{self}: #{key.inspect}")
log_trace(" => #{val.inspect}")
send("bin:#{key}:#{val}")
end
|
#send_bullet(bullet_line) ⇒ Object
179
180
181
182
183
184
185
186
187
188
|
# File 'lib/grueserve/client.rb', line 179
def send_bullet(bullet_line)
msg = new_message
bullet = XML::Node.new("BULLET")
bullet["x1"] = bullet_line.p1.x.to_i.to_s
bullet["y1"] = bullet_line.p1.y.to_i.to_s
bullet["x2"] = bullet_line.p2.x.to_i.to_s
bullet["y2"] = bullet_line.p2.y.to_i.to_s
msg.root << bullet
send_xml(msg.to_s)
end
|
#send_message(m) ⇒ Object
204
205
206
207
208
209
210
|
# File 'lib/grueserve/client.rb', line 204
def send_message(m)
msg = new_message
broadcast = XML::Node.new("BROADCAST")
broadcast["message"] = m
msg.root << broadcast
send_xml(msg.to_s)
end
|
#send_noise(sound, volume = 1.0, angle = nil) ⇒ Object
212
213
214
215
216
217
218
219
220
|
# File 'lib/grueserve/client.rb', line 212
def send_noise(sound, volume = 1.0, angle = nil)
msg = new_message
noise = XML::Node.new("NOISE")
noise["angle"] = angle.to_s
noise["volume"] = volume.to_s
noise["sound"] = sound
msg.root << noise
send_xml(msg.to_s)
end
|
#send_throw(thro_line, speed) ⇒ Object
167
168
169
170
171
172
173
174
175
176
177
|
# File 'lib/grueserve/client.rb', line 167
def send_throw(thro_line, speed)
msg = new_message
thro = XML::Node.new("THROW")
thro["x1"] = thro_line.p1.x.to_i.to_s
thro["y1"] = thro_line.p1.y.to_i.to_s
thro["x2"] = thro_line.p2.x.to_i.to_s
thro["y2"] = thro_line.p2.y.to_i.to_s
thro["speed"] = speed.to_i.to_s
msg.root << thro
send_xml(msg.to_s)
end
|
#send_xml(message) ⇒ Object
132
133
134
135
|
# File 'lib/grueserve/client.rb', line 132
def send_xml(message)
log_debug("Going to send xml to #{self}: #{message.inspect}")
send("xml:#{message}")
end
|
#shot_at(client, bullet_line) ⇒ Object
269
270
271
272
273
274
275
276
277
278
279
|
# File 'lib/grueserve/client.rb', line 269
def shot_at(client, bullet_line)
if hit_me?(bullet_line)
if self.state != :dead
self.hitpoints -= adjusted_damage(client.damage)
if self.hitpoints <= 0
killed_by(client)
client.killed(self)
end
end
end
end
|
#shutdown ⇒ Object
88
89
90
91
92
93
94
95
96
97
98
99
|
# File 'lib/grueserve/client.rb', line 88
def shutdown
if registered?
self.unregister!
client_threads.each do |thread|
thread.kill
end
viewers.each do |viewer|
viewer.send_disappearance(self)
end
broadcast_message("#{nickname} disconnected")
end
end
|
#speed ⇒ Object
323
324
325
326
327
328
|
# File 'lib/grueserve/client.rb', line 323
def speed
rval = running_speed
rval /= 5.0 if state == :dodging
rval *= application.map.speed_factor(body.origo)
return rval
end
|
#standing_profile ⇒ Object
307
308
309
|
# File 'lib/grueserve/client.rb', line 307
def standing_profile
1.0
end
|
#thread_with_rescue(&block) ⇒ Object
76
77
78
79
80
81
82
83
84
85
86
87
|
# File 'lib/grueserve/client.rb', line 76
def thread_with_rescue(&block)
new_thread = Thread.new do
begin
yield
rescue Exception => e
log_fatal(e)
ensure
self.client_threads.delete(Thread.current)
end
end
self.client_threads << new_thread
end
|