chichilku3 5.0.0 → 14.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e90a2851bf8d4a37c61c581919708cd7fc75c8592291755c0281e090e03e5d84
4
- data.tar.gz: 10e3825729ef2c5a0f17543a8c4519cbbf61f021805d624b54a8f79e314db898
3
+ metadata.gz: 7e5346f7d8aab4cd33e49493ca114e692abd3758e7f982e9c2ddf3c11c1b1a07
4
+ data.tar.gz: 91118f6a4a6f7946c726bb4e85fe58f94c3a315d36a6669fa0ff2dc2ac049c46
5
5
  SHA512:
6
- metadata.gz: 2452e5c7f2764142ea99f151828994b6c163d301370835558a464c8215c6f1689036a2de9ed681b7d937d90787a8f1d124c241848e63a7d79e3f0fc3c40937be
7
- data.tar.gz: 610086071507b30d4acdaaefdb029f485d1c2696c3df1a36369e224f14a9afe67dbc7454affbb3c0d968d47bbd3eeef323223e7f9530924cea85c0e14ecc6399
6
+ metadata.gz: 758de7b2cdda9900c0b3d567daa6a64057ff392a23dd826c5b4d0cbed6821a6e27457a690c075eb455ee3dec88ccfbf896465cabd539f0d47dc732dff151e6cd
7
+ data.tar.gz: 12480157f9ffda4791ed5f189bee520bde245b39c10bf49c2814269dc61b0928469c0a9952098f30edc558464ef828d4f34ac5d5b16d2ca7018e5aa11a2a0986
@@ -2,5 +2,6 @@
2
2
  "ip": "localhost",
3
3
  "port": 9900,
4
4
  "username": "00000000",
5
- "fullscreen": false
5
+ "fullscreen": false,
6
+ "autorecord": false
6
7
  }
@@ -7,10 +7,11 @@ STATE_MENU = -1
7
7
  STATE_OFFLINE = 0
8
8
  STATE_CONNECTING = 1
9
9
  STATE_INGAME = 2
10
+ STATE_REC_PLAYBACK = 3
10
11
 
11
12
  # Networking part of the game clientside
12
13
  class Client
13
- attr_reader :id, :state
14
+ attr_reader :id, :state, :server_version
14
15
  def initialize(console, cfg)
15
16
  @id = nil
16
17
  @tick = 0
@@ -22,6 +23,13 @@ class Client
22
23
 
23
24
  @s = nil # network socket (set in connect() method)
24
25
 
26
+ @recording_ticks = []
27
+ @recording_ticks_len = 0
28
+ @recording_file = "autorec.txt"
29
+ @is_recording = false
30
+
31
+ @server_version = nil
32
+
25
33
  # state variables
26
34
  @req_playerlist = Time.now - 8
27
35
 
@@ -43,16 +51,65 @@ class Client
43
51
  @s = TCPSocket.open(ip, port)
44
52
  @s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) # nagle's algorithm-
45
53
  @state = STATE_CONNECTING
54
+ start_recording() if @cfg.data['autorecord']
46
55
  end
47
56
 
48
57
  def disconnect()
49
58
  return if @state == STATE_MENU
59
+
50
60
  @console.log "disconnecting from server."
51
61
  @s.close
52
62
  @s = nil
53
63
  reset
54
64
  end
55
65
 
