chichilku3 14.0.4 → 15.0.0

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.
data/lib/share/network.rb CHANGED
@@ -1,22 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'socket'
2
4
  # check doc_network.rb for documentation
3
5
 
4
6
  # update GAME_VERSION on network protocol changes
5
- GAME_VERSION = '0014'
7
+ GAME_VERSION = '0015'
6
8
 
7
9
  # game
8
10
 
9
11
  TILE_SIZE = 64
10
- WINDOW_SIZE_X = TILE_SIZE * 16
11
- WINDOW_SIZE_Y = TILE_SIZE * 9
12
+ PLAYER_SIZE = TILE_SIZE - 2
13
+ MAP_WIDTH = 16
14
+ MAP_HEIGHT = 9
15
+ WINDOW_SIZE_X = TILE_SIZE * MAP_WIDTH
16
+ WINDOW_SIZE_Y = TILE_SIZE * MAP_HEIGHT
12
17
  FULLHD_X = 1920
13
- UI_SCALE = WINDOW_SIZE_X.to_f / FULLHD_X.to_f
18
+ UI_SCALE = WINDOW_SIZE_X.to_f / FULLHD_X
14
19
  SPEED = TILE_SIZE
15
20
 
16
21
  # networking
17
22
 
18
23
  CMD_LEN = 7
19
24
  NAME_LEN = 9
25
+ MAX_MAPNAME_LEN = 43
20
26
  MAX_CLIENTS = 12
21
27
  PLAYER_PACKAGE_LEN = 16
22
28
  CLIENT_PACKAGE_LEN = 11 # used by server
@@ -24,40 +30,41 @@ SERVER_PACKAGE_LEN = MAX_CLIENTS * PLAYER_PACKAGE_LEN + 4 # used by client
24
30
 
25
31
  MAX_TIMEOUT = 5
26
32
  MAX_TICK_SPEED = 0.01 # the lower the faster client and server tick
33
+ # MAX_TICK_SPEED = 0.07
27
34
  # MAX_TICK_SPEED = 0.005
28
35
 
29
- NET_ERR_FULL = "404"
30
- NET_ERR_DISCONNECT = "001"
31
- NET_ERR_KICK = "002"
32
- NET_ERR_BAN = "003"
33
- NET_ERR_SERVER_OUTDATED = "004"
34
- NET_ERR_CLIENT_OUTDATED = "005"
36
+ NET_ERR_FULL = '404'
37
+ NET_ERR_DISCONNECT = '001'
38
+ NET_ERR_KICK = '002'
39
+ NET_ERR_BAN = '003'
40
+ NET_ERR_SERVER_OUTDATED = '004'
41
+ NET_ERR_CLIENT_OUTDATED = '005'
35
42
 
36
43
  NET_ERR = {
37
- "404" => "SERVER FULL",
38
- "001" => "DISCONNECTED",
39
- "002" => "KICKED",
40
- "003" => "BANNED",
41
- "004" => "SERVER OUTDATED",
42
- "005" => "CLIENT OUTDATED"
43
- }
44
+ '404' => 'SERVER FULL',
45
+ '001' => 'DISCONNECTED',
46
+ '002' => 'KICKED',
47
+ '003' => 'BANNED',
48
+ '004' => 'SERVER OUTDATED',
49
+ '005' => 'CLIENT OUTDATED'
50
+ }.freeze
44
51
 
45
52
  CLIENT_PCK_TYPE = {
46
- :error => "0",
47
- :join => "1",
48
- :move => "2",
49
- :info => "3",
50
- :cmd => "4"
51
- }
53
+ error: '0',
54
+ join: '1',
55
+ move: '2',
56
+ info: '3',
57
+ cmd: '4'
58
+ }.freeze
52
59
 
53
60
  SERVER_PCK_TYPE = {
54
- :error => "0",
55
- :update => "1",
61
+ error: '0',
62
+ update: '1',
56
63
  # TODO: find a good name here
57
- :info => "3",
58
- :cmd => "4",
59
- :event => "5"
60
- }
64
+ info: '3',
65
+ cmd: '4',
66
+ event: '5'
67
+ }.freeze
61
68
 
62
69
  NET_INT_OFFSET = 33
63
70
  NET_INT_BASE = 93
@@ -70,13 +77,13 @@ NET_MIN_INT = 0
70
77
  # the base of the network is NET_INT_BASE
71
78
  # so the number 93 is the last single character number represented as '~'
72
79
  #
73
- # @param [Integer, #chr] int decimal based number
80
+ # @param [Integer, #chr] int decimal based number
74
81
  # @return [String] the int converted to base NET_INT_BASE
75
82
 
76
83
  def net_pack_int(int)
77
84
  net_error "#{__method__}: '#{int}' is too low allowed range #{NET_MIN_INT}-#{NET_MAX_INT}" if int < NET_MIN_INT
78
85
  net_error "#{__method__}: '#{int}' is too high allowed range #{NET_MIN_INT}-#{NET_MAX_INT}" if int > NET_MAX_INT
79
- int = int + NET_INT_OFFSET
86
+ int += NET_INT_OFFSET
80
87
  int.chr
81
88
  end
82
89
 
@@ -101,17 +108,18 @@ end
101
108
  # @return [String] the int converted to base NET_INT_BASE
102
109
 
103
110
  def net_pack_bigint(int, size)
104
- sum = ""
111
+ sum = ''
105
112
  div = size - 1
106
113
  (size - 1).times do
107
- buf = int / ((NET_MAX_INT+1) ** div)
114
+ buf = int / ((NET_MAX_INT + 1)**div)
108
115
  sum += net_pack_int(buf)
109
- int = int % ((NET_MAX_INT+1) ** div)
116
+ int = int % ((NET_MAX_INT + 1)**div)
117
+ div -= 1
110
118
  end
111
119
  sum += net_pack_int(int)
112
120
  # TODO: check reminder and so on
113
121
  # throw and error when int is too big for size
114
- int = int / NET_MAX_INT
122
+ int /= NET_MAX_INT
115
123
  sum
116
124
  end
117
125
 
@@ -127,21 +135,18 @@ def net_unpack_bigint(net_int)
127
135
  if i.zero?
128
136
  sum = net_unpack_int(c)
129
137
  else
130
- sum += net_unpack_int(c) * i * (NET_MAX_INT+1)
138
+ sum += net_unpack_int(c) * (NET_MAX_INT + 1)**i
131
139
  end
132
140
  end
133
141
  sum
134
142
  end
135
143
 
136
144
  def save_read(socket, size)
137
- begin
138
- return socket.read_nonblock(size)
139
- rescue IO::WaitReadable
140
- return ''
141
- end
145
+ socket.read_nonblock(size)
146
+ rescue IO::WaitReadable
147
+ ''
142
148
  end
143
149
 
144
150
  def net_error(err)
145
151
  raise "NetError: #{err}"
146
- exit 1
147
152
  end
data/lib/share/player.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Player used by Client and Server
2
4
  require_relative 'console'
3
5
  require_relative 'network'
@@ -6,26 +8,29 @@ require_relative 'projectile'
6
8
  SPAWN_X = 512
7
9
  SPAWN_Y = 100
8
10
 
11
+ # Player objects represent stick figures
9
12
  class Player
10
- attr_accessor :x, :y, :dy, :dx, :id, :name, :score, :state, :dead, :dead_ticks, :was_crouching
11
- attr_accessor :aimX, :aimY, :projectile, :fire_ticks
13
+ attr_accessor :x, :y, :dy, :dx, :id, :name, :score, :state, :dead, :dead_ticks,
14
+ :was_crouching, :wants_crouch, :aim_x, :aim_y,
15
+ :projectile, :fire_ticks, :map_download
12
16
  attr_reader :collide, :collide_str, :img_index, :version, :w, :h
13
17
 
14
18
  def initialize(id, score, x = nil, y = nil, name = 'def', version = nil, ip = nil)
15
19
  @id = id
16
20
  @x = x.nil? ? SPAWN_X : x
17
21
  @y = y.nil? ? SPAWN_Y : y
18
- @w = TILE_SIZE / 2
19
- @h = TILE_SIZE
20
- @aimX = 0
21
- @aimY = 0
22
+ @w = PLAYER_SIZE / 2
23
+ @h = PLAYER_SIZE
24
+ @aim_x = 0
25
+ @aim_y = 0
22
26
  @projectile = Projectile.new
23
27
  @dx = 0
24
28
  @dy = 0
25
29
  @health = 3
26
- @collide = {up: false, down: false, right: false, left: false}
27
- @state = {bleeding: false, crouching: false, fire: 0}
30
+ @collide = { up: false, down: false, right: false, left: false }
31
+ @state = { bleeding: false, crouching: false, fire: 0 }
28
32
  @was_crouching = false
33
+ @wants_crouch = false
29
34
  @name = name
30
35
  @score = score
31
36
  @dead = false # only used by server for now
@@ -41,6 +46,7 @@ class Player
41
46
  @not_changed_y = 0
42
47
 
43
48
  # used by server
49
+ @map_download = -2
44
50
  @version = version
45
51
  @ip = ip
46
52
  end
@@ -56,9 +62,8 @@ class Player
56
62
 
57
63
  def update_img
58
64
  return if @tick % 5 != 0
59
- if @x != @last_x
60
- new_x = true
61
- end
65
+
66
+ new_x = true if @x != @last_x
62
67
  if @y != @last_y
63
68
  new_y = true
64
69
  @not_changed_y = 0
@@ -90,13 +95,13 @@ class Player
90
95
  players.find { |player| id == player.id }
91
96
  end
92
97
 
93
- def self.update_player(players, id, x, y, score, aimX, aimY)
98
+ def self.update_player(players, id, x, y, score, aim_x, aim_y)
94
99
  player = get_player_by_id(players, id)
95
100
  player.x = x
96
101
  player.y = y
97
102
  player.score = score
98
- player.aimX = aimX
99
- player.aimY = aimY
103
+ player.aim_x = aim_x
104
+ player.aim_y = aim_y
100
105
  player
101
106
  end
102
107
 
@@ -104,42 +109,53 @@ class Player
104
109
  # server only #
105
110
  ###############
106
111
 
107
- def set_name(name)
108
- @name = name
109
- end
110
-
111
112
  def tick
112
113
  move_x(@dx)
113
114
  move_y(@dy)
114
115
  @dx = normalize_zero(@dx)
115
- @dy = normalize_zero(@dy)
116
- check_out_of_world
117
- if @bleed_ticks > 0
118
- @bleed_ticks -= 1
119
- self.state[:bleeding] = @bleed_ticks.zero? == false
120
- end
116
+ # @dy = normalize_zero(@dy)
117
+ check_out_of_game_map
118
+ return unless @bleed_ticks.positive?
119
+
120
+ @bleed_ticks -= 1
121
+ state[:bleeding] = @bleed_ticks.zero? == false
122
+ end
123
+
124
+ def crouch!
125
+ @state[:crouching] = true
126
+ @w = PLAYER_SIZE
127
+ @h = PLAYER_SIZE / 2
128
+ end
129
+
130
+ def stop_crouch!
131
+ @state[:crouching] = false
132
+ @w = PLAYER_SIZE / 2
133
+ @h = PLAYER_SIZE
134
+ end
135
+
136
+ def crouching?
137
+ @state[:crouching]
121
138
  end
122
139
 
123
140
  def check_player_collide(other)
124
141
  # $console.log "x: #{@x} y: #{@y} ox: #{other.x} oy: #{other.y}"
125
142
  # x crash is more rare so make it the outer condition
126
- if other.x + other.w > @x && other.x < @x + @w
127
- if other.y + other.h > @y && other.y < @y + @h
128
- # $console.log "collide!"
129
- return @x < other.x ? -7 : 7
130
- end
143
+ if other.x + other.w > @x && other.x < @x + @w && (other.y + other.h > @y && other.y < @y + @h)
144
+ # $console.log "collide!"
145
+ return @x < other.x ? -7 : 7
131
146
  end
132
- return 0
147
+
148
+ 0
133
149
  end
134
150
 
135
151
  def damage(attacker)
136
152
  @bleed_ticks = 3
137
153
  @health -= 1
138
- $console.log "player='#{attacker.name}' damaged player='#{@name}'"
154
+ $console.log "'#{attacker.id}:#{attacker.name}' damaged '#{@id}:#{@name}'"
139
155
  die(attacker) if @health <= 0
140
156
  end
141
157
 
142
- # def check_out_of_world #die
158
+ # def check_out_of_game_map #die
143
159
  # # y
144
160
  # if @y < 0
145
161
  # die
@@ -153,15 +169,16 @@ class Player
153
169
  # die
154
170
  # end
155
171
  # end
156
- def check_out_of_world # swap size
172
+ # swap size
173
+ def check_out_of_game_map
157
174
  # y
158
- if @y < 0
175
+ if @y.negative?
159
176
  die
160
- elsif @y > WINDOW_SIZE_Y
177
+ elsif @y >= WINDOW_SIZE_Y - TILE_SIZE
161
178
  die
162
179
  end
163
180
  # x ( comment me out to add the glitch feature agian )
164
- if @x < 0
181
+ if @x.negative?
165
182
  @x = WINDOW_SIZE_X - @w - 2
166
183
  elsif @x > WINDOW_SIZE_X - @w - 1
167
184
  @x = 0
@@ -170,32 +187,76 @@ class Player
170
187
 
171
188
  def die(killer = nil)
172
189
  if killer.nil?
173
- $console.log("[death] id=#{@id} name='#{@name}'")
190
+ $console.log("player ID=#{@id} name='#{@name}' died")
174
191
  else
175
- if killer.id == self.id
176
- killer.score = (killer.score - 1).clamp(0, NET_MAX_INT)
192
+ if killer.id == id
193
+ killer.score -= 1
177
194
  else
178
195
  killer.score += 1
179
196
  end
180
- $console.log("[kill] id=#{@id} name='#{@name}' killer='#{killer.name}'")
197
+ killer.score = killer.score.clamp(0, NET_MAX_INT)
198
+ $console.log("player '#{@id}:#{@name}' was killed by '#{killer.id}:#{killer.name}'")
181
199
  end
182
200
  @x = SPAWN_X
183
201
  @y = SPAWN_Y
184
202
  @health = 3
185
203
  end
186
204
 
187
- #TODO: check for collision before update
205
+ # TODO: check for collision before update
188
206
  # if move_left or move_right set u on a collided field
189
207
  # dont update the position or slow down speed
190
208
  # idk make sure to not get stuck in walls
191
- def move_left
209
+
210
+ def check_move_left(game_map)
211
+ # left bottom
212
+ col = game_map.collision?(@x / TILE_SIZE, (@y + @h - 1) / TILE_SIZE)
213
+ if col
214
+ @x = (col[:x] + 1) * TILE_SIZE
215
+ @x += 1
216
+ do_collide(:left, true)
217
+ end
218
+
219
+ # left top
220
+ col = game_map.collision?(@x / TILE_SIZE, (@y + 1) / TILE_SIZE)
221
+ if col
222
+ @x = (col[:x] + 1) * TILE_SIZE
223
+ @x += 1
224
+ do_collide(:left, true)
225
+ end
226
+ nil
227
+ end
228
+
229
+ def check_move_right(game_map)
230
+ # right bottom
231
+ col = game_map.collision?((@x + @w) / TILE_SIZE, (@y + @h - 1) / TILE_SIZE)
232
+ if col
233
+ @x = col[:x] * TILE_SIZE
234
+ @x -= crouching? ? PLAYER_SIZE : PLAYER_SIZE / 2
235
+ @x -= 1
236
+ do_collide(:right, true)
237
+ end
238
+
239
+ # right top
240
+ col = game_map.collision?((@x + @w) / TILE_SIZE, (@y + 1) / TILE_SIZE)
241
+ if col
242
+ @x = col[:x] * TILE_SIZE
243
+ @x -= crouching? ? PLAYER_SIZE : PLAYER_SIZE / 2
244
+ @x -= 1
245
+ do_collide(:right, true)
246
+ end
247
+ nil
248
+ end
249
+
250
+ def move_left(game_map)
192
251
  # @dx = -8
193
- @x -= state[:crouching] ? 4 : 8
252
+ @x -= crouching? ? 4 : 8
253
+ check_move_left(game_map)
194
254
  end
195
255
 
196
- def move_right
256
+ def move_right(game_map)
197
257
  # @dx = 8
198
- @x += state[:crouching] ? 4 : 8
258
+ @x += crouching? ? 4 : 8
259
+ check_move_right(game_map)
199
260
  end
200
261
 
201
262
  def apply_force(x, y)
@@ -204,13 +265,13 @@ class Player
204
265
  end
205
266
 
206
267
  def do_jump
207
- return if !@collide[:down]
268
+ return unless @collide[:down]
208
269
 
209
- if @dead
210
- @dy = -5
211
- else
212
- @dy = state[:crouching] ? -20 : -30
213
- end
270
+ @dy = if @dead
271
+ -5
272
+ else
273
+ crouching? ? -15 : -20
274
+ end
214
275
  end
215
276
 
216
277
  def add_score(score = 1)
@@ -225,20 +286,20 @@ class Player
225
286
  end
226
287
 
227
288
  def do_collide(position, value)
228
- if position == :right && @dx > 0
289
+ if position == :right && @dx.positive?
229
290
  @dx = 0
230
- elsif position == :left && @dx < 0
291
+ elsif position == :left && @dx.negative?
231
292
  @dx = 0
232
- elsif position == :down && @dy > 0
293
+ elsif position == :down && @dy.positive?
233
294
  @dy = 0
234
- elsif position == :up && @dy < 0
295
+ elsif position == :up && @dy.negative?
235
296
  @dy = 0
236
297
  end
237
298
  @collide[position] = value
238
299
  end
239
300
 
240
301
  def reset_collide
241
- @collide = {up: false, down: false, right: false, left: false}
302
+ @collide = { up: false, down: false, right: false, left: false }
242
303
  end
243
304
 
244
305
  ##
@@ -249,83 +310,84 @@ class Player
249
310
  # @return [String] partial network packet
250
311
 
251
312
  def to_n_pck
252
- name = @name.ljust(NAME_LEN, '_')
313
+ name = @name.ljust(NAME_LEN, ' ')
253
314
  "#{@id.to_s(16)}#{net_pack_int(@score)}#{name}"
254
315
  end
255
316
 
256
317
  def to_s
257
- pos="#{net_pack_bigint(@x, 2)}#{net_pack_bigint(@y, 2)}"
258
- proj=@projectile.r.to_i.to_s # hack nil to "0"
259
- fake_y = @projectile.y > 0 ? @projectile.y : 0
260
- proj+="#{net_pack_bigint(@projectile.x, 2)}#{net_pack_bigint(fake_y, 2)}"
261
- aim="#{net_pack_bigint(@aimX, 2)}#{net_pack_bigint(@aimY, 2)}"
262
- "#{@id.to_s(16)}#{net_pack_int(@score)}#{state_to_net()}#{proj}#{aim}#{pos}"
318
+ pos = "#{net_pack_bigint(@x, 2)}#{net_pack_bigint(@y, 2)}"
319
+ proj = @projectile.r.to_i.to_s # HACK: nil to "0"
320
+ fake_y = @projectile.y.positive? ? @projectile.y : 0
321
+ proj += "#{net_pack_bigint(@projectile.x, 2)}#{net_pack_bigint(fake_y, 2)}"
322
+ aim = "#{net_pack_bigint(@aim_x, 2)}#{net_pack_bigint(@aim_y, 2)}"
323
+ "#{@id.to_s(16)}#{net_pack_int(@score)}#{state_to_net}#{proj}#{aim}#{pos}"
263
324
  end
264
325
 
265
326
  def state_to_net
266
- @w = TILE_SIZE / 2
267
- @h = TILE_SIZE
268
- if @state[:bleeding] && @state[:crouching]
269
- "s"
327
+ @w = PLAYER_SIZE / 2
328
+ @h = PLAYER_SIZE
329
+ if @state[:bleeding] && crouching?
330
+ 's'
270
331
  elsif @state[:bleeding] && @state[:fire] == 1
271
- "x"
332
+ 'x'
272
333
  elsif @state[:bleeding] && @state[:fire] == 2
273
- "y"
334
+ 'y'
274
335
  elsif @state[:bleeding] && @state[:fire] == 3
275
- "z"
336
+ 'z'
276
337
  elsif @state[:bleeding]
277
- "b"
278
- elsif @state[:crouching]
279
- @w = TILE_SIZE
280
- @h = TILE_SIZE / 2
281
- "c"
338
+ 'b'
339
+ elsif crouching?
340
+ @w = PLAYER_SIZE
341
+ @h = PLAYER_SIZE / 2
342
+ 'c'
282
343
  elsif @state[:fire] == 1
283
- "1"
344
+ '1'
284
345
  elsif @state[:fire] == 2
285
- "2"
346
+ '2'
286
347
  elsif @state[:fire] == 3
287
- "3"
348
+ '3'
288
349
  else
289
- "0"
350
+ '0'
290
351
  end
291
352
  end
292
353
 
293
354
  def net_to_state(net)
294
- if net == "b"
295
- @state = {bleeding: true, crouching: false, fire: 0}
296
- elsif net == "c"
297
- @state = {bleeding: false, crouching: true, fire: 0}
298
- elsif net == "s"
299
- @state = {bleeding: true, crouching: true, fire: 0}
300
- elsif net == "x"
301
- @state = {bleeding: true, crouching: false, fire: 1}
302
- elsif net == "y"
303
- @state = {bleeding: true, crouching: false, fire: 2}
304
- elsif net == "z"
305
- @state = {bleeding: true, crouching: false, fire: 3}
306
- elsif net == "1"
307
- @state = {bleeding: false, crouching: false, fire: 1}
308
- elsif net == "2"
309
- @state = {bleeding: false, crouching: false, fire: 2}
310
- elsif net == "3"
311
- @state = {bleeding: false, crouching: false, fire: 3}
312
- else
313
- @state = {bleeding: false, crouching: false, fire: 0}
314
- end
355
+ @state = case net
356
+ when 'b'
357
+ { bleeding: true, crouching: false, fire: 0 }
358
+ when 'c'
359
+ { bleeding: false, crouching: true, fire: 0 }
360
+ when 's'
361
+ { bleeding: true, crouching: true, fire: 0 }
362
+ when 'x'
363
+ { bleeding: true, crouching: false, fire: 1 }
364
+ when 'y'
365
+ { bleeding: true, crouching: false, fire: 2 }
366
+ when 'z'
367
+ { bleeding: true, crouching: false, fire: 3 }
368
+ when '1'
369
+ { bleeding: false, crouching: false, fire: 1 }
370
+ when '2'
371
+ { bleeding: false, crouching: false, fire: 2 }
372
+ when '3'
373
+ { bleeding: false, crouching: false, fire: 3 }
374
+ else
375
+ { bleeding: false, crouching: false, fire: 0 }
376
+ end
315
377
  end
316
378
 
317
379
  private
318
380
 
319
381
  def move_x(x)
320
- return if x < 0 && @collide[:left]
321
- return if x > 0 && @collide[:right]
382
+ return if x.negative? && @collide[:left]
383
+ return if x.positive? && @collide[:right]
322
384
 
323
385
  @x += x
324
386
  end
325
387
 
326
388
  def move_y(y)
327
- return if y < 0 && @collide[:up]
328
- return if y > 0 && @collide[:down]
389
+ return if y.negative? && @collide[:up]
390
+ return if y.positive? && @collide[:down]
329
391
 
330
392
  @y += y
331
393
  end
@@ -335,7 +397,8 @@ class Player
335
397
  def normalize_zero(x)
336
398
  return x if x.zero?
337
399
 
338
- return x - 1 if x > 0
400
+ return x - 1 if x.positive?
401
+
339
402
  x + 1
340
403
  end
341
404
  end