chichilku3 14.0.3 → 15.0.1
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 +4 -4
- data/bin/chichilku3 +1 -0
- data/bin/chichilku3-server +1 -0
- data/lib/client/chichilku3.rb +3 -1
- data/lib/client/client.rb +112 -59
- data/lib/client/client_cfg.rb +2 -1
- data/lib/client/gui.rb +219 -197
- data/lib/client/img/stick128/arm64/arm0.png +0 -0
- data/lib/client/img/stick128/arm64/arm1.png +0 -0
- data/lib/client/img/stick128/arm64/arm2.png +0 -0
- data/lib/client/img/stick128/arm64/arm3.png +0 -0
- data/lib/client/img/stick128/noarms/stick0.png +0 -0
- data/lib/client/img/stick128/noarms/stick1.png +0 -0
- data/lib/client/img/stick128/noarms/stick2.png +0 -0
- data/lib/client/img/stick128/noarms/stick3.png +0 -0
- data/lib/client/img/stick128/noarms/stick4.png +0 -0
- data/lib/client/img/stick128/noarms/stick5.png +0 -0
- data/lib/client/keys.rb +29 -0
- data/lib/client/particles.rb +54 -0
- data/lib/client/scoreboard.rb +29 -27
- data/lib/{client → external/gosu}/text.rb +29 -38
- data/lib/external/rubyzip/recursive.rb +58 -0
- data/lib/server/chichilku3_server.rb +169 -64
- data/lib/server/gamelogic.rb +107 -51
- data/lib/server/server_cfg.rb +2 -0
- data/lib/share/config.rb +21 -7
- data/lib/share/console.rb +22 -5
- data/lib/share/game_map.rb +279 -0
- data/lib/share/math.rb +14 -0
- data/lib/share/network.rb +47 -42
- data/lib/share/player.rb +168 -105
- data/lib/share/projectile.rb +97 -98
- data/lib/share/string.rb +24 -0
- data/server.json +3 -2
- metadata +49 -23
- data/lib/client/img/battle1024x576.png +0 -0
- data/lib/client/img/grass1024x512.png +0 -0
- data/lib/client/img/stick128/stick_noarms.png +0 -0
- data/lib/client/test.rb +0 -39
data/lib/client/gui.rb
CHANGED
@@ -1,26 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'gosu'
|
2
4
|
require_relative 'client'
|
3
|
-
require_relative 'text'
|
5
|
+
require_relative '../external/gosu/text'
|
4
6
|
require_relative 'scoreboard'
|
5
7
|
require_relative '../share/console'
|
6
8
|
require_relative '../share/player'
|
7
|
-
|
8
|
-
|
9
|
-
KEY_C = 6
|
10
|
-
KEY_D = 7
|
11
|
-
KEY_H = 11
|
12
|
-
KEY_J = 13
|
13
|
-
KEY_K = 14
|
14
|
-
KEY_L = 15
|
15
|
-
KEY_M = 16
|
16
|
-
KEY_Q = 20
|
17
|
-
KEY_S = 22
|
18
|
-
KEY_T = 23
|
19
|
-
KEY_W = 26
|
20
|
-
KEY_RIGHT = 79
|
21
|
-
KEY_LEFT = 80
|
22
|
-
KEY_DOWN = 81
|
23
|
-
KEY_UP = 82
|
9
|
+
require_relative 'keys'
|
10
|
+
require_relative 'particles'
|
24
11
|
|
25
12
|
MENU_MAIN = 0
|
26
13
|
MENU_CONNECT = 1
|
@@ -28,13 +15,13 @@ MENU_USERNAME = 2
|
|
28
15
|
|
29
16
|
MOUSE_RADIUS = 200
|
30
17
|
|
31
|
-
$time_point=Time.now
|
32
|
-
$time_buffer=0
|
18
|
+
$time_point = Time.now
|
19
|
+
$time_buffer = 0
|
33
20
|
|
34
|
-
def
|
21
|
+
def frame_time
|
35
22
|
diff = Time.now - $time_point
|
36
23
|
$time_point = Time.now
|
37
|
-
|
24
|
+
diff
|
38
25
|
end
|
39
26
|
|
40
27
|
# Main Game getting gui form gosu
|
@@ -44,34 +31,34 @@ class Gui < Gosu::Window
|
|
44
31
|
self.caption = 'chichilku3'
|
45
32
|
self.fullscreen = true if cfg.data['fullscreen']
|
46
33
|
# images
|
47
|
-
@crosshair = Gosu::Image.new(img(
|
48
|
-
@background_image =
|
49
|
-
@connecting_image = Gosu::Image.new(img(
|
50
|
-
@menu_image = Gosu::Image.new(img(
|
51
|
-
@arrow_image = Gosu::Image.new(img(
|
34
|
+
@crosshair = Gosu::Image.new(img('crosshair128x128.png'))
|
35
|
+
@background_image = nil
|
36
|
+
@connecting_image = Gosu::Image.new(img('connecting1024x512.png'))
|
37
|
+
@menu_image = Gosu::Image.new(img('menu1920x1080.png'))
|
38
|
+
@arrow_image = Gosu::Image.new(img('arrow64.png'))
|
52
39
|
@stick_arm_images = []
|
53
|
-
@stick_arm_images << Gosu::Image.new(img(
|
54
|
-
@stick_arm_images << Gosu::Image.new(img(
|
55
|
-
@stick_arm_images << Gosu::Image.new(img(
|
56
|
-
@stick_arm_images << Gosu::Image.new(img(
|
40
|
+
@stick_arm_images << Gosu::Image.new(img('stick128/arm64/arm0.png'))
|
41
|
+
@stick_arm_images << Gosu::Image.new(img('stick128/arm64/arm1.png'))
|
42
|
+
@stick_arm_images << Gosu::Image.new(img('stick128/arm64/arm2.png'))
|
43
|
+
@stick_arm_images << Gosu::Image.new(img('stick128/arm64/arm3.png'))
|
57
44
|
@stick_crouching = []
|
58
|
-
@stick_crouching << Gosu::Image.new(img(
|
59
|
-
@stick_crouching << Gosu::Image.new(img(
|
60
|
-
@stick_crouching << Gosu::Image.new(img(
|
61
|
-
@stick_crouching << Gosu::Image.new(img(
|
62
|
-
@stick_crouching << Gosu::Image.new(img(
|
63
|
-
@stick_crouching << Gosu::Image.new(img(
|
45
|
+
@stick_crouching << Gosu::Image.new(img('stick128/stick_crouching0.png'))
|
46
|
+
@stick_crouching << Gosu::Image.new(img('stick128/stick_crouching1.png'))
|
47
|
+
@stick_crouching << Gosu::Image.new(img('stick128/stick_crouching2.png'))
|
48
|
+
@stick_crouching << Gosu::Image.new(img('stick128/stick_crouching3.png'))
|
49
|
+
@stick_crouching << Gosu::Image.new(img('stick128/stick_crouching4.png'))
|
50
|
+
@stick_crouching << Gosu::Image.new(img('stick128/stick_crouching5.png'))
|
64
51
|
@stick_images = []
|
65
|
-
@stick_images << Gosu::Image.new(img(
|
66
|
-
@stick_images << Gosu::Image.new(img(
|
67
|
-
@stick_images << Gosu::Image.new(img(
|
68
|
-
@stick_images << Gosu::Image.new(img(
|
69
|
-
@stick_images << Gosu::Image.new(img(
|
52
|
+
@stick_images << Gosu::Image.new(img('stick128/noarms/stick0.png'))
|
53
|
+
@stick_images << Gosu::Image.new(img('stick128/noarms/stick1.png'))
|
54
|
+
@stick_images << Gosu::Image.new(img('stick128/noarms/stick2.png'))
|
55
|
+
@stick_images << Gosu::Image.new(img('stick128/noarms/stick3.png'))
|
56
|
+
@stick_images << Gosu::Image.new(img('stick128/noarms/stick4.png'))
|
70
57
|
@bow_images = []
|
71
|
-
@bow_images << Gosu::Image.new(img(
|
72
|
-
@bow_images << Gosu::Image.new(img(
|
73
|
-
@bow_images << Gosu::Image.new(img(
|
74
|
-
@bow_images << Gosu::Image.new(img(
|
58
|
+
@bow_images << Gosu::Image.new(img('bow64/bow0.png'))
|
59
|
+
@bow_images << Gosu::Image.new(img('bow64/bow1.png'))
|
60
|
+
@bow_images << Gosu::Image.new(img('bow64/bow2.png'))
|
61
|
+
@bow_images << Gosu::Image.new(img('bow64/bow3.png'))
|
75
62
|
# TODO: add arms back in if no bow is in use
|
76
63
|
# @stick_images << Gosu::Image.new(img("stick128/stick0.png"))
|
77
64
|
# @stick_images << Gosu::Image.new(img("stick128/stick1.png"))
|
@@ -85,49 +72,61 @@ class Gui < Gosu::Window
|
|
85
72
|
@cfg = cfg
|
86
73
|
@tick = 0
|
87
74
|
@console = Console.new
|
88
|
-
@net_client = Client.new(@console, @cfg)
|
75
|
+
@net_client = Client.new(@console, @cfg, self)
|
76
|
+
@particles = Particles.new(@console)
|
89
77
|
@net_err = nil
|
90
78
|
@state = @net_client.state
|
91
79
|
@menu_page = MENU_MAIN
|
92
80
|
@font = Gosu::Font.new(20)
|
93
81
|
@is_debug = false
|
82
|
+
@is_dbg_grid = false
|
94
83
|
@is_chat = false
|
95
84
|
@is_scoreboard = false
|
96
|
-
@chat_msg =
|
97
|
-
@server_chat_msg =
|
85
|
+
@chat_msg = '' # what we type
|
86
|
+
@server_chat_msg = '' # what we get from server
|
98
87
|
@chat_show_time = 4
|
99
88
|
@server_chat_recv = Time.now - @chat_show_time
|
100
89
|
@last_key = nil
|
101
90
|
@events = {
|
102
|
-
:
|
91
|
+
blood: []
|
103
92
|
}
|
104
93
|
@menu_items = []
|
105
94
|
@selected_menu_item = 0
|
106
95
|
@menu_textfield = TextField.new(self, 60, 200)
|
107
|
-
@demo_ticks = [0,0]
|
96
|
+
@demo_ticks = [0, 0]
|
97
|
+
@download_progress = [0, 0]
|
108
98
|
# @chat_inp_stream = nil #TextInput.new
|
109
99
|
# @chat_inp_stream.text # didnt get it working <--- nobo xd
|
110
|
-
|
100
|
+
|
111
101
|
@last_pressed_button = {}
|
112
102
|
|
113
|
-
|
114
|
-
# @con_msg = Gosu::Image.from_text(self, "connecting to #{@cfg.data['ip']}:#{@cfg.data['port']}...", Gosu.default_font_name, 45)
|
115
|
-
init_menu()
|
103
|
+
init_menu
|
116
104
|
|
117
|
-
if ARGV.
|
118
|
-
|
119
|
-
|
120
|
-
|
105
|
+
return if ARGV.empty?
|
106
|
+
|
107
|
+
port = ARGV.length > 1 ? ARGV[1].to_i : 9900
|
108
|
+
connect(ARGV[0], port)
|
109
|
+
end
|
110
|
+
|
111
|
+
def needs_cursor?
|
112
|
+
@state != STATE_INGAME
|
121
113
|
end
|
122
114
|
|
123
115
|
def img(path)
|
124
|
-
File.join(File.dirname(__FILE__),
|
116
|
+
File.join(File.dirname(__FILE__), '../../lib/client/img/', path)
|
117
|
+
end
|
118
|
+
|
119
|
+
def load_background_image(map_path)
|
120
|
+
bg_path = File.join(map_path, 'background.png')
|
121
|
+
@console.log "loading background image '#{bg_path}' ..."
|
122
|
+
@background_image = Gosu::Image.new(bg_path)
|
125
123
|
end
|
126
124
|
|
127
125
|
def button_press?(button)
|
128
126
|
last_btn = @last_pressed_button[button]
|
129
127
|
@last_pressed_button[button] = button_down?(button)
|
130
128
|
return false if last_btn == true
|
129
|
+
|
131
130
|
button_down?(button)
|
132
131
|
end
|
133
132
|
|
@@ -144,22 +143,19 @@ class Gui < Gosu::Window
|
|
144
143
|
@is_chat = false
|
145
144
|
return @chat_msg
|
146
145
|
else
|
147
|
-
|
146
|
+
unless button_down?(@last_key)
|
148
147
|
@last_key = nil # refresh blocker
|
149
148
|
end
|
150
|
-
if button_down?(Gosu::KB_BACKSPACE)
|
151
|
-
|
152
|
-
|
153
|
-
@chat_msg = @chat_msg[0..-2]
|
154
|
-
@last_key = Gosu::KB_BACKSPACE
|
155
|
-
end
|
149
|
+
if button_down?(Gosu::KB_BACKSPACE) && (button_down?(Gosu::KB_LEFT_SHIFT) || @last_key != Gosu::KB_BACKSPACE)
|
150
|
+
@chat_msg = @chat_msg[0..-2]
|
151
|
+
@last_key = Gosu::KB_BACKSPACE
|
156
152
|
end
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
153
|
+
(4..30).each do |key| # alphabet lowercase
|
154
|
+
next unless button_down?(key)
|
155
|
+
|
156
|
+
if @last_key != key
|
157
|
+
@chat_msg += button_id_to_char(key)
|
158
|
+
@last_key = key
|
163
159
|
end
|
164
160
|
end
|
165
161
|
end
|
@@ -167,15 +163,17 @@ class Gui < Gosu::Window
|
|
167
163
|
end
|
168
164
|
|
169
165
|
def main_tick
|
170
|
-
|
171
|
-
|
166
|
+
case @state
|
167
|
+
when STATE_MENU
|
168
|
+
case @menu_page
|
169
|
+
when MENU_CONNECT
|
172
170
|
enter_ip_tick
|
173
|
-
|
171
|
+
when MENU_USERNAME
|
174
172
|
enter_name_tick
|
175
173
|
else
|
176
174
|
menu_tick
|
177
175
|
end
|
178
|
-
|
176
|
+
when STATE_ERROR
|
179
177
|
if button_down?(Gosu::KB_ESCAPE)
|
180
178
|
@state = STATE_MENU
|
181
179
|
@net_client.disconnect
|
@@ -202,14 +200,14 @@ class Gui < Gosu::Window
|
|
202
200
|
|
203
201
|
def enter_ip_tick
|
204
202
|
if button_down?(Gosu::KB_ESCAPE)
|
205
|
-
ip = @menu_textfield.text.split(
|
203
|
+
ip = @menu_textfield.text.split(':')
|
206
204
|
@cfg.data['ip'] = ip[0]
|
207
205
|
@cfg.data['port'] = ip[1] if ip.length > 1
|
208
206
|
@state = STATE_MENU
|
209
207
|
@menu_page = MENU_MAIN
|
210
208
|
elsif button_press?(Gosu::KB_RETURN)
|
211
209
|
if @last_key != Gosu::KB_RETURN
|
212
|
-
ip = @menu_textfield.text.split(
|
210
|
+
ip = @menu_textfield.text.split(':')
|
213
211
|
@cfg.data['ip'] = ip[0]
|
214
212
|
@cfg.data['port'] = ip[1] if ip.length > 1
|
215
213
|
connect(@cfg.data['ip'], @cfg.data['port'])
|
@@ -221,17 +219,17 @@ class Gui < Gosu::Window
|
|
221
219
|
|
222
220
|
def menu_tick
|
223
221
|
if button_down?(KEY_Q)
|
224
|
-
puts
|
222
|
+
puts 'quitting the game.'
|
225
223
|
@cfg.save
|
226
224
|
exit
|
227
225
|
elsif button_down?(KEY_C)
|
228
226
|
connect_menu
|
229
227
|
return
|
230
228
|
end
|
231
|
-
if button_press?(KEY_DOWN)
|
229
|
+
if button_press?(KEY_DOWN) || button_press?(KEY_S) || button_press?(KEY_J) || button_press?(Gosu::MS_WHEEL_DOWN)
|
232
230
|
@selected_menu_item += 1 if @selected_menu_item < @menu_items.length - 1
|
233
|
-
elsif button_press?(KEY_UP)
|
234
|
-
@selected_menu_item -= 1 if @selected_menu_item
|
231
|
+
elsif button_press?(KEY_UP) || button_press?(KEY_W) || button_press?(KEY_K) || button_press?(Gosu::MS_WHEEL_UP)
|
232
|
+
@selected_menu_item -= 1 if @selected_menu_item.positive?
|
235
233
|
elsif button_press?(Gosu::KB_RETURN)
|
236
234
|
@menu_items[@selected_menu_item][1].call
|
237
235
|
end
|
@@ -239,72 +237,62 @@ class Gui < Gosu::Window
|
|
239
237
|
|
240
238
|
def game_tick
|
241
239
|
if button_down?(Gosu::KB_ESCAPE)
|
242
|
-
|
240
|
+
case @state
|
241
|
+
when STATE_CONNECTING
|
243
242
|
@state = STATE_MENU
|
244
243
|
@net_client.disconnect
|
245
|
-
|
244
|
+
when STATE_INGAME
|
246
245
|
@state = STATE_MENU
|
247
246
|
@net_client.disconnect
|
248
247
|
return
|
249
|
-
|
248
|
+
when STATE_REC_PLAYBACK
|
250
249
|
@state = STATE_MENU
|
251
250
|
return
|
252
251
|
end
|
253
252
|
end
|
254
253
|
net_request = '0000'.split('')
|
255
|
-
net_request <<
|
254
|
+
net_request << '!!!!'
|
256
255
|
protocol = 2
|
257
256
|
|
258
257
|
if @is_chat
|
259
258
|
msg = chat_tick
|
260
|
-
|
259
|
+
unless msg.nil?
|
261
260
|
# @console.dbg "rawmsg: #{msg}"
|
262
|
-
msg = msg.ljust(8, '
|
261
|
+
msg = msg.ljust(8, ' ')
|
263
262
|
net_request = msg[0..CMD_LEN].split('')
|
264
263
|
# @console.dbg "prepedmsg: #{net_request}"
|
265
264
|
protocol = 4
|
266
265
|
end
|
267
266
|
else
|
268
267
|
net_request[0] = '0' # space for more
|
269
|
-
if button_down?(KEY_S)
|
270
|
-
|
271
|
-
|
272
|
-
if button_down?(
|
273
|
-
|
274
|
-
|
275
|
-
if button_down?(KEY_D)
|
276
|
-
net_request[1] = 'r'
|
277
|
-
end
|
278
|
-
if button_down?(Gosu::KB_SPACE)
|
279
|
-
net_request[2] = '1'
|
280
|
-
end
|
281
|
-
if button_press?(KEY_M)
|
282
|
-
@is_debug = !@is_debug
|
283
|
-
end
|
268
|
+
net_request[0] = '1' if button_down?(KEY_S)
|
269
|
+
net_request[1] = 'l' if button_down?(KEY_A)
|
270
|
+
net_request[1] = 'r' if button_down?(KEY_D)
|
271
|
+
net_request[2] = '1' if button_down?(Gosu::KB_SPACE)
|
272
|
+
@is_debug = !@is_debug if button_press?(KEY_M)
|
273
|
+
@is_dbg_grid = !@is_dbg_grid if button_press?(KEY_G) && @is_debug
|
284
274
|
if button_down?(KEY_T)
|
285
275
|
@last_key = KEY_T
|
286
276
|
@is_chat = true
|
287
|
-
@chat_msg =
|
288
|
-
end
|
289
|
-
if button_down?(Gosu::MsLeft)
|
290
|
-
net_request[3] = '1'
|
277
|
+
@chat_msg = ''
|
291
278
|
end
|
279
|
+
net_request[3] = '1' if button_down?(Gosu::MsLeft)
|
292
280
|
# TODO: check for active window
|
293
281
|
# do not leak mouse movement in other applications than chichilku3
|
294
|
-
net_request[4] = net_pack_bigint(
|
295
|
-
net_request[5] = net_pack_bigint(
|
282
|
+
net_request[4] = net_pack_bigint(mouse_x.to_i.clamp(0, 8834), 2)
|
283
|
+
net_request[5] = net_pack_bigint(mouse_y.to_i.clamp(0, 8834), 2)
|
296
284
|
@is_scoreboard = button_down?(Gosu::KB_TAB)
|
297
285
|
end
|
298
286
|
|
299
287
|
if @state == STATE_REC_PLAYBACK
|
300
|
-
net_data = @net_client.recording_playback_tick
|
288
|
+
net_data = @net_client.recording_playback_tick
|
301
289
|
@demo_ticks = net_data[3] unless net_data.nil?
|
302
290
|
else
|
303
291
|
# Networking
|
304
292
|
begin
|
305
293
|
net_data = @net_client.tick(net_request, protocol, @tick)
|
306
294
|
rescue Errno::ECONNRESET, Errno::EPIPE
|
307
|
-
net_data = [@players, @flags, [0, NET_ERR_DISCONNECT,
|
295
|
+
net_data = [@players, @flags, [0, NET_ERR_DISCONNECT, 'connection to server lost']]
|
308
296
|
@net_client.disconnect
|
309
297
|
end
|
310
298
|
end
|
@@ -315,26 +303,28 @@ class Gui < Gosu::Window
|
|
315
303
|
msg = net_data[2]
|
316
304
|
if msg
|
317
305
|
type = msg[0]
|
318
|
-
|
306
|
+
case type
|
307
|
+
when 0
|
319
308
|
@net_err = msg[1..-1]
|
320
309
|
@state = STATE_ERROR
|
321
|
-
|
310
|
+
when 1
|
322
311
|
@server_chat_msg = msg[1]
|
323
312
|
@server_chat_recv = Time.now
|
324
313
|
end
|
325
314
|
end
|
315
|
+
@download_progress = net_data[3] if @state == STATE_DOWNLOADING && !net_data[3].nil?
|
326
316
|
return if @flags[:skip]
|
327
317
|
|
328
318
|
@players = net_data[0]
|
329
319
|
end
|
330
320
|
|
331
321
|
def update
|
332
|
-
$time_buffer +=
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
322
|
+
$time_buffer += frame_time
|
323
|
+
return unless $time_buffer > MAX_TICK_SPEED
|
324
|
+
|
325
|
+
@tick += 1
|
326
|
+
main_tick
|
327
|
+
$time_buffer = 0
|
338
328
|
end
|
339
329
|
|
340
330
|
def draw_main_menu
|
@@ -352,17 +342,15 @@ class Gui < Gosu::Window
|
|
352
342
|
end
|
353
343
|
|
354
344
|
def event_blood(x, y)
|
345
|
+
splashes = []
|
346
|
+
20.times do
|
347
|
+
splashes << [x, y, rand(-3..2), rand(-10..-5), rand(1..6), rand(1..6)]
|
348
|
+
end
|
355
349
|
@events[:blood] << [
|
356
350
|
x,
|
357
351
|
y,
|
358
352
|
0,
|
359
|
-
|
360
|
-
[x, y, rand(12) - 6, rand(12) - 24, rand(3..12), rand(3..12)],
|
361
|
-
[x, y, rand(12) - 6, rand(12) - 24, rand(3..12), rand(3..12)],
|
362
|
-
[x, y, rand(12) - 6, rand(12) - 24, rand(3..12), rand(3..12)],
|
363
|
-
[x, y, rand(12) - 6, rand(12) - 24, rand(3..12), rand(3..12)],
|
364
|
-
[x, y, rand(12) - 6, rand(12) - 24, rand(3..12), rand(3..12)]
|
365
|
-
]
|
353
|
+
splashes
|
366
354
|
]
|
367
355
|
end
|
368
356
|
|
@@ -387,41 +375,62 @@ class Gui < Gosu::Window
|
|
387
375
|
draw_rect(sx, sy, sw, sh, 0xAAFF0000)
|
388
376
|
new_splashes << [sx, sy, dx, dy, sw, sh]
|
389
377
|
end
|
390
|
-
unless tick > 200
|
391
|
-
bloods << [x, y, tick + 1, new_splashes]
|
392
|
-
end
|
378
|
+
bloods << [x, y, tick + 1, new_splashes] unless tick > 200
|
393
379
|
end
|
394
380
|
@events[:blood] = bloods
|
395
381
|
end
|
396
382
|
|
397
|
-
def draw_debug(x, y, s=1)
|
383
|
+
def draw_debug(x, y, s = 1)
|
398
384
|
return unless @is_debug
|
399
385
|
|
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)
|
386
|
+
draw_rect(x, y, 4 * s, 4 * s, 0xFFFF0000, 1)
|
387
|
+
draw_rect(x + 1 * s, y + 1 * s, 2 * s, 2 * s, 0xFF00FF00, 1)
|
388
|
+
end
|
389
|
+
|
390
|
+
def draw_debug_gametiles
|
391
|
+
return unless @net_client.game_map&.ready
|
392
|
+
|
393
|
+
(0..(MAP_HEIGHT - 1)).each do |gy|
|
394
|
+
(0..(MAP_WIDTH - 1)).each do |gx|
|
395
|
+
if @net_client.game_map.collision?(gx, gy)
|
396
|
+
draw_rect(gx * TILE_SIZE, gy * TILE_SIZE, TILE_SIZE, TILE_SIZE, 0xAA00EE00)
|
397
|
+
elsif @net_client.game_map.death?(gx, gy)
|
398
|
+
draw_rect(gx * TILE_SIZE, gy * TILE_SIZE, TILE_SIZE, TILE_SIZE, 0xAAEE0000)
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
402
|
end
|
403
403
|
|
404
404
|
def draw
|
405
|
-
|
406
|
-
|
407
|
-
|
405
|
+
case @state
|
406
|
+
when STATE_MENU
|
407
|
+
case @menu_page
|
408
|
+
when MENU_CONNECT
|
408
409
|
@connecting_image.draw(0, 0, 0)
|
409
|
-
@font.draw_text(
|
410
|
+
@font.draw_text('Enter server ip', 20, 20, 0, 5, 5)
|
410
411
|
@menu_textfield.draw(0)
|
411
|
-
|
412
|
+
when MENU_USERNAME
|
412
413
|
@connecting_image.draw(0, 0, 0)
|
413
|
-
@font.draw_text(
|
414
|
+
@font.draw_text('Choose a username', 20, 20, 0, 5, 5)
|
414
415
|
@menu_textfield.draw(0)
|
415
416
|
else
|
416
|
-
draw_main_menu
|
417
|
+
draw_main_menu
|
417
418
|
end
|
418
|
-
|
419
|
+
when STATE_CONNECTING
|
419
420
|
@connecting_image.draw(0, 0, 0)
|
420
421
|
@font.draw_text("connecting to #{@cfg.data['ip']}:#{@cfg.data['port']}...", 20, 20, 0, 3, 3)
|
421
|
-
|
422
|
-
|
423
|
-
@
|
424
|
-
|
422
|
+
when STATE_DOWNLOADING
|
423
|
+
@connecting_image.draw(0, 0, 0)
|
424
|
+
@font.draw_text("downloading map #{@download_progress[0]} / #{@download_progress[1]} ...", 20, 20, 0, 3, 3)
|
425
|
+
when STATE_INGAME, STATE_REC_PLAYBACK
|
426
|
+
# TODO: remove this dirty nil check
|
427
|
+
# this is used for demo recordings
|
428
|
+
# there seems to be some sort of race coniditon when repaying and already rendering
|
429
|
+
# before the map packet was parsed
|
430
|
+
# just render black background for a few ticks
|
431
|
+
# but what should be done is adding a loading state for demos
|
432
|
+
@background_image&.draw(0, 0, 0)
|
433
|
+
@crosshair.draw(mouse_x - 16, mouse_y - 16, 0, 0.25, 0.25)
|
425
434
|
# useless mouse trap
|
426
435
|
# since its buggo and your character moves maybe keep it free
|
427
436
|
# mouse players should go fullscreen
|
@@ -430,27 +439,27 @@ class Gui < Gosu::Window
|
|
430
439
|
# self.mouse_y = (WINDOW_SIZE_Y / 2) + MOUSE_RADIUS - 1 if self.mouse_y > (WINDOW_SIZE_Y / 2) + MOUSE_RADIUS
|
431
440
|
# self.mouse_y = (WINDOW_SIZE_Y / 2) - MOUSE_RADIUS + 1 if self.mouse_y < (WINDOW_SIZE_Y / 2) - MOUSE_RADIUS
|
432
441
|
@players.each do |player|
|
433
|
-
event_blood(player.x, player.y) if player.state[:bleeding]
|
442
|
+
event_blood(player.x + (player.w / 2), player.y + (player.h / 2)) if player.state[:bleeding]
|
434
443
|
player.draw_tick
|
435
444
|
@console.dbg "drawing player id=#{player.id} pos=#{player.x}/#{player.y}"
|
436
445
|
# draw_rect(player.x, player.y, TILE_SIZE, TILE_SIZE, Gosu::Color::WHITE)
|
437
|
-
if player.
|
446
|
+
if player.crouching?
|
438
447
|
@stick_crouching[player.img_index].draw(player.x, player.y, 0, 0.5, 0.5)
|
439
448
|
else
|
440
449
|
@stick_images[player.img_index].draw(player.x, player.y, 0, 0.5, 0.5)
|
441
|
-
x = player.
|
442
|
-
y = player.
|
450
|
+
x = player.aim_x - player.x
|
451
|
+
y = player.aim_y - player.y
|
443
452
|
rot = Math.atan2(x, y) * 180 / Math::PI * -1 + 90 * -1
|
444
453
|
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
|
454
|
+
stick_center_x = player.x + TILE_SIZE / 4
|
455
|
+
stick_center_y = player.y + TILE_SIZE / 2
|
447
456
|
d = -8
|
448
457
|
d += player.state[:fire] * 3
|
449
458
|
arr_x = stick_center_x + (d * Math.cos((rot2 + 180) / 180 * Math::PI))
|
450
459
|
arr_y = stick_center_y + (d * Math.sin((rot2 + 180) / 180 * Math::PI))
|
451
460
|
@bow_images[player.state[:fire]].draw_rot(stick_center_x, stick_center_y, 0, rot, 0.5, 0.5, 0.5, 0.5)
|
452
461
|
@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
|
462
|
+
if player.projectile.x.zero? && player.projectile.y.zero?
|
454
463
|
@arrow_image.draw_rot(arr_x, arr_y, 0, rot2, 0.5, 0.5, 0.5, 0.5)
|
455
464
|
end
|
456
465
|
if @is_debug
|
@@ -458,39 +467,44 @@ class Gui < Gosu::Window
|
|
458
467
|
draw_debug(stick_center_x, stick_center_y, 1)
|
459
468
|
draw_line(arr_x, arr_y, 0xFFFF0000, stick_center_x, stick_center_y, 0xFF000000)
|
460
469
|
@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})",
|
470
|
+
@font.draw_text("d=#{d} (#{stick_center_x}/#{stick_center_y}) -> (#{arr_x.to_i}/#{arr_y.to_i})",
|
471
|
+
player.x - 80, player.y - 80, 0, 1, 1, 0xFF000000)
|
462
472
|
end
|
463
473
|
end
|
464
|
-
unless player.projectile.x
|
474
|
+
unless player.projectile.x.zero? || player.projectile.y.zero?
|
465
475
|
rot = player.projectile.r.to_i * 45
|
466
476
|
@arrow_image.draw_rot(player.projectile.x, player.projectile.y, 0, rot, 0.5, 0.5, 0.5, 0.5)
|
467
477
|
end
|
468
478
|
if @is_debug # print id
|
469
479
|
# aim
|
470
|
-
draw_rect(player.
|
471
|
-
draw_rect(player.
|
472
|
-
draw_rect(player.
|
473
|
-
draw_rect(player.
|
480
|
+
draw_rect(player.aim_x - 2, player.aim_y - 16, 4, 32, 0xCC33FF33)
|
481
|
+
draw_rect(player.aim_x - 16, player.aim_y - 2, 32, 4, 0xCC33FF33)
|
482
|
+
draw_rect(player.aim_x, player.aim_y - 15, 1, 30, 0xAA000000)
|
483
|
+
draw_rect(player.aim_x - 15, player.aim_y, 30, 1, 0xAA000000)
|
474
484
|
# text background
|
475
485
|
draw_rect(player.x - 2, player.y - 60, 32, 20, 0xAA000000)
|
476
486
|
@font.draw_text("#{player.id}:#{player.score}", player.x, player.y - 60, 0, 1, 1)
|
477
487
|
# @font.draw_text("#{player.id}:#{player.img_index}", player.x, player.y - TILE_SIZE * 2, 0, 1, 1)
|
478
|
-
if player.
|
479
|
-
draw_rect(player.x, player.y,
|
488
|
+
if player.crouching?
|
489
|
+
draw_rect(player.x, player.y, PLAYER_SIZE, PLAYER_SIZE / 2, 0xAA00EE00)
|
480
490
|
else
|
481
|
-
draw_rect(player.x, player.y,
|
491
|
+
draw_rect(player.x, player.y, PLAYER_SIZE / 2, PLAYER_SIZE, 0xAA00EE00)
|
482
492
|
end
|
483
|
-
unless player.projectile.x
|
493
|
+
unless player.projectile.x.zero? || player.projectile.y.zero?
|
484
494
|
draw_rect(player.projectile.x, player.projectile.y, player.projectile.w, player.projectile.h, 0xAA00EE00)
|
485
495
|
end
|
486
496
|
end
|
487
|
-
|
497
|
+
next unless @net_client.game_map&.ready
|
498
|
+
|
499
|
+
unless @net_client.game_map.grass?(player.x / TILE_SIZE, player.y / TILE_SIZE)
|
500
|
+
@font.draw_text(player.name, player.x - (TILE_SIZE / 6), player.y - TILE_SIZE / 2, 0, 1, 1, 0xff_000000)
|
501
|
+
end
|
488
502
|
end
|
489
503
|
|
504
|
+
@particles.draw(@net_client.game_map, @players) if @net_client.game_map&.ready
|
505
|
+
|
490
506
|
# chat input
|
491
|
-
if @is_chat
|
492
|
-
@font.draw_text("> #{@chat_msg}", 10, WINDOW_SIZE_Y - 30, 0, 1, 1)
|
493
|
-
end
|
507
|
+
@font.draw_text("> #{@chat_msg}", 10, WINDOW_SIZE_Y - 30, 0, 1, 1) if @is_chat
|
494
508
|
|
495
509
|
# chat output
|
496
510
|
if @server_chat_recv + @chat_show_time > Time.now
|
@@ -501,36 +515,44 @@ class Gui < Gosu::Window
|
|
501
515
|
player = Player.get_player_by_id(@players, @flags[:id])
|
502
516
|
unless player.nil?
|
503
517
|
draw_rect(5, 10, 290, 85, 0xAA000000)
|
504
|
-
@font.draw_text(
|
518
|
+
@font.draw_text('Press m to deactivate debug mode', 10, 10, 0, 1, 1)
|
505
519
|
@font.draw_text("x: #{player.x} y: #{player.y}", 10, 30, 0, 1, 1)
|
506
|
-
@font.draw_text("
|
507
|
-
@font.draw_text("gamestate: #{@flags[:gamestate]}", 10, 60, 0
|
508
|
-
@font.draw_text("server version: #{@net_client.server_version}", 10, 75, 0
|
520
|
+
@font.draw_text("aim_x: #{player.aim_x} aim_y: #{player.aim_y}", 10, 45, 0, 1, 1)
|
521
|
+
@font.draw_text("gamestate: #{@flags[:gamestate]}", 10, 60, 0, 1, 1)
|
522
|
+
@font.draw_text("server version: #{@net_client.server_version}", 10, 75, 0, 1, 1)
|
509
523
|
# thats useless because collide/delta speed is not sent over the network
|
510
524
|
# @font.draw_text("dx: #{player.dx} dy: #{player.dy}", 10, 50, 0, 1, 1)
|
511
525
|
# @font.draw_text(player.collide_string, 10, 70, 0, 1, 1)
|
512
526
|
end
|
527
|
+
|
528
|
+
if @is_dbg_grid
|
529
|
+
(1..MAP_WIDTH).each do |gx|
|
530
|
+
draw_rect(gx * TILE_SIZE, 0, 1, WINDOW_SIZE_Y, 0xAA00EE00)
|
531
|
+
end
|
532
|
+
(1..MAP_HEIGHT).each do |gy|
|
533
|
+
draw_rect(0, gy * TILE_SIZE, WINDOW_SIZE_X, 1, 0xAA00EE00)
|
534
|
+
end
|
535
|
+
draw_debug_gametiles
|
536
|
+
end
|
513
537
|
end
|
514
538
|
|
515
|
-
draw_events
|
539
|
+
draw_events
|
516
540
|
|
517
|
-
if @is_scoreboard
|
518
|
-
|
519
|
-
end
|
520
|
-
if @state == STATE_REC_PLAYBACK && !(@demo_ticks.nil?)
|
541
|
+
draw_scoreboard(WINDOW_SIZE_X, WINDOW_SIZE_Y, @players, @font, @is_debug) if @is_scoreboard
|
542
|
+
if @state == STATE_REC_PLAYBACK && !@demo_ticks.nil?
|
521
543
|
@font.draw_text("#{@demo_ticks[0]}/#{@demo_ticks[1]}", 10, WINDOW_SIZE_Y - 20, 0)
|
522
544
|
end
|
523
|
-
|
545
|
+
when STATE_ERROR
|
524
546
|
net_err_code = @net_err[0]
|
525
547
|
net_err_msg = @net_err[1]
|
526
548
|
@connecting_image.draw(0, 0, 0)
|
527
|
-
if
|
549
|
+
if [NET_ERR_SERVER_OUTDATED, NET_ERR_CLIENT_OUTDATED].include?(net_err_code)
|
528
550
|
server_version = net_err_msg[0..4]
|
529
551
|
net_err_msg = net_err_msg[5..-1]
|
530
552
|
@font.draw_text("Server version: #{server_version} Your version: #{GAME_VERSION}", 50, 150, 0, 2, 2)
|
531
553
|
end
|
532
|
-
@font.draw_text(
|
533
|
-
@font.draw_text(
|
554
|
+
@font.draw_text((NET_ERR[net_err_code]).to_s, 50, 30, 0, 5, 5)
|
555
|
+
@font.draw_text(net_err_msg.to_s, 50, 200, 0, 2, 2)
|
534
556
|
else
|
535
557
|
@connecting_image.draw(0, 0, 0)
|
536
558
|
@font.draw_text('UNKOWN CLIENT STATE!!!', 20, 20, 0, 2, 10)
|
@@ -543,17 +565,17 @@ class Gui < Gosu::Window
|
|
543
565
|
@console.log "connecting to server '#{ip}:#{port}' ..."
|
544
566
|
begin
|
545
567
|
@net_client.connect(ip, port)
|
546
|
-
@state = STATE_CONNECTING
|
568
|
+
@state = STATE_CONNECTING
|
547
569
|
@menu_page = MENU_MAIN
|
548
570
|
rescue Errno::ECONNREFUSED
|
549
571
|
@state = STATE_ERROR
|
550
572
|
@menu_page = MENU_MAIN
|
551
|
-
@net_err = [NET_ERR_DISCONNECT,
|
573
|
+
@net_err = [NET_ERR_DISCONNECT, 'connection refused']
|
552
574
|
@net_client.disconnect
|
553
575
|
end
|
554
576
|
end
|
555
577
|
|
556
|
-
def connect_menu
|
578
|
+
def connect_menu
|
557
579
|
@last_key = Gosu::KB_RETURN
|
558
580
|
self.text_input = @menu_textfield
|
559
581
|
@menu_textfield.text = "#{@cfg.data['ip']}:#{@cfg.data['port']}"
|
@@ -561,34 +583,34 @@ class Gui < Gosu::Window
|
|
561
583
|
@menu_page = MENU_CONNECT
|
562
584
|
end
|
563
585
|
|
564
|
-
def username_page
|
586
|
+
def username_page
|
565
587
|
@last_key = Gosu::KB_RETURN
|
566
588
|
self.text_input = @menu_textfield
|
567
|
-
@menu_textfield.text =
|
589
|
+
@menu_textfield.text = @cfg.data['username'].to_s
|
568
590
|
@state = STATE_MENU
|
569
591
|
@menu_page = MENU_USERNAME
|
570
592
|
end
|
571
593
|
|
572
|
-
def toggle_fullscreen
|
573
|
-
if @cfg.data['fullscreen']
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
594
|
+
def toggle_fullscreen
|
595
|
+
@cfg.data['fullscreen'] = self.fullscreen = if @cfg.data['fullscreen']
|
596
|
+
false
|
597
|
+
else
|
598
|
+
true
|
599
|
+
end
|
578
600
|
end
|
579
601
|
|
580
|
-
def play_recording
|
602
|
+
def play_recording
|
581
603
|
@net_client.load_recording('autorec.txt')
|
582
604
|
@state = STATE_REC_PLAYBACK
|
583
605
|
end
|
584
606
|
|
585
|
-
def init_menu
|
607
|
+
def init_menu
|
586
608
|
@menu_items = []
|
587
|
-
add_menu_item(
|
588
|
-
add_menu_item(
|
589
|
-
add_menu_item(
|
590
|
-
add_menu_item(
|
591
|
-
add_menu_item(
|
609
|
+
add_menu_item('[c]onnect', proc { connect_menu })
|
610
|
+
add_menu_item('username', proc { username_page })
|
611
|
+
add_menu_item('fullscreen', proc { toggle_fullscreen })
|
612
|
+
add_menu_item('recording', proc { play_recording })
|
613
|
+
add_menu_item('[q]uit', proc { exit })
|
592
614
|
end
|
593
615
|
|
594
616
|
def add_menu_item(name, callback)
|