66
+ def load_recording(recording_file)
67
+ recording_file = "#{@cfg.chichilku3_dir}recordings/#{recording_file}"
68
+ @recording_ticks = []
69
+ @tick = 0
70
+ update_state(STATE_REC_PLAYBACK)
71
+ File.readlines(recording_file).each do |data|
72
+ @recording_ticks << data[0..-2] # cut off newline
73
+ end
74
+ # TODO: check if this .length lookup eats performance in ruby
75
+ @recording_ticks_len = @recording_ticks.length
76
+ @console.log "loaded recording containing #{@recording_ticks.size} ticks"
77
+ end
78
+
79
+ def start_recording()
80
+ @recording_file = "autorec.txt"
81
+ rec_file = "#{@cfg.chichilku3_dir}recordings/#{@recording_file}"
82
+ @is_recording = true
83
+ File.delete(rec_file) if File.exists? rec_file
84
+ end
85
+
86
+ def recording_record_tick(data)
87
+ return unless @is_recording
88
+
89
+ recording_file = "#{@cfg.chichilku3_dir}recordings/#{@recording_file}"
90
+ IO.write(recording_file, data + "\n", mode: 'a')
91
+ end
92
+
93
+ def recording_playback_tick()
94
+ if @recording_ticks_len <= @tick
95
+ @console.log "finished playing back recording"
96
+ update_state(STATE_MENU)
97
+ return [[], @flags, nil]
98
+ end
99
+ data = @recording_ticks[@tick]
100
+ if data.length != SERVER_PACKAGE_LEN
101
+ @console.err "failed to parse recording data=#{data.length} server=#{SERVER_PACKAGE_LEN}"
102
+ return nil
103
+ end
104
+
105
+ @tick += 1
106
+ @flags[:skip] = false
107
+
108
+ # save protocol and cut it off
109
+ msg = handle_protocol(data[0].to_i, data[1], data[2..-1])
110
+ [@players, @flags, msg, [@tick, @recording_ticks_len]]
111
+ end
112
+
56
113
  def tick(client_data, protocol, tick)
57
114
  return nil if @state == STATE_MENU
58
115
 
@@ -67,8 +124,7 @@ class Client
67
124
  data = fetch_server_data
68
125
  return nil if data.nil?
69
126
 
70
- # only process the long packages and ignore ip packages here
71
- return nil if data.length != SERVER_PACKAGE_LEN
127
+ recording_record_tick(data)
72
128
 
73
129
  # save protocol and cut it off
74
130
  msg = handle_protocol(data[0].to_i, data[1], data[2..-1])
@@ -129,24 +185,20 @@ class Client
129
185
  if @id.nil?
130
186
  # request id has priority
131
187
  # resend after 100 ticks if no respond
132
- name = @cfg.data['username'].ljust(5, '-')
133
- net_write("1l#{name}") if (@tick % 200).zero?
188
+ net_write("1l#{GAME_VERSION}XXXXX") if (@tick % 200).zero?
134
189
  return
135
190
  end
136
191
 
137
192
  # if no playerlist yet -> request one
138
193
  if @players == [] && @req_playerlist < Time.now - 4
139
- net_write("3l#{id}#{GAME_VERSION}")
194
+ name = @cfg.data['username'].ljust(NAME_LEN, ' ')
195
+ net_write("3l#{name}")
140
196
  @console.log('requesting a playerlist')
141
197
  @req_playerlist = Time.now
142
198
  return
143
199
  end
144
200
 
145
- # prefix data with id
146
- # prot 2 = update pck
147
- # prot updated to dynamic becuase we now also send cmds
148
- # data = format("#{protocol}l%02d#{data.join('')}", @id) # old 2byte id
149
- data = "#{protocol}l#{@id}#{data.join('')}" # new 1byte id
201
+ data = "#{protocol}l#{@id.to_s(16)}#{data.join('')}"
150
202
  net_write(data)
151
203
  end
152
204
 
@@ -163,10 +215,10 @@ class Client
163
215
 
164
216
  def grab_id(data)
165
217
  @console.log 'Trying to read id...'
166
- @playercount = data[0..1]
167
- id = data[2..3].to_i
218
+ @playercount = net_unpack_int(data[0..1])
219
+ id = data[2].to_i(16)
168
220
  set_id(id)
169
- update_state(STATE_INGAME)
221
+ update_state(STATE_INGAME) unless @state == STATE_REC_PLAYBACK
170
222
  end
171
223
 
172
224
  def id_packet(data)
@@ -178,12 +230,20 @@ class Client
178
230
  end
179
231
 
180
232
  def get_server_version(data)
181
- server_version = data[4..8]
182
- @console.log "server version='#{server_version}'"
233
+ @server_version = data[4..7]
234
+ @console.log "server version='#{@server_version}'"
183
235
  end
184
236
 
185
237
  def fetch_server_data
186
- server_data = save_read(@s, SERVER_PACKAGE_LEN)
238
+ server_data = save_read(@s, 3)
239
+ return nil if server_data == ''
240
+
241
+ if server_data[0] == "1"
242
+ len = net_unpack_int(server_data[2]) * PLAYER_PACKAGE_LEN
243
+ server_data += save_read(@s, len+1)
244
+ else
245
+ server_data += save_read(@s, SERVER_PACKAGE_LEN-3)
246
+ end
187
247
  return nil if server_data == ''
188
248
 
189
249
  @console.dbg "recived data: #{server_data}"
@@ -207,17 +267,18 @@ class Client
207
267
  # And its dependencies:
208
268
  def protocol_names(data)
209
269
  # 3 0 00 00000 00 00000 00 00000 000
210
- playercount = data[0].to_i
270
+ playercount = net_unpack_int(data[0])
211
271
  @flags[:gamestate] = data[1]
212
272
  data = data[2..-1]
213
273
  p_strs = protocol_names_to_player_strs(playercount, data)
214
274
  protocol_names_strs_to_objs(p_strs)
215
275
  end
216
276
 
217
- def protocol_names_to_player_strs(slots, data)
277
+ def protocol_names_to_player_strs(used_slots, data)
218
278
  players = []
219
- slots.times do |index|
220
- players[index] = data[index * 7..index * 7 + 6]
279
+ used_slots.times do |index|
280
+ size = NAME_LEN + 2 # id|score|name
281
+ players[index] = data[index * size..index * size + size-1]
221
282
  end
222
283
  players
223
284
  end
@@ -225,7 +286,7 @@ class Client
225
286
  def protocol_names_strs_to_objs(player_strs)
226
287
  players = []
227
288
  player_strs.each do |player_str|
228
- id = player_str[0].to_i
289
+ id = player_str[0].to_i(16)
229
290
  score = net_unpack_int(player_str[1])
230
291
  name = player_str[2..-1]
231
292
  players << Player.new(id, 0, 0, score, name) unless id.zero?
@@ -241,20 +302,20 @@ class Client
241
302
  def server_package_to_player_array(data)
242
303
  # /(?<count>\d{2})(?<player>(?<id>\d{2})(?<x>\d{3})(?<y>\d{3}))/
243
304
  # @console.log "data: #{data}"
244
- slots = data[0].to_i # save occupado slots
305
+ used_slots = net_unpack_int(data[0]) # save occupado slots
245
306
  # gamestate = data[1].to_i # save gamestate
246
307
  @flags[:gamestate] = data[1]
247
308
  # @console.log "gamestate: " + @flags[:gamestate]
248
309
  data = data[2..-1] # cut slots and gamestate off
249
- players = server_package_to_player_strs(slots, data)
310
+ players = server_package_to_player_strs(used_slots, data)
250
311
  # @console.log "players: \n#{players}"
251
312
  player_strs_to_objects(players)
252
313
  end
253
314
 
254
- def server_package_to_player_strs(slots, data)
315
+ def server_package_to_player_strs(used_slots, data)
255
316
  players = []
256
- slots.times do |index|
257
- players[index] = data[index * 8..index * 8 + 7]
317
+ used_slots.times do |index|
318
+ players[index] = data[index * PLAYER_PACKAGE_LEN..index * PLAYER_PACKAGE_LEN + PLAYER_PACKAGE_LEN-1]
258
319
  end
259
320
  players
260
321
  end
@@ -262,13 +323,17 @@ class Client
262
323
  def player_strs_to_objects(player_strs)
263
324
  players = []
264
325
  player_strs.each do |player_str|
265
- id = player_str[0].to_i
326
+ id = player_str[0].to_i(16)
266
327
  score = net_unpack_int(player_str[1])
267
- unused = player_str[2]
268
- net_state = player_str[3]
269
- x = net_unpack_bigint(player_str[4..5])
270
- y = net_unpack_bigint(player_str[6..7])
271
- # puts "id: #{id} x: #{x} y: #{y}"
328
+ net_state = player_str[2]
329
+ projR = player_str[3]
330
+ projX = net_unpack_bigint(player_str[4..5])
331
+ projY = net_unpack_bigint(player_str[6..7])
332
+ aimX = net_unpack_bigint(player_str[8..9])
333
+ aimY = net_unpack_bigint(player_str[10..11])
334
+ x = net_unpack_bigint(player_str[12..13])
335
+ y = net_unpack_bigint(player_str[14..15])
336
+ # puts "'#{player_str}' id: #{id} x: #{x} '#{player_str[12..13]}' y: #{y} '#{player_str[14..15]}'"
272
337
  # players << Player.new(id, x, y) unless id.zero?
273
338
 
274
339
  @console.dbg "-- updt player id=#{id} score=#{score}--"
@@ -278,7 +343,10 @@ class Client
278
343
  next if p_index.nil?
279
344
 
280
345
  @console.dbg "got player: #{@players[p_index]}"
281
- new_player = Player.update_player(@players, id, x, y, score)
346
+ new_player = Player.update_player(@players, id, x, y, score, aimX, aimY)
347
+ new_player.projectile.r = projR
348
+ new_player.projectile.x = projX
349
+ new_player.projectile.y = projY
282
350
  new_player.net_to_state(net_state)
283
351
  @players[Player.get_player_index_by_id(@players, id)] = new_player
284
352
  end
@@ -2,7 +2,7 @@ require 'json'
2
2
  require_relative '../share/network'
3
3
  require_relative '../share/config'
4
4
 
5
- # The client side repository usign JSON
5
+ # The client side repository using JSON
6
6
  class ClientCfg < Config
7
7
  def sanitize_data(data)
8
8
  data = JSON.parse(File.read(@file))
@@ -26,6 +26,8 @@ MENU_MAIN = 0
26
26
  MENU_CONNECT = 1
27
27
  MENU_USERNAME = 2
28
28
 
29
+ MOUSE_RADIUS = 200
30
+
29
31
  $time_point=Time.now
30
32
  $time_buffer=0
31
33
 
@@ -42,24 +44,41 @@ class Gui < Gosu::Window
42
44
  self.caption = 'chichilku3'
43
45
  self.fullscreen = true if cfg.data['fullscreen']
44
46
  # images
45
- @background_image = Gosu::Image.new("lib/client/img/battle1024x576.png")
46
- @connecting_image = Gosu::Image.new("lib/client/img/connecting1024x512.png")
47
- @menu_image = Gosu::Image.new("lib/client/img/menu1920x1080.png")
48
- @stick = Gosu::Image.new("lib/client/img/stick128/stick0.png")
47
+ @crosshair = Gosu::Image.new(img("crosshair128x128.png"))
48
+ @background_image = Gosu::Image.new(img("battle1024x576.png"))
49
+ @connecting_image = Gosu::Image.new(img("connecting1024x512.png"))
50
+ @menu_image = Gosu::Image.new(img("menu1920x1080.png"))
51
+ @arrow_image = Gosu::Image.new(img("arrow64.png"))
52
+ @stick_arm_images = []
53
+ @stick_arm_images << Gosu::Image.new(img("stick128/arm64/arm0.png"))
54
+ @stick_arm_images << Gosu::Image.new(img("stick128/arm64/arm1.png"))
55
+ @stick_arm_images << Gosu::Image.new(img("stick128/arm64/arm2.png"))
56
+ @stick_arm_images << Gosu::Image.new(img("stick128/arm64/arm3.png"))
49
57
  @stick_crouching = []
50
- @stick_crouching << Gosu::Image.new("lib/client/img/stick128/stick_crouching0.png")
51
- @stick_crouching << Gosu::Image.new("lib/client/img/stick128/stick_crouching1.png")
52
- @stick_crouching << Gosu::Image.new("lib/client/img/stick128/stick_crouching2.png")
53
- @stick_crouching << Gosu::Image.new("lib/client/img/stick128/stick_crouching3.png")
54
- @stick_crouching << Gosu::Image.new("lib/client/img/stick128/stick_crouching4.png")
55
- @stick_crouching << Gosu::Image.new("lib/client/img/stick128/stick_crouching5.png")
58
+ @stick_crouching << Gosu::Image.new(img("stick128/stick_crouching0.png"))
59
+ @stick_crouching << Gosu::Image.new(img("stick128/stick_crouching1.png"))
60
+ @stick_crouching << Gosu::Image.new(img("stick128/stick_crouching2.png"))
61
+ @stick_crouching << Gosu::Image.new(img("stick128/stick_crouching3.png"))
62
+ @stick_crouching << Gosu::Image.new(img("stick128/stick_crouching4.png"))
63
+ @stick_crouching << Gosu::Image.new(img("stick128/stick_crouching5.png"))
56
64
  @stick_images = []
57
- @stick_images << Gosu::Image.new("lib/client/img/stick128/stick0.png")
58
- @stick_images << Gosu::Image.new("lib/client/img/stick128/stick1.png")
59
- @stick_images << Gosu::Image.new("lib/client/img/stick128/stick2.png")
60
- @stick_images << Gosu::Image.new("lib/client/img/stick128/stick3.png")
61
- @stick_images << Gosu::Image.new("lib/client/img/stick128/stick4.png")
62
- @stick_images << Gosu::Image.new("lib/client/img/stick128/stick5.png")
65
+ @stick_images << Gosu::Image.new(img("stick128/stick_noarms.png"))
66
+ @stick_images << Gosu::Image.new(img("stick128/stick_noarms.png"))
67
+ @stick_images << Gosu::Image.new(img("stick128/stick_noarms.png"))
68
+ @stick_images << Gosu::Image.new(img("stick128/stick_noarms.png"))
69
+ @stick_images << Gosu::Image.new(img("stick128/stick_noarms.png"))
70
+ @bow_images = []
71
+ @bow_images << Gosu::Image.new(img("bow64/bow0.png"))
72
+ @bow_images << Gosu::Image.new(img("bow64/bow1.png"))
73
+ @bow_images << Gosu::Image.new(img("bow64/bow2.png"))
74
+ @bow_images << Gosu::Image.new(img("bow64/bow3.png"))
75
+ # TODO: add arms back in if no bow is in use
76
+ # @stick_images << Gosu::Image.new(img("stick128/stick0.png"))
77
+ # @stick_images << Gosu::Image.new(img("stick128/stick1.png"))
78
+ # @stick_images << Gosu::Image.new(img("stick128/stick2.png"))
79
+ # @stick_images << Gosu::Image.new(img("stick128/stick3.png"))
80
+ # @stick_images << Gosu::Image.new(img("stick128/stick4.png"))
81
+ # @stick_images << Gosu::Image.new(img("stick128/stick5.png"))
63
82
  @x = 0
64
83
  @y = 0
65
84
  @players = []
@@ -85,6 +104,7 @@ class Gui < Gosu::Window
85
104
  @menu_items = []
86
105
  @selected_menu_item = 0
87
106
  @menu_textfield = TextField.new(self, 60, 200)
107
+ @demo_ticks = [0,0]
88
108
  # @chat_inp_stream = nil #TextInput.new
89
109
  # @chat_inp_stream.text # didnt get it working <--- nobo xd
90
110
 
@@ -93,6 +113,15 @@ class Gui < Gosu::Window
93
113
  # depreciated ._.
94
114
  # @con_msg = Gosu::Image.from_text(self, "connecting to #{@cfg.data['ip']}:#{@cfg.data['port']}...", Gosu.default_font_name, 45)
95
115
  init_menu()
116
+
117
+ if ARGV.length > 0
118
+ port = ARGV.length > 1 ? ARGV[1].to_i : 9900
119
+ connect(ARGV[0], port)
120
+ end
121
+ end
122
+
123
+ def img(path)
124
+ File.join(File.dirname(__FILE__), "../../lib/client/img/", path)
96
125
  end
97
126
 
98
127
  def button_press?(button)
@@ -183,7 +212,7 @@ class Gui < Gosu::Window
183
212
  ip = @menu_textfield.text.split(":")
184
213
  @cfg.data['ip'] = ip[0]
185
214
  @cfg.data['port'] = ip[1] if ip.length > 1
186
- connect
215
+ connect(@cfg.data['ip'], @cfg.data['port'])
187
216
  end
188
217
  else
189
218
  @last_key = nil
@@ -217,17 +246,21 @@ class Gui < Gosu::Window
217
246
  @state = STATE_MENU
218
247
  @net_client.disconnect
219
248
  return
249
+ elsif @state == STATE_REC_PLAYBACK
250
+ @state = STATE_MENU
251
+ return
220
252
  end
221
253
  end
222
254
  net_request = '0000'.split('')
255
+ net_request << "!!!!"
223
256
  protocol = 2
224
257
 
225
258
  if @is_chat
226
259
  msg = chat_tick
227
260
  if !msg.nil?
228
261
  # @console.dbg "rawmsg: #{msg}"
229
- msg = msg.ljust(4, '0')
230
- net_request = msg[0..3].split('')
262
+ msg = msg.ljust(8, '0')
263
+ net_request = msg[0..CMD_LEN].split('')
231
264
  # @console.dbg "prepedmsg: #{net_request}"
232
265
  protocol = 4
233
266
  end
@@ -237,13 +270,13 @@ class Gui < Gosu::Window
237
270
  net_request[0] = '1'
238
271
  end
239
272
  if button_down?(KEY_A)
240
- net_request[1] = '1'
273
+ net_request[1] = 'l'
241
274
  end
242
275
  if button_down?(KEY_D)
243
- net_request[2] = '1'
276
+ net_request[1] = 'r'
244
277
  end
245
278
  if button_down?(Gosu::KB_SPACE)
246
- net_request[3] = '1'
279
+ net_request[2] = '1'
247
280
  end
248
281
  if button_press?(KEY_M)
249
282
  @is_debug = !@is_debug
@@ -253,15 +286,27 @@ class Gui < Gosu::Window
253
286
  @is_chat = true
254
287
  @chat_msg = ""
255
288
  end
289
+ if button_down?(Gosu::MsLeft)
290
+ net_request[3] = '1'
291
+ end
292
+ # TODO: check for active window
293
+ # do not leak mouse movement in other applications than chichilku3
294
+ net_request[4] = net_pack_bigint(self.mouse_x.to_i.clamp(0, 8834), 2)
295
+ net_request[5] = net_pack_bigint(self.mouse_y.to_i.clamp(0, 8834), 2)
256
296
  @is_scoreboard = button_down?(Gosu::KB_TAB)
257
297
  end
258
298
 
259
- # Networking
260
- begin
261
- net_data = @net_client.tick(net_request, protocol, @tick)
262
- rescue Errno::ECONNRESET, Errno::EPIPE
263
- net_data = [@players, @flags, [0, NET_ERR_DISCONNECT, "connection to server lost"]]
264
- @net_client.disconnect
299
+ if @state == STATE_REC_PLAYBACK
300
+ net_data = @net_client.recording_playback_tick()
301
+ @demo_ticks = net_data[3] unless net_data.nil?
302
+ else
303
+ # Networking
304
+ begin
305
+ net_data = @net_client.tick(net_request, protocol, @tick)
306
+ rescue Errno::ECONNRESET, Errno::EPIPE
307
+ net_data = [@players, @flags, [0, NET_ERR_DISCONNECT, "connection to server lost"]]
308
+ @net_client.disconnect
309
+ end
265
310
  end
266
311
  return if net_data.nil?
267
312
 
@@ -349,6 +394,13 @@ class Gui < Gosu::Window
349
394
  @events[:blood] = bloods
350
395
  end
351
396
 
397
+ def draw_debug(x, y, s=1)
398
+ return unless @is_debug
399
+
400
+ draw_rect(x, y, 4*s, 4*s, 0xFFFF0000, 1)
401
+ draw_rect(x+1*s, y+1*s, 2*s, 2*s, 0xFF00FF00, 1)
402
+ end
403
+
352
404
  def draw
353
405
  # draw_quad(0, 0, 0xffff8888, WINDOW_SIZE_X, WINDOW_SIZE_Y, 0xffffffff, 0, 0, 0xffffffff, WINDOW_SIZE_X, WINDOW_SIZE_Y, 0xffffffff, 0)
354
406
  if @state == STATE_MENU
@@ -365,22 +417,61 @@ class Gui < Gosu::Window
365
417
  end
366
418
  elsif @state == STATE_CONNECTING
367
419
  @connecting_image.draw(0, 0, 0)
368
- @font.draw_text("connecting to #{@cfg.data['ip']}:#{@cfg.data['port']}...", 20, 20, 0, 2, 5)
420
+ @font.draw_text("connecting to #{@cfg.data['ip']}:#{@cfg.data['port']}...", 20, 20, 0, 3, 3)
369
421
  # @con_msg.draw(100,200,0)
370
- elsif @state == STATE_INGAME
422
+ elsif @state == STATE_INGAME || @state == STATE_REC_PLAYBACK
371
423
  @background_image.draw(0, 0, 0)
424
+ @crosshair.draw(self.mouse_x-16, self.mouse_y-16, 0, 0.25, 0.25)
425
+ # useless mouse trap
426
+ # since its buggo and your character moves maybe keep it free
427
+ # mouse players should go fullscreen
428
+ # self.mouse_x = (WINDOW_SIZE_X / 2) + MOUSE_RADIUS - 1 if self.mouse_x > (WINDOW_SIZE_X / 2) + MOUSE_RADIUS
429
+ # self.mouse_x = (WINDOW_SIZE_X / 2) - MOUSE_RADIUS + 1 if self.mouse_x < (WINDOW_SIZE_X / 2) - MOUSE_RADIUS
430
+ # self.mouse_y = (WINDOW_SIZE_Y / 2) + MOUSE_RADIUS - 1 if self.mouse_y > (WINDOW_SIZE_Y / 2) + MOUSE_RADIUS
431
+ # self.mouse_y = (WINDOW_SIZE_Y / 2) - MOUSE_RADIUS + 1 if self.mouse_y < (WINDOW_SIZE_Y / 2) - MOUSE_RADIUS
372
432
  @players.each do |player|
373
433
  event_blood(player.x, player.y) if player.state[:bleeding]
374
434
  player.draw_tick
375
435
  @console.dbg "drawing player id=#{player.id} pos=#{player.x}/#{player.y}"
376
436
  # draw_rect(player.x, player.y, TILE_SIZE, TILE_SIZE, Gosu::Color::WHITE)
377
- # @stick.draw(player.x, player.y, 0)
378
437
  if player.state[:crouching]
379
438
  @stick_crouching[player.img_index].draw(player.x, player.y, 0, 0.5, 0.5)
380
439
  else
381
440
  @stick_images[player.img_index].draw(player.x, player.y, 0, 0.5, 0.5)
441
+ x = player.aimX - player.x
442
+ y = player.aimY - player.y
443
+ rot = Math.atan2(x, y) * 180 / Math::PI * -1 + 90 * -1
444
+ rot2 = Math.atan2(x, y) * 180 / Math::PI * -1 + 270 * -1
445
+ stick_center_x = player.x + TILE_SIZE/4
446
+ stick_center_y = player.y + TILE_SIZE/2
447
+ d = -8
448
+ d += player.state[:fire] * 3
449
+ arr_x = stick_center_x + (d * Math.cos((rot2 + 180) / 180 * Math::PI))
450
+ arr_y = stick_center_y + (d * Math.sin((rot2 + 180) / 180 * Math::PI))
451
+ @bow_images[player.state[:fire]].draw_rot(stick_center_x, stick_center_y, 0, rot, 0.5, 0.5, 0.5, 0.5)
452
+ @stick_arm_images[player.state[:fire]].draw_rot(stick_center_x, stick_center_y, 0, rot, 0.5, 0.5, 0.5, 0.5)
453
+ if player.projectile.x == 0 and player.projectile.y == 0
454
+ @arrow_image.draw_rot(arr_x, arr_y, 0, rot2, 0.5, 0.5, 0.5, 0.5)
455
+ end
456
+ if @is_debug
457
+ draw_debug(arr_x, arr_y, 2)
458
+ draw_debug(stick_center_x, stick_center_y, 1)
459
+ draw_line(arr_x, arr_y, 0xFFFF0000, stick_center_x, stick_center_y, 0xFF000000)
460
+ @font.draw_text("rot=#{rot.to_i} rot2=#{rot2.to_i}", player.x - 60, player.y - 100, 0, 1, 1, 0xFF000000)
461
+ @font.draw_text("d=#{d} (#{stick_center_x}/#{stick_center_y}) -> (#{arr_x.to_i}/#{arr_y.to_i})", player.x - 80, player.y - 80, 0, 1, 1, 0xFF000000)
462
+ end
463
+ end
464
+ unless player.projectile.x == 0 or player.projectile.y == 0
465
+ rot = player.projectile.r.to_i * 45
466
+ @arrow_image.draw_rot(player.projectile.x, player.projectile.y, 0, rot, 0.5, 0.5, 0.5, 0.5)
382
467
  end
383
468
  if @is_debug # print id
469
+ # aim
470
+ draw_rect(player.aimX - 2, player.aimY - 16, 4, 32, 0xCC33FF33)
471
+ draw_rect(player.aimX - 16, player.aimY - 2, 32, 4, 0xCC33FF33)
472
+ draw_rect(player.aimX, player.aimY - 15, 1, 30, 0xAA000000)
473
+ draw_rect(player.aimX - 15, player.aimY, 30, 1, 0xAA000000)
474
+ # text background
384
475
  draw_rect(player.x - 2, player.y - 60, 32, 20, 0xAA000000)
385
476
  @font.draw_text("#{player.id}:#{player.score}", player.x, player.y - 60, 0, 1, 1)
386
477
  # @font.draw_text("#{player.id}:#{player.img_index}", player.x, player.y - TILE_SIZE * 2, 0, 1, 1)
@@ -389,7 +480,9 @@ class Gui < Gosu::Window
389
480
  else
390
481
  draw_rect(player.x, player.y, TILE_SIZE/2, TILE_SIZE, 0xAA00EE00)
391
482
  end
392
- else
483
+ unless player.projectile.x == 0 or player.projectile.y == 0
484
+ draw_rect(player.projectile.x, player.projectile.y, player.projectile.w, player.projectile.h, 0xAA00EE00)
485
+ end
393
486
  end
394
487
  @font.draw_text(player.name, player.x - (TILE_SIZE/6), player.y - TILE_SIZE / 2, 0, 1, 1, 0xff_000000)
395
488
  end
@@ -407,10 +500,12 @@ class Gui < Gosu::Window
407
500
  if @is_debug
408
501
  player = Player.get_player_by_id(@players, @flags[:id])
409
502
  unless player.nil?
410
- draw_rect(5, 10, 295, 75, 0xAA000000)
503
+ draw_rect(5, 10, 290, 85, 0xAA000000)
411
504
  @font.draw_text("Press m to deactivate debug mode", 10, 10, 0, 1, 1)
412
505
  @font.draw_text("x: #{player.x} y: #{player.y}", 10, 30, 0, 1, 1)
506
+ @font.draw_text("aimX: #{player.aimX} aimY: #{player.aimY}", 10, 45, 0, 1, 1)
413
507
  @font.draw_text("gamestate: #{@flags[:gamestate]}", 10, 60, 0 , 1, 1)
508
+ @font.draw_text("server version: #{@net_client.server_version}", 10, 75, 0 , 1, 1)
414
509
  # thats useless because collide/delta speed is not sent over the network
415
510
  # @font.draw_text("dx: #{player.dx} dy: #{player.dy}", 10, 50, 0, 1, 1)
416
511
  # @font.draw_text(player.collide_string, 10, 70, 0, 1, 1)
@@ -420,7 +515,10 @@ class Gui < Gosu::Window
420
515
  draw_events()
421
516
 
422
517
  if @is_scoreboard
423
- draw_scoreboard(WINDOW_SIZE_X, WINDOW_SIZE_Y, @players, @font)
518
+ draw_scoreboard(WINDOW_SIZE_X, WINDOW_SIZE_Y, @players, @font, @is_debug)
519
+ end
520
+ if @state == STATE_REC_PLAYBACK && !(@demo_ticks.nil?)
521
+ @font.draw_text("#{@demo_ticks[0]}/#{@demo_ticks[1]}", 10, WINDOW_SIZE_Y - 20, 0)
424
522
  end
425
523
  elsif @state == STATE_ERROR
426
524
  net_err_code = @net_err[0]
@@ -441,9 +539,10 @@ class Gui < Gosu::Window
441
539
 
442
540
  private
443
541
 
444
- def connect()
542
+ def connect(ip, port)
543
+ @console.log "connecting to server '#{ip}:#{port}' ..."
445
544
  begin
446
- @net_client.connect(@cfg.data['ip'], @cfg.data['port'])
545
+ @net_client.connect(ip, port)
447
546
  @state = STATE_CONNECTING;
448
547
  @menu_page = MENU_MAIN
449
548
  rescue Errno::ECONNREFUSED
@@ -478,11 +577,17 @@ class Gui < Gosu::Window
478
577
  end
479
578
  end
480
579
 
580
+ def play_recording()
581
+ @net_client.load_recording('autorec.txt')
582
+ @state = STATE_REC_PLAYBACK
583
+ end
584
+
481
585
  def init_menu()
482
586
  @menu_items = []
483
587
  add_menu_item("[c]onnect", Proc.new { connect_menu() })
484
588
  add_menu_item("username", Proc.new { username_page() })
485
589
  add_menu_item("fullscreen", Proc.new { toggle_fullscreen() })
590
+ add_menu_item("recording", Proc.new { play_recording() })
486
591
  add_menu_item("[q]uit", Proc.new { exit() })
487
592
  end
488
593