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 +4 -4
- data/client.json +2 -1
- data/lib/client/client.rb +102 -34
- data/lib/client/client_cfg.rb +1 -1
- data/lib/client/gui.rb +141 -36
- data/lib/client/img/arrow64.png +0 -0
- data/lib/client/img/bow64/bow0.png +0 -0
- data/lib/client/img/bow64/bow1.png +0 -0
- data/lib/client/img/bow64/bow2.png +0 -0
- data/lib/client/img/bow64/bow3.png +0 -0
- data/lib/client/img/crosshair128x128.png +0 -0
- 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/stick_noarms.png +0 -0
- data/lib/client/scoreboard.rb +9 -3
- data/lib/server/chichilku3_server.rb +48 -48
- data/lib/server/gamelogic.rb +30 -4
- data/lib/share/config.rb +10 -9
- data/lib/share/console.rb +7 -2
- data/lib/share/network.rb +7 -5
- data/lib/share/player.rb +75 -20
- data/lib/share/projectile.rb +115 -0
- metadata +74 -5
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/lib/client/scoreboard.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
def draw_scoreboard(win_size_x, win_size_y, players, font)
|
2
|
+
def draw_scoreboard(win_size_x, win_size_y, players, font, debug)
|
3
3
|
# TODO: do not compute those every frame
|
4
4
|
padX = win_size_x / 3
|
5
5
|
sizeX = win_size_x / 3
|
@@ -19,7 +19,13 @@ def draw_scoreboard(win_size_x, win_size_y, players, font)
|
|
19
19
|
end
|
20
20
|
players.each_with_index do | player, i |
|
21
21
|
score_offset = text_scale * 10 * player.score.to_s.length
|
22
|
-
|
23
|
-
|
22
|
+
dbg = 0
|
23
|
+
if debug
|
24
|
+
dbg += 25
|
25
|
+
score_offset += 25
|
26
|
+
font.draw_text(player.id, padX + 5, padY + (i * slot_height), 0, text_scale, text_scale, 0xFF00FF00)
|
27
|
+
end
|
28
|
+
font.draw_text(player.name, dbg + padX + 5, padY + (i * slot_height), 0, text_scale, text_scale)
|
29
|
+
font.draw_text(player.score, dbg + padX + sizeX - score_offset, padY + (i * slot_height), 0, text_scale, text_scale)
|
24
30
|
end
|
25
31
|
end
|
@@ -34,8 +34,8 @@ class ServerCore
|
|
34
34
|
def parse_client_version(data)
|
35
35
|
return if data.nil?
|
36
36
|
|
37
|
-
id = data[0].to_i
|
38
|
-
version = data[1
|
37
|
+
id = data[0].to_i(16)
|
38
|
+
version = data[1..4]
|
39
39
|
player = Player.get_player_by_id(@players, id)
|
40
40
|
if player
|
41
41
|
@console.log "name req id='#{id}' vrs='#{version}' name='#{player.name}'"
|
@@ -46,25 +46,20 @@ class ServerCore
|
|
46
46
|
player
|
47
47
|
end
|
48
48
|
|
49
|
-
def create_name_package(data)
|
49
|
+
def create_name_package(data, client)
|
50
|
+
if !client.nil? && !data.nil?
|
51
|
+
player = Player.get_player_by_id(@players, client[PLAYER_ID])
|
52
|
+
player.set_name(data)
|
53
|
+
end
|
54
|
+
|
50
55
|
# protocol 3 name prot
|
51
|
-
#
|
52
|
-
|
53
|
-
#
|
54
|
-
# |
|
55
|
-
pck = "3l#{@players.count}g"
|
56
|
-
# pck = format('3l%02d', @players.count) # old 2 digit player count
|
56
|
+
# gamestate
|
57
|
+
# |
|
58
|
+
pck = "3l#{net_pack_int(@players.count)}g"
|
57
59
|
@players.each do |p|
|
58
60
|
pck += p.to_n_pck
|
59
61
|
@console.dbg "pname='#{p.name}'"
|
60
62
|
end
|
61
|
-
unless player.nil?
|
62
|
-
if player.version.to_i < GAME_VERSION.to_i
|
63
|
-
return "0l#{NET_ERR_CLIENT_OUTDATED}#{GAME_VERSION} "
|
64
|
-
elsif player.version.to_i > GAME_VERSION.to_i
|
65
|
-
return "0l#{NET_ERR_SERVER_OUTDATED}#{GAME_VERSION} "
|
66
|
-
end
|
67
|
-
end
|
68
63
|
pck.ljust(SERVER_PACKAGE_LEN, '0')
|
69
64
|
end
|
70
65
|
|
@@ -79,67 +74,72 @@ class ServerCore
|
|
79
74
|
-1
|
80
75
|
end
|
81
76
|
|
82
|
-
def add_player(name, client, ip)
|
77
|
+
def add_player(name, version, client, ip)
|
83
78
|
@current_id = get_free_id()
|
84
79
|
return -1 if @current_id > MAX_CLIENTS || @current_id < 1
|
85
80
|
|
86
|
-
@console.log "Added player id='#{@current_id}' ip='#{ip}'"
|
87
|
-
@players << Player.new(@current_id, 0, nil, nil, name, ip)
|
81
|
+
@console.log "Added player id='#{@current_id}' version='#{version}' ip='#{ip}'"
|
82
|
+
@players << Player.new(@current_id, 0, nil, nil, name, version, ip)
|
88
83
|
client[PLAYER_ID] = @current_id
|
89
84
|
@current_id # implicit return
|
90
85
|
end
|
91
86
|
|
92
87
|
def delete_player(id)
|
93
|
-
@console.log "Deleted player id='#{id}'"
|
94
88
|
@players.delete(Player.get_player_by_id(@players, id))
|
95
89
|
end
|
96
90
|
|
97
91
|
def players_to_packet
|
98
|
-
#
|
99
|
-
|
100
|
-
packet = @players.empty? ? '0' : @players.count.to_s
|
92
|
+
# player count
|
93
|
+
packet = net_pack_int(@players.empty? ? 0 : @players.count)
|
101
94
|
packet += 'g' # gamestate
|
102
95
|
@players.each do |player|
|
103
96
|
packet += player.to_s
|
104
97
|
end
|
105
|
-
|
106
|
-
packet.ljust(SERVER_PACKAGE_LEN - 2, '0') # implicit return
|
98
|
+
packet
|
107
99
|
end
|
108
100
|
|
109
101
|
def update_pck(data, dt)
|
110
|
-
id = data[0].to_i
|
102
|
+
id = data[0].to_i(16)
|
111
103
|
@console.dbg "got player with id: #{id}"
|
112
104
|
@players = @gamelogic.handle_client_requests(data[1..-1], id, @players, dt)
|
113
105
|
nil # defaults to normal update pck
|
114
106
|
end
|
115
107
|
|
116
108
|
def id_pck(data, client, ip)
|
117
|
-
|
118
|
-
id = add_player(
|
109
|
+
player_version = data[0..3]
|
110
|
+
id = add_player("(connecting)", player_version, client, ip)
|
119
111
|
if id == -1
|
120
112
|
@console.log "'#{name}' failed to connect (server full)"
|
121
113
|
# protocol 0 (error) code=404 slot not found
|
122
114
|
return "0l#{NET_ERR_FULL} "
|
123
115
|
end
|
124
|
-
|
116
|
+
if player_version.to_i < GAME_VERSION.to_i
|
117
|
+
@console.log "IP='#{ip}' failed to connect (client too old '#{player_version}' < '#{GAME_VERSION}')"
|
118
|
+
return "0l#{NET_ERR_CLIENT_OUTDATED}#{GAME_VERSION}".ljust(SERVER_PACKAGE_LEN, ' ')
|
119
|
+
elsif player_version.to_i > GAME_VERSION.to_i
|
120
|
+
@console.log "IP='#{ip}' failed to connect (client too new '#{player_version}' < '#{GAME_VERSION}')"
|
121
|
+
return "0l#{NET_ERR_SERVER_OUTDATED}#{GAME_VERSION}".ljust(SERVER_PACKAGE_LEN, ' ')
|
122
|
+
end
|
123
|
+
@console.log "id='#{id}' ip='#{ip}' joined the game"
|
125
124
|
@global_pack = "true"
|
126
125
|
# protocol 2 (id)
|
127
|
-
|
126
|
+
"2l#{net_pack_int(@players.count)}#{net_pack_int(MAX_CLIENTS)}#{id.to_s(16)}X#{GAME_VERSION}".ljust(SERVER_PACKAGE_LEN, '0')
|
128
127
|
end
|
129
128
|
|
130
129
|
def command_package(data, client)
|
131
|
-
id = data[0..1].to_i
|
130
|
+
id = data[0..1].to_i(16)
|
132
131
|
cmd = data[1..-1]
|
133
132
|
@console.log "[chat] ID=#{id} command='#{cmd}'"
|
134
133
|
msg = "server_recived_cmd: #{cmd}"
|
135
134
|
msg = msg.ljust(SERVER_PACKAGE_LEN - 2, '0')
|
136
|
-
msg = msg[0..SERVER_PACKAGE_LEN -
|
135
|
+
msg = msg[0..SERVER_PACKAGE_LEN - CMD_LEN]
|
137
136
|
if cmd == "test"
|
138
137
|
# return "0l#{NET_ERR_DISCONNECT} SAMPLE MESSAGE "
|
139
138
|
msg = "id=#{client[PLAYER_ID]}"
|
140
139
|
end
|
141
140
|
msg = msg.ljust(SERVER_PACKAGE_LEN - 2, ' ')
|
142
|
-
msg = msg[0..SERVER_PACKAGE_LEN -
|
141
|
+
msg = msg[0..SERVER_PACKAGE_LEN - 2]
|
142
|
+
# protocol 4 (chat command)
|
143
143
|
"4l#{msg}"
|
144
144
|
end
|
145
145
|
|
@@ -149,18 +149,18 @@ class ServerCore
|
|
149
149
|
@console.log "Error pck=#{data}"
|
150
150
|
elsif protocol == 1 # id pck
|
151
151
|
return id_pck(data, client, ip)
|
152
|
+
elsif protocol == 3 # initial request names
|
153
|
+
return create_name_package(data, client)
|
152
154
|
else
|
153
155
|
# all other types require id
|
154
|
-
id = data[0].to_i
|
156
|
+
id = data[0].to_i(16)
|
155
157
|
if id != client[PLAYER_ID]
|
156
158
|
@console.log("id=#{client[PLAYER_ID]} tried to spoof id=#{id} ip=#{ip}")
|
157
|
-
disconnect_client(client, "0l#{NET_ERR_DISCONNECT}invalid player id
|
159
|
+
disconnect_client(client, "0l#{NET_ERR_DISCONNECT}invalid player id ")
|
158
160
|
return nil
|
159
161
|
end
|
160
162
|
if protocol == 2 # update pck
|
161
163
|
return update_pck(data, dt)
|
162
|
-
elsif protocol == 3 # initial request names
|
163
|
-
return create_name_package(data)
|
164
164
|
elsif protocol == 4 # command
|
165
165
|
return command_package(data, client)
|
166
166
|
else
|
@@ -178,8 +178,7 @@ class ServerCore
|
|
178
178
|
return response unless response.nil?
|
179
179
|
|
180
180
|
if (@tick % 100).zero?
|
181
|
-
|
182
|
-
return create_name_package(nil)
|
181
|
+
return create_name_package(nil, nil)
|
183
182
|
end
|
184
183
|
|
185
184
|
# some debug suff for class vars
|
@@ -212,11 +211,10 @@ class ServerCore
|
|
212
211
|
return
|
213
212
|
end
|
214
213
|
|
215
|
-
@console.dbg "recv: #{client_data}"
|
214
|
+
@console.dbg "tick recv: '#{client_data}'"
|
216
215
|
@last_alive_pck_by_client = Time.now
|
217
216
|
port, ip = Socket.unpack_sockaddr_in(cli[NET_CLIENT].getpeername)
|
218
217
|
server_response = handle_client_data(cli, client_data, ip, dt)
|
219
|
-
# server_response = '1l03011001010220020203300303'
|
220
218
|
pck_type = server_response[0]
|
221
219
|
if pck_type == SERVER_PCK_TYPE[:error]
|
222
220
|
disconnect_client(cli, server_response)
|
@@ -251,9 +249,15 @@ class ServerCore
|
|
251
249
|
loop do
|
252
250
|
diff = 0 # TODO: unused lmao traced it through the half source
|
253
251
|
t = Time.now
|
254
|
-
|
255
|
-
|
252
|
+
if $next_tick > t
|
253
|
+
sleep $next_tick - t
|
254
|
+
else
|
255
|
+
unless @tick.zero?
|
256
|
+
@console.log "[WARNING] tick took #{t - $next_tick} too long"
|
257
|
+
end
|
258
|
+
end
|
256
259
|
$next_tick = Time.now + MAX_TICK_SPEED
|
260
|
+
@tick += 1
|
257
261
|
@players = @gamelogic.tick(@players, diff)
|
258
262
|
# there is no gurantee the client will tick here
|
259
263
|
# there might be 2 gamelogic ticks and posticks
|
@@ -262,7 +266,7 @@ class ServerCore
|
|
262
266
|
@clients.each do |client|
|
263
267
|
begin
|
264
268
|
client_tick(client, diff)
|
265
|
-
rescue Errno::ECONNRESET, EOFError, IOError
|
269
|
+
rescue Errno::ECONNRESET, Errno::ENOTCONN, EOFError, IOError
|
266
270
|
disconnect_client(client)
|
267
271
|
end
|
268
272
|
end
|
@@ -280,10 +284,6 @@ class ServerCore
|
|
280
284
|
end
|
281
285
|
|
282
286
|
def net_write(data, cli)
|
283
|
-
if data.length != SERVER_PACKAGE_LEN
|
284
|
-
@console.log "ERROR pack len: #{data.length}/#{SERVER_PACKAGE_LEN} pck: #{data}"
|
285
|
-
exit
|
286
|
-
end
|
287
287
|
@console.dbg("sending: #{data}")
|
288
288
|
cli.write(data)
|
289
289
|
end
|
data/lib/server/gamelogic.rb
CHANGED
@@ -21,6 +21,7 @@ class GameLogic
|
|
21
21
|
|
22
22
|
gravity(player, dt)
|
23
23
|
player.tick
|
24
|
+
player.projectile.tick(players)
|
24
25
|
# player collsions works
|
25
26
|
# but it eats performance and delays jumping
|
26
27
|
check_collide(players, player)
|
@@ -52,18 +53,43 @@ class GameLogic
|
|
52
53
|
player.x -= TILE_SIZE / 4 unless player.was_crouching
|
53
54
|
player.was_crouching = true
|
54
55
|
end
|
55
|
-
if data[1] == '
|
56
|
+
if data[1] == 'l'
|
56
57
|
@console.dbg "player=#{id} wants to walk left"
|
57
58
|
player.move_left
|
58
59
|
end
|
59
|
-
if data[
|
60
|
+
if data[1] == 'r'
|
60
61
|
@console.dbg "player=#{id} wants to walk right"
|
61
62
|
player.move_right
|
62
63
|
end
|
63
|
-
if data[
|
64
|
+
if data[2] == '1'
|
64
65
|
@console.dbg "player=#{id} wants to jump"
|
65
66
|
player.do_jump
|
66
67
|
end
|
68
|
+
if data[3] == '1' && player.state[:crouching] == false
|
69
|
+
@console.dbg "player=#{id} wants to fire"
|
70
|
+
player.fire_ticks += 1
|
71
|
+
if player.fire_ticks > 29
|
72
|
+
player.state[:fire] = 3
|
73
|
+
elsif player.fire_ticks > 19
|
74
|
+
player.state[:fire] = 2
|
75
|
+
elsif player.fire_ticks > 9
|
76
|
+
player.state[:fire] = 1
|
77
|
+
end
|
78
|
+
else
|
79
|
+
if player.fire_ticks > 0
|
80
|
+
dx = (player.aimX - player.x).clamp(-200, 200) / 20
|
81
|
+
dy = (player.aimY - player.y).clamp(-200, 200) / 20
|
82
|
+
dx *= (player.fire_ticks / 10).clamp(1, 3)
|
83
|
+
dy *= (player.fire_ticks / 10).clamp(1, 3)
|
84
|
+
player.projectile.fire(player.x + TILE_SIZE/4, player.y + TILE_SIZE/2, dx, dy, player)
|
85
|
+
end
|
86
|
+
player.fire_ticks = 0
|
87
|
+
player.state[:fire] = 0
|
88
|
+
end
|
89
|
+
player.aimX = net_unpack_bigint(data[4..5])
|
90
|
+
player.aimY = net_unpack_bigint(data[6..7])
|
91
|
+
# player.projectile.x = player.aimX + 20
|
92
|
+
# player.projectile.y = player.aimY + 20
|
67
93
|
|
68
94
|
player.check_out_of_world
|
69
95
|
|
@@ -92,7 +118,7 @@ class GameLogic
|
|
92
118
|
player.die
|
93
119
|
end
|
94
120
|
else
|
95
|
-
if player.y >
|
121
|
+
if player.y + player.h > 384 # too far down --> die
|
96
122
|
player.dead = true
|
97
123
|
player.dead_ticks = 0
|
98
124
|
end
|
data/lib/share/config.rb
CHANGED
@@ -4,24 +4,25 @@ require 'fileutils'
|
|
4
4
|
|
5
5
|
# chichilku3 config base used by client and server
|
6
6
|
class Config
|
7
|
-
attr_reader :data
|
7
|
+
attr_reader :data, :chichilku3_dir
|
8
8
|
|
9
9
|
def initialize(console, file)
|
10
|
-
chichilku3_dir = ""
|
10
|
+
@chichilku3_dir = ""
|
11
11
|
if OS.linux?
|
12
|
-
chichilku3_dir = "#{ENV['HOME']}/.chichilku/chichilku3/"
|
12
|
+
@chichilku3_dir = "#{ENV['HOME']}/.chichilku/chichilku3/"
|
13
13
|
elsif OS.mac?
|
14
|
-
chichilku3_dir = "#{ENV['HOME']}/Library/Application Support/chichilku/chichilku3/"
|
14
|
+
@chichilku3_dir = "#{ENV['HOME']}/Library/Application Support/chichilku/chichilku3/"
|
15
15
|
# elsif OS.windows?
|
16
|
-
# chichilku3_dir = "%APPDATA%\\chichilku\\chichilku3\\"
|
16
|
+
# @chichilku3_dir = "%APPDATA%\\chichilku\\chichilku3\\"
|
17
17
|
else
|
18
18
|
puts "os not supported."
|
19
19
|
exit
|
20
20
|
end
|
21
|
-
puts "path: " + chichilku3_dir
|
22
|
-
FileUtils.mkdir_p chichilku3_dir
|
23
|
-
|
24
|
-
|
21
|
+
puts "path: " + @chichilku3_dir
|
22
|
+
FileUtils.mkdir_p @chichilku3_dir
|
23
|
+
FileUtils.mkdir_p "#{@chichilku3_dir}recordings"
|
24
|
+
create_default_cfg(file, "#{@chichilku3_dir}/#{file}")
|
25
|
+
@file = @chichilku3_dir + file
|
25
26
|
@console = console
|
26
27
|
@data = load
|
27
28
|
end
|
data/lib/share/console.rb
CHANGED
@@ -4,14 +4,19 @@ DEBUG = false
|
|
4
4
|
class Console
|
5
5
|
def log(message)
|
6
6
|
t = Time.now
|
7
|
-
puts "[
|
7
|
+
puts format("[%02d:%02d:%02d][log] %s", t.hour, t.min, t.sec, message)
|
8
|
+
end
|
9
|
+
|
10
|
+
def err(message)
|
11
|
+
t = Time.now
|
12
|
+
puts format("[%02d:%02d:%02d][error] %s", t.hour, t.min, t.sec, message)
|
8
13
|
end
|
9
14
|
|
10
15
|
def dbg(message)
|
11
16
|
return unless DEBUG
|
12
17
|
|
13
18
|
t = Time.now
|
14
|
-
puts "[
|
19
|
+
puts format("[%02d:%02d:%02d][debug] %s", t.hour, t.min, t.sec, message)
|
15
20
|
end
|
16
21
|
end
|
17
22
|
|
data/lib/share/network.rb
CHANGED
@@ -2,7 +2,7 @@ require 'socket'
|
|
2
2
|
# check doc_network.rb for documentation
|
3
3
|
|
4
4
|
# update GAME_VERSION on network protocol changes
|
5
|
-
GAME_VERSION = '
|
5
|
+
GAME_VERSION = '0014'
|
6
6
|
|
7
7
|
# game
|
8
8
|
|
@@ -15,10 +15,12 @@ SPEED = TILE_SIZE
|
|
15
15
|
|
16
16
|
# networking
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
CMD_LEN = 7
|
19
|
+
NAME_LEN = 9
|
20
|
+
MAX_CLIENTS = 12
|
21
|
+
PLAYER_PACKAGE_LEN = 16
|
22
|
+
CLIENT_PACKAGE_LEN = 11 # used by server
|
23
|
+
SERVER_PACKAGE_LEN = MAX_CLIENTS * PLAYER_PACKAGE_LEN + 4 # used by client
|
22
24
|
|
23
25
|
MAX_TIMEOUT = 5
|
24
26
|
MAX_TICK_SPEED = 0.01 # the lower the faster client and server tick
|
data/lib/share/player.rb
CHANGED
@@ -1,29 +1,37 @@
|
|
1
1
|
# Player used by Client and Server
|
2
2
|
require_relative 'console'
|
3
3
|
require_relative 'network'
|
4
|
+
require_relative 'projectile'
|
4
5
|
|
5
6
|
SPAWN_X = 512
|
6
7
|
SPAWN_Y = 100
|
7
8
|
|
8
9
|
class Player
|
9
10
|
attr_accessor :x, :y, :dy, :dx, :id, :name, :score, :state, :dead, :dead_ticks, :was_crouching
|
11
|
+
attr_accessor :aimX, :aimY, :projectile, :fire_ticks
|
10
12
|
attr_reader :collide, :collide_str, :img_index, :version, :w, :h
|
11
13
|
|
12
|
-
def initialize(id, score, x = nil, y = nil, name = 'def', ip = nil)
|
14
|
+
def initialize(id, score, x = nil, y = nil, name = 'def', version = nil, ip = nil)
|
13
15
|
@id = id
|
14
16
|
@x = x.nil? ? SPAWN_X : x
|
15
17
|
@y = y.nil? ? SPAWN_Y : y
|
16
18
|
@w = TILE_SIZE / 2
|
17
19
|
@h = TILE_SIZE
|
20
|
+
@aimX = 0
|
21
|
+
@aimY = 0
|
22
|
+
@projectile = Projectile.new
|
18
23
|
@dx = 0
|
19
24
|
@dy = 0
|
25
|
+
@health = 3
|
20
26
|
@collide = {up: false, down: false, right: false, left: false}
|
21
|
-
@state = {bleeding: false, crouching: false}
|
27
|
+
@state = {bleeding: false, crouching: false, fire: 0}
|
22
28
|
@was_crouching = false
|
23
29
|
@name = name
|
24
30
|
@score = score
|
25
31
|
@dead = false # only used by server for now
|
26
32
|
@dead_ticks = 0
|
33
|
+
@bleed_ticks = 0
|
34
|
+
@fire_ticks = 0
|
27
35
|
|
28
36
|
# used by client
|
29
37
|
@img_index = 0
|
@@ -33,7 +41,7 @@ class Player
|
|
33
41
|
@not_changed_y = 0
|
34
42
|
|
35
43
|
# used by server
|
36
|
-
@version =
|
44
|
+
@version = version
|
37
45
|
@ip = ip
|
38
46
|
end
|
39
47
|
|
@@ -82,11 +90,13 @@ class Player
|
|
82
90
|
players.find { |player| id == player.id }
|
83
91
|
end
|
84
92
|
|
85
|
-
def self.update_player(players, id, x, y, score)
|
93
|
+
def self.update_player(players, id, x, y, score, aimX, aimY)
|
86
94
|
player = get_player_by_id(players, id)
|
87
95
|
player.x = x
|
88
96
|
player.y = y
|
89
97
|
player.score = score
|
98
|
+
player.aimX = aimX
|
99
|
+
player.aimY = aimY
|
90
100
|
player
|
91
101
|
end
|
92
102
|
|
@@ -94,8 +104,8 @@ class Player
|
|
94
104
|
# server only #
|
95
105
|
###############
|
96
106
|
|
97
|
-
def
|
98
|
-
@
|
107
|
+
def set_name(name)
|
108
|
+
@name = name
|
99
109
|
end
|
100
110
|
|
101
111
|
def tick
|
@@ -104,6 +114,10 @@ class Player
|
|
104
114
|
@dx = normalize_zero(@dx)
|
105
115
|
@dy = normalize_zero(@dy)
|
106
116
|
check_out_of_world
|
117
|
+
if @bleed_ticks > 0
|
118
|
+
@bleed_ticks -= 1
|
119
|
+
self.state[:bleeding] = @bleed_ticks.zero? == false
|
120
|
+
end
|
107
121
|
end
|
108
122
|
|
109
123
|
def check_player_collide(other)
|
@@ -118,6 +132,13 @@ class Player
|
|
118
132
|
return 0
|
119
133
|
end
|
120
134
|
|
135
|
+
def damage(attacker)
|
136
|
+
@bleed_ticks = 3
|
137
|
+
@health -= 1
|
138
|
+
$console.log "player='#{attacker.name}' damaged player='#{@name}'"
|
139
|
+
die(attacker) if @health <= 0
|
140
|
+
end
|
141
|
+
|
121
142
|
# def check_out_of_world #die
|
122
143
|
# # y
|
123
144
|
# if @y < 0
|
@@ -147,10 +168,20 @@ class Player
|
|
147
168
|
end
|
148
169
|
end
|
149
170
|
|
150
|
-
def die
|
151
|
-
|
171
|
+
def die(killer = nil)
|
172
|
+
if killer.nil?
|
173
|
+
$console.log("[death] id=#{@id} name='#{@name}'")
|
174
|
+
else
|
175
|
+
if killer.id == self.id
|
176
|
+
killer.score = (killer.score - 1).clamp(0, NET_MAX_INT)
|
177
|
+
else
|
178
|
+
killer.score += 1
|
179
|
+
end
|
180
|
+
$console.log("[kill] id=#{@id} name='#{@name}' killer='#{killer.name}'")
|
181
|
+
end
|
152
182
|
@x = SPAWN_X
|
153
183
|
@y = SPAWN_Y
|
184
|
+
@health = 3
|
154
185
|
end
|
155
186
|
|
156
187
|
#TODO: check for collision before update
|
@@ -218,17 +249,17 @@ class Player
|
|
218
249
|
# @return [String] partial network packet
|
219
250
|
|
220
251
|
def to_n_pck
|
221
|
-
name = @name.ljust(
|
222
|
-
#
|
223
|
-
"#{@id}#{net_pack_int(@score)}#{name}" # new 1 char id
|
252
|
+
name = @name.ljust(NAME_LEN, '_')
|
253
|
+
"#{@id.to_s(16)}#{net_pack_int(@score)}#{name}"
|
224
254
|
end
|
225
255
|
|
226
256
|
def to_s
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
#
|
231
|
-
"#{
|
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}"
|
232
263
|
end
|
233
264
|
|
234
265
|
def state_to_net
|
@@ -236,12 +267,24 @@ class Player
|
|
236
267
|
@h = TILE_SIZE
|
237
268
|
if @state[:bleeding] && @state[:crouching]
|
238
269
|
"s"
|
270
|
+
elsif @state[:bleeding] && @state[:fire] == 1
|
271
|
+
"x"
|
272
|
+
elsif @state[:bleeding] && @state[:fire] == 2
|
273
|
+
"y"
|
274
|
+
elsif @state[:bleeding] && @state[:fire] == 3
|
275
|
+
"z"
|
239
276
|
elsif @state[:bleeding]
|
240
277
|
"b"
|
241
278
|
elsif @state[:crouching]
|
242
279
|
@w = TILE_SIZE
|
243
280
|
@h = TILE_SIZE / 2
|
244
281
|
"c"
|
282
|
+
elsif @state[:fire] == 1
|
283
|
+
"1"
|
284
|
+
elsif @state[:fire] == 2
|
285
|
+
"2"
|
286
|
+
elsif @state[:fire] == 3
|
287
|
+
"3"
|
245
288
|
else
|
246
289
|
"0"
|
247
290
|
end
|
@@ -249,13 +292,25 @@ class Player
|
|
249
292
|
|
250
293
|
def net_to_state(net)
|
251
294
|
if net == "b"
|
252
|
-
@state = {bleeding: true, crouching: false}
|
295
|
+
@state = {bleeding: true, crouching: false, fire: 0}
|
253
296
|
elsif net == "c"
|
254
|
-
@state = {bleeding: false, crouching: true}
|
297
|
+
@state = {bleeding: false, crouching: true, fire: 0}
|
255
298
|
elsif net == "s"
|
256
|
-
@state = {bleeding: true, crouching: true}
|
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}
|
257
312
|
else
|
258
|
-
@state = {bleeding: false, crouching: false}
|
313
|
+
@state = {bleeding: false, crouching: false, fire: 0}
|
259
314
|
end
|
260
315
|
end
|
261
316
|
|