grueserve 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/grueserve +6 -0
- data/bin/grueserve_path2lines +59 -0
- data/example/attributes.yaml +28 -0
- data/example/map.gif +0 -0
- data/example/sprites/black_soldier_dead.gif +0 -0
- data/example/sprites/black_soldier_dodging_0PI1_1.gif +0 -0
- data/example/sprites/black_soldier_dodging_0PI1_2.gif +0 -0
- data/example/sprites/black_soldier_dodging_0PI1_3.gif +0 -0
- data/example/sprites/black_soldier_dodging_1PI1_1.gif +0 -0
- data/example/sprites/black_soldier_dodging_1PI1_2.gif +0 -0
- data/example/sprites/black_soldier_dodging_1PI1_3.gif +0 -0
- data/example/sprites/black_soldier_dodging_1PI2_1.gif +0 -0
- data/example/sprites/black_soldier_dodging_1PI2_2.gif +0 -0
- data/example/sprites/black_soldier_dodging_1PI2_3.gif +0 -0
- data/example/sprites/black_soldier_dodging_3PI2_1.gif +0 -0
- data/example/sprites/black_soldier_dodging_3PI2_2.gif +0 -0
- data/example/sprites/black_soldier_dodging_3PI2_3.gif +0 -0
- data/example/sprites/black_soldier_standing_0PI1_1.gif +0 -0
- data/example/sprites/black_soldier_standing_0PI1_2.gif +0 -0
- data/example/sprites/black_soldier_standing_0PI1_3.gif +0 -0
- data/example/sprites/black_soldier_standing_1PI1_1.gif +0 -0
- data/example/sprites/black_soldier_standing_1PI1_2.gif +0 -0
- data/example/sprites/black_soldier_standing_1PI1_3.gif +0 -0
- data/example/sprites/black_soldier_standing_1PI2_1.gif +0 -0
- data/example/sprites/black_soldier_standing_1PI2_2.gif +0 -0
- data/example/sprites/black_soldier_standing_1PI2_3.gif +0 -0
- data/example/sprites/black_soldier_standing_3PI2_1.gif +0 -0
- data/example/sprites/black_soldier_standing_3PI2_2.gif +0 -0
- data/example/sprites/black_soldier_standing_3PI2_3.gif +0 -0
- data/example/sprites/brown_soldier_dead.gif +0 -0
- data/example/sprites/brown_soldier_dodging_0PI1_1.gif +0 -0
- data/example/sprites/brown_soldier_dodging_0PI1_2.gif +0 -0
- data/example/sprites/brown_soldier_dodging_0PI1_3.gif +0 -0
- data/example/sprites/brown_soldier_dodging_1PI1_1.gif +0 -0
- data/example/sprites/brown_soldier_dodging_1PI1_2.gif +0 -0
- data/example/sprites/brown_soldier_dodging_1PI1_3.gif +0 -0
- data/example/sprites/brown_soldier_dodging_1PI2_1.gif +0 -0
- data/example/sprites/brown_soldier_dodging_1PI2_2.gif +0 -0
- data/example/sprites/brown_soldier_dodging_1PI2_3.gif +0 -0
- data/example/sprites/brown_soldier_dodging_3PI2_1.gif +0 -0
- data/example/sprites/brown_soldier_dodging_3PI2_2.gif +0 -0
- data/example/sprites/brown_soldier_dodging_3PI2_3.gif +0 -0
- data/example/sprites/brown_soldier_standing_0PI1_1.gif +0 -0
- data/example/sprites/brown_soldier_standing_0PI1_2.gif +0 -0
- data/example/sprites/brown_soldier_standing_0PI1_3.gif +0 -0
- data/example/sprites/brown_soldier_standing_1PI1_1.gif +0 -0
- data/example/sprites/brown_soldier_standing_1PI1_2.gif +0 -0
- data/example/sprites/brown_soldier_standing_1PI1_3.gif +0 -0
- data/example/sprites/brown_soldier_standing_1PI2_1.gif +0 -0
- data/example/sprites/brown_soldier_standing_1PI2_2.gif +0 -0
- data/example/sprites/brown_soldier_standing_1PI2_3.gif +0 -0
- data/example/sprites/brown_soldier_standing_3PI2_1.gif +0 -0
- data/example/sprites/brown_soldier_standing_3PI2_2.gif +0 -0
- data/example/sprites/brown_soldier_standing_3PI2_3.gif +0 -0
- data/example/sprites/explosion_1.gif +0 -0
- data/example/sprites/explosion_10.gif +0 -0
- data/example/sprites/explosion_11.gif +0 -0
- data/example/sprites/explosion_12.gif +0 -0
- data/example/sprites/explosion_13.gif +0 -0
- data/example/sprites/explosion_14.gif +0 -0
- data/example/sprites/explosion_15.gif +0 -0
- data/example/sprites/explosion_16.gif +0 -0
- data/example/sprites/explosion_17.gif +0 -0
- data/example/sprites/explosion_18.gif +0 -0
- data/example/sprites/explosion_19.gif +0 -0
- data/example/sprites/explosion_2.gif +0 -0
- data/example/sprites/explosion_20.gif +0 -0
- data/example/sprites/explosion_21.gif +0 -0
- data/example/sprites/explosion_22.gif +0 -0
- data/example/sprites/explosion_23.gif +0 -0
- data/example/sprites/explosion_24.gif +0 -0
- data/example/sprites/explosion_25.gif +0 -0
- data/example/sprites/explosion_26.gif +0 -0
- data/example/sprites/explosion_27.gif +0 -0
- data/example/sprites/explosion_3.gif +0 -0
- data/example/sprites/explosion_4.gif +0 -0
- data/example/sprites/explosion_5.gif +0 -0
- data/example/sprites/explosion_6.gif +0 -0
- data/example/sprites/explosion_7.gif +0 -0
- data/example/sprites/explosion_8.gif +0 -0
- data/example/sprites/explosion_9.gif +0 -0
- data/example/sprites/green_soldier_dead.gif +0 -0
- data/example/sprites/green_soldier_dodging_0PI1_1.gif +0 -0
- data/example/sprites/green_soldier_dodging_0PI1_2.gif +0 -0
- data/example/sprites/green_soldier_dodging_0PI1_3.gif +0 -0
- data/example/sprites/green_soldier_dodging_1PI1_1.gif +0 -0
- data/example/sprites/green_soldier_dodging_1PI1_2.gif +0 -0
- data/example/sprites/green_soldier_dodging_1PI1_3.gif +0 -0
- data/example/sprites/green_soldier_dodging_1PI2_1.gif +0 -0
- data/example/sprites/green_soldier_dodging_1PI2_2.gif +0 -0
- data/example/sprites/green_soldier_dodging_1PI2_3.gif +0 -0
- data/example/sprites/green_soldier_dodging_3PI2_1.gif +0 -0
- data/example/sprites/green_soldier_dodging_3PI2_2.gif +0 -0
- data/example/sprites/green_soldier_dodging_3PI2_3.gif +0 -0
- data/example/sprites/green_soldier_standing_0PI1_1.gif +0 -0
- data/example/sprites/green_soldier_standing_0PI1_2.gif +0 -0
- data/example/sprites/green_soldier_standing_0PI1_3.gif +0 -0
- data/example/sprites/green_soldier_standing_1PI1_1.gif +0 -0
- data/example/sprites/green_soldier_standing_1PI1_2.gif +0 -0
- data/example/sprites/green_soldier_standing_1PI1_3.gif +0 -0
- data/example/sprites/green_soldier_standing_1PI2_1.gif +0 -0
- data/example/sprites/green_soldier_standing_1PI2_2.gif +0 -0
- data/example/sprites/green_soldier_standing_1PI2_3.gif +0 -0
- data/example/sprites/green_soldier_standing_3PI2_1.gif +0 -0
- data/example/sprites/green_soldier_standing_3PI2_2.gif +0 -0
- data/example/sprites/green_soldier_standing_3PI2_3.gif +0 -0
- data/ext/extconf.rb +93 -0
- data/ext/grueserve_ext.c +2083 -0
- data/lib/grueserve.rb +28 -0
- data/lib/grueserve/application.rb +72 -0
- data/lib/grueserve/client.rb +339 -0
- data/lib/grueserve/debuggable.rb +114 -0
- data/lib/grueserve/map.rb +178 -0
- data/lib/grueserve/rated.rb +44 -0
- data/lib/grueserve/server.rb +201 -0
- data/lib/grueserve/soldier.rb +181 -0
- metadata +179 -0
data/bin/grueserve
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
if ARGV.size < 1 || !File.exists?(ARGV.first)
|
4
|
+
puts "Usage: #{$0} GIMP_POLYGON_PATH_EXPORT_FILE"
|
5
|
+
exit 1
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'rexml/document'
|
9
|
+
require 'pp'
|
10
|
+
|
11
|
+
lines = []
|
12
|
+
current_points = []
|
13
|
+
d = REXML::Document.new(open(ARGV.first).read)
|
14
|
+
d.each_element("svg/path") do |element|
|
15
|
+
mode = :start
|
16
|
+
element.attributes["d"].split.each do |word|
|
17
|
+
pieces = [word]
|
18
|
+
if match = word.match(/([\d.,]+)M/)
|
19
|
+
pieces = [match[1], "M"]
|
20
|
+
end
|
21
|
+
for piece in pieces
|
22
|
+
if piece == "M"
|
23
|
+
unless current_points.empty?
|
24
|
+
lines << current_points
|
25
|
+
current_points = []
|
26
|
+
end
|
27
|
+
mode = :first_point
|
28
|
+
elsif mode == :first_point && (match = piece.match(/([\d.]+),([\d.]+)/))
|
29
|
+
current_points << [match[1].to_i, match[2].to_i]
|
30
|
+
mode = :first_point_control
|
31
|
+
elsif mode == :first_point_control && (match = piece.match(/([\d.]+),([\d.]+)/))
|
32
|
+
mode = :data
|
33
|
+
elsif mode == :data && (match = piece.match(/([\d.]+),([\d.]+)/))
|
34
|
+
current_points << [match[1].to_i, match[2].to_i]
|
35
|
+
mode = :control_1
|
36
|
+
elsif mode == :control_1 && piece =~ /([\d.]+),([\d.]+)/
|
37
|
+
mode = :control_2
|
38
|
+
elsif mode == :control_2 && (match = piece.match(/([\d.]+),([\d.]+)/))
|
39
|
+
mode = :data
|
40
|
+
elsif mode == :control_2 && piece == "Z"
|
41
|
+
current_points << :loop
|
42
|
+
mode = :start
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
unless current_points.empty?
|
47
|
+
lines << current_points
|
48
|
+
end
|
49
|
+
end
|
50
|
+
puts(lines.collect do |line|
|
51
|
+
line.collect do |point|
|
52
|
+
case point
|
53
|
+
when Symbol
|
54
|
+
point.to_s
|
55
|
+
when Array
|
56
|
+
"#{point.first},#{point.last}"
|
57
|
+
end
|
58
|
+
end.join(" ")
|
59
|
+
end.join(":"))
|
@@ -0,0 +1,28 @@
|
|
1
|
+
---
|
2
|
+
map: map.gif
|
3
|
+
teams: green black
|
4
|
+
green_start_points: 144,396 72,80 280,64
|
5
|
+
black_start_points: 48,568 156,768 432,780
|
6
|
+
hearing_distance_cutoff: 100
|
7
|
+
viewing_distance_limit: 1000
|
8
|
+
|
9
|
+
movement_obstacles: 312,40 463,40 463,246 312,246 loop:691,60 955,60 955,514 691,514 loop:28,433 282,433 282,525 28,525 loop:685,703 925,703 925,855 685,855 loop:78,1111 319,1111 319,1263 78,1263 loop:181,1341 423,1341 423,1491 181,1491 loop:91,1636 333,1636 333,1786 91,1786 loop:690,1824 981,1824 981,1900 690,1900 loop:378,759 370,748 378,739 385,745 loop:201,736 190,723 202,714 210,723 loop:127,835 148,828 174,831 199,831 220,819 249,810 271,811 291,828 316,844 343,853 378,859 396,879 405,907 388,930 366,951 354,978 339,1006 313,1011 297,984 274,966 244,963 208,963 172,957 153,930 147,898 130,874 121,856 loop:846,964 862,978 879,999 880,1027 877,1065 870,1096 864,1132 859,1164 859,1189 856,1233 856,1297 864,1350 874,1408 885,1465 882,1537 867,1579 843,1623 822,1644 801,1650 784,1644 780,1624 778,1585 774,1528 762,1488 756,1428 754,1381 771,1333 787,1282 789,1252 780,1215 768,1164 772,1108 786,1059 792,1023 789,981 805,964 822,955 loop:0,0 1023,0 1023,2064 0,2064 loop
|
10
|
+
|
11
|
+
visibility_obstacles: 312,40 463,40 463,246 312,246 loop:691,60 955,60 955,514 691,514 loop:28,433 282,433 282,525 28,525 loop:685,703 925,703 925,855 685,855 loop:78,1111 319,1111 319,1263 78,1263 loop:181,1341 423,1341 423,1491 181,1491 loop:91,1636 333,1636 333,1786 91,1786 loop:690,1824 981,1824 981,1900 690,1900 loop:378,759 370,748 378,739 385,745 loop:201,736 190,723 202,714 210,723 loop
|
12
|
+
|
13
|
+
bullet_obstacles: 312,40 463,40 463,246 312,246 loop:691,60 955,60 955,514 691,514 loop:28,433 282,433 282,525 28,525 loop:685,703 925,703 925,855 685,855 loop:78,1111 319,1111 319,1263 78,1263 loop:181,1341 423,1341 423,1491 181,1491 loop:91,1636 333,1636 333,1786 91,1786 loop:690,1824 981,1824 981,1900 690,1900 loop:378,759 370,748 378,739 385,745 loop:201,736 190,723 202,714 210,723 loop
|
14
|
+
|
15
|
+
hearing_obstacles_default_value: 800
|
16
|
+
hearing_obstacles: 312,40 463,40 463,246 312,246 loop=500:691,60 955,60 955,514 691,514 loop:28,433 282,433 282,525 28,525 loop:685,703 925,703 925,855 685,855 loop:78,1111 319,1111 319,1263 78,1263 loop:181,1341 423,1341 423,1491 181,1491 loop:91,1636 333,1636 333,1786 91,1786 loop:690,1824 981,1824 981,1900 690,1900 loop:378,759 370,748 378,739 385,745 loop:201,736 190,723 202,714 210,723 loop=2000
|
17
|
+
|
18
|
+
fortifications_default_value: 500
|
19
|
+
fortifications: 383,488 502,489:391,649 511,649=800
|
20
|
+
|
21
|
+
speed_areas_default_value: 1500
|
22
|
+
speed_areas: 176,230 256,102 256,362 96,362 340,322 96,100 loop:340,322 258,350 256,300 370,300 370,574 314,574 576,604 314,348 loop:576,604 2,574 0,630 1018,630 574,554 1018,576 loop=1600:574,554 628,2 520,2 520,2054 628,2054 loop=1700
|
23
|
+
|
24
|
+
protection_areas_default_value: 500
|
25
|
+
protection_areas: 204,725 168,703 183,693 205,711 219,705 232,725 230,748 218,740 215,748 202,736 186,758 174,728 167,721 375,750 174,713 loop:375,750 343,747 358,731 374,736 402,721 421,730 408,739 424,756 414,757 398,786 379,761 362,773 357,767 340,776 347,753 loop=600
|
26
|
+
|
27
|
+
hidden_areas_default_value: 50000
|
28
|
+
hidden_areas: 204,725 168,703 183,693 205,711 219,705 232,725 230,748 218,740 215,748 202,736 186,758 174,728 167,721 375,750 174,713 loop:375,750 343,747 358,731 374,736 402,721 421,730 408,739 424,756 414,757 398,786 379,761 362,773 357,767 340,776 347,753 loop
|
data/example/map.gif
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# grueserve - a game server in c and ruby for the gruesome game
|
2
|
+
# Copyright (C) 2008 Martin Kihlgren <zond at troja dot ath dot cx>
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or
|
5
|
+
# modify it under the terms of the GNU General Public License
|
6
|
+
# as published by the Free Software Foundation; either version 2
|
7
|
+
# of the License, or (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17
|
+
|
18
|
+
require 'mkmf'
|
19
|
+
require 'pathname'
|
20
|
+
|
21
|
+
def crash(s)
|
22
|
+
puts "--------------------------------------------------"
|
23
|
+
puts " extconf failure: #{s}"
|
24
|
+
puts "--------------------------------------------------"
|
25
|
+
exit 1
|
26
|
+
end
|
27
|
+
|
28
|
+
crash("pkg-config needed") unless find_executable("pkg-config")
|
29
|
+
|
30
|
+
crash "libglib-2.0 needed" unless have_library('glib-2.0')
|
31
|
+
|
32
|
+
$CFLAGS += " -std=c99 -Wall " + `pkg-config --cflags glib-2.0`.strip
|
33
|
+
|
34
|
+
gem = if find_executable("gem")
|
35
|
+
"gem"
|
36
|
+
elsif find_executable("gem1.8")
|
37
|
+
"gem1.8"
|
38
|
+
else
|
39
|
+
crash("gem needed")
|
40
|
+
end
|
41
|
+
|
42
|
+
geo_path = Pathname.glob(Pathname.new(`#{gem} environment`.match(/- GEM PATH.?:\s*- ([^\n]+)/)[1]).join("gems").join("geo-*")).sort.last
|
43
|
+
|
44
|
+
geo_include = geo_path.join("ext")
|
45
|
+
found_includes = false
|
46
|
+
Pathname.glob(geo_include.join("*.h")).each do |header|
|
47
|
+
crash("couldnt compile against #{header}") unless find_header(header.basename, geo_include)
|
48
|
+
found_includes = true
|
49
|
+
end
|
50
|
+
crash("couldnt find geo includes") unless found_includes
|
51
|
+
|
52
|
+
found_libs = false
|
53
|
+
Pathname.glob(geo_include.join("*.o")).each do |lib|
|
54
|
+
$LOCAL_LIBS += " #{lib}"
|
55
|
+
found_libs = true
|
56
|
+
end
|
57
|
+
Pathname.glob(geo_path.join("lib").join("*.so")).each do |lib|
|
58
|
+
$LOCAL_LIBS += " #{lib}"
|
59
|
+
found_libs = true
|
60
|
+
end
|
61
|
+
[
|
62
|
+
"rb_is_a", # common.c
|
63
|
+
"Init_geo", # geo.c
|
64
|
+
"geo_set_free", # geo_set.c
|
65
|
+
"free_intersection", # intersection.c
|
66
|
+
"line_free", # line.c
|
67
|
+
"line_set_mark", # line_set.c
|
68
|
+
"new_point", # point.c
|
69
|
+
"point_set_mark", # point_set.c
|
70
|
+
"triangle_inspect", # triangle.c
|
71
|
+
"triangle_set_mark" # triangle_set.c
|
72
|
+
].each do |func|
|
73
|
+
puts "checking for #{func}"
|
74
|
+
crash("couldnt find #{func}") unless try_func(func, [])
|
75
|
+
puts "... yes"
|
76
|
+
end
|
77
|
+
crash("couldnt find geo libs") unless found_libs
|
78
|
+
|
79
|
+
if ARGV.include?("-d")
|
80
|
+
$CFLAGS += " -D GEO_DEBUG"
|
81
|
+
end
|
82
|
+
|
83
|
+
if ARGV.include?("-O0")
|
84
|
+
$CFLAGS.gsub!(/-O./, "-O0")
|
85
|
+
else
|
86
|
+
$CFLAGS.gsub!(/-O./, "-O3")
|
87
|
+
end
|
88
|
+
|
89
|
+
if ARGV.include?("-gdb")
|
90
|
+
$CFLAGS += " -g -gdwarf-2 -g3"
|
91
|
+
end
|
92
|
+
|
93
|
+
create_makefile("grueserve_ext")
|
data/ext/grueserve_ext.c
ADDED
@@ -0,0 +1,2083 @@
|
|
1
|
+
// grueserve - a game server in c and ruby for the gruesome game
|
2
|
+
// Copyright (C) 2008 Martin Kihlgren <zond at troja dot ath dot cx>
|
3
|
+
//
|
4
|
+
// This program is free software; you can redistribute it and/or
|
5
|
+
// modify it under the terms of the GNU General Public License
|
6
|
+
// as published by the Free Software Foundation; either version 2
|
7
|
+
// of the License, or (at your option) any later version.
|
8
|
+
//
|
9
|
+
// This program is distributed in the hope that it will be useful,
|
10
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
// GNU General Public License for more details.
|
13
|
+
//
|
14
|
+
// You should have received a copy of the GNU General Public License
|
15
|
+
// along with this program; if not, write to the Free Software
|
16
|
+
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17
|
+
|
18
|
+
#define _POSIX_SOURCE
|
19
|
+
|
20
|
+
#include "ruby.h"
|
21
|
+
#include "rubyio.h"
|
22
|
+
#include "intern.h"
|
23
|
+
#include <stdlib.h>
|
24
|
+
#include <unistd.h>
|
25
|
+
#include <math.h>
|
26
|
+
#include <glib.h>
|
27
|
+
#include <common.h>
|
28
|
+
#include <time.h>
|
29
|
+
#include <stdio.h>
|
30
|
+
|
31
|
+
static VALUE rb_client;
|
32
|
+
static VALUE rb_command;
|
33
|
+
static VALUE rb_command_set;
|
34
|
+
static VALUE rb_body;
|
35
|
+
static VALUE rb_map;
|
36
|
+
static VALUE rb_e_terminated_connection;
|
37
|
+
|
38
|
+
static VALUE rb_standing;
|
39
|
+
static VALUE rb_dodging;
|
40
|
+
static VALUE rb_dead;
|
41
|
+
|
42
|
+
static char* standing = "standing";
|
43
|
+
static char* dodging = "dodging";
|
44
|
+
static char* dead = "dead";
|
45
|
+
|
46
|
+
#define RB_CLIENT(client_pointer,klass) ((client_pointer)->rbClient = Data_Wrap_Struct(klass, client_mark, client_free, (client_pointer)))
|
47
|
+
#define CLIENT(rb_client,client_pointer) Data_Get_Struct((rb_client), Client, (client_pointer))
|
48
|
+
#define RB_BODY(body_pointer,klass) ((body_pointer)->rbBody = Data_Wrap_Struct(klass, body_mark, free, (body_pointer)))
|
49
|
+
#define BODY(rb_body,body_pointer) Data_Get_Struct((rb_body), Body, (body_pointer))
|
50
|
+
#define RB_COMMAND(command_pointer,klass) ((command_pointer)->rbCommand = Data_Wrap_Struct(klass, NULL, command_free, (command_pointer)))
|
51
|
+
#define COMMAND(rb_command,command_pointer) Data_Get_Struct((rb_command), Command, (command_pointer))
|
52
|
+
#define RB_MAP(map_pointer,klass) ((map_pointer)->rbMap = Data_Wrap_Struct(klass, map_mark, map_free, (map_pointer)))
|
53
|
+
#define MAP(rb_map,map_pointer) Data_Get_Struct((rb_map), Map, (map_pointer))
|
54
|
+
#define RB_COMMAND_SET(command_set_pointer,klass) ((command_set_pointer)->rbCommandSet = Data_Wrap_Struct(klass, command_set_mark, command_set_free, (command_set_pointer)))
|
55
|
+
#define COMMAND_SET(rb_command_set,command_set_pointer) Data_Get_Struct((rb_command_set), CommandSet, (command_set_pointer))
|
56
|
+
|
57
|
+
#define COMMAND_P(l) (!NIL_P((l)) && rb_is_a((l), rb_command))
|
58
|
+
#define CHECK_COMMAND(l) if (!COMMAND_P((l))) rb_raise(rb_eTypeError, "Expected Grueserve::Client::Command!")
|
59
|
+
#define COMMAND_SET_P(l) (!NIL_P((l)) && rb_is_a((l), rb_command_set))
|
60
|
+
#define CHECK_COMMAND_SET(l) if (!COMMAND_SET_P((l))) rb_raise(rb_eTypeError, "Expected Grueserve::Client::CommandSet!")
|
61
|
+
#define MAP_P(l) (!NIL_P((l)) && rb_is_a((l), rb_map))
|
62
|
+
#define CHECK_MAP(l) if (!MAP_P((l))) rb_raise(rb_eTypeError, "Expected Grueserve::Map!")
|
63
|
+
#define CLIENT_P(l) (!NIL_P((l)) && rb_is_a((l), rb_client))
|
64
|
+
#define CHECK_CLIENT(l) if (!CLIENT_P((l))) rb_raise(rb_eTypeError, "Expected Grueserve::Client!")
|
65
|
+
|
66
|
+
#define COMMAND_SET_INCLUDES(command_set,name) (g_hash_table_lookup((command_set)->commands, (name)) != NULL)
|
67
|
+
|
68
|
+
#define SPRITE_WIDTH 16.0
|
69
|
+
#define SPRITE_HEIGHT 24.0
|
70
|
+
|
71
|
+
#define UP "UP"
|
72
|
+
#define DOWN "DOWN"
|
73
|
+
#define LEFT "LEFT"
|
74
|
+
#define RIGHT "RIGHT"
|
75
|
+
#define DODGE "DODGE"
|
76
|
+
#define LBUTTON "LBUTTON"
|
77
|
+
|
78
|
+
#define BUFFER_UNIT 1024
|
79
|
+
|
80
|
+
typedef struct {
|
81
|
+
GeoSet *movement_obstacles;
|
82
|
+
GeoSet *visibility_obstacles;
|
83
|
+
GeoSet *bullet_obstacles;
|
84
|
+
GeoSet *hearing_obstacles;
|
85
|
+
GeoSet *fortifications;
|
86
|
+
GeoSet *speed_areas;
|
87
|
+
GeoSet *protection_areas;
|
88
|
+
GeoSet *hidden_areas;
|
89
|
+
GHashTable *config_by_whatever;
|
90
|
+
|
91
|
+
GeoSet *bodies;
|
92
|
+
GeoSet *eyes;
|
93
|
+
GeoSet *body_parts;
|
94
|
+
GHashTable *client_by_whatever;
|
95
|
+
|
96
|
+
gint timeout;
|
97
|
+
gdouble viewing_distance_limit;
|
98
|
+
|
99
|
+
VALUE rbMap;
|
100
|
+
} Map;
|
101
|
+
|
102
|
+
typedef struct {
|
103
|
+
GHashTable *attributes;
|
104
|
+
gchar *name;
|
105
|
+
VALUE rbCommand;
|
106
|
+
} Command;
|
107
|
+
|
108
|
+
typedef struct {
|
109
|
+
GHashTable *commands;
|
110
|
+
VALUE rbCommandSet;
|
111
|
+
} CommandSet;
|
112
|
+
|
113
|
+
struct ClientStruct;
|
114
|
+
|
115
|
+
typedef struct {
|
116
|
+
Line *vertical_axis;
|
117
|
+
Line *horizontal_axis;
|
118
|
+
Point *origo;
|
119
|
+
VALUE rbBody;
|
120
|
+
struct ClientStruct *client;
|
121
|
+
} Body;
|
122
|
+
|
123
|
+
struct ClientStruct {
|
124
|
+
Body *body;
|
125
|
+
CommandSet *current_command;
|
126
|
+
GHashTable *last_command;
|
127
|
+
Map *map;
|
128
|
+
VALUE rbClient;
|
129
|
+
VALUE state;
|
130
|
+
time_t last_ping;
|
131
|
+
gdouble running_speed;
|
132
|
+
OpenFile *socket;
|
133
|
+
VALUE rbSocket;
|
134
|
+
gboolean socket_locked;
|
135
|
+
gchar *team;
|
136
|
+
gchar *behaviour;
|
137
|
+
gchar *nickname;
|
138
|
+
gboolean status_dirty;
|
139
|
+
gdouble score;
|
140
|
+
gdouble kills;
|
141
|
+
gdouble deaths;
|
142
|
+
gdouble hitpoints;
|
143
|
+
gchar *extra_status;
|
144
|
+
GHashTable *subscriptions;
|
145
|
+
};
|
146
|
+
|
147
|
+
typedef struct ClientStruct Client;
|
148
|
+
|
149
|
+
typedef gpointer
|
150
|
+
(*viewing_handler)(Client *viewer, Client *viewee, gpointer user_data);
|
151
|
+
|
152
|
+
typedef gpointer
|
153
|
+
(*client_handler)(Client *client, gpointer user_data);
|
154
|
+
|
155
|
+
static void
|
156
|
+
map_mark(Map *map) {
|
157
|
+
rb_gc_mark(map->movement_obstacles->rbGeoSet);
|
158
|
+
rb_gc_mark(map->visibility_obstacles->rbGeoSet);
|
159
|
+
rb_gc_mark(map->bullet_obstacles->rbGeoSet);
|
160
|
+
rb_gc_mark(map->hearing_obstacles->rbGeoSet);
|
161
|
+
rb_gc_mark(map->fortifications->rbGeoSet);
|
162
|
+
rb_gc_mark(map->speed_areas->rbGeoSet);
|
163
|
+
rb_gc_mark(map->protection_areas->rbGeoSet);
|
164
|
+
rb_gc_mark(map->hidden_areas->rbGeoSet);
|
165
|
+
|
166
|
+
rb_gc_mark(map->bodies->rbGeoSet);
|
167
|
+
rb_gc_mark(map->eyes->rbGeoSet);
|
168
|
+
rb_gc_mark(map->body_parts->rbGeoSet);
|
169
|
+
}
|
170
|
+
|
171
|
+
static void
|
172
|
+
map_free(Map *map) {
|
173
|
+
g_hash_table_destroy(map->client_by_whatever);
|
174
|
+
g_hash_table_destroy(map->config_by_whatever);
|
175
|
+
}
|
176
|
+
|
177
|
+
static void
|
178
|
+
client_free(Client *client) {
|
179
|
+
if (client->team != NULL)
|
180
|
+
free(client->team);
|
181
|
+
if (client->behaviour != NULL)
|
182
|
+
free(client->behaviour);
|
183
|
+
if (client->nickname != NULL)
|
184
|
+
free(client->nickname);
|
185
|
+
if (client->extra_status != NULL)
|
186
|
+
free(client->extra_status);
|
187
|
+
g_hash_table_destroy(client->subscriptions);
|
188
|
+
g_hash_table_destroy(client->last_command);
|
189
|
+
}
|
190
|
+
|
191
|
+
static void
|
192
|
+
client_mark(Client *client) {
|
193
|
+
rb_gc_mark(client->body->rbBody);
|
194
|
+
rb_gc_mark(client->current_command->rbCommandSet);
|
195
|
+
rb_gc_mark(client->map->rbMap);
|
196
|
+
rb_gc_mark(client->rbSocket);
|
197
|
+
}
|
198
|
+
|
199
|
+
static void
|
200
|
+
body_mark(Body *body) {
|
201
|
+
rb_gc_mark(body->vertical_axis->rbLine);
|
202
|
+
rb_gc_mark(body->horizontal_axis->rbLine);
|
203
|
+
rb_gc_mark(body->origo->rbPoint);
|
204
|
+
rb_gc_mark(body->client->rbClient);
|
205
|
+
}
|
206
|
+
|
207
|
+
static void
|
208
|
+
command_free(Command *command) {
|
209
|
+
free(command->name);
|
210
|
+
g_hash_table_destroy(command->attributes);
|
211
|
+
}
|
212
|
+
|
213
|
+
static void
|
214
|
+
g_hash_table_mark_command(gpointer name, gpointer command, gpointer null) {
|
215
|
+
rb_gc_mark(( (Command *) command )->rbCommand);
|
216
|
+
}
|
217
|
+
|
218
|
+
static void
|
219
|
+
command_set_mark(CommandSet *command_set) {
|
220
|
+
g_hash_table_foreach(command_set->commands, g_hash_table_mark_command, NULL);
|
221
|
+
}
|
222
|
+
|
223
|
+
static void
|
224
|
+
command_set_free(CommandSet *command_set) {
|
225
|
+
g_hash_table_destroy(command_set->commands);
|
226
|
+
free(command_set);
|
227
|
+
}
|
228
|
+
|
229
|
+
static CommandSet*
|
230
|
+
new_command_set() {
|
231
|
+
CommandSet *command_set = ALLOC(CommandSet);
|
232
|
+
command_set->commands = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
|
233
|
+
return command_set;
|
234
|
+
}
|
235
|
+
|
236
|
+
static Body*
|
237
|
+
new_body() {
|
238
|
+
Body *body = ALLOC(Body);
|
239
|
+
body->vertical_axis = new_line_with_coordinates(-SPRITE_WIDTH / 2, 0,
|
240
|
+
SPRITE_WIDTH / 2, 0);
|
241
|
+
body->horizontal_axis = new_line_with_coordinates(0,-SPRITE_HEIGHT / 2,
|
242
|
+
0,SPRITE_HEIGHT / 2);
|
243
|
+
body->origo = new_point(0,0);
|
244
|
+
RB_BODY(body, rb_body);
|
245
|
+
RB_LINE(body->vertical_axis, rb_line);
|
246
|
+
RB_POINT(body->vertical_axis->p1, rb_point);
|
247
|
+
RB_POINT(body->vertical_axis->p2, rb_point);
|
248
|
+
RB_LINE(body->horizontal_axis, rb_line);
|
249
|
+
RB_POINT(body->horizontal_axis->p1, rb_point);
|
250
|
+
RB_POINT(body->horizontal_axis->p2, rb_point);
|
251
|
+
RB_POINT(body->origo, rb_point);
|
252
|
+
return body;
|
253
|
+
}
|
254
|
+
|
255
|
+
static VALUE
|
256
|
+
rb_client_alloc(VALUE class) {
|
257
|
+
Client *client = ALLOC(Client);
|
258
|
+
client->state = rb_standing;
|
259
|
+
client->last_ping = time(NULL);
|
260
|
+
client->running_speed = 1;
|
261
|
+
client->current_command = new_command_set();
|
262
|
+
RB_COMMAND_SET(client->current_command, rb_command_set);
|
263
|
+
client->last_command = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
|
264
|
+
client->map = NULL;
|
265
|
+
client->socket = NULL;
|
266
|
+
client->rbSocket = 0;
|
267
|
+
client->socket_locked = FALSE;
|
268
|
+
client->team = NULL;
|
269
|
+
client->behaviour = NULL;
|
270
|
+
client->nickname = NULL;
|
271
|
+
client->status_dirty = TRUE;
|
272
|
+
client->score = 0.0;
|
273
|
+
client->kills = 0.0;
|
274
|
+
client->deaths = 0.0;
|
275
|
+
client->hitpoints = 0.0;
|
276
|
+
client->extra_status = NULL;
|
277
|
+
|
278
|
+
client->body = new_body();
|
279
|
+
client->body->client = client;
|
280
|
+
|
281
|
+
client->subscriptions = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
|
282
|
+
return RB_CLIENT(client, class);
|
283
|
+
}
|
284
|
+
|
285
|
+
static void
|
286
|
+
map_register_body(Map *map, Body *body) {
|
287
|
+
g_hash_table_insert(map->bodies->table, body->origo, body->origo);
|
288
|
+
g_hash_table_insert(map->client_by_whatever, body->origo, body->client);
|
289
|
+
|
290
|
+
g_hash_table_insert(map->body_parts->table, body->vertical_axis, body->vertical_axis);
|
291
|
+
g_hash_table_insert(map->client_by_whatever, body->vertical_axis, body->client);
|
292
|
+
g_hash_table_insert(map->eyes->table, body->vertical_axis->p1, body->vertical_axis->p1);
|
293
|
+
g_hash_table_insert(map->client_by_whatever, body->vertical_axis->p1, body->client);
|
294
|
+
g_hash_table_insert(map->eyes->table, body->vertical_axis->p2, body->vertical_axis->p2);
|
295
|
+
g_hash_table_insert(map->client_by_whatever, body->vertical_axis->p2, body->client);
|
296
|
+
|
297
|
+
g_hash_table_insert(map->body_parts->table, body->horizontal_axis, body->horizontal_axis);
|
298
|
+
g_hash_table_insert(map->client_by_whatever, body->horizontal_axis, body->client);
|
299
|
+
g_hash_table_insert(map->eyes->table, body->horizontal_axis->p1, body->horizontal_axis->p1);
|
300
|
+
g_hash_table_insert(map->client_by_whatever, body->horizontal_axis->p1, body->client);
|
301
|
+
g_hash_table_insert(map->eyes->table, body->horizontal_axis->p2, body->horizontal_axis->p2);
|
302
|
+
g_hash_table_insert(map->client_by_whatever, body->horizontal_axis->p2, body->client);
|
303
|
+
}
|
304
|
+
|
305
|
+
static void
|
306
|
+
map_unregister_body(Map *map, Body *body) {
|
307
|
+
g_hash_table_remove(map->bodies->table, body->origo);
|
308
|
+
g_hash_table_remove(map->client_by_whatever, body->origo);
|
309
|
+
|
310
|
+
g_hash_table_remove(map->body_parts->table, body->vertical_axis);
|
311
|
+
g_hash_table_remove(map->client_by_whatever, body->vertical_axis);
|
312
|
+
g_hash_table_remove(map->eyes->table, body->vertical_axis->p1);
|
313
|
+
g_hash_table_remove(map->client_by_whatever, body->vertical_axis->p1);
|
314
|
+
g_hash_table_remove(map->eyes->table, body->vertical_axis->p2);
|
315
|
+
g_hash_table_remove(map->client_by_whatever, body->vertical_axis->p2);
|
316
|
+
|
317
|
+
g_hash_table_remove(map->body_parts->table, body->horizontal_axis);
|
318
|
+
g_hash_table_remove(map->client_by_whatever, body->horizontal_axis);
|
319
|
+
g_hash_table_remove(map->eyes->table, body->horizontal_axis->p1);
|
320
|
+
g_hash_table_remove(map->client_by_whatever, body->horizontal_axis->p1);
|
321
|
+
g_hash_table_remove(map->eyes->table, body->horizontal_axis->p2);
|
322
|
+
g_hash_table_remove(map->client_by_whatever, body->horizontal_axis->p2);
|
323
|
+
}
|
324
|
+
|
325
|
+
static VALUE
|
326
|
+
rb_command_alloc(VALUE class) {
|
327
|
+
Command *command = ALLOC(Command);
|
328
|
+
command->name = g_strndup("", 0);
|
329
|
+
command->attributes = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
|
330
|
+
return RB_COMMAND(command, class);
|
331
|
+
}
|
332
|
+
|
333
|
+
static VALUE
|
334
|
+
rb_command_set_alloc(VALUE class) {
|
335
|
+
CommandSet *command_set = new_command_set();
|
336
|
+
return RB_COMMAND_SET(command_set, class);
|
337
|
+
}
|
338
|
+
|
339
|
+
static VALUE
|
340
|
+
rb_command_set_name(VALUE self, VALUE name) {
|
341
|
+
Command *command;
|
342
|
+
Check_Type(name, T_STRING);
|
343
|
+
COMMAND(self, command);
|
344
|
+
command->name = g_strndup(RSTRING(name)->ptr, RSTRING(name)->len);
|
345
|
+
return name;
|
346
|
+
}
|
347
|
+
|
348
|
+
static VALUE
|
349
|
+
rb_command_get_name(VALUE self) {
|
350
|
+
Command *command;
|
351
|
+
COMMAND(self, command);
|
352
|
+
return rb_str_new2(command->name);
|
353
|
+
}
|
354
|
+
|
355
|
+
static VALUE
|
356
|
+
rb_command_insert(VALUE self, VALUE key, VALUE value) {
|
357
|
+
Command *command;
|
358
|
+
Check_Type(key, T_STRING);
|
359
|
+
Check_Type(value, T_STRING);
|
360
|
+
COMMAND(self, command);
|
361
|
+
g_hash_table_insert(command->attributes, g_strndup(RSTRING(key)->ptr, RSTRING(key)->len), g_strndup(RSTRING(value)->ptr, RSTRING(value)->len));
|
362
|
+
return value;
|
363
|
+
}
|
364
|
+
|
365
|
+
static VALUE
|
366
|
+
rb_command_get(VALUE self, VALUE key) {
|
367
|
+
Command *command;
|
368
|
+
gpointer value;
|
369
|
+
Check_Type(key, T_STRING);
|
370
|
+
COMMAND(self, command);
|
371
|
+
value = g_hash_table_lookup(command->attributes, RSTRING(key)->ptr);
|
372
|
+
if (value == NULL)
|
373
|
+
return Qnil;
|
374
|
+
else
|
375
|
+
return rb_str_new2((gchar *) value);
|
376
|
+
}
|
377
|
+
|
378
|
+
static VALUE
|
379
|
+
rb_command_set_get(VALUE self, VALUE key) {
|
380
|
+
CommandSet *command_set;
|
381
|
+
gpointer value;
|
382
|
+
Check_Type(key, T_STRING);
|
383
|
+
COMMAND_SET(self, command_set);
|
384
|
+
value = g_hash_table_lookup(command_set->commands, RSTRING(key)->ptr);
|
385
|
+
if (value == NULL)
|
386
|
+
return Qnil;
|
387
|
+
else
|
388
|
+
return ( (Command *) value )->rbCommand;
|
389
|
+
}
|
390
|
+
|
391
|
+
static VALUE
|
392
|
+
rb_command_set_push(VALUE self, VALUE command_value) {
|
393
|
+
CommandSet *command_set;
|
394
|
+
Command *command;
|
395
|
+
CHECK_COMMAND(command_value);
|
396
|
+
COMMAND_SET(self, command_set);
|
397
|
+
COMMAND(command_value, command);
|
398
|
+
g_hash_table_insert(command_set->commands, g_strdup(command->name), command);
|
399
|
+
return self;
|
400
|
+
}
|
401
|
+
|
402
|
+
static VALUE
|
403
|
+
rb_command_set_include(VALUE self, VALUE key) {
|
404
|
+
CommandSet *command_set;
|
405
|
+
Check_Type(key, T_STRING);
|
406
|
+
COMMAND_SET(self, command_set);
|
407
|
+
if (g_hash_table_lookup(command_set->commands, RSTRING(key)->ptr) == NULL)
|
408
|
+
return Qfalse;
|
409
|
+
else
|
410
|
+
return Qtrue;
|
411
|
+
}
|
412
|
+
|
413
|
+
static VALUE
|
414
|
+
rb_client_get_body(VALUE self) {
|
415
|
+
Client *client;
|
416
|
+
CLIENT(self, client);
|
417
|
+
return client->body->rbBody;
|
418
|
+
}
|
419
|
+
|
420
|
+
static VALUE
|
421
|
+
rb_body_get_origo(VALUE self) {
|
422
|
+
Body *body;
|
423
|
+
BODY(self, body);
|
424
|
+
return body->origo->rbPoint;
|
425
|
+
}
|
426
|
+
|
427
|
+
static VALUE
|
428
|
+
rb_body_get_vertical_axis(VALUE self) {
|
429
|
+
Body *body;
|
430
|
+
BODY(self, body);
|
431
|
+
return body->vertical_axis->rbLine;
|
432
|
+
}
|
433
|
+
|
434
|
+
static VALUE
|
435
|
+
rb_body_get_horizontal_axis(VALUE self) {
|
436
|
+
Body *body;
|
437
|
+
BODY(self, body);
|
438
|
+
return body->horizontal_axis->rbLine;
|
439
|
+
}
|
440
|
+
|
441
|
+
static void
|
442
|
+
body_relocate(Body *body, Point *point) {
|
443
|
+
gdouble width;
|
444
|
+
gdouble height;
|
445
|
+
if (body->client->state == rb_dodging && !DBL_EQL(point->x, body->origo->x)) {
|
446
|
+
width = SPRITE_HEIGHT;
|
447
|
+
height = SPRITE_WIDTH;
|
448
|
+
} else {
|
449
|
+
width = SPRITE_WIDTH;
|
450
|
+
height = SPRITE_HEIGHT;
|
451
|
+
}
|
452
|
+
body->origo->x = point->x;
|
453
|
+
body->origo->y = point->y;
|
454
|
+
body->vertical_axis->p1->x = point->x;
|
455
|
+
body->vertical_axis->p1->y = point->y - height / 2;
|
456
|
+
body->vertical_axis->p2->x = point->x;
|
457
|
+
body->vertical_axis->p2->y = point->y + height / 2;
|
458
|
+
body->horizontal_axis->p1->x = point->x - width / 2;
|
459
|
+
body->horizontal_axis->p1->y = point->y;
|
460
|
+
body->horizontal_axis->p2->x = point->x + width / 2;
|
461
|
+
body->horizontal_axis->p2->y = point->y;
|
462
|
+
}
|
463
|
+
|
464
|
+
static VALUE
|
465
|
+
rb_body_relocate(VALUE self, VALUE new_origo) {
|
466
|
+
Body *body;
|
467
|
+
Point *point;
|
468
|
+
CHECK_POINT(new_origo);
|
469
|
+
POINT(new_origo, point);
|
470
|
+
BODY(self, body);
|
471
|
+
body_relocate(body, point);
|
472
|
+
return new_origo;
|
473
|
+
}
|
474
|
+
|
475
|
+
static void
|
476
|
+
g_hash_table_insert_key_equals_value_into_string(gpointer key, gpointer value, gpointer user_data) {
|
477
|
+
gpointer *args = (gpointer *) user_data;
|
478
|
+
gchar *str = (gchar *) args[0];
|
479
|
+
gboolean *first = (gboolean *) args[1];
|
480
|
+
gchar neue[BUFFER_UNIT];
|
481
|
+
gint len = strlen(str);
|
482
|
+
gint neuelen = 0;
|
483
|
+
if (*first)
|
484
|
+
snprintf(neue, BUFFER_UNIT, "%s=%s", (gchar *) key, (gchar *) value);
|
485
|
+
else
|
486
|
+
snprintf(neue, BUFFER_UNIT, ", %s=%s", (gchar *) key, (gchar *) value);
|
487
|
+
*first = FALSE;
|
488
|
+
neuelen = strlen(neue);
|
489
|
+
str = realloc(str, sizeof(gchar) * (len + neuelen + 1));
|
490
|
+
strncpy(str + len, neue, neuelen);
|
491
|
+
}
|
492
|
+
|
493
|
+
static gchar*
|
494
|
+
command_inspect(Command *command) {
|
495
|
+
gchar *rval = calloc(BUFFER_UNIT, sizeof(gchar));
|
496
|
+
gboolean first = TRUE;
|
497
|
+
gpointer args[2] = { rval, &first };
|
498
|
+
gint new_len = 0;
|
499
|
+
snprintf(rval, BUFFER_UNIT, "<%s:%p name=%s attributes=[", rb_obj_classname(command->rbCommand), command, command->name);
|
500
|
+
g_hash_table_foreach(command->attributes, g_hash_table_insert_key_equals_value_into_string, args);
|
501
|
+
new_len = strlen(rval);
|
502
|
+
rval = realloc(rval, sizeof(gchar) * (new_len + 3));
|
503
|
+
snprintf(rval + new_len, 3, "]>");
|
504
|
+
return rval;
|
505
|
+
}
|
506
|
+
|
507
|
+
static VALUE
|
508
|
+
rb_command_inspect(VALUE self) {
|
509
|
+
gchar *str;
|
510
|
+
Command *command;
|
511
|
+
VALUE rval;
|
512
|
+
COMMAND(self, command);
|
513
|
+
str = command_inspect(command);
|
514
|
+
rval = rb_str_new2(str);
|
515
|
+
free(str);
|
516
|
+
return rval;
|
517
|
+
}
|
518
|
+
|
519
|
+
static void
|
520
|
+
g_hash_table_insert_command_into_string(gpointer key, gpointer value, gpointer user_data) {
|
521
|
+
gpointer *args = (gpointer *) user_data;
|
522
|
+
gchar *str = (gchar *) args[0];
|
523
|
+
gboolean *first = (gboolean *) args[1];
|
524
|
+
gchar neue[(BUFFER_UNIT * 2)];
|
525
|
+
gint len = strlen(str);
|
526
|
+
gint neuelen = 0;
|
527
|
+
gchar *command_str = command_inspect((Command *) value);
|
528
|
+
if (*first)
|
529
|
+
snprintf(neue, (BUFFER_UNIT * 2), "%s", command_str);
|
530
|
+
else
|
531
|
+
snprintf(neue, (BUFFER_UNIT * 2), ", %s", command_str);
|
532
|
+
free(command_str);
|
533
|
+
*first = FALSE;
|
534
|
+
neuelen = strlen(neue);
|
535
|
+
str = realloc(str, sizeof(gchar) * (len + neuelen + 1));
|
536
|
+
strncpy(str + len, neue, neuelen);
|
537
|
+
}
|
538
|
+
|
539
|
+
static gchar*
|
540
|
+
command_set_inspect(CommandSet *command_set) {
|
541
|
+
gchar *rval = calloc(BUFFER_UNIT, sizeof(gchar));
|
542
|
+
gboolean first = TRUE;
|
543
|
+
gpointer args[2] = { rval, &first };
|
544
|
+
gint new_len = 0;
|
545
|
+
snprintf(rval, BUFFER_UNIT, "<%s:%p commands=[", rb_obj_classname(command_set->rbCommandSet), command_set);
|
546
|
+
g_hash_table_foreach(command_set->commands, g_hash_table_insert_command_into_string, args);
|
547
|
+
new_len = strlen(rval);
|
548
|
+
rval = realloc(rval, sizeof(gchar) * (new_len + 3));
|
549
|
+
snprintf(rval + new_len, 3, "]>");
|
550
|
+
return rval;
|
551
|
+
}
|
552
|
+
|
553
|
+
static VALUE
|
554
|
+
rb_command_set_inspect(VALUE self) {
|
555
|
+
gchar *str;
|
556
|
+
CommandSet *command_set;
|
557
|
+
VALUE rval;
|
558
|
+
COMMAND_SET(self, command_set);
|
559
|
+
str = command_set_inspect(command_set);
|
560
|
+
rval = rb_str_new2(str);
|
561
|
+
free(str);
|
562
|
+
return rval;
|
563
|
+
}
|
564
|
+
|
565
|
+
static VALUE
|
566
|
+
rb_body_inspect(VALUE self) {
|
567
|
+
gchar rval[BUFFER_UNIT];
|
568
|
+
Body *b;
|
569
|
+
gchar *origo;
|
570
|
+
gchar *vert;
|
571
|
+
gchar *hori;
|
572
|
+
BODY(self, b);
|
573
|
+
origo = point_inspect(b->origo);
|
574
|
+
vert = line_inspect(b->vertical_axis);
|
575
|
+
hori = line_inspect(b->horizontal_axis);
|
576
|
+
snprintf(rval, BUFFER_UNIT, "<%s:%p origo=%s vertical_axis=%s horizontal_axis=%s>",
|
577
|
+
rb_obj_classname(self), b,
|
578
|
+
origo,
|
579
|
+
vert,
|
580
|
+
hori);
|
581
|
+
free(origo);
|
582
|
+
free(vert);
|
583
|
+
free(hori);
|
584
|
+
return rb_str_new2(rval);
|
585
|
+
}
|
586
|
+
|
587
|
+
static VALUE
|
588
|
+
rb_client_get_state(VALUE self) {
|
589
|
+
Client *client;
|
590
|
+
CLIENT(self, client);
|
591
|
+
return client->state;
|
592
|
+
}
|
593
|
+
|
594
|
+
static VALUE
|
595
|
+
rb_client_set_state(VALUE self, VALUE new_state) {
|
596
|
+
Client *client;
|
597
|
+
CLIENT(self, client);
|
598
|
+
if (client->state != new_state) {
|
599
|
+
client->status_dirty = TRUE;
|
600
|
+
client->state = new_state;
|
601
|
+
}
|
602
|
+
return new_state;
|
603
|
+
}
|
604
|
+
|
605
|
+
static VALUE
|
606
|
+
rb_client_set_current_command(VALUE self, VALUE new_command) {
|
607
|
+
Client *client;
|
608
|
+
CommandSet *command_set;
|
609
|
+
CHECK_COMMAND_SET(new_command);
|
610
|
+
CLIENT(self, client);
|
611
|
+
COMMAND_SET(new_command, command_set);
|
612
|
+
client->current_command = command_set;
|
613
|
+
return new_command;
|
614
|
+
}
|
615
|
+
|
616
|
+
static VALUE
|
617
|
+
rb_client_get_current_command(VALUE self) {
|
618
|
+
Client *client;
|
619
|
+
CLIENT(self, client);
|
620
|
+
return client->current_command->rbCommandSet;
|
621
|
+
}
|
622
|
+
|
623
|
+
static void
|
624
|
+
init_grueserve_globals() {
|
625
|
+
rb_standing = ID2SYM(rb_intern(standing));
|
626
|
+
rb_dodging = ID2SYM(rb_intern(dodging));
|
627
|
+
rb_dead = ID2SYM(rb_intern(dead));
|
628
|
+
}
|
629
|
+
|
630
|
+
static VALUE
|
631
|
+
rb_client_registered(VALUE self) {
|
632
|
+
Client *client;
|
633
|
+
CLIENT(self, client);
|
634
|
+
return GBOOL2RB(g_hash_table_lookup(client->map->bodies->table, client->body->origo) != NULL);
|
635
|
+
}
|
636
|
+
|
637
|
+
static VALUE
|
638
|
+
rb_client_moving(VALUE self) {
|
639
|
+
Client *client;
|
640
|
+
CLIENT(self, client);
|
641
|
+
return GBOOL2RB(g_hash_table_lookup(client->current_command->commands, UP) != NULL ||
|
642
|
+
g_hash_table_lookup(client->current_command->commands, DOWN) != NULL ||
|
643
|
+
g_hash_table_lookup(client->current_command->commands, LEFT) != NULL ||
|
644
|
+
g_hash_table_lookup(client->current_command->commands, RIGHT) != NULL);
|
645
|
+
}
|
646
|
+
|
647
|
+
static gpointer
|
648
|
+
map_yield_client(Client *client, gpointer user_data) {
|
649
|
+
rb_yield(( (Client *) client)->rbClient);
|
650
|
+
return NULL;
|
651
|
+
}
|
652
|
+
|
653
|
+
static gboolean
|
654
|
+
g_hash_table_call_handler_for_client_for_body_until(gpointer key, gpointer value, gpointer user_data) {
|
655
|
+
gpointer *args = (gpointer *) user_data;
|
656
|
+
Map *map = (Map *) args[0];
|
657
|
+
client_handler handler = (client_handler) args[1];
|
658
|
+
gpointer handler_args = args[2];
|
659
|
+
gpointer *rval = (gpointer *) args[3];
|
660
|
+
Client *client = (Client *) g_hash_table_lookup(map->client_by_whatever, key);
|
661
|
+
if (client == NULL)
|
662
|
+
rb_raise(rb_eRuntimeError, "%s: Weird! The body doesnt have a Client!", __PRETTY_FUNCTION__);
|
663
|
+
if (((*rval) = handler(client, handler_args)) != NULL)
|
664
|
+
return TRUE;
|
665
|
+
else
|
666
|
+
return FALSE;
|
667
|
+
}
|
668
|
+
|
669
|
+
static gpointer
|
670
|
+
map_each_client_until(Map *map, client_handler handler, gpointer handler_args) {
|
671
|
+
gpointer rval;
|
672
|
+
gpointer args[4] = { map, handler, handler_args, &rval };
|
673
|
+
g_hash_table_find(map->bodies->table, g_hash_table_call_handler_for_client_for_body_until, args);
|
674
|
+
return rval;
|
675
|
+
}
|
676
|
+
|
677
|
+
static VALUE
|
678
|
+
rb_map_each_client(VALUE self) {
|
679
|
+
Map *map;
|
680
|
+
MAP(self, map);
|
681
|
+
map_each_client_until(map, map_yield_client, NULL);
|
682
|
+
return Qnil;
|
683
|
+
}
|
684
|
+
|
685
|
+
static VALUE
|
686
|
+
rb_map_alloc(VALUE class) {
|
687
|
+
Map *map = ALLOC(Map);
|
688
|
+
map->movement_obstacles = new_geo_set();
|
689
|
+
RB_LINE_SET(map->movement_obstacles, rb_line_set);
|
690
|
+
map->visibility_obstacles = new_geo_set();
|
691
|
+
RB_LINE_SET(map->visibility_obstacles, rb_line_set);
|
692
|
+
map->bullet_obstacles = new_geo_set();
|
693
|
+
RB_LINE_SET(map->bullet_obstacles, rb_line_set);
|
694
|
+
map->hearing_obstacles = new_geo_set();
|
695
|
+
RB_LINE_SET(map->hearing_obstacles, rb_line_set);
|
696
|
+
map->fortifications = new_geo_set();
|
697
|
+
RB_LINE_SET(map->fortifications, rb_line_set);
|
698
|
+
map->speed_areas = new_geo_set();
|
699
|
+
RB_TRIANGLE_SET(map->speed_areas, rb_triangle_set);
|
700
|
+
map->protection_areas = new_geo_set();
|
701
|
+
RB_TRIANGLE_SET(map->protection_areas, rb_triangle_set);
|
702
|
+
map->hidden_areas = new_geo_set();
|
703
|
+
RB_TRIANGLE_SET(map->hidden_areas, rb_triangle_set);
|
704
|
+
|
705
|
+
map->config_by_whatever = g_hash_table_new(g_direct_hash, g_direct_equal);
|
706
|
+
|
707
|
+
map->bodies = new_geo_set();
|
708
|
+
map->bodies->indexed = FALSE;
|
709
|
+
RB_POINT_SET(map->bodies, rb_point_set);
|
710
|
+
map->eyes = new_geo_set();
|
711
|
+
map->eyes->indexed = FALSE;
|
712
|
+
RB_POINT_SET(map->eyes, rb_point_set);
|
713
|
+
map->body_parts = new_geo_set();
|
714
|
+
map->body_parts->indexed = FALSE;
|
715
|
+
RB_LINE_SET(map->body_parts, rb_line_set);
|
716
|
+
|
717
|
+
map->client_by_whatever = g_hash_table_new(g_direct_hash, g_direct_equal);
|
718
|
+
|
719
|
+
map->timeout = 10;
|
720
|
+
map->viewing_distance_limit = 1000.0;
|
721
|
+
|
722
|
+
return RB_MAP(map, class);
|
723
|
+
}
|
724
|
+
|
725
|
+
static VALUE
|
726
|
+
rb_map_set(VALUE self, VALUE key, VALUE value) {
|
727
|
+
Map *map;
|
728
|
+
gpointer key_p;
|
729
|
+
if (LINE_P(key)) {
|
730
|
+
LINE(key, key_p);
|
731
|
+
} else if (TRIANGLE_P(key)) {
|
732
|
+
TRIANGLE(key, key_p);
|
733
|
+
} else if (POINT_P(key)) {
|
734
|
+
POINT(key, key_p);
|
735
|
+
} else {
|
736
|
+
rb_raise(rb_eTypeError, "%s#[]= requires a Geo::Line, a Geo::Point or a Geo::Triangle as first parameter.", rb_obj_classname(self));
|
737
|
+
}
|
738
|
+
MAP(self, map);
|
739
|
+
Check_Type(value, T_FIXNUM);
|
740
|
+
g_hash_table_insert(map->config_by_whatever, key_p, GINT_TO_POINTER(NUM2INT(value)));
|
741
|
+
return value;
|
742
|
+
}
|
743
|
+
|
744
|
+
static VALUE
|
745
|
+
rb_map_get(VALUE self, VALUE key) {
|
746
|
+
gpointer key_p;
|
747
|
+
gpointer rval;
|
748
|
+
Map *map;
|
749
|
+
if (LINE_P(key)) {
|
750
|
+
LINE(key, key_p);
|
751
|
+
} else if (POINT_P(key)) {
|
752
|
+
POINT(key, key_p);
|
753
|
+
} else if (TRIANGLE_P(key)) {
|
754
|
+
TRIANGLE(key, key_p);
|
755
|
+
} else {
|
756
|
+
rb_raise(rb_eTypeError, "%s[] requires a Geo::Line, a Geo::Point or a Geo::Triangle as argument.", rb_obj_classname(self));
|
757
|
+
}
|
758
|
+
MAP(self, map);
|
759
|
+
if ((rval = g_hash_table_lookup(map->config_by_whatever, key_p)) != NULL) {
|
760
|
+
return INT2NUM(GPOINTER_TO_INT(rval));
|
761
|
+
} else if ((rval = g_hash_table_lookup(map->client_by_whatever, key_p)) != NULL) {
|
762
|
+
return ( (Client *) rval )->rbClient;
|
763
|
+
}
|
764
|
+
return Qnil;
|
765
|
+
}
|
766
|
+
|
767
|
+
static VALUE
|
768
|
+
rb_map_movement_obstacles(VALUE self) {
|
769
|
+
Map *map;
|
770
|
+
MAP(self, map);
|
771
|
+
return map->movement_obstacles->rbGeoSet;
|
772
|
+
}
|
773
|
+
|
774
|
+
static VALUE
|
775
|
+
rb_map_visibility_obstacles(VALUE self) {
|
776
|
+
Map *map;
|
777
|
+
MAP(self, map);
|
778
|
+
return map->visibility_obstacles->rbGeoSet;
|
779
|
+
}
|
780
|
+
|
781
|
+
static VALUE
|
782
|
+
rb_map_bullet_obstacles(VALUE self) {
|
783
|
+
Map *map;
|
784
|
+
MAP(self, map);
|
785
|
+
return map->bullet_obstacles->rbGeoSet;
|
786
|
+
}
|
787
|
+
|
788
|
+
static VALUE
|
789
|
+
rb_map_hearing_obstacles(VALUE self) {
|
790
|
+
Map *map;
|
791
|
+
MAP(self, map);
|
792
|
+
return map->hearing_obstacles->rbGeoSet;
|
793
|
+
}
|
794
|
+
|
795
|
+
static VALUE
|
796
|
+
rb_map_fortifications(VALUE self) {
|
797
|
+
Map *map;
|
798
|
+
MAP(self, map);
|
799
|
+
return map->fortifications->rbGeoSet;
|
800
|
+
}
|
801
|
+
|
802
|
+
static VALUE
|
803
|
+
rb_map_speed_areas(VALUE self) {
|
804
|
+
Map *map;
|
805
|
+
MAP(self, map);
|
806
|
+
return map->speed_areas->rbGeoSet;
|
807
|
+
}
|
808
|
+
|
809
|
+
static VALUE
|
810
|
+
rb_map_protection_areas(VALUE self) {
|
811
|
+
Map *map;
|
812
|
+
MAP(self, map);
|
813
|
+
return map->protection_areas->rbGeoSet;
|
814
|
+
}
|
815
|
+
|
816
|
+
static VALUE
|
817
|
+
rb_map_hidden_areas(VALUE self) {
|
818
|
+
Map *map;
|
819
|
+
MAP(self, map);
|
820
|
+
return map->hidden_areas->rbGeoSet;
|
821
|
+
}
|
822
|
+
|
823
|
+
static VALUE
|
824
|
+
rb_client_set_map(VALUE self, VALUE new_map) {
|
825
|
+
Client *client;
|
826
|
+
Map *map;
|
827
|
+
CHECK_MAP(new_map);
|
828
|
+
CLIENT(self, client);
|
829
|
+
MAP(new_map, map);
|
830
|
+
client->map = map;
|
831
|
+
return new_map;
|
832
|
+
}
|
833
|
+
|
834
|
+
static VALUE
|
835
|
+
rb_client_get_map(VALUE self) {
|
836
|
+
Client *client;
|
837
|
+
CLIENT(self, client);
|
838
|
+
if (client->map == NULL)
|
839
|
+
return Qnil;
|
840
|
+
return client->map->rbMap;
|
841
|
+
}
|
842
|
+
|
843
|
+
static VALUE
|
844
|
+
rb_client_client_id(VALUE self) {
|
845
|
+
Client *client;
|
846
|
+
gchar rval[BUFFER_UNIT];
|
847
|
+
CLIENT(self, client);
|
848
|
+
snprintf(rval, BUFFER_UNIT, "%p", client);
|
849
|
+
return rb_str_new2(rval);
|
850
|
+
}
|
851
|
+
|
852
|
+
static VALUE
|
853
|
+
rb_client_get_last_ping(VALUE self) {
|
854
|
+
Client *client;
|
855
|
+
CLIENT(self, client);
|
856
|
+
return INT2NUM((gint) client->last_ping);
|
857
|
+
}
|
858
|
+
|
859
|
+
static VALUE
|
860
|
+
rb_client_ping(VALUE self) {
|
861
|
+
Client *client;
|
862
|
+
CLIENT(self, client);
|
863
|
+
client->last_ping = time(NULL);
|
864
|
+
return INT2NUM((gint) client->last_ping);
|
865
|
+
}
|
866
|
+
|
867
|
+
static void
|
868
|
+
map_move(Map *map, Point *from, Point *to, Point *rval) {
|
869
|
+
Line *movement_line = new_line_with_coordinates(from->x, from->y,
|
870
|
+
to->x, to->y);
|
871
|
+
line_set_slide_point(map->movement_obstacles, movement_line, 3);
|
872
|
+
rval->x = movement_line->p2->x;
|
873
|
+
rval->y = movement_line->p2->y;
|
874
|
+
line_free(movement_line);
|
875
|
+
}
|
876
|
+
|
877
|
+
static gpointer
|
878
|
+
map_add_overlap_factor_to_virtual_length(GeoSet *set, gpointer triangle, gpointer user_data) {
|
879
|
+
gpointer *args = (gpointer *) user_data;
|
880
|
+
Line *line = (Line *) args[0];
|
881
|
+
gdouble *virtual_length = (gdouble *) args[1];
|
882
|
+
Map *map = (Map *) args[2];
|
883
|
+
Line *overlap = triangle_overlap((Triangle *) triangle, line);
|
884
|
+
gint triangle_value = GPOINTER_TO_INT(g_hash_table_lookup(map->config_by_whatever, triangle));
|
885
|
+
(*virtual_length) += (DISTANCE(overlap->p1, overlap->p2) * (triangle_value / 1000.0));
|
886
|
+
line_free(overlap);
|
887
|
+
return NULL;
|
888
|
+
}
|
889
|
+
|
890
|
+
static gboolean
|
891
|
+
map_line_hidden(Map *map, Line *line) {
|
892
|
+
gdouble virtual_length = DISTANCE(line->p1, line->p2);
|
893
|
+
gpointer args[3] = { line, &virtual_length, map };
|
894
|
+
triangle_set_each_intersector_until(map->hidden_areas, line, map_add_overlap_factor_to_virtual_length, args);
|
895
|
+
return virtual_length > map->viewing_distance_limit;
|
896
|
+
}
|
897
|
+
|
898
|
+
static gpointer
|
899
|
+
map_call_client_handler_if_within_visible_range(GeoSet *set, gpointer line, gpointer user_data) {
|
900
|
+
gpointer *args = (gpointer *) user_data;
|
901
|
+
client_handler handler = (client_handler) args[0];
|
902
|
+
gpointer handler_args = args[1];
|
903
|
+
Map *map = (Map *) args[2];
|
904
|
+
GHashTable *seen_clients = (GHashTable *) args[3];
|
905
|
+
Client *client = (Client *) g_hash_table_lookup(map->client_by_whatever, ( (Line *) line )->p2);
|
906
|
+
if (client == NULL) {
|
907
|
+
rb_raise(rb_eRuntimeError, "%s: Weird! The viewing Point doesnt seem to have a Client!", __PRETTY_FUNCTION__);
|
908
|
+
}
|
909
|
+
if (!map_line_hidden(map, (Line *) line)) {
|
910
|
+
if (g_hash_table_lookup(seen_clients, client) == NULL) {
|
911
|
+
handler(client, handler_args);
|
912
|
+
g_hash_table_insert(seen_clients, client, GINT_TO_POINTER(1));
|
913
|
+
}
|
914
|
+
}
|
915
|
+
return NULL;
|
916
|
+
}
|
917
|
+
|
918
|
+
static void
|
919
|
+
map_each_viewer_of(Map *map, Point *what, client_handler handler, gpointer user_data) {
|
920
|
+
GeoSet *what_set = new_geo_set();
|
921
|
+
GHashTable *seen_clients = g_hash_table_new(g_direct_hash, g_direct_equal);
|
922
|
+
gpointer args[4] = { handler, user_data, map, seen_clients };
|
923
|
+
|
924
|
+
g_hash_table_insert(what_set->table, what, what);
|
925
|
+
|
926
|
+
line_set_each_intersection_free_endpoint(map->visibility_obstacles,
|
927
|
+
what_set,
|
928
|
+
map->eyes,
|
929
|
+
map->viewing_distance_limit,
|
930
|
+
map_call_client_handler_if_within_visible_range,
|
931
|
+
args);
|
932
|
+
g_hash_table_destroy(seen_clients);
|
933
|
+
geo_set_free(what_set);
|
934
|
+
}
|
935
|
+
|
936
|
+
static gpointer
|
937
|
+
client_add_client_to_rb_ary(Client *client, gpointer user_data) {
|
938
|
+
rb_ary_push(*( (VALUE *) user_data), client->rbClient);
|
939
|
+
return NULL;
|
940
|
+
}
|
941
|
+
|
942
|
+
static VALUE
|
943
|
+
rb_map_viewers_of(VALUE self, VALUE p) {
|
944
|
+
Map *map;
|
945
|
+
Point *point;
|
946
|
+
VALUE rval;
|
947
|
+
CHECK_POINT(p);
|
948
|
+
MAP(self, map);
|
949
|
+
POINT(p, point);
|
950
|
+
rval = rb_ary_new();
|
951
|
+
map_each_viewer_of(map, point, client_add_client_to_rb_ary, &rval);
|
952
|
+
return rval;
|
953
|
+
}
|
954
|
+
|
955
|
+
static gpointer
|
956
|
+
client_call_viewing_handler_if_clients_within_visible_range(GeoSet *set, gpointer line, gpointer user_data) {
|
957
|
+
gpointer *args = (gpointer *) user_data;
|
958
|
+
viewing_handler handler = (viewing_handler) args[0];
|
959
|
+
gpointer handler_args = args[1];
|
960
|
+
Client *viewer = (Client *) args[2];
|
961
|
+
Client *viewee = (Client *) args[3];
|
962
|
+
GHashTable *seen_viewers = (GHashTable *) args[4];
|
963
|
+
GHashTable *seen_viewees = (GHashTable *) args[5];
|
964
|
+
Map *map = (Map *) args[6];
|
965
|
+
if (viewer != NULL) {
|
966
|
+
if (viewer->map == NULL)
|
967
|
+
rb_raise(rb_eRuntimeError, "%s: Weird! The viewer doesnt have a Map!", __PRETTY_FUNCTION__);
|
968
|
+
if ((viewee = (Client *) g_hash_table_lookup(viewer->map->client_by_whatever, ( (Line *) line )->p2)) != NULL) {
|
969
|
+
if (!map_line_hidden(map, (Line *) line)) {
|
970
|
+
if (g_hash_table_lookup(seen_viewees, viewee) == NULL) {
|
971
|
+
handler(viewer, viewee, handler_args);
|
972
|
+
g_hash_table_insert(seen_viewees, viewee, GINT_TO_POINTER(1));
|
973
|
+
}
|
974
|
+
}
|
975
|
+
} else {
|
976
|
+
rb_raise(rb_eRuntimeError, "%s: Weird! The viewed Point doesnt seem to have a Client!", __PRETTY_FUNCTION__);
|
977
|
+
}
|
978
|
+
} else if (viewee != NULL) {
|
979
|
+
if (viewee->map == NULL)
|
980
|
+
rb_raise(rb_eRuntimeError, "%s: Weird! The viewee doesnt have a Map!", __PRETTY_FUNCTION__);
|
981
|
+
if ((viewer = (Client *) g_hash_table_lookup(viewee->map->client_by_whatever, ( (Line *) line )->p2)) != NULL) {
|
982
|
+
if (!map_line_hidden(map, (Line *) line)) {
|
983
|
+
if (g_hash_table_lookup(seen_viewers, viewer) == NULL) {
|
984
|
+
handler(viewer, viewee, handler_args);
|
985
|
+
g_hash_table_insert(seen_viewers, viewer, GINT_TO_POINTER(1));
|
986
|
+
}
|
987
|
+
}
|
988
|
+
} else {
|
989
|
+
rb_raise(rb_eRuntimeError, "%s: Weird! The viewing Point doesnt seem to have a Client!", __PRETTY_FUNCTION__);
|
990
|
+
}
|
991
|
+
} else {
|
992
|
+
rb_raise(rb_eRuntimeError, "%s: Weird! map_call_viewing_handler should always have either viewer or viewee set!", __PRETTY_FUNCTION__);
|
993
|
+
}
|
994
|
+
return NULL;
|
995
|
+
}
|
996
|
+
|
997
|
+
static void
|
998
|
+
client_each_viewee(Client *viewer, viewing_handler handler, gpointer user_data) {
|
999
|
+
GeoSet *eyes = new_geo_set();
|
1000
|
+
GHashTable *seen_viewees = g_hash_table_new(g_direct_hash, g_direct_equal);
|
1001
|
+
gpointer args[7] = { handler, user_data, viewer, NULL, NULL, seen_viewees, viewer->map };
|
1002
|
+
|
1003
|
+
g_hash_table_insert(eyes->table, viewer->body->horizontal_axis->p1, viewer->body->horizontal_axis->p1);
|
1004
|
+
g_hash_table_insert(eyes->table, viewer->body->horizontal_axis->p2, viewer->body->horizontal_axis->p2);
|
1005
|
+
g_hash_table_insert(eyes->table, viewer->body->vertical_axis->p1, viewer->body->vertical_axis->p1);
|
1006
|
+
g_hash_table_insert(eyes->table, viewer->body->vertical_axis->p2, viewer->body->vertical_axis->p2);
|
1007
|
+
|
1008
|
+
line_set_each_intersection_free_endpoint(viewer->map->visibility_obstacles,
|
1009
|
+
eyes,
|
1010
|
+
viewer->map->bodies,
|
1011
|
+
viewer->map->viewing_distance_limit,
|
1012
|
+
client_call_viewing_handler_if_clients_within_visible_range,
|
1013
|
+
args);
|
1014
|
+
|
1015
|
+
g_hash_table_destroy(seen_viewees);
|
1016
|
+
geo_set_free(eyes);
|
1017
|
+
}
|
1018
|
+
|
1019
|
+
static void
|
1020
|
+
client_each_viewer(Client *viewee, viewing_handler handler, gpointer user_data) {
|
1021
|
+
GeoSet *body_set = new_geo_set();
|
1022
|
+
GHashTable *seen_viewers = g_hash_table_new(g_direct_hash, g_direct_equal);
|
1023
|
+
gpointer args[7] = { handler, user_data, NULL, viewee, seen_viewers, NULL, viewee->map };
|
1024
|
+
|
1025
|
+
g_hash_table_insert(body_set->table, viewee->body->origo, viewee->body->origo);
|
1026
|
+
|
1027
|
+
line_set_each_intersection_free_endpoint(viewee->map->visibility_obstacles,
|
1028
|
+
body_set,
|
1029
|
+
viewee->map->eyes,
|
1030
|
+
viewee->map->viewing_distance_limit,
|
1031
|
+
client_call_viewing_handler_if_clients_within_visible_range,
|
1032
|
+
args);
|
1033
|
+
g_hash_table_destroy(seen_viewers);
|
1034
|
+
geo_set_free(body_set);
|
1035
|
+
}
|
1036
|
+
|
1037
|
+
static gpointer
|
1038
|
+
client_add_viewer_to_rb_ary(Client *viewer, Client *viewee, gpointer user_data) {
|
1039
|
+
rb_ary_push(*( (VALUE *) user_data), viewer->rbClient);
|
1040
|
+
return NULL;
|
1041
|
+
}
|
1042
|
+
|
1043
|
+
static gpointer
|
1044
|
+
client_add_viewee_to_rb_ary(Client *viewer, Client *viewee, gpointer user_data) {
|
1045
|
+
rb_ary_push(*( (VALUE *) user_data), viewee->rbClient);
|
1046
|
+
return NULL;
|
1047
|
+
}
|
1048
|
+
|
1049
|
+
static VALUE
|
1050
|
+
rb_client_viewers(VALUE self) {
|
1051
|
+
Client *client;
|
1052
|
+
VALUE rval = rb_ary_new();
|
1053
|
+
CLIENT(self, client);
|
1054
|
+
client_each_viewer(client, client_add_viewer_to_rb_ary, &rval);
|
1055
|
+
return rval;
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
static VALUE
|
1059
|
+
rb_client_viewees(VALUE self) {
|
1060
|
+
Client *client;
|
1061
|
+
VALUE rval = rb_ary_new();
|
1062
|
+
CLIENT(self, client);
|
1063
|
+
client_each_viewee(client, client_add_viewee_to_rb_ary, &rval);
|
1064
|
+
return rval;
|
1065
|
+
}
|
1066
|
+
|
1067
|
+
static gpointer
|
1068
|
+
map_increase_gdouble_with_config(GeoSet *set, gpointer triangle, gpointer user_data) {
|
1069
|
+
gpointer *args = (gpointer *) user_data;
|
1070
|
+
Map *map = (Map *) args[0];
|
1071
|
+
gdouble *to_increase = (gdouble *) args[1];
|
1072
|
+
gint config = GPOINTER_TO_INT(g_hash_table_lookup(map->config_by_whatever, triangle));
|
1073
|
+
if (*to_increase < (config / 1000.0))
|
1074
|
+
(*to_increase) = (config / 1000.0);
|
1075
|
+
return NULL;
|
1076
|
+
}
|
1077
|
+
|
1078
|
+
static gdouble
|
1079
|
+
map_speed_factor(Map *map, Point *point) {
|
1080
|
+
gdouble rval = 1.0;
|
1081
|
+
gpointer args[2] = { map, &rval };
|
1082
|
+
triangle_set_each_container_until(map->speed_areas, point, map_increase_gdouble_with_config, args);
|
1083
|
+
return rval;
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
static gdouble
|
1087
|
+
client_speed(Client *client) {
|
1088
|
+
gdouble rval = client->running_speed;
|
1089
|
+
if (client->state == rb_dodging)
|
1090
|
+
rval /= 5.0;
|
1091
|
+
rval *= map_speed_factor(client->map, client->body->origo);
|
1092
|
+
return rval;
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
static gpointer
|
1096
|
+
client_add_viewer_to_hash(Client *viewer, Client *viewee, gpointer user_data) {
|
1097
|
+
g_hash_table_insert((GHashTable *) user_data, viewer, viewer);
|
1098
|
+
return NULL;
|
1099
|
+
}
|
1100
|
+
|
1101
|
+
static gpointer
|
1102
|
+
client_add_viewee_to_hash(Client *viewer, Client *viewee, gpointer user_data) {
|
1103
|
+
g_hash_table_insert((GHashTable *) user_data, viewee, viewee);
|
1104
|
+
return NULL;
|
1105
|
+
}
|
1106
|
+
|
1107
|
+
static gboolean
|
1108
|
+
socket_send(gint fn, gchar *to_send, gint to_send_len, struct timeval wait_time) {
|
1109
|
+
gchar *position = to_send;
|
1110
|
+
gint write_rval;
|
1111
|
+
while (position < to_send + to_send_len) {
|
1112
|
+
write_rval = write(fn, position, to_send_len + to_send - position);
|
1113
|
+
if (write_rval != -1) {
|
1114
|
+
gchar blaj[to_send_len];
|
1115
|
+
snprintf(blaj, write_rval + 1, "%s", position);
|
1116
|
+
position += write_rval;
|
1117
|
+
} else if (errno == EAGAIN) {
|
1118
|
+
rb_thread_wait_for(wait_time);
|
1119
|
+
} else {
|
1120
|
+
return FALSE;
|
1121
|
+
}
|
1122
|
+
}
|
1123
|
+
return TRUE;
|
1124
|
+
}
|
1125
|
+
|
1126
|
+
static void
|
1127
|
+
client_send(Client *client, gchar *str, gint len) {
|
1128
|
+
FILE *file;
|
1129
|
+
gchar header[BUFFER_UNIT];
|
1130
|
+
gint fn;
|
1131
|
+
struct timeval wait_time = { 0, 1000 };
|
1132
|
+
|
1133
|
+
while (client->socket_locked)
|
1134
|
+
rb_thread_wait_for(wait_time);
|
1135
|
+
|
1136
|
+
client->socket_locked = TRUE;
|
1137
|
+
|
1138
|
+
file = GetWriteFile(client->socket);
|
1139
|
+
rb_io_set_nonblock(client->socket);
|
1140
|
+
fn = fileno(file);
|
1141
|
+
|
1142
|
+
snprintf(header, BUFFER_UNIT, "%i:", len);
|
1143
|
+
if (!socket_send(fn, header, strlen(header), wait_time)) {
|
1144
|
+
client->socket_locked = FALSE;
|
1145
|
+
rb_sys_fail(client->socket->path);
|
1146
|
+
}
|
1147
|
+
|
1148
|
+
if (!socket_send(fn, str, len, wait_time)) {
|
1149
|
+
client->socket_locked = FALSE;
|
1150
|
+
rb_sys_fail(client->socket->path);
|
1151
|
+
}
|
1152
|
+
|
1153
|
+
DEBUG("sent to %p: %s%s", client, header, str);
|
1154
|
+
|
1155
|
+
client->socket_locked = FALSE;
|
1156
|
+
}
|
1157
|
+
|
1158
|
+
static gpointer
|
1159
|
+
client_send_unscore_for(Client *recipient, gpointer other) {
|
1160
|
+
gchar msg[BUFFER_UNIT * 2];
|
1161
|
+
Client *client = (Client *) other;
|
1162
|
+
snprintf(msg, BUFFER_UNIT * 2, "xml:<MESSAGE><UNSCORE id=\"%p\"/></MESSAGE>",
|
1163
|
+
client);
|
1164
|
+
client_send(recipient, msg, strlen(msg));
|
1165
|
+
return NULL;
|
1166
|
+
}
|
1167
|
+
|
1168
|
+
static void
|
1169
|
+
client_broadcast_unscore(Client *client) {
|
1170
|
+
map_each_client_until(client->map, client_send_unscore_for, client);
|
1171
|
+
}
|
1172
|
+
|
1173
|
+
static VALUE
|
1174
|
+
rb_client_unregister(VALUE self) {
|
1175
|
+
Client *client;
|
1176
|
+
CLIENT(self, client);
|
1177
|
+
map_unregister_body(client->map, client->body);
|
1178
|
+
client_broadcast_unscore(client);
|
1179
|
+
return self;
|
1180
|
+
}
|
1181
|
+
|
1182
|
+
static gchar*
|
1183
|
+
client_model(Client *client) {
|
1184
|
+
gchar *rval = calloc(BUFFER_UNIT, sizeof(gchar));
|
1185
|
+
snprintf(rval, BUFFER_UNIT, "%s_%s", client->team, client->behaviour);
|
1186
|
+
return rval;
|
1187
|
+
}
|
1188
|
+
|
1189
|
+
static gpointer
|
1190
|
+
map_sum_score_for_team(Client *client, gpointer user_data) {
|
1191
|
+
gpointer *args = (gpointer *) user_data;
|
1192
|
+
gchar *team = (gchar *) args[0];
|
1193
|
+
gdouble *sum = (gdouble *) args[1];
|
1194
|
+
if (strcmp(team, client->team) == 0)
|
1195
|
+
(*sum) += client->score;
|
1196
|
+
return NULL;
|
1197
|
+
}
|
1198
|
+
|
1199
|
+
static gdouble
|
1200
|
+
map_team_score(Map *map, gchar *team) {
|
1201
|
+
gdouble sum = 0;
|
1202
|
+
gpointer args[2] = { team, &sum };
|
1203
|
+
map_each_client_until(map, map_sum_score_for_team, args);
|
1204
|
+
return sum;
|
1205
|
+
}
|
1206
|
+
|
1207
|
+
static char*
|
1208
|
+
client_state(Client *client) {
|
1209
|
+
return client->state == rb_standing ? standing : (client->state == rb_dodging ? dodging : dead);
|
1210
|
+
}
|
1211
|
+
|
1212
|
+
static void
|
1213
|
+
client_send_score(Client *recipient, Client *subject) {
|
1214
|
+
gchar msg[BUFFER_UNIT * 2];
|
1215
|
+
snprintf(msg, BUFFER_UNIT * 2, "xml:<MESSAGE><SCORE id=\"%p\" nickname=\"%s\" team=\"%s\" state=\"%s\" score=\"%.1f\" kills=\"%.0f\" deaths=\"%.0f\"/></MESSAGE>",
|
1216
|
+
subject,
|
1217
|
+
subject->nickname,
|
1218
|
+
subject->team,
|
1219
|
+
client_state(subject),
|
1220
|
+
subject->score,
|
1221
|
+
subject->kills,
|
1222
|
+
subject->deaths);
|
1223
|
+
client_send(recipient, msg, strlen(msg));
|
1224
|
+
}
|
1225
|
+
|
1226
|
+
static gpointer
|
1227
|
+
client_send_score_for(Client *recipient, gpointer other) {
|
1228
|
+
client_send_score(recipient, (Client *) other);
|
1229
|
+
return NULL;
|
1230
|
+
}
|
1231
|
+
|
1232
|
+
static void
|
1233
|
+
client_broadcast_score(Client *client) {
|
1234
|
+
map_each_client_until(client->map, client_send_score_for, client);
|
1235
|
+
}
|
1236
|
+
|
1237
|
+
static gpointer
|
1238
|
+
client_receive_score_for(Client *subject, gpointer recipient) {
|
1239
|
+
client_send_score((Client *) recipient, subject);
|
1240
|
+
return NULL;
|
1241
|
+
}
|
1242
|
+
|
1243
|
+
static void
|
1244
|
+
client_receive_scores(Client *client) {
|
1245
|
+
map_each_client_until(client->map, client_receive_score_for, client);
|
1246
|
+
}
|
1247
|
+
|
1248
|
+
static VALUE
|
1249
|
+
rb_client_register(VALUE self) {
|
1250
|
+
Client *client;
|
1251
|
+
CLIENT(self, client);
|
1252
|
+
map_register_body(client->map, client->body);
|
1253
|
+
client_receive_scores(client);
|
1254
|
+
client->status_dirty = TRUE;
|
1255
|
+
return self;
|
1256
|
+
}
|
1257
|
+
|
1258
|
+
static void
|
1259
|
+
client_send_status(Client *client) {
|
1260
|
+
if (client->status_dirty) {
|
1261
|
+
gchar msg[BUFFER_UNIT * 2];
|
1262
|
+
snprintf(msg, BUFFER_UNIT * 2, "xml:<MESSAGE><STATUS player_score=\"%.1f\" team_score=\"%.1f\" hitpoints=\"%.1f\" extra=\"%s\" id=\"%p\"/></MESSAGE>",
|
1263
|
+
client->score,
|
1264
|
+
map_team_score(client->map, client->team),
|
1265
|
+
client->hitpoints,
|
1266
|
+
client->extra_status != NULL ? client->extra_status : "",
|
1267
|
+
client);
|
1268
|
+
client_send(client, msg, strlen(msg));
|
1269
|
+
|
1270
|
+
client_broadcast_score(client);
|
1271
|
+
|
1272
|
+
client->status_dirty = FALSE;
|
1273
|
+
}
|
1274
|
+
}
|
1275
|
+
|
1276
|
+
static void
|
1277
|
+
client_send_sighting(Client *viewer, Client *viewee) {
|
1278
|
+
gchar msg[BUFFER_UNIT];
|
1279
|
+
gchar *model = client_model(viewee);
|
1280
|
+
snprintf(msg, BUFFER_UNIT, "xml:<MESSAGE><SIGHTING id=\"%p\" nickname=\"%s\" model=\"%s\" state=\"%s\" x=\"%i\" y=\"%i\"/></MESSAGE>",
|
1281
|
+
viewee,
|
1282
|
+
viewee->nickname,
|
1283
|
+
model,
|
1284
|
+
client_state(viewee),
|
1285
|
+
(gint) round(viewee->body->origo->x),
|
1286
|
+
(gint) round(viewee->body->origo->y));
|
1287
|
+
free(model);
|
1288
|
+
client_send(viewer, msg, strlen(msg));
|
1289
|
+
}
|
1290
|
+
|
1291
|
+
static VALUE
|
1292
|
+
rb_client_send_sighting(VALUE self, VALUE o) {
|
1293
|
+
Client *client;
|
1294
|
+
Client *other;
|
1295
|
+
CHECK_CLIENT(o);
|
1296
|
+
CLIENT(self, client);
|
1297
|
+
CLIENT(o, other);
|
1298
|
+
client_send_sighting(client, other);
|
1299
|
+
return o;
|
1300
|
+
}
|
1301
|
+
|
1302
|
+
static void
|
1303
|
+
client_send_disappearance(Client *viewer, Client *viewee) {
|
1304
|
+
gchar msg[BUFFER_UNIT];
|
1305
|
+
snprintf(msg, BUFFER_UNIT, "xml:<MESSAGE><DISAPPEARANCE id=\"%p\"/></MESSAGE>",
|
1306
|
+
viewee);
|
1307
|
+
client_send(viewer, msg, strlen(msg));
|
1308
|
+
}
|
1309
|
+
|
1310
|
+
static VALUE
|
1311
|
+
rb_client_send_disappearance(VALUE self, VALUE o) {
|
1312
|
+
Client *client;
|
1313
|
+
Client *other;
|
1314
|
+
CHECK_CLIENT(o);
|
1315
|
+
CLIENT(self, client);
|
1316
|
+
CLIENT(o, other);
|
1317
|
+
client_send_disappearance(client, other);
|
1318
|
+
return o;
|
1319
|
+
}
|
1320
|
+
|
1321
|
+
static gpointer
|
1322
|
+
client_send_sighting_and_remove_viewer_from_hash(Client *viewer, Client *viewee, gpointer user_data) {
|
1323
|
+
GHashTable *old_viewers = (GHashTable *) user_data;
|
1324
|
+
client_send_sighting(viewer, viewee);
|
1325
|
+
if (g_hash_table_lookup(old_viewers, viewer) != NULL)
|
1326
|
+
g_hash_table_remove(old_viewers, viewer);
|
1327
|
+
return NULL;
|
1328
|
+
}
|
1329
|
+
|
1330
|
+
static gpointer
|
1331
|
+
client_send_sighting_and_remove_viewee_from_hash(Client *viewer, Client *viewee, gpointer user_data) {
|
1332
|
+
gpointer *args = (gpointer *) user_data;
|
1333
|
+
GHashTable *old_viewees = (GHashTable *) args[0];
|
1334
|
+
Client *self = (Client *) args[1];
|
1335
|
+
if (viewee != self)
|
1336
|
+
client_send_sighting(viewer, viewee);
|
1337
|
+
if (g_hash_table_lookup(old_viewees, viewee) != NULL)
|
1338
|
+
g_hash_table_remove(old_viewees, viewee);
|
1339
|
+
return NULL;
|
1340
|
+
}
|
1341
|
+
|
1342
|
+
static void
|
1343
|
+
g_hash_table_send_disappearance_to_key(gpointer key, gpointer value, gpointer user_data) {
|
1344
|
+
client_send_disappearance((Client *) key, (Client *) user_data);
|
1345
|
+
}
|
1346
|
+
|
1347
|
+
static void
|
1348
|
+
g_hash_table_send_disappearance_to_user_data(gpointer key, gpointer value, gpointer user_data) {
|
1349
|
+
client_send_disappearance((Client *) user_data, (Client *) key);
|
1350
|
+
}
|
1351
|
+
|
1352
|
+
static void
|
1353
|
+
client_update_viewers(Client *client, GHashTable *old_viewers) {
|
1354
|
+
client_each_viewer(client, client_send_sighting_and_remove_viewer_from_hash, old_viewers);
|
1355
|
+
g_hash_table_foreach(old_viewers, g_hash_table_send_disappearance_to_key, client);
|
1356
|
+
}
|
1357
|
+
|
1358
|
+
static void
|
1359
|
+
client_update_viewees(Client *client, GHashTable *old_viewees) {
|
1360
|
+
gpointer args[2] = { old_viewees, client };
|
1361
|
+
client_each_viewee(client, client_send_sighting_and_remove_viewee_from_hash, args);
|
1362
|
+
g_hash_table_foreach(old_viewees, g_hash_table_send_disappearance_to_user_data, client);
|
1363
|
+
}
|
1364
|
+
|
1365
|
+
static void
|
1366
|
+
client_update_viewing(Client *client, GHashTable *old_viewers, GHashTable *old_viewees) {
|
1367
|
+
client_update_viewers(client, old_viewers);
|
1368
|
+
client_update_viewees(client, old_viewees);
|
1369
|
+
}
|
1370
|
+
|
1371
|
+
static VALUE
|
1372
|
+
rb_client_update_viewing(VALUE self) {
|
1373
|
+
Client *client;
|
1374
|
+
GHashTable *old_viewers = g_hash_table_new(g_direct_hash, g_direct_equal);
|
1375
|
+
GHashTable *old_viewees = g_hash_table_new(g_direct_hash, g_direct_equal);
|
1376
|
+
CLIENT(self, client);
|
1377
|
+
client_update_viewing(client, old_viewers, old_viewees);
|
1378
|
+
g_hash_table_destroy(old_viewers);
|
1379
|
+
g_hash_table_destroy(old_viewees);
|
1380
|
+
return self;
|
1381
|
+
}
|
1382
|
+
|
1383
|
+
static void
|
1384
|
+
client_set_position(Client *client, Point *new_location, VALUE new_state) {
|
1385
|
+
if (round(new_location->x) != round(client->body->origo->x) ||
|
1386
|
+
round(new_location->y) != round(client->body->origo->y) ||
|
1387
|
+
new_state != client->state) {
|
1388
|
+
|
1389
|
+
GHashTable *old_viewers = g_hash_table_new(g_direct_hash, g_direct_equal);
|
1390
|
+
GHashTable *old_viewees = g_hash_table_new(g_direct_hash, g_direct_equal);
|
1391
|
+
|
1392
|
+
client_each_viewer(client, client_add_viewer_to_hash, old_viewers);
|
1393
|
+
client_each_viewee(client, client_add_viewee_to_hash, old_viewees);
|
1394
|
+
|
1395
|
+
body_relocate(client->body, new_location);
|
1396
|
+
if (client->state != new_state)
|
1397
|
+
client->status_dirty = TRUE;
|
1398
|
+
client->state = new_state;
|
1399
|
+
|
1400
|
+
client_update_viewing(client, old_viewers, old_viewees);
|
1401
|
+
|
1402
|
+
g_hash_table_destroy(old_viewers);
|
1403
|
+
g_hash_table_destroy(old_viewees);
|
1404
|
+
} else {
|
1405
|
+
body_relocate(client->body, new_location);
|
1406
|
+
client->state = new_state;
|
1407
|
+
}
|
1408
|
+
}
|
1409
|
+
|
1410
|
+
static VALUE
|
1411
|
+
rb_client_set_position(VALUE self, VALUE new_loc_val, VALUE new_state) {
|
1412
|
+
Client *client;
|
1413
|
+
Point *new_loc;
|
1414
|
+
CHECK_POINT(new_loc_val);
|
1415
|
+
CLIENT(self, client);
|
1416
|
+
POINT(new_loc_val, new_loc);
|
1417
|
+
client_set_position(client, new_loc, new_state);
|
1418
|
+
return Qnil;
|
1419
|
+
}
|
1420
|
+
|
1421
|
+
static gboolean
|
1422
|
+
command_not_includes_attribute(gpointer key, gpointer value, gpointer other_command_gp) {
|
1423
|
+
Command *other_command = (Command *) other_command_gp;
|
1424
|
+
gchar *other_value;
|
1425
|
+
if ((other_value = (gchar *) g_hash_table_lookup(other_command->attributes, key)) == NULL)
|
1426
|
+
return TRUE;
|
1427
|
+
return strcmp(other_value, (gchar *) value) != 0;
|
1428
|
+
}
|
1429
|
+
|
1430
|
+
static gboolean
|
1431
|
+
command_set_not_includes_command(gpointer name, gpointer command, gpointer other_set_gp) {
|
1432
|
+
CommandSet *other_set = (CommandSet *) other_set_gp;
|
1433
|
+
Command *other_command;
|
1434
|
+
Command *this_command = (Command *) command;
|
1435
|
+
if ((other_command = (Command *) g_hash_table_lookup(other_set->commands, name)) == NULL)
|
1436
|
+
return TRUE;
|
1437
|
+
return (g_hash_table_find(this_command->attributes, command_not_includes_attribute, other_command) != NULL &&
|
1438
|
+
g_hash_table_find(other_command->attributes, command_not_includes_attribute, this_command) != NULL);
|
1439
|
+
}
|
1440
|
+
|
1441
|
+
static gboolean
|
1442
|
+
command_set_equal(CommandSet *set1, CommandSet *set2) {
|
1443
|
+
return (g_hash_table_find(set1->commands, command_set_not_includes_command, set2) == NULL &&
|
1444
|
+
g_hash_table_find(set2->commands, command_set_not_includes_command, set1) == NULL);
|
1445
|
+
}
|
1446
|
+
|
1447
|
+
static VALUE
|
1448
|
+
rb_command_set_equal(VALUE self, VALUE other) {
|
1449
|
+
CommandSet *me;
|
1450
|
+
CommandSet *o;
|
1451
|
+
CHECK_COMMAND_SET(other);
|
1452
|
+
COMMAND_SET(self, me);
|
1453
|
+
COMMAND_SET(other, o);
|
1454
|
+
return GBOOL2RB(command_set_equal(me, o));
|
1455
|
+
}
|
1456
|
+
|
1457
|
+
static void
|
1458
|
+
client_insert_into_last_command(gpointer name, gpointer command, gpointer client) {
|
1459
|
+
gchar *dup = g_strdup((gchar *) name);
|
1460
|
+
g_hash_table_insert(( (Client *) client)->last_command, dup, dup);
|
1461
|
+
}
|
1462
|
+
|
1463
|
+
static void
|
1464
|
+
client_save_current_command(Client *client) {
|
1465
|
+
g_hash_table_remove_all(client->last_command);
|
1466
|
+
g_hash_table_foreach(client->current_command->commands, client_insert_into_last_command, client);
|
1467
|
+
}
|
1468
|
+
|
1469
|
+
static VALUE
|
1470
|
+
rb_client_save_current_command(VALUE self) {
|
1471
|
+
Client *client;
|
1472
|
+
CLIENT(self, client);
|
1473
|
+
client_save_current_command(client);
|
1474
|
+
return self;
|
1475
|
+
}
|
1476
|
+
|
1477
|
+
static void
|
1478
|
+
g_hash_table_insert_string_into_rb_ary(gpointer key, gpointer value, gpointer ary) {
|
1479
|
+
rb_ary_push(*((VALUE *) ary), rb_str_new2((gchar *) key));
|
1480
|
+
}
|
1481
|
+
|
1482
|
+
static VALUE
|
1483
|
+
rb_client_last_command(VALUE self) {
|
1484
|
+
Client *client;
|
1485
|
+
VALUE rval;
|
1486
|
+
CLIENT(self, client);
|
1487
|
+
rval = rb_ary_new();
|
1488
|
+
g_hash_table_foreach(client->last_command, g_hash_table_insert_string_into_rb_ary, &rval);
|
1489
|
+
return rval;
|
1490
|
+
}
|
1491
|
+
|
1492
|
+
static void
|
1493
|
+
client_call_subscription_if_subscribed(gpointer key, gpointer value, gpointer client_gp) {
|
1494
|
+
Client *client = (Client *) client_gp;
|
1495
|
+
ID *meth;
|
1496
|
+
if ((meth = g_hash_table_lookup(client->subscriptions, key)) != NULL) {
|
1497
|
+
rb_funcall(client->rbClient, *meth, 1, ( (Command *) value )->rbCommand);
|
1498
|
+
}
|
1499
|
+
}
|
1500
|
+
|
1501
|
+
static void
|
1502
|
+
client_call_subscription_if_command_disappeared(gpointer key, gpointer value, gpointer client_gp) {
|
1503
|
+
Client *client = (Client *) client_gp;
|
1504
|
+
ID *meth;
|
1505
|
+
if ((meth = g_hash_table_lookup(client->subscriptions, key)) != NULL &&
|
1506
|
+
g_hash_table_lookup(client->current_command->commands, key) == NULL) {
|
1507
|
+
rb_funcall(client->rbClient, *meth, 1, Qnil);
|
1508
|
+
}
|
1509
|
+
}
|
1510
|
+
|
1511
|
+
static void
|
1512
|
+
client_call_subscriptions(Client *client) {
|
1513
|
+
g_hash_table_foreach(client->current_command->commands, client_call_subscription_if_subscribed, client);
|
1514
|
+
g_hash_table_foreach(client->last_command, client_call_subscription_if_command_disappeared, client);
|
1515
|
+
}
|
1516
|
+
|
1517
|
+
static void
|
1518
|
+
client_update(Client *client) {
|
1519
|
+
if (client->state != rb_dead) {
|
1520
|
+
Point new_location = { 0, 0, 0};
|
1521
|
+
gdouble direction = -1.0;
|
1522
|
+
VALUE new_state;
|
1523
|
+
|
1524
|
+
client_call_subscriptions(client);
|
1525
|
+
|
1526
|
+
new_location.x = client->body->origo->x;
|
1527
|
+
new_location.y = client->body->origo->y;
|
1528
|
+
new_state = client->state;
|
1529
|
+
|
1530
|
+
if (COMMAND_SET_INCLUDES(client->current_command, UP)) {
|
1531
|
+
if (COMMAND_SET_INCLUDES(client->current_command, LEFT)) {
|
1532
|
+
direction = 3.0 * M_PI_4;
|
1533
|
+
} else if (COMMAND_SET_INCLUDES(client->current_command, RIGHT)) {
|
1534
|
+
direction = 1.0 * M_PI_4;
|
1535
|
+
} else {
|
1536
|
+
direction = M_PI_2;
|
1537
|
+
}
|
1538
|
+
} else if (COMMAND_SET_INCLUDES(client->current_command, DOWN)) {
|
1539
|
+
if (COMMAND_SET_INCLUDES(client->current_command, LEFT)) {
|
1540
|
+
direction = 5.0 * M_PI_4;
|
1541
|
+
} else if (COMMAND_SET_INCLUDES(client->current_command, RIGHT)) {
|
1542
|
+
direction = 7.0 * M_PI_4;
|
1543
|
+
} else {
|
1544
|
+
direction = 3.0 * M_PI_2;
|
1545
|
+
}
|
1546
|
+
} else if (COMMAND_SET_INCLUDES(client->current_command, LEFT)) {
|
1547
|
+
direction = M_PI;
|
1548
|
+
} else if (COMMAND_SET_INCLUDES(client->current_command, RIGHT)) {
|
1549
|
+
direction = 0.0;
|
1550
|
+
}
|
1551
|
+
|
1552
|
+
if (COMMAND_SET_INCLUDES(client->current_command, DODGE)) {
|
1553
|
+
new_state = rb_dodging;
|
1554
|
+
} else {
|
1555
|
+
new_state = rb_standing;
|
1556
|
+
}
|
1557
|
+
|
1558
|
+
if (direction != -1) {
|
1559
|
+
gdouble speed = client_speed(client);
|
1560
|
+
Point wanted_new_destination = { client->body->origo->x + speed * cos(direction), client->body->origo->y - speed * sin(direction), 0 };
|
1561
|
+
map_move(client->map, client->body->origo, &wanted_new_destination, &new_location);
|
1562
|
+
}
|
1563
|
+
|
1564
|
+
client_set_position(client, &new_location, new_state);
|
1565
|
+
client_send_status(client);
|
1566
|
+
|
1567
|
+
client_save_current_command(client);
|
1568
|
+
}
|
1569
|
+
}
|
1570
|
+
|
1571
|
+
static gpointer
|
1572
|
+
map_update_client_until(Client *client, gpointer null) {
|
1573
|
+
client_update(client);
|
1574
|
+
return NULL;
|
1575
|
+
}
|
1576
|
+
|
1577
|
+
static VALUE
|
1578
|
+
rb_map_update(VALUE self) {
|
1579
|
+
Map *map;
|
1580
|
+
MAP(self, map);
|
1581
|
+
map_each_client_until(map, map_update_client_until, NULL);
|
1582
|
+
return Qnil;
|
1583
|
+
}
|
1584
|
+
|
1585
|
+
static VALUE
|
1586
|
+
rb_client_update(VALUE self) {
|
1587
|
+
Client *client;
|
1588
|
+
CLIENT(self, client);
|
1589
|
+
|
1590
|
+
client_update(client);
|
1591
|
+
|
1592
|
+
return Qnil;
|
1593
|
+
}
|
1594
|
+
|
1595
|
+
static VALUE
|
1596
|
+
rb_map_get_timeout(VALUE self) {
|
1597
|
+
Map *map;
|
1598
|
+
MAP(self, map);
|
1599
|
+
return INT2NUM(map->timeout);
|
1600
|
+
}
|
1601
|
+
|
1602
|
+
static VALUE
|
1603
|
+
rb_map_set_timeout(VALUE self, VALUE timeout) {
|
1604
|
+
Map *map;
|
1605
|
+
MAP(self, map);
|
1606
|
+
CHECK_NUMERICALITY(timeout);
|
1607
|
+
map->timeout = NUM2INT(timeout);
|
1608
|
+
return timeout;
|
1609
|
+
}
|
1610
|
+
|
1611
|
+
static VALUE
|
1612
|
+
rb_map_get_viewing_distance_limit(VALUE self) {
|
1613
|
+
Map *map;
|
1614
|
+
MAP(self, map);
|
1615
|
+
return INT2NUM(map->viewing_distance_limit);
|
1616
|
+
}
|
1617
|
+
|
1618
|
+
static VALUE
|
1619
|
+
rb_map_set_viewing_distance_limit(VALUE self, VALUE viewing_distance_limit) {
|
1620
|
+
Map *map;
|
1621
|
+
MAP(self, map);
|
1622
|
+
CHECK_NUMERICALITY(viewing_distance_limit);
|
1623
|
+
map->viewing_distance_limit = NUM2INT(viewing_distance_limit);
|
1624
|
+
return viewing_distance_limit;
|
1625
|
+
}
|
1626
|
+
|
1627
|
+
static VALUE
|
1628
|
+
rb_client_get_running_speed(VALUE self) {
|
1629
|
+
Client *client;
|
1630
|
+
CLIENT(self, client);
|
1631
|
+
return INT2NUM(client->running_speed);
|
1632
|
+
}
|
1633
|
+
|
1634
|
+
static VALUE
|
1635
|
+
rb_client_set_running_speed(VALUE self, VALUE running_speed) {
|
1636
|
+
Client *client;
|
1637
|
+
CLIENT(self, client);
|
1638
|
+
CHECK_NUMERICALITY(running_speed);
|
1639
|
+
client->running_speed = NUM2INT(running_speed);
|
1640
|
+
return running_speed;
|
1641
|
+
}
|
1642
|
+
|
1643
|
+
static VALUE
|
1644
|
+
rb_client_model(VALUE self) {
|
1645
|
+
Client *client;
|
1646
|
+
VALUE rval;
|
1647
|
+
gchar *str;
|
1648
|
+
CLIENT(self, client);
|
1649
|
+
str = client_model(client);
|
1650
|
+
rval = rb_str_new2(str);
|
1651
|
+
free(str);
|
1652
|
+
return rval;
|
1653
|
+
}
|
1654
|
+
|
1655
|
+
static VALUE
|
1656
|
+
rb_client_get_team(VALUE self) {
|
1657
|
+
Client *client;
|
1658
|
+
CLIENT(self, client);
|
1659
|
+
if (client->team == NULL)
|
1660
|
+
return Qnil;
|
1661
|
+
return rb_str_new2(client->team);
|
1662
|
+
}
|
1663
|
+
|
1664
|
+
static VALUE
|
1665
|
+
rb_client_set_team(VALUE self, VALUE v) {
|
1666
|
+
Client *client;
|
1667
|
+
Check_Type(v, T_STRING);
|
1668
|
+
CLIENT(self, client);
|
1669
|
+
if (client->team != NULL) {
|
1670
|
+
if (strcmp(client->extra_status, RSTRING(v)->ptr) != 0) {
|
1671
|
+
free(client->team);
|
1672
|
+
client->team = g_strndup(RSTRING(v)->ptr, RSTRING(v)->len);
|
1673
|
+
client->status_dirty = TRUE;
|
1674
|
+
}
|
1675
|
+
} else {
|
1676
|
+
client->team = g_strndup(RSTRING(v)->ptr, RSTRING(v)->len);
|
1677
|
+
client->status_dirty = TRUE;
|
1678
|
+
}
|
1679
|
+
return v;
|
1680
|
+
}
|
1681
|
+
|
1682
|
+
static VALUE
|
1683
|
+
rb_client_get_extra_status(VALUE self) {
|
1684
|
+
Client *client;
|
1685
|
+
CLIENT(self, client);
|
1686
|
+
if (client->extra_status == NULL)
|
1687
|
+
return Qnil;
|
1688
|
+
return rb_str_new2(client->extra_status);
|
1689
|
+
}
|
1690
|
+
|
1691
|
+
static VALUE
|
1692
|
+
rb_client_set_extra_status(VALUE self, VALUE v) {
|
1693
|
+
Client *client;
|
1694
|
+
Check_Type(v, T_STRING);
|
1695
|
+
CLIENT(self, client);
|
1696
|
+
if (client->extra_status != NULL) {
|
1697
|
+
if (strcmp(client->extra_status, RSTRING(v)->ptr) != 0) {
|
1698
|
+
free(client->extra_status);
|
1699
|
+
client->extra_status = g_strndup(RSTRING(v)->ptr, RSTRING(v)->len);
|
1700
|
+
client->status_dirty = TRUE;
|
1701
|
+
}
|
1702
|
+
} else {
|
1703
|
+
client->extra_status = g_strndup(RSTRING(v)->ptr, RSTRING(v)->len);
|
1704
|
+
client->status_dirty = TRUE;
|
1705
|
+
}
|
1706
|
+
return v;
|
1707
|
+
}
|
1708
|
+
|
1709
|
+
static VALUE
|
1710
|
+
rb_client_get_behaviour(VALUE self) {
|
1711
|
+
Client *client;
|
1712
|
+
CLIENT(self, client);
|
1713
|
+
if (client->behaviour == NULL)
|
1714
|
+
return Qnil;
|
1715
|
+
return rb_str_new2(client->behaviour);
|
1716
|
+
}
|
1717
|
+
|
1718
|
+
static VALUE
|
1719
|
+
rb_client_set_behaviour(VALUE self, VALUE v) {
|
1720
|
+
Client *client;
|
1721
|
+
Check_Type(v, T_STRING);
|
1722
|
+
CLIENT(self, client);
|
1723
|
+
if (client->behaviour != NULL) {
|
1724
|
+
if (strcmp(client->behaviour, RSTRING(v)->ptr) != 0) {
|
1725
|
+
free(client->behaviour);
|
1726
|
+
client->behaviour = g_strndup(RSTRING(v)->ptr, RSTRING(v)->len);
|
1727
|
+
client->status_dirty = TRUE;
|
1728
|
+
}
|
1729
|
+
} else {
|
1730
|
+
client->behaviour = g_strndup(RSTRING(v)->ptr, RSTRING(v)->len);
|
1731
|
+
client->status_dirty = TRUE;
|
1732
|
+
}
|
1733
|
+
return v;
|
1734
|
+
}
|
1735
|
+
|
1736
|
+
static VALUE
|
1737
|
+
rb_client_get_nickname(VALUE self) {
|
1738
|
+
Client *client;
|
1739
|
+
CLIENT(self, client);
|
1740
|
+
if (client->nickname == NULL)
|
1741
|
+
return Qnil;
|
1742
|
+
return rb_str_new2(client->nickname);
|
1743
|
+
}
|
1744
|
+
|
1745
|
+
static VALUE
|
1746
|
+
rb_client_set_nickname(VALUE self, VALUE v) {
|
1747
|
+
Client *client;
|
1748
|
+
Check_Type(v, T_STRING);
|
1749
|
+
CLIENT(self, client);
|
1750
|
+
if (client->nickname != NULL) {
|
1751
|
+
if (strcmp(client->nickname, RSTRING(v)->ptr) != 0) {
|
1752
|
+
free(client->nickname);
|
1753
|
+
client->nickname = g_strndup(RSTRING(v)->ptr, RSTRING(v)->len);
|
1754
|
+
client->status_dirty = TRUE;
|
1755
|
+
}
|
1756
|
+
} else {
|
1757
|
+
client->nickname = g_strndup(RSTRING(v)->ptr, RSTRING(v)->len);
|
1758
|
+
client->status_dirty = TRUE;
|
1759
|
+
}
|
1760
|
+
return v;
|
1761
|
+
}
|
1762
|
+
|
1763
|
+
static VALUE
|
1764
|
+
rb_client_get_socket(VALUE self) {
|
1765
|
+
Client *client;
|
1766
|
+
CLIENT(self, client);
|
1767
|
+
return client->rbSocket;
|
1768
|
+
}
|
1769
|
+
|
1770
|
+
static VALUE
|
1771
|
+
rb_client_set_socket(VALUE self, VALUE new_socket) {
|
1772
|
+
Client *client;
|
1773
|
+
OpenFile *fptr;
|
1774
|
+
|
1775
|
+
GetOpenFile(new_socket, fptr);
|
1776
|
+
rb_io_check_writable(fptr);
|
1777
|
+
CLIENT(self, client);
|
1778
|
+
|
1779
|
+
client->socket = fptr;
|
1780
|
+
client->rbSocket = new_socket;
|
1781
|
+
|
1782
|
+
return new_socket;
|
1783
|
+
}
|
1784
|
+
|
1785
|
+
static VALUE
|
1786
|
+
rb_client_send(VALUE self, VALUE str) {
|
1787
|
+
Client *client;
|
1788
|
+
|
1789
|
+
Check_Type(str, T_STRING);
|
1790
|
+
CLIENT(self, client);
|
1791
|
+
if (client->socket == NULL)
|
1792
|
+
rb_raise(rb_eRuntimeError, "Client %p does not have a socket!", client);
|
1793
|
+
|
1794
|
+
client_send(client, RSTRING(str)->ptr, RSTRING(str)->len);
|
1795
|
+
|
1796
|
+
return str;
|
1797
|
+
}
|
1798
|
+
|
1799
|
+
static VALUE
|
1800
|
+
rb_client_status_dirty(VALUE self) {
|
1801
|
+
Client *client;
|
1802
|
+
CLIENT(self, client);
|
1803
|
+
return GBOOL2RB(client->status_dirty);
|
1804
|
+
}
|
1805
|
+
|
1806
|
+
static VALUE
|
1807
|
+
rb_client_set_status_dirty(VALUE self) {
|
1808
|
+
Client *client;
|
1809
|
+
CLIENT(self, client);
|
1810
|
+
client->status_dirty = TRUE;
|
1811
|
+
return Qtrue;
|
1812
|
+
}
|
1813
|
+
|
1814
|
+
static VALUE
|
1815
|
+
rb_client_set_status_clean(VALUE self) {
|
1816
|
+
Client *client;
|
1817
|
+
CLIENT(self, client);
|
1818
|
+
client->status_dirty = FALSE;
|
1819
|
+
return Qfalse;
|
1820
|
+
}
|
1821
|
+
|
1822
|
+
static VALUE
|
1823
|
+
rb_map_body_parts(VALUE self) {
|
1824
|
+
Map *map;
|
1825
|
+
MAP(self, map);
|
1826
|
+
return map->body_parts->rbGeoSet;
|
1827
|
+
}
|
1828
|
+
|
1829
|
+
static VALUE
|
1830
|
+
rb_map_bodies(VALUE self) {
|
1831
|
+
Map *map;
|
1832
|
+
MAP(self, map);
|
1833
|
+
return map->bodies->rbGeoSet;
|
1834
|
+
}
|
1835
|
+
|
1836
|
+
static VALUE
|
1837
|
+
rb_map_eyes(VALUE self) {
|
1838
|
+
Map *map;
|
1839
|
+
MAP(self, map);
|
1840
|
+
return map->eyes->rbGeoSet;
|
1841
|
+
}
|
1842
|
+
|
1843
|
+
static VALUE
|
1844
|
+
rb_client_get_score(VALUE self) {
|
1845
|
+
Client *client;
|
1846
|
+
CLIENT(self, client);
|
1847
|
+
return rb_float_new(client->score);
|
1848
|
+
}
|
1849
|
+
|
1850
|
+
static VALUE
|
1851
|
+
rb_client_set_score(VALUE self, VALUE new_score) {
|
1852
|
+
Client *client;
|
1853
|
+
gdouble new_score_gdouble;
|
1854
|
+
CHECK_NUMERICALITY(new_score);
|
1855
|
+
CLIENT(self, client);
|
1856
|
+
new_score_gdouble = NUM2DBL(new_score);
|
1857
|
+
if (!DBL_EQL(new_score_gdouble, client->score)) {
|
1858
|
+
client->status_dirty = TRUE;
|
1859
|
+
client->score = new_score_gdouble;
|
1860
|
+
}
|
1861
|
+
return new_score;
|
1862
|
+
}
|
1863
|
+
|
1864
|
+
static VALUE
|
1865
|
+
rb_client_get_kills(VALUE self) {
|
1866
|
+
Client *client;
|
1867
|
+
CLIENT(self, client);
|
1868
|
+
return rb_float_new(client->kills);
|
1869
|
+
}
|
1870
|
+
|
1871
|
+
static VALUE
|
1872
|
+
rb_client_set_kills(VALUE self, VALUE new_kills) {
|
1873
|
+
Client *client;
|
1874
|
+
gdouble new_kills_gdouble;
|
1875
|
+
CHECK_NUMERICALITY(new_kills);
|
1876
|
+
CLIENT(self, client);
|
1877
|
+
new_kills_gdouble = NUM2DBL(new_kills);
|
1878
|
+
if (!DBL_EQL(new_kills_gdouble, client->kills)) {
|
1879
|
+
client->status_dirty = TRUE;
|
1880
|
+
client->kills = new_kills_gdouble;
|
1881
|
+
}
|
1882
|
+
return new_kills;
|
1883
|
+
}
|
1884
|
+
|
1885
|
+
static VALUE
|
1886
|
+
rb_client_get_deaths(VALUE self) {
|
1887
|
+
Client *client;
|
1888
|
+
CLIENT(self, client);
|
1889
|
+
return rb_float_new(client->deaths);
|
1890
|
+
}
|
1891
|
+
|
1892
|
+
static VALUE
|
1893
|
+
rb_client_set_deaths(VALUE self, VALUE new_deaths) {
|
1894
|
+
Client *client;
|
1895
|
+
gdouble new_deaths_gdouble;
|
1896
|
+
CHECK_NUMERICALITY(new_deaths);
|
1897
|
+
CLIENT(self, client);
|
1898
|
+
new_deaths_gdouble = NUM2DBL(new_deaths);
|
1899
|
+
if (!DBL_EQL(new_deaths_gdouble, client->deaths)) {
|
1900
|
+
client->status_dirty = TRUE;
|
1901
|
+
client->deaths = new_deaths_gdouble;
|
1902
|
+
}
|
1903
|
+
return new_deaths;
|
1904
|
+
}
|
1905
|
+
|
1906
|
+
static VALUE
|
1907
|
+
rb_client_get_hitpoints(VALUE self) {
|
1908
|
+
Client *client;
|
1909
|
+
CLIENT(self, client);
|
1910
|
+
return rb_float_new(client->hitpoints);
|
1911
|
+
}
|
1912
|
+
|
1913
|
+
static VALUE
|
1914
|
+
rb_client_set_hitpoints(VALUE self, VALUE new_hitpoints) {
|
1915
|
+
Client *client;
|
1916
|
+
gdouble new_hitpoints_gdouble;
|
1917
|
+
CHECK_NUMERICALITY(new_hitpoints);
|
1918
|
+
CLIENT(self, client);
|
1919
|
+
new_hitpoints_gdouble = NUM2DBL(new_hitpoints);
|
1920
|
+
if (!DBL_EQL(new_hitpoints_gdouble, client->hitpoints)) {
|
1921
|
+
client->status_dirty = TRUE;
|
1922
|
+
client->hitpoints = new_hitpoints_gdouble;
|
1923
|
+
}
|
1924
|
+
return new_hitpoints;
|
1925
|
+
}
|
1926
|
+
|
1927
|
+
static VALUE
|
1928
|
+
rb_client_subscribe(VALUE self, VALUE n, VALUE meth) {
|
1929
|
+
Client *client;
|
1930
|
+
ID *id;
|
1931
|
+
gchar *name;
|
1932
|
+
Check_Type(n, T_STRING);
|
1933
|
+
Check_Type(meth, T_SYMBOL);
|
1934
|
+
CLIENT(self, client);
|
1935
|
+
id = ALLOC(ID);
|
1936
|
+
*id = SYM2ID(meth);
|
1937
|
+
name = g_strndup(RSTRING(n)->ptr, RSTRING(n)->len);
|
1938
|
+
g_hash_table_insert(client->subscriptions, name, id);
|
1939
|
+
return self;
|
1940
|
+
}
|
1941
|
+
|
1942
|
+
static VALUE
|
1943
|
+
rb_client_unsubscribe(VALUE self, VALUE n) {
|
1944
|
+
Client *client;
|
1945
|
+
ID *id;
|
1946
|
+
VALUE rval = 0;
|
1947
|
+
Check_Type(n, T_STRING);
|
1948
|
+
CLIENT(self, client);
|
1949
|
+
id = g_hash_table_lookup(client->subscriptions, RSTRING(n)->ptr);
|
1950
|
+
if (id != NULL)
|
1951
|
+
rval = ID2SYM(*id);
|
1952
|
+
g_hash_table_remove(client->subscriptions, RSTRING(n)->ptr);
|
1953
|
+
if (rval != 0)
|
1954
|
+
return rval;
|
1955
|
+
else
|
1956
|
+
return Qnil;
|
1957
|
+
}
|
1958
|
+
|
1959
|
+
#ifdef __cplusplus
|
1960
|
+
extern "C" {
|
1961
|
+
#endif
|
1962
|
+
void Init_grueserve_ext() {
|
1963
|
+
init_grueserve_globals();
|
1964
|
+
|
1965
|
+
VALUE rb_grueserve = rb_define_module("Grueserve");
|
1966
|
+
rb_map = rb_define_class_under(rb_grueserve,
|
1967
|
+
"Map",
|
1968
|
+
rb_cObject);
|
1969
|
+
rb_client = rb_define_class_under(rb_grueserve,
|
1970
|
+
"Client",
|
1971
|
+
rb_cObject);
|
1972
|
+
rb_command = rb_define_class_under(rb_client,
|
1973
|
+
"Command",
|
1974
|
+
rb_cObject);
|
1975
|
+
rb_command_set = rb_define_class_under(rb_client,
|
1976
|
+
"CommandSet",
|
1977
|
+
rb_cObject);
|
1978
|
+
rb_body = rb_define_class_under(rb_client,
|
1979
|
+
"Body",
|
1980
|
+
rb_cObject);
|
1981
|
+
rb_e_terminated_connection = rb_define_class_under(rb_client,
|
1982
|
+
"TerminatedConnection",
|
1983
|
+
rb_eRuntimeError);
|
1984
|
+
|
1985
|
+
rb_define_alloc_func(rb_client, rb_client_alloc);
|
1986
|
+
rb_define_method(rb_client, "register!", rb_client_register, 0);
|
1987
|
+
rb_define_method(rb_client, "unregister!", rb_client_unregister, 0);
|
1988
|
+
rb_define_method(rb_client, "registered?", rb_client_registered, 0);
|
1989
|
+
rb_define_method(rb_client, "body", rb_client_get_body, 0);
|
1990
|
+
rb_define_method(rb_client, "state", rb_client_get_state, 0);
|
1991
|
+
rb_define_method(rb_client, "state=", rb_client_set_state, 1);
|
1992
|
+
rb_define_method(rb_client, "moving?", rb_client_moving, 0);
|
1993
|
+
rb_define_method(rb_client, "current_command", rb_client_get_current_command, 0);
|
1994
|
+
rb_define_method(rb_client, "current_command=", rb_client_set_current_command, 1);
|
1995
|
+
rb_define_method(rb_client, "last_command", rb_client_last_command, 0);
|
1996
|
+
rb_define_method(rb_client, "save_current_command!", rb_client_save_current_command, 0);
|
1997
|
+
rb_define_method(rb_client, "map", rb_client_get_map, 0);
|
1998
|
+
rb_define_method(rb_client, "map=", rb_client_set_map, 1);
|
1999
|
+
rb_define_method(rb_client, "client_id", rb_client_client_id, 0);
|
2000
|
+
rb_define_method(rb_client, "last_ping", rb_client_get_last_ping, 0);
|
2001
|
+
rb_define_method(rb_client, "ping!", rb_client_ping, 0);
|
2002
|
+
rb_define_method(rb_client, "update!", rb_client_update, 0);
|
2003
|
+
rb_define_method(rb_client, "running_speed", rb_client_get_running_speed, 0);
|
2004
|
+
rb_define_method(rb_client, "running_speed=", rb_client_set_running_speed, 1);
|
2005
|
+
rb_define_method(rb_client, "socket=", rb_client_set_socket, 1);
|
2006
|
+
rb_define_method(rb_client, "socket", rb_client_get_socket, 0);
|
2007
|
+
rb_define_method(rb_client, "send", rb_client_send, 1);
|
2008
|
+
rb_define_method(rb_client, "team", rb_client_get_team, 0);
|
2009
|
+
rb_define_method(rb_client, "team=", rb_client_set_team, 1);
|
2010
|
+
rb_define_method(rb_client, "extra_status", rb_client_get_extra_status, 0);
|
2011
|
+
rb_define_method(rb_client, "extra_status=", rb_client_set_extra_status, 1);
|
2012
|
+
rb_define_method(rb_client, "behaviour", rb_client_get_behaviour, 0);
|
2013
|
+
rb_define_method(rb_client, "behaviour=", rb_client_set_behaviour, 1);
|
2014
|
+
rb_define_method(rb_client, "nickname", rb_client_get_nickname, 0);
|
2015
|
+
rb_define_method(rb_client, "nickname=", rb_client_set_nickname, 1);
|
2016
|
+
rb_define_method(rb_client, "model", rb_client_model, 0);
|
2017
|
+
rb_define_method(rb_client, "send_sighting", rb_client_send_sighting, 1);
|
2018
|
+
rb_define_method(rb_client, "send_disappearance", rb_client_send_disappearance, 1);
|
2019
|
+
rb_define_method(rb_client, "viewers", rb_client_viewers, 0);
|
2020
|
+
rb_define_method(rb_client, "viewees", rb_client_viewees, 0);
|
2021
|
+
rb_define_method(rb_client, "update_viewing", rb_client_update_viewing, 0);
|
2022
|
+
rb_define_method(rb_client, "status_dirty?", rb_client_status_dirty, 0);
|
2023
|
+
rb_define_method(rb_client, "status_dirty!", rb_client_set_status_dirty, 0);
|
2024
|
+
rb_define_method(rb_client, "status_clean!", rb_client_set_status_clean, 0);
|
2025
|
+
rb_define_method(rb_client, "score", rb_client_get_score, 0);
|
2026
|
+
rb_define_method(rb_client, "score=", rb_client_set_score, 1);
|
2027
|
+
rb_define_method(rb_client, "kills", rb_client_get_kills, 0);
|
2028
|
+
rb_define_method(rb_client, "kills=", rb_client_set_kills, 1);
|
2029
|
+
rb_define_method(rb_client, "deaths", rb_client_get_deaths, 0);
|
2030
|
+
rb_define_method(rb_client, "deaths=", rb_client_set_deaths, 1);
|
2031
|
+
rb_define_method(rb_client, "hitpoints", rb_client_get_hitpoints, 0);
|
2032
|
+
rb_define_method(rb_client, "hitpoints=", rb_client_set_hitpoints, 1);
|
2033
|
+
rb_define_method(rb_client, "set_position", rb_client_set_position, 2);
|
2034
|
+
rb_define_method(rb_client, "subscribe", rb_client_subscribe, 2);
|
2035
|
+
rb_define_method(rb_client, "unsubscribe", rb_client_unsubscribe, 1);
|
2036
|
+
|
2037
|
+
rb_define_alloc_func(rb_map, rb_map_alloc);
|
2038
|
+
rb_define_method(rb_map, "movement_obstacles", rb_map_movement_obstacles, 0);
|
2039
|
+
rb_define_method(rb_map, "visibility_obstacles", rb_map_visibility_obstacles, 0);
|
2040
|
+
rb_define_method(rb_map, "bullet_obstacles", rb_map_bullet_obstacles, 0);
|
2041
|
+
rb_define_method(rb_map, "hearing_obstacles", rb_map_hearing_obstacles, 0);
|
2042
|
+
rb_define_method(rb_map, "fortifications", rb_map_fortifications, 0);
|
2043
|
+
rb_define_method(rb_map, "speed_areas", rb_map_speed_areas, 0);
|
2044
|
+
rb_define_method(rb_map, "protection_areas", rb_map_protection_areas, 0);
|
2045
|
+
rb_define_method(rb_map, "hidden_areas", rb_map_hidden_areas, 0);
|
2046
|
+
rb_define_method(rb_map, "body_parts", rb_map_body_parts, 0);
|
2047
|
+
rb_define_method(rb_map, "bodies", rb_map_bodies, 0);
|
2048
|
+
rb_define_method(rb_map, "eyes", rb_map_eyes, 0);
|
2049
|
+
rb_define_method(rb_map, "[]", rb_map_get, 1);
|
2050
|
+
rb_define_method(rb_map, "[]=", rb_map_set, 2);
|
2051
|
+
rb_define_method(rb_map, "timeout", rb_map_get_timeout, 0);
|
2052
|
+
rb_define_method(rb_map, "timeout=", rb_map_set_timeout, 1);
|
2053
|
+
rb_define_method(rb_map, "viewing_distance_limit", rb_map_get_viewing_distance_limit, 0);
|
2054
|
+
rb_define_method(rb_map, "viewing_distance_limit=", rb_map_set_viewing_distance_limit, 1);
|
2055
|
+
rb_define_method(rb_map, "each_client", rb_map_each_client, 0);
|
2056
|
+
rb_define_method(rb_map, "viewers_of", rb_map_viewers_of, 1);
|
2057
|
+
rb_define_method(rb_map, "update!", rb_map_update, 0);
|
2058
|
+
|
2059
|
+
rb_undef_method(rb_body, "initialize");
|
2060
|
+
rb_define_method(rb_body, "origo", rb_body_get_origo, 0);
|
2061
|
+
rb_define_method(rb_body, "vertical_axis", rb_body_get_vertical_axis, 0);
|
2062
|
+
rb_define_method(rb_body, "horizontal_axis", rb_body_get_horizontal_axis, 0);
|
2063
|
+
rb_define_method(rb_body, "relocate", rb_body_relocate, 1);
|
2064
|
+
rb_define_method(rb_body, "inspect", rb_body_inspect, 0);
|
2065
|
+
|
2066
|
+
rb_define_alloc_func(rb_command, rb_command_alloc);
|
2067
|
+
rb_define_method(rb_command, "[]", rb_command_get, 1);
|
2068
|
+
rb_define_method(rb_command, "[]=", rb_command_insert, 2);
|
2069
|
+
rb_define_method(rb_command, "name", rb_command_get_name, 0);
|
2070
|
+
rb_define_method(rb_command, "name=", rb_command_set_name, 1);
|
2071
|
+
rb_define_method(rb_command, "inspect", rb_command_inspect, 0);
|
2072
|
+
|
2073
|
+
rb_define_alloc_func(rb_command_set, rb_command_set_alloc);
|
2074
|
+
rb_define_method(rb_command_set, "[]", rb_command_set_get, 1);
|
2075
|
+
rb_define_method(rb_command_set, "<<", rb_command_set_push, 1);
|
2076
|
+
rb_define_method(rb_command_set, "include?", rb_command_set_include, 1);
|
2077
|
+
rb_define_method(rb_command_set, "inspect", rb_command_set_inspect, 0);
|
2078
|
+
rb_define_method(rb_command_set, "==", rb_command_set_equal, 1);
|
2079
|
+
}
|
2080
|
+
#ifdef __cplusplus
|
2081
|
+
}
|
2082
|
+
#endif
|
2083
|
+
|