updated on Wed Jan 18 08:00:29 UTC 2012
[aur-mirror.git] / teecomp / teecomp-0.7.0_tw-0.5.2.patch
blob7a676272fea820cd958784d7459f1b524c98fca5
1 diff -Nru teeworlds-0.5.2-src/datasrc/content.py teeworlds-0.5.2-teecomp/datasrc/content.py
2 --- teeworlds-0.5.2-src/datasrc/content.py 2009-10-26 19:04:31.000000000 +0100
3 +++ teeworlds-0.5.2-teecomp/datasrc/content.py 2009-10-27 19:06:18.000000000 +0100
4 @@ -228,6 +228,7 @@
6 container.images.Add(image_null)
7 container.images.Add(image_game)
8 +container.images.Add(Image("game_gray", "game.png"))
9 container.images.Add(image_particles)
10 container.images.Add(Image("cursor", "gui_cursor.png"))
11 container.images.Add(Image("banner", "gui_logo.png"))
12 diff -Nru teeworlds-0.5.2-src/readme_teecomp.txt teeworlds-0.5.2-teecomp/readme_teecomp.txt
13 --- teeworlds-0.5.2-src/readme_teecomp.txt 1970-01-01 01:00:00.000000000 +0100
14 +++ teeworlds-0.5.2-teecomp/readme_teecomp.txt 2009-11-10 17:00:09.000000000 +0100
15 @@ -0,0 +1,96 @@
17 + _____ ___
18 + |_ _|__ ___ / __|___ _ __ _ __
19 + | |/ -_) -_) (__/ _ \ ' \| '_ \
20 + |_|\___\___|\___\___/_|_|_| .__/
21 + |_|
24 +TeeComp is a modification of the standard Teeworlds client (client mod).
25 +It includes several features players from Unreal Tournament or Quake like.
26 +The binary file is guaranteed without aimbot, cheating system, virus, keylogger or any other malware that could
27 +damage your system or send personal data over the Internet.
29 +==========
30 + Features
31 +==========
32 +* Custom Tees' colors in team games
33 +* HUD colors matching Tees' ones
34 +* Flags colors matching Tees' ones
35 +* Force opponents' skin
36 +* Use DM colors in team games
37 +* Custom name plates colors by team
38 +* Shadow under the name plates for an improved readability
39 +* Score displayed in name plates
40 +* Custom laser color
41 +* Stat board with
42 + * Frags, deaths, and suicides count
43 + * Ratio or net score
44 + * Frags per minute
45 + * Frags and deaths for each weapon
46 + * Captured flags count
47 +* Displaying of Tee's speed
48 +* Disabling chat
49 +* Player following while spectating
50 +* Automatic demo recording
51 +* Automatic screenshot at the end of the match
53 +All these features are also available when watching a demo recorded from a standard client.
54 +TeeComp is compatible with any game mode accepting standard clients.
56 +===========
57 + Downloads
58 +===========
60 +TeeComp is available for Windows (XP or better) and Linux.
61 +Visit http://spl0k.unreal-design.com/teeworlds/downloads/
62 +Check http://eigan.no/tee/ for Mac versions.
64 +=======
65 + Usage
66 +=======
68 +After downloading the file, unzip (untar) it in your Teeworlds folder and run teecomp.exe (teecomp) instead
69 +of teeworlds.exe (teeworlds).
71 +=========
72 + Credits
73 +=========
75 +TeeComp, by Alban 'spl0k' Feron
76 + - http://spl0k.unreal-design.com/
77 +but two or three lines are from torch ;)
79 +Based on the standard Teeworlds client, mainly by Magnus 'matricks' Auvinen
80 + - http://www.teeworlds.com/
82 +With some advices from Sd`, Tho, Eve and some other MonkeyStyle members
84 +===========
85 + Changelog
86 +===========
88 +Version 0.7.0
89 +- Fixed connection crash when one wished to display scores
90 +- Added warmup end support with stats
91 +- Added ability to choose which fields are displayed on the global stat board
92 +- Added fields to the global stat board:
93 + - Suicides
94 + - Captured flags
95 +- Added an individual stat board
96 +- Added ability to hide the flag when we're carrying it
97 +- Added ability to force other players' skins
98 +- Added option to use DM colors in team games
99 +- Added option to change laser color
100 +- Added ability to mute chat
101 +- Added player following in spectator mode
103 +Version 0.6.4
104 +- Fixed auto screenshot applying to demos
105 +- Chat now use Tees colors
106 +- Added a 'Reset to defaults' button to the settings page
107 +- Team names now match Tees colors in the score board and in-game menu.
109 +Version 0.6.0
110 +- First release
112 diff -Nru teeworlds-0.5.2-src/src/engine/client/ec_client.c teeworlds-0.5.2-teecomp/src/engine/client/ec_client.c
113 --- teeworlds-0.5.2-src/src/engine/client/ec_client.c 2009-10-26 19:04:31.000000000 +0100
114 +++ teeworlds-0.5.2-teecomp/src/engine/client/ec_client.c 2009-10-27 19:06:18.000000000 +0100
115 @@ -5,6 +5,7 @@
116 #include <stdlib.h>
117 #include <stdio.h>
118 #include <math.h>
119 +#include <time.h>
121 #include <base/system.h>
122 #include <engine/e_engine.h>
123 @@ -578,6 +579,19 @@
124 modc_statechange(state, old);
127 +void teecomp_demo_start()
129 + char filename[512];
130 + time_t rawtime;
131 + struct tm *tmp;
133 + time(&rawtime);
134 + tmp = localtime(&rawtime);
136 + str_format(filename, sizeof(filename), "demos/%d-%02d-%d_%02d-%02d-%02d_%s.demo", tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec, current_map);
137 + demorec_record_start(filename, modc_net_version(), current_map, current_map_crc, "client");
140 /* called when the map is loaded and we should init for a new round */
141 static void client_on_enter_game()
143 diff -Nru teeworlds-0.5.2-src/src/engine/e_if_client.h teeworlds-0.5.2-teecomp/src/engine/e_if_client.h
144 --- teeworlds-0.5.2-src/src/engine/e_if_client.h 2009-10-26 19:04:31.000000000 +0100
145 +++ teeworlds-0.5.2-teecomp/src/engine/e_if_client.h 2009-10-27 19:06:18.000000000 +0100
146 @@ -576,4 +576,7 @@
147 void client_serverinfo(SERVER_INFO *serverinfo);
148 void client_serverinfo_request();
149 void client_serverbrowse_request(NETADDR *addr);
151 +void teecomp_demo_start();
153 #endif
154 diff -Nru teeworlds-0.5.2-src/src/game/client/components/camera.cpp teeworlds-0.5.2-teecomp/src/game/client/components/camera.cpp
155 --- teeworlds-0.5.2-src/src/game/client/components/camera.cpp 2009-10-26 19:04:31.000000000 +0100
156 +++ teeworlds-0.5.2-teecomp/src/game/client/components/camera.cpp 2009-10-27 19:06:18.000000000 +0100
157 @@ -22,7 +22,12 @@
159 // update camera center
160 if(gameclient.snap.spectate)
161 - center = gameclient.controls->mouse_pos;
163 + if(gameclient.freeview)
164 + center = gameclient.controls->mouse_pos;
165 + else
166 + center = gameclient.spectate_pos;
168 else
171 diff -Nru teeworlds-0.5.2-src/src/game/client/components/chat.cpp teeworlds-0.5.2-teecomp/src/game/client/components/chat.cpp
172 --- teeworlds-0.5.2-src/src/game/client/components/chat.cpp 2009-10-26 19:04:31.000000000 +0100
173 +++ teeworlds-0.5.2-teecomp/src/game/client/components/chat.cpp 2009-10-27 19:06:18.000000000 +0100
174 @@ -5,6 +5,7 @@
175 #include <game/generated/gc_data.hpp>
177 #include <game/client/gameclient.hpp>
178 +#include <game/client/teecomp.hpp>
180 #include <game/client/components/sounds.hpp>
182 @@ -88,11 +89,12 @@
183 if(msgtype == NETMSGTYPE_SV_CHAT)
185 NETMSG_SV_CHAT *msg = (NETMSG_SV_CHAT *)rawmsg;
186 - add_line(msg->cid, msg->team, msg->message);
187 + if(msg->cid < 0 || !config.tc_disable_chat)
188 + add_line(msg->cid, msg->team, msg->message);
190 - if(msg->cid >= 0)
191 + if(msg->cid >= 0 && !config.tc_disable_chat)
192 gameclient.sounds->play(SOUNDS::CHN_GUI, SOUND_CHAT_CLIENT, 0, vec2(0,0));
193 - else
194 + else if(msg->cid < 0)
195 gameclient.sounds->play(SOUNDS::CHN_GUI, SOUND_CHAT_SERVER, 0, vec2(0,0));
198 @@ -184,15 +186,34 @@
199 cursor.line_width = 200.0f;
201 // render name
202 + vec3 tcolor;
203 gfx_text_color(0.8f,0.8f,0.8f,1);
204 if(lines[r].client_id == -1)
205 gfx_text_color(1,1,0.5f,1); // system
206 else if(lines[r].team)
207 gfx_text_color(0.45f,0.9f,0.45f,1); // team message
208 else if(lines[r].name_color == 0)
209 - gfx_text_color(1.0f,0.5f,0.5f,1); // red
211 + if(!gameclient.snap.local_info)
212 + gfx_text_color(1.0f,0.5f,0.5f,1); // red
213 + else
215 + tcolor = TeecompUtils::getTeamColor(0, gameclient.snap.local_info->team, config.tc_colored_tees_team1,
216 + config.tc_colored_tees_team2, config.tc_colored_tees_method);
217 + gfx_text_color(tcolor.r, tcolor.g, tcolor.b, 1);
220 else if(lines[r].name_color == 1)
221 - gfx_text_color(0.7f,0.7f,1.0f,1); // blue
223 + if(!gameclient.snap.local_info)
224 + gfx_text_color(0.7f,0.7f,1.0f,1); // blue
225 + else
227 + tcolor = TeecompUtils::getTeamColor(1, gameclient.snap.local_info->team, config.tc_colored_tees_team1,
228 + config.tc_colored_tees_team2, config.tc_colored_tees_method);
229 + gfx_text_color(tcolor.r, tcolor.g, tcolor.b, 1);
230 + }
232 else if(lines[r].name_color == -1)
233 gfx_text_color(0.75f,0.5f,0.75f, 1); // spectator
235 diff -Nru teeworlds-0.5.2-src/src/game/client/components/controls.cpp teeworlds-0.5.2-teecomp/src/game/client/components/controls.cpp
236 --- teeworlds-0.5.2-src/src/game/client/components/controls.cpp 2009-10-26 19:04:31.000000000 +0100
237 +++ teeworlds-0.5.2-teecomp/src/game/client/components/controls.cpp 2009-10-27 19:06:18.000000000 +0100
238 @@ -103,7 +103,15 @@
240 input_direction_left = 0;
241 input_direction_right = 0;
244 + // Keep following while chatting/in console/in menu
245 + if(gameclient.snap.spectate && !gameclient.freeview)
247 + input_data.target_x = (int)mouse_pos.x;
248 + input_data.target_y = (int)mouse_pos.y;
249 + send = true;
252 mem_copy(data, &input_data, sizeof(input_data));
254 // send once a second just to be sure
255 @@ -189,11 +197,16 @@
257 if(gameclient.snap.spectate)
259 - if(mouse_pos.x < 200.0f) mouse_pos.x = 200.0f;
260 - if(mouse_pos.y < 200.0f) mouse_pos.y = 200.0f;
261 - if(mouse_pos.x > col_width()*32-200.0f) mouse_pos.x = col_width()*32-200.0f;
262 - if(mouse_pos.y > col_height()*32-200.0f) mouse_pos.y = col_height()*32-200.0f;
264 + if(gameclient.freeview)
266 + if(mouse_pos.x < 200.0f) mouse_pos.x = 200.0f;
267 + if(mouse_pos.y < 200.0f) mouse_pos.y = 200.0f;
268 + if(mouse_pos.x > col_width()*32-200.0f) mouse_pos.x = col_width()*32-200.0f;
269 + if(mouse_pos.y > col_height()*32-200.0f) mouse_pos.y = col_height()*32-200.0f;
272 + else
273 + mouse_pos = gameclient.spectate_pos;
274 target_pos = mouse_pos;
276 else
277 diff -Nru teeworlds-0.5.2-src/src/game/client/components/hud.cpp teeworlds-0.5.2-teecomp/src/game/client/components/hud.cpp
278 --- teeworlds-0.5.2-src/src/game/client/components/hud.cpp 2009-10-26 19:04:31.000000000 +0100
279 +++ teeworlds-0.5.2-teecomp/src/game/client/components/hud.cpp 2009-10-27 19:06:18.000000000 +0100
280 @@ -1,6 +1,7 @@
281 #include <memory.h> // memcmp
283 #include <engine/e_client_interface.h>
284 +#include <engine/e_demorec.h>
285 #include <game/generated/g_protocol.hpp>
286 #include <game/generated/gc_data.hpp>
288 @@ -16,6 +17,8 @@
289 #include "voting.hpp"
290 #include "binds.hpp"
292 +#include <game/client/teecomp.hpp>
294 HUD::HUD()
297 @@ -74,10 +77,20 @@
298 gfx_blend_normal();
299 gfx_texture_set(-1);
300 gfx_quads_begin();
301 - if(t == 0)
302 - gfx_setcolor(1,0,0,0.25f);
303 + if(!config.tc_hud_match)
305 + if(t == 0)
306 + gfx_setcolor(1,0,0,0.25f);
307 + else
308 + gfx_setcolor(0,0,1,0.25f);
310 else
311 - gfx_setcolor(0,0,1,0.25f);
313 + vec3 col = TeecompUtils::getTeamColor(t, gameclient.snap.local_info->team,
314 + config.tc_colored_tees_team1, config.tc_colored_tees_team2, config.tc_colored_tees_method);
315 + gfx_setcolor(col.r, col.g, col.b, 0.25f);
318 draw_round_rect(whole-40, 300-40-15+t*20, 50, 18, 5.0f);
319 gfx_quads_end();
321 @@ -93,12 +106,25 @@
322 if(gameclient.snap.flags[t]->carried_by == -2 || (gameclient.snap.flags[t]->carried_by == -1 && ((client_tick()/10)&1)))
324 gfx_blend_normal();
325 - gfx_texture_set(data->images[IMAGE_GAME].id);
326 + if(config.tc_colored_flags)
327 + gfx_texture_set(data->images[IMAGE_GAME_GRAY].id);
328 + else
329 + gfx_texture_set(data->images[IMAGE_GAME].id);
330 gfx_quads_begin();
332 if(t == 0) select_sprite(SPRITE_FLAG_RED);
333 else select_sprite(SPRITE_FLAG_BLUE);
335 + if(config.tc_colored_flags)
337 + vec3 col = TeecompUtils::getTeamColor(t,
338 + gameclient.snap.local_info->team,
339 + config.tc_colored_tees_team1,
340 + config.tc_colored_tees_team2,
341 + config.tc_colored_tees_method);
342 + gfx_setcolor(col.r, col.g, col.b, 1.0f);
345 float size = 16;
346 gfx_quads_drawTL(whole-40+5, 300-40-15+t*20+1, size/2, size);
347 gfx_quads_end();
348 @@ -283,6 +309,66 @@
349 gfx_quads_end();
352 +void HUD::render_speed()
354 + if(!config.tc_speedmeter)
355 + return;
357 + // We calculate the speed instead of getting it from character.velocity cause it's buggy when
358 + // walking in front of a wall or when using the ninja sword
359 + static float speed;
360 + static vec2 oldpos;
361 + static const int SMOOTH_TABLE_SIZE = 16;
362 + static const int ACCEL_THRESHOLD = 25;
363 + static float smooth_table[SMOOTH_TABLE_SIZE];
364 + static int smooth_index = 0;
366 + smooth_table[smooth_index] = distance(gameclient.local_character_pos, oldpos)/client_frametime();
367 + if(demorec_isplaying()) {
368 + float mult = client_demoplayer_getinfo()->speed;
369 + smooth_table[smooth_index] /= mult;
371 + smooth_index = (smooth_index + 1) % SMOOTH_TABLE_SIZE;
372 + oldpos = gameclient.local_character_pos;
373 + speed = 0;
374 + for(int i=0; i<SMOOTH_TABLE_SIZE; i++)
375 + speed += smooth_table[i];
376 + speed /= SMOOTH_TABLE_SIZE;
378 + int t = (gameclient.snap.gameobj->flags & GAMEFLAG_TEAMS)? -1 : 1;
379 + int last_index = smooth_index - 1;
380 + if(last_index < 0)
381 + last_index = SMOOTH_TABLE_SIZE - 1;
383 + gfx_blend_normal();
384 + gfx_texture_set(-1);
385 + gfx_quads_begin();
386 + if(config.tc_speedmeter_accel && speed - smooth_table[last_index] > ACCEL_THRESHOLD)
387 + gfx_setcolor(0.6f, 0.1f, 0.1f, 0.25f);
388 + else if(config.tc_speedmeter_accel && speed - smooth_table[last_index] < -ACCEL_THRESHOLD)
389 + gfx_setcolor(0.1f, 0.6f, 0.1f, 0.25f);
390 + else
391 + gfx_setcolor(0.1, 0.1, 0.1, 0.25);
392 + draw_round_rect(width-40, 245+t*20, 50, 18, 5.0f);
393 + gfx_quads_end();
395 + char buf[16];
396 + str_format(buf, sizeof(buf), "%.0f", speed);
397 + gfx_text(0, width-5-gfx_text_width(0,12,buf,-1), 246+t*20, 12, buf, -1);
400 +void HUD::render_spectate()
402 + if(gameclient.freeview)
403 + gfx_text(0, 4*gfx_screenaspect(), 4, 8, "Freeview", -1);
404 + else
406 + char buf[96];
407 + str_format(buf, sizeof(buf), "Following: %s", gameclient.clients[gameclient.spectate_cid].name);
408 + gfx_text(0, 4*gfx_screenaspect(), 4, 8, buf, -1);
412 void HUD::on_render()
414 if(!gameclient.snap.gameobj)
415 @@ -295,7 +381,10 @@
416 spectate = true;
418 if(gameclient.snap.local_character && !spectate && !(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over))
420 render_healthandammo();
421 + render_speed();
424 render_goals();
425 render_fps();
426 @@ -304,4 +393,6 @@
427 render_teambalancewarning();
428 render_voting();
429 render_cursor();
430 + if(spectate && !(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over))
431 + render_spectate();
433 diff -Nru teeworlds-0.5.2-src/src/game/client/components/hud.hpp teeworlds-0.5.2-teecomp/src/game/client/components/hud.hpp
434 --- teeworlds-0.5.2-src/src/game/client/components/hud.hpp 2009-10-26 19:04:31.000000000 +0100
435 +++ teeworlds-0.5.2-teecomp/src/game/client/components/hud.hpp 2009-10-27 19:06:18.000000000 +0100
436 @@ -12,6 +12,8 @@
437 void render_voting();
438 void render_healthandammo();
439 void render_goals();
440 + void render_speed();
441 + void render_spectate();
443 public:
444 HUD();
445 diff -Nru teeworlds-0.5.2-src/src/game/client/components/items.cpp teeworlds-0.5.2-teecomp/src/game/client/components/items.cpp
446 --- teeworlds-0.5.2-src/src/game/client/components/items.cpp 2009-10-26 19:04:31.000000000 +0100
447 +++ teeworlds-0.5.2-teecomp/src/game/client/components/items.cpp 2009-10-27 19:06:18.000000000 +0100
448 @@ -12,6 +12,8 @@
450 #include "items.hpp"
452 +#include <game/client/teecomp.hpp>
454 void ITEMS::render_projectile(const NETOBJ_PROJECTILE *current, int itemid)
457 @@ -121,10 +123,23 @@
458 float angle = 0.0f;
459 float size = 42.0f;
461 + if(gameclient.snap.local_info && current->carried_by == gameclient.snap.local_info->cid && config.tc_hide_carrying)
462 + return;
464 gfx_blend_normal();
465 - gfx_texture_set(data->images[IMAGE_GAME].id);
466 + if(config.tc_colored_flags)
467 + gfx_texture_set(data->images[IMAGE_GAME_GRAY].id);
468 + else
469 + gfx_texture_set(data->images[IMAGE_GAME].id);
470 gfx_quads_begin();
472 + if(config.tc_colored_flags && gameclient.snap.local_info)
474 + vec3 col = TeecompUtils::getTeamColor(current->team, gameclient.snap.local_info->team,
475 + config.tc_colored_tees_team1, config.tc_colored_tees_team2, config.tc_colored_tees_method);
476 + gfx_setcolor(col.r, col.g, col.b, 1.0f);
479 if(current->team == 0) // red team
480 select_sprite(SPRITE_FLAG_RED);
481 else
482 @@ -169,7 +184,10 @@
483 //vec4 outer_color(0.65f,0.85f,1.0f,1.0f);
485 // do outline
486 - vec4 outer_color(0.075f,0.075f,0.25f,1.0f);
487 + vec4 outer_color(
488 + (config.tc_laser_color_outer>>16)/255.0f,
489 + ((config.tc_laser_color_outer>>8)&0xff)/255.0f,
490 + (config.tc_laser_color_outer&0xff)/255.0f, 1.0f);
491 gfx_setcolor(outer_color.r,outer_color.g,outer_color.b,1.0f);
492 out = vec2(dir.y, -dir.x) * (7.0f*ia);
494 @@ -181,7 +199,10 @@
497 // do inner
498 - vec4 inner_color(0.5f,0.5f,1.0f,1.0f);
499 + vec4 inner_color(
500 + (config.tc_laser_color_inner>>16)/255.0f,
501 + ((config.tc_laser_color_inner>>8)&0xff)/255.0f,
502 + (config.tc_laser_color_inner&0xff)/255.0f, 1.0f);
503 out = vec2(dir.y, -dir.x) * (5.0f*ia);
504 gfx_setcolor(inner_color.r, inner_color.g, inner_color.b, 1.0f); // center
506 diff -Nru teeworlds-0.5.2-src/src/game/client/components/items.hpp teeworlds-0.5.2-teecomp/src/game/client/components/items.hpp
507 --- teeworlds-0.5.2-src/src/game/client/components/items.hpp 2009-10-26 19:04:31.000000000 +0100
508 +++ teeworlds-0.5.2-teecomp/src/game/client/components/items.hpp 2009-10-27 19:06:18.000000000 +0100
509 @@ -5,9 +5,9 @@
510 void render_projectile(const NETOBJ_PROJECTILE *current, int itemid);
511 void render_pickup(const NETOBJ_PICKUP *prev, const NETOBJ_PICKUP *current);
512 void render_flag(const NETOBJ_FLAG *prev, const NETOBJ_FLAG *current);
513 - void render_laser(const struct NETOBJ_LASER *current);
515 public:
516 virtual void on_render();
517 + static void render_laser(const struct NETOBJ_LASER *current); // Bleh changing visibility + static
520 diff -Nru teeworlds-0.5.2-src/src/game/client/components/killmessages.cpp teeworlds-0.5.2-teecomp/src/game/client/components/killmessages.cpp
521 --- teeworlds-0.5.2-src/src/game/client/components/killmessages.cpp 2009-10-26 19:04:31.000000000 +0100
522 +++ teeworlds-0.5.2-teecomp/src/game/client/components/killmessages.cpp 2009-10-27 19:06:18.000000000 +0100
523 @@ -6,6 +6,8 @@
524 #include <game/client/animstate.hpp>
525 #include "killmessages.hpp"
527 +#include <game/client/teecomp.hpp>
529 void KILLMESSAGES::on_reset()
531 killmsg_current = 0;
532 @@ -67,11 +69,22 @@
533 if(killmsgs[r].mode_special&1)
535 gfx_blend_normal();
536 - gfx_texture_set(data->images[IMAGE_GAME].id);
537 + if(config.tc_colored_flags)
538 + gfx_texture_set(data->images[IMAGE_GAME_GRAY].id);
539 + else
540 + gfx_texture_set(data->images[IMAGE_GAME].id);
541 gfx_quads_begin();
543 if(gameclient.clients[killmsgs[r].victim].team == 0) select_sprite(SPRITE_FLAG_BLUE);
544 else select_sprite(SPRITE_FLAG_RED);
545 + if(config.tc_colored_flags)
547 + vec3 col = TeecompUtils::getTeamColor(1-gameclient.clients[killmsgs[r].victim].team,
548 + gameclient.snap.local_info->team,
549 + config.tc_colored_tees_team1, config.tc_colored_tees_team2,
550 + config.tc_colored_tees_method);
551 + gfx_setcolor(col.r, col.g, col.b, 1.0f);
554 float size = 56.0f;
555 gfx_quads_drawTL(x, y-16, size/2, size);
556 @@ -101,11 +114,22 @@
557 if(killmsgs[r].mode_special&2)
559 gfx_blend_normal();
560 - gfx_texture_set(data->images[IMAGE_GAME].id);
561 + if(config.tc_colored_flags)
562 + gfx_texture_set(data->images[IMAGE_GAME_GRAY].id);
563 + else
564 + gfx_texture_set(data->images[IMAGE_GAME].id);
565 gfx_quads_begin();
567 if(gameclient.clients[killmsgs[r].killer].team == 0) select_sprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
568 else select_sprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
569 + if(config.tc_colored_flags)
571 + vec3 col = TeecompUtils::getTeamColor(1-gameclient.clients[killmsgs[r].killer].team,
572 + gameclient.snap.local_info->team,
573 + config.tc_colored_tees_team1, config.tc_colored_tees_team2,
574 + config.tc_colored_tees_method);
575 + gfx_setcolor(col.r, col.g, col.b, 1.0f);
578 float size = 56.0f;
579 gfx_quads_drawTL(x-56, y-16, size/2, size);
580 diff -Nru teeworlds-0.5.2-src/src/game/client/components/menus.hpp teeworlds-0.5.2-teecomp/src/game/client/components/menus.hpp
581 --- teeworlds-0.5.2-src/src/game/client/components/menus.hpp 2009-10-26 19:04:31.000000000 +0100
582 +++ teeworlds-0.5.2-teecomp/src/game/client/components/menus.hpp 2009-10-27 19:06:18.000000000 +0100
583 @@ -3,6 +3,12 @@
584 #include <game/client/component.hpp>
585 #include <game/client/ui.hpp>
587 +typedef struct
589 + const char *name;
590 + const char *command;
591 + int keyid;
592 +} KEYINFO;
594 // compnent to fetch keypresses, override all other input
595 class MENUS_KEYBINDER : public COMPONENT
596 @@ -162,6 +168,14 @@
597 void render_settings_graphics(RECT main_view);
598 void render_settings_sound(RECT main_view);
599 void render_settings(RECT main_view);
600 + // TeeComp related
601 + void render_rgb_sliders(RECT* main_view, RECT* button, int &r, int &g, int &b, bool enabled);
602 + void ui_do_keybinder(KEYINFO& key, RECT* r);
603 + void render_settings_teecomp(RECT main_view);
604 + void render_settings_teecomp_skins(RECT main_view);
605 + void render_settings_teecomp_stats(RECT main_view);
606 + void render_settings_teecomp_misc(RECT main_view);
607 + void render_settings_teecomp_about(RECT main_view);
609 void set_active(bool active);
610 public:
611 @@ -181,3 +195,4 @@
612 virtual bool on_input(INPUT_EVENT e);
613 virtual bool on_mousemove(float x, float y);
616 diff -Nru teeworlds-0.5.2-src/src/game/client/components/menus_ingame.cpp teeworlds-0.5.2-teecomp/src/game/client/components/menus_ingame.cpp
617 --- teeworlds-0.5.2-src/src/game/client/components/menus_ingame.cpp 2009-10-26 19:04:31.000000000 +0100
618 +++ teeworlds-0.5.2-teecomp/src/game/client/components/menus_ingame.cpp 2009-10-27 19:06:18.000000000 +0100
619 @@ -13,6 +13,8 @@
620 #include <game/client/gameclient.hpp>
621 #include <game/client/animstate.hpp>
623 +#include <game/client/teecomp.hpp>
625 #include "menus.hpp"
626 #include "motd.hpp"
627 #include "voting.hpp"
628 @@ -49,12 +51,17 @@
630 if(gameclient.snap.gameobj->flags & GAMEFLAG_TEAMS)
632 + char buf[32];
633 if(gameclient.snap.local_info->team != 0)
635 ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
636 ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
637 static int spectate_button = 0;
638 - if(ui_do_button(&spectate_button, "Join Red", 0, &button, ui_draw_menu_button, 0))
639 + if(gameclient.snap.local_info->team == -1 || config.tc_colored_tees_method == 0)
640 + str_format(buf, sizeof(buf), "Join %s", TeecompUtils::rgb_to_name(config.tc_colored_tees_team1));
641 + else
642 + str_format(buf, sizeof(buf), "Join %s", TeecompUtils::rgb_to_name(config.tc_colored_tees_team2));
643 + if(ui_do_button(&spectate_button, buf, 0, &button, ui_draw_menu_button, 0))
645 gameclient.send_switch_team(0);
646 set_active(false);
647 @@ -66,7 +73,8 @@
648 ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
649 ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
650 static int spectate_button = 0;
651 - if(ui_do_button(&spectate_button, "Join Blue", 0, &button, ui_draw_menu_button, 0))
652 + str_format(buf, sizeof(buf), "Join %s", TeecompUtils::rgb_to_name(config.tc_colored_tees_team2));
653 + if(ui_do_button(&spectate_button, buf, 0, &button, ui_draw_menu_button, 0))
655 gameclient.send_switch_team(1);
656 set_active(false);
657 diff -Nru teeworlds-0.5.2-src/src/game/client/components/menus_settings.cpp teeworlds-0.5.2-teecomp/src/game/client/components/menus_settings.cpp
658 --- teeworlds-0.5.2-src/src/game/client/components/menus_settings.cpp 2009-10-26 19:04:31.000000000 +0100
659 +++ teeworlds-0.5.2-teecomp/src/game/client/components/menus_settings.cpp 2009-10-27 19:06:18.000000000 +0100
660 @@ -241,13 +241,6 @@
662 typedef void (*assign_func_callback)(CONFIGURATION *config, int value);
664 -typedef struct
666 - const char *name;
667 - const char *command;
668 - int keyid;
669 -} KEYINFO;
671 KEYINFO keys[] =
673 { "Move Left:", "+left", 0},
674 @@ -636,7 +629,7 @@
676 RECT button;
678 - const char *tabs[] = {"Player", "Controls", "Graphics", "Sound"};
679 + const char *tabs[] = {"Player", "Controls", "Graphics", "Sound", "TeeComp"};
680 int num_tabs = (int)(sizeof(tabs)/sizeof(*tabs));
682 for(int i = 0; i < num_tabs; i++)
683 @@ -657,8 +650,10 @@
684 render_settings_graphics(main_view);
685 else if(settings_page == 3)
686 render_settings_sound(main_view);
687 + else if(settings_page == 4)
688 + render_settings_teecomp(main_view);
690 - if(need_restart)
691 + if(need_restart && settings_page != 4)
693 RECT restart_warning;
694 ui_hsplit_b(&main_view, 40, &main_view, &restart_warning);
695 diff -Nru teeworlds-0.5.2-src/src/game/client/components/menus_teecomp.cpp teeworlds-0.5.2-teecomp/src/game/client/components/menus_teecomp.cpp
696 --- teeworlds-0.5.2-src/src/game/client/components/menus_teecomp.cpp 1970-01-01 01:00:00.000000000 +0100
697 +++ teeworlds-0.5.2-teecomp/src/game/client/components/menus_teecomp.cpp 2009-10-27 19:41:48.000000000 +0100
698 @@ -0,0 +1,555 @@
699 +#include <string.h>
701 +#include <engine/e_client_interface.h>
703 +#include <game/generated/g_protocol.hpp>
704 +#include <game/generated/gc_data.hpp>
706 +#include <game/version.hpp>
707 +#include <game/client/ui.hpp>
708 +#include <game/client/render.hpp>
709 +#include <game/client/gameclient.hpp>
710 +#include <game/client/animstate.hpp>
712 +#include "binds.hpp"
713 +#include "menus.hpp"
714 +#include "skins.hpp"
715 +#include "items.hpp"
717 +#include <game/client/teecomp.hpp>
719 +void MENUS::render_rgb_sliders(RECT* main_view, RECT* button, int &r, int &g, int &b, bool enabled)
721 + const char *labels[] = {"R.", "G.", "B."};
722 + int *color_slider[3] = {&r, &g, &b};
723 + for(int i=0; i<3; i++)
725 + RECT text;
726 + ui_hsplit_t(main_view, 19.0f, button, main_view);
727 + ui_vmargin(button, 15.0f, button);
728 + ui_vsplit_l(button, 30.0f, &text, button);
729 + ui_vsplit_r(button, 5.0f, button, 0);
730 + ui_hsplit_t(button, 4.0f, 0, button);
732 + if(enabled)
734 + float k = (*color_slider[i]) / 255.0f;
735 + k = ui_do_scrollbar_h(color_slider[i], button, k);
736 + *color_slider[i] = (int)(k*255.0f);
738 + else
739 + ui_do_scrollbar_h(color_slider[i], button, 0);
740 + ui_do_label(&text, labels[i], 15.0f, -1);
744 +void MENUS::ui_do_keybinder(KEYINFO& key, RECT* r)
746 + RECT label, button;
747 + ui_hsplit_t(r, 20.0f, &button, r);
748 + ui_vsplit_r(&button, 5.0f, &button, 0);
749 + ui_vsplit_l(&button, 130.0f, &label, &button);
751 + ui_do_label(&label, key.name, 14.0f, -1);
752 + int oldid = key.keyid;
753 + int newid = ui_do_key_reader((void *)key.name, &button, oldid);
754 + if(newid != oldid)
756 + gameclient.binds->bind(oldid, "");
757 + gameclient.binds->bind(newid, key.command);
759 + ui_hsplit_t(r, 5.0f, 0, r);
762 +void MENUS::render_settings_teecomp(RECT main_view)
764 + RECT button;
765 + static int settings_page = 0;
767 + if(settings_page != 3)
769 + ui_hsplit_b(&main_view, 20.0f, 0, &button);
770 + ui_vsplit_l(&button, main_view.w/3, &button, 0);
771 + static int default_button = 0;
772 + if(ui_do_button((void*)&default_button, "Reset to defaults", 0, &button, ui_draw_menu_button, 0))
773 + TeecompUtils::reset_config();
775 + ui_hsplit_b(&main_view, 10.0f, &main_view, &button);
776 + ui_do_label(&button, "http://spl0k.unreal-design.com/teeworlds/", 10.0f, 1);
777 + ui_hsplit_b(&main_view, 10.0f, &main_view, &button);
778 + char buf[64];
779 + str_format(buf, sizeof(buf), "Teeworlds %s with TeeComp %s by spl0k", GAME_VERSION, TEECOMP_VERSION);
780 + ui_do_label(&button, buf, 10.0f, 1);
781 + ui_hsplit_b(&main_view, 10.0f, &main_view, 0);
784 + // render background
785 + RECT tabbar;
786 + ui_hsplit_t(&main_view, 24.0f, &tabbar, &main_view);
787 + //ui_draw_rect(&main_view, color_tabbar_active, CORNER_ALL, 10.0f);
789 + const char *tabs[] = {"Skins", "Stats", "Misc", "About"};
790 + int num_tabs = (int)(sizeof(tabs)/sizeof(*tabs));
792 + for(int i=0; i<num_tabs; i++)
794 + ui_vsplit_l(&tabbar, 10.0f, &button, &tabbar);
795 + ui_vsplit_l(&tabbar, 80.0f, &button, &tabbar);
796 + int corners = CORNER_ALL;
797 + if(ui_do_button(tabs[i], tabs[i], settings_page == i, &button, ui_draw_menu_tab_button, &corners))
798 + settings_page = i;
801 + if(settings_page != 3)
802 + ui_margin(&main_view, 10.0f, &main_view);
804 + if(settings_page == 0)
805 + render_settings_teecomp_skins(main_view);
806 + else if(settings_page == 1)
807 + render_settings_teecomp_stats(main_view);
808 + else if(settings_page == 2)
809 + render_settings_teecomp_misc(main_view);
810 + else if(settings_page == 3)
811 + render_settings_teecomp_about(main_view);
814 +void MENUS::render_settings_teecomp_skins(RECT main_view)
816 + RECT button, left_view, right_view;
817 + ui_vsplit_l(&main_view, main_view.w/2, &left_view, &right_view);
819 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
820 + if(ui_do_button(&config.tc_colored_tees_method, "Enemy based colors", config.tc_colored_tees_method, &button, ui_draw_checkbox, 0))
821 + config.tc_colored_tees_method ^= 1;
823 + // Colors team 1
825 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
826 + char buf[128];
827 + str_format(buf, sizeof(buf), "Use DM colors for team %s", (config.tc_colored_tees_method)?"mates":"1");
828 + if(ui_do_button(&config.tc_dm_colors_team1, buf, config.tc_dm_colors_team1, &button, ui_draw_checkbox, 0))
829 + config.tc_dm_colors_team1 ^= 1;
831 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
832 + ui_do_label(&button, (config.tc_colored_tees_method)?"Team mates":"Team 1", 14.0f, -1);
833 + int r1, g1, b1, r2, g2, b2;
834 + r1 = config.tc_colored_tees_team1>>16;
835 + g1 = (config.tc_colored_tees_team1>>8)&0xff;
836 + b1 = config.tc_colored_tees_team1&0xff;
837 + render_rgb_sliders(&left_view, &button, r1, g1, b1, !config.tc_dm_colors_team1);
838 + config.tc_colored_tees_team1 = (r1<<16) + (g1<<8) + b1;
840 + const SKINS::SKIN *s = gameclient.skins->get(max(0, gameclient.skins->find(config.tc_forced_skin1)));
841 + TEE_RENDER_INFO info;
842 + if(!config.tc_dm_colors_team1)
844 + info.texture = s->color_texture;
845 + info.color_body = vec4(r1/255.0f, g1/255.0f, b1/255.0f, 1.0f);
846 + info.color_feet = vec4(r1/255.0f, g1/255.0f, b1/255.0f, 1.0f);
848 + else
850 + info.texture = s->org_texture;
851 + info.color_body = vec4(1.0f, 1.0f, 1.0f, 1.0f);
852 + info.color_feet = vec4(1.0f, 1.0f, 1.0f, 1.0f);
854 + info.size = ui_scale()*50.f;
856 + ui_hsplit_t(&button, 70.0f, 0, &button);
857 + render_tee(ANIMSTATE::get_idle(), &info, 0, vec2(1, 0), vec2(button.x, button.y+button.h/2));
858 + ui_hsplit_t(&left_view, 50.0f, 0, &left_view);
860 + // Colors team 2
862 + ui_hsplit_t(&right_view, 20.0f, 0, &right_view);
863 + ui_hsplit_t(&right_view, 20.0f, &button, &right_view);
864 + str_format(buf, sizeof(buf), "Use DM colors for %s", (config.tc_colored_tees_method)?"enemies":"team 2");
865 + if(ui_do_button(&config.tc_dm_colors_team2, buf, config.tc_dm_colors_team2, &button, ui_draw_checkbox, 0))
866 + config.tc_dm_colors_team2 ^= 1;
868 + ui_hsplit_t(&right_view, 20.0f, &button, &right_view);
869 + ui_do_label(&button, (config.tc_colored_tees_method)?"Enemies":"Team 2", 14.0f, -1);
870 + r2 = config.tc_colored_tees_team2>>16;
871 + g2 = (config.tc_colored_tees_team2>>8)&0xff;
872 + b2 = config.tc_colored_tees_team2&0xff;
873 + render_rgb_sliders(&right_view, &button, r2, g2, b2, !config.tc_dm_colors_team2);
874 + config.tc_colored_tees_team2 = (r2<<16) + (g2<<8) + b2;
876 + s = gameclient.skins->get(max(0, gameclient.skins->find(config.tc_forced_skin2)));
877 + if(!config.tc_dm_colors_team2)
879 + info.texture = s->color_texture;
880 + info.color_body = vec4(r2/255.0f, g2/255.0f, b2/255.0f, 1.0f);
881 + info.color_feet = vec4(r2/255.0f, g2/255.0f, b2/255.0f, 1.0f);
883 + else
885 + info.texture = s->org_texture;
886 + info.color_body = vec4(1.0f, 1.0f, 1.0f, 1.0f);
887 + info.color_feet = vec4(1.0f, 1.0f, 1.0f, 1.0f);
890 + ui_hsplit_t(&button, 70.0f, 0, &button);
891 + render_tee(ANIMSTATE::get_idle(), &info, 0, vec2(1, 0), vec2(button.x, button.y+button.h/2));
892 + ui_hsplit_t(&right_view, 50.0f, 0, &right_view);
894 + // Force skins team 1
896 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
897 + if(ui_do_button(&config.tc_forced_skins_method, "Enemy based skins", config.tc_forced_skins_method, &button, ui_draw_checkbox, 0))
898 + config.tc_forced_skins_method ^= 1;
900 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
901 + str_format(buf, sizeof(buf), "Force team %s/FFA skins", (config.tc_forced_skins_method)?"mates":"1");
902 + if(ui_do_button(&config.tc_force_skin_team1, buf, config.tc_force_skin_team1, &button, ui_draw_checkbox, 0))
903 + config.tc_force_skin_team1 ^= 1;
905 + RECT skinselection, scroll;
906 + ui_margin(&left_view, 10.0f, &skinselection);
908 + ui_hsplit_t(&skinselection, 20, &button, &skinselection);
909 + ui_draw_rect(&button, vec4(1,1,1,0.25f), CORNER_T, 5.0f);
910 + ui_do_label(&button, "Forced skin", 14.0f, 0);
912 + ui_draw_rect(&skinselection, vec4(0,0,0,0.15f), 0, 0);
913 + ui_vsplit_r(&skinselection, 15, &skinselection, &scroll);
915 + RECT list = skinselection;
916 + ui_hsplit_t(&list, 20, &button, &list);
918 + int num = (int)(skinselection.h/button.h);
919 + static float scrollvalue = 0;
920 + static int scrollbar = 0;
921 + ui_hmargin(&scroll, 5.0f, &scroll);
922 + scrollvalue = ui_do_scrollbar_v(&scrollbar, &scroll, scrollvalue);
924 + int start = (int)((gameclient.skins->num()-num)*scrollvalue);
925 + if(start < 0)
926 + start = 0;
928 + for(int i=start; i<start+num && i<gameclient.skins->num(); i++)
930 + const SKINS::SKIN *s = gameclient.skins->get(i);
932 + str_format(buf, sizeof(buf), "%s", s->name);
933 + int selected = 0;
934 + if(strcmp(s->name, config.tc_forced_skin1) == 0)
935 + selected = 1;
937 + if(ui_do_button(s, "", selected, &button, ui_draw_list_row, 0))
938 + str_copy(config.tc_forced_skin1, s->name, sizeof(config.tc_forced_skin1));
940 + ui_vmargin(&button, 5.0f, &button);
941 + ui_hsplit_t(&button, 1.0f, 0, &button);
942 + ui_do_label(&button, buf, 14.0f, -1);
944 + ui_hsplit_t(&list, 20.0f, &button, &list);
947 + // Forced skin team 2
949 + ui_hsplit_t(&right_view, 20.0f, 0, &right_view);
950 + ui_hsplit_t(&right_view, 20.0f, &button, &right_view);
951 + str_format(buf, sizeof(buf), "Force %s skins", (config.tc_forced_skins_method)?"enemies":"team 2");
952 + if(ui_do_button(&config.tc_force_skin_team2, buf, config.tc_force_skin_team2, &button, ui_draw_checkbox, 0))
953 + config.tc_force_skin_team2 ^= 1;
955 + ui_margin(&right_view, 10.0f, &skinselection);
957 + ui_hsplit_t(&skinselection, 20, &button, &skinselection);
958 + ui_draw_rect(&button, vec4(1,1,1,0.25f), CORNER_T, 5.0f);
959 + ui_do_label(&button, "Forced skin", 14.0f, 0);
961 + ui_draw_rect(&skinselection, vec4(0,0,0,0.15f), 0, 0);
962 + ui_vsplit_r(&skinselection, 15, &skinselection, &scroll);
964 + list = skinselection;
965 + ui_hsplit_t(&list, 20, &button, &list);
967 + num = (int)(skinselection.h/button.h);
968 + static float scrollvalue2 = 0;
969 + static int scrollbar2 = 0;
970 + ui_hmargin(&scroll, 5.0f, &scroll);
971 + scrollvalue2 = ui_do_scrollbar_v(&scrollbar2, &scroll, scrollvalue2);
973 + start = (int)((gameclient.skins->num()-num)*scrollvalue2);
974 + if(start < 0)
975 + start = 0;
977 + for(int i=start; i<start+num && i<gameclient.skins->num(); i++)
979 + const SKINS::SKIN *s = gameclient.skins->get(i);
981 + str_format(buf, sizeof(buf), "%s", s->name);
982 + int selected = 0;
983 + if(strcmp(s->name, config.tc_forced_skin2) == 0)
984 + selected = 1;
986 + if(ui_do_button(s+gameclient.skins->num(), "", selected, &button, ui_draw_list_row, 0))
987 + str_copy(config.tc_forced_skin2, s->name, sizeof(config.tc_forced_skin2));
989 + ui_vmargin(&button, 5.0f, &button);
990 + ui_hsplit_t(&button, 1.0f, 0, &button);
991 + ui_do_label(&button, buf, 14.0f, -1);
993 + ui_hsplit_t(&list, 20.0f, &button, &list);
997 +void MENUS::render_settings_teecomp_stats(RECT main_view)
999 + RECT button, left_view;
1001 + ui_vsplit_l(&main_view, main_view.w/2, &left_view, &main_view);
1003 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1004 + ui_do_label(&button, "Show in global statboard:", 16.0f, -1);
1006 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1007 + if(ui_do_button(&config.tc_statboard_infos, "Frags", config.tc_statboard_infos & TC_STATS_FRAGS, &button, ui_draw_checkbox, 0))
1008 + config.tc_statboard_infos ^= TC_STATS_FRAGS;
1010 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1011 + if(ui_do_button(&config.tc_statboard_infos+1, "Deaths", config.tc_statboard_infos & TC_STATS_DEATHS, &button, ui_draw_checkbox, 0))
1012 + config.tc_statboard_infos ^= TC_STATS_DEATHS;
1014 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1015 + if(ui_do_button(&config.tc_statboard_infos+2, "Suicides", config.tc_statboard_infos & TC_STATS_SUICIDES, &button, ui_draw_checkbox, 0))
1016 + config.tc_statboard_infos ^= TC_STATS_SUICIDES;
1018 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1019 + if(ui_do_button(&config.tc_statboard_infos+3, "Ratio", config.tc_statboard_infos & TC_STATS_RATIO, &button, ui_draw_checkbox, 0))
1020 + config.tc_statboard_infos ^= TC_STATS_RATIO;
1022 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1023 + if(ui_do_button(&config.tc_statboard_infos+4, "Net score", config.tc_statboard_infos & TC_STATS_NET, &button, ui_draw_checkbox, 0))
1024 + config.tc_statboard_infos ^= TC_STATS_NET;
1026 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1027 + if(ui_do_button(&config.tc_statboard_infos+5, "Frags per minute", config.tc_statboard_infos & TC_STATS_FPM, &button, ui_draw_checkbox, 0))
1028 + config.tc_statboard_infos ^= TC_STATS_FPM;
1030 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1031 + if(ui_do_button(&config.tc_statboard_infos+6, "Weapons stats", config.tc_statboard_infos & TC_STATS_WEAPS, &button, ui_draw_checkbox, 0))
1032 + config.tc_statboard_infos ^= TC_STATS_WEAPS;
1034 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1035 + if(ui_do_button(&config.tc_statboard_infos+7, "Flag captures", config.tc_statboard_infos & TC_STATS_FLAGS, &button, ui_draw_checkbox, 0))
1036 + config.tc_statboard_infos ^= TC_STATS_FLAGS;
1038 + ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
1039 + ui_do_label(&button, "Key bindings:", 16.0f, -1);
1040 + KEYINFO keys[] = {{ "Global statboard:", "+stats 1", 0},
1041 + { "Individual statboard:", "+stats 2", 0},
1042 + { "Next individual stats:", "+next_stats", 0}};
1044 + for(int keyid=0; keyid<KEY_LAST; keyid++)
1046 + const char *bind = gameclient.binds->get(keyid);
1047 + if(!bind[0])
1048 + continue;
1050 + for(int i=0; i<sizeof(keys)/sizeof(KEYINFO); i++)
1051 + if(strcmp(bind, keys[i].command) == 0)
1053 + keys[i].keyid = keyid;
1054 + break;
1058 + for(int i=0; i<sizeof(keys)/sizeof(KEYINFO); i++)
1059 + ui_do_keybinder(keys[i], &main_view);
1062 +void MENUS::render_settings_teecomp_misc(RECT main_view)
1064 + RECT left_view, right_view, button;
1066 + ui_vsplit_l(&main_view, main_view.w/2, &left_view, &right_view);
1068 + ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
1069 + ui_do_label(&button, "Name plates", 16.0f, 0);
1070 + ui_hsplit_t(&left_view, 20.0f, 0, &left_view);
1071 + ui_hsplit_t(&right_view, 20.0f, 0, &right_view);
1073 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1074 + if(ui_do_button(&config.tc_colored_nameplates, "Colored name plates", config.tc_colored_nameplates&1, &button, ui_draw_checkbox, 0))
1075 + config.tc_colored_nameplates ^= 1;
1077 + ui_hsplit_t(&right_view, 20.0f, &button, &right_view);
1078 + if(ui_do_button(&config.tc_colored_nameplates+1, "Enemy based colors", config.tc_colored_nameplates&2, &button, ui_draw_checkbox, 0))
1079 + config.tc_colored_nameplates ^= 2;
1081 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1082 + ui_do_label(&button, (config.tc_colored_nameplates&2)?"Team mates":"Team 1", 14.0f, -1);
1083 + int r1, g1, b1, r2, g2, b2;
1084 + r1 = config.tc_colored_nameplates_team1>>16;
1085 + g1 = (config.tc_colored_nameplates_team1>>8)&0xff;
1086 + b1 = config.tc_colored_nameplates_team1&0xff;
1087 + render_rgb_sliders(&left_view, &button, r1, g1, b1, true);
1088 + config.tc_colored_nameplates_team1 = (r1<<16) + (g1<<8) + b1;
1090 + ui_hsplit_t(&left_view, 25.0f, &button, &left_view);
1091 + ui_vsplit_l(&button, 30.0f, 0, &button);
1092 + gfx_text_color(r1/255.0f, g1/255.0f, b1/255.0f, 1);
1093 + ui_do_label(&button, (config.tc_colored_nameplates&2)?"Team mates":"Team 1", 15.0f, -1);
1094 + gfx_text_color(1,1,1,1);
1096 + ui_hsplit_t(&right_view, 20.0f, &button, &right_view);
1097 + ui_do_label(&button, (config.tc_colored_nameplates&2)?"Enemies":"Team 2", 14.0f, -1);
1098 + r2 = config.tc_colored_nameplates_team2>>16;
1099 + g2 = (config.tc_colored_nameplates_team2>>8)&0xff;
1100 + b2 = config.tc_colored_nameplates_team2&0xff;
1101 + render_rgb_sliders(&right_view, &button, r2, g2, b2, true);
1102 + config.tc_colored_nameplates_team2 = (r2<<16) + (g2<<8) + b2;
1104 + ui_hsplit_t(&right_view, 25.0f, &button, &right_view);
1105 + ui_vsplit_l(&button, 30.0f, 0, &button);
1106 + gfx_text_color(r2/255.0f, g2/255.0f, b2/255.0f, 1);
1107 + ui_do_label(&button, (config.tc_colored_nameplates&2)?"Enemies":"Team 2", 15.0f, -1);
1108 + gfx_text_color(1,1,1,1);
1110 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1111 + if(ui_do_button(&config.tc_nameplate_shadow, "Show name plate shadow", config.tc_nameplate_shadow, &button, ui_draw_checkbox, 0))
1112 + config.tc_nameplate_shadow ^= 1;
1114 + ui_hsplit_t(&right_view, 20.0f, &button, &right_view);
1115 + if(ui_do_button(&config.tc_nameplate_score, "Show score in name plate", config.tc_nameplate_score, &button, ui_draw_checkbox, 0))
1116 + config.tc_nameplate_score ^= 1;
1118 + ui_hsplit_t(&main_view, 160.0f, 0, &main_view);
1119 + ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
1120 + ui_do_label(&button, "Laser", 16.0f, 0);
1121 + ui_hsplit_t(&left_view, 40.0f, 0, &left_view);
1122 + ui_hsplit_t(&right_view, 40.0f, 0, &right_view);
1124 + int lri, lro, lgi, lgo, lbi, lbo;
1125 + lri = config.tc_laser_color_inner>>16;
1126 + lgi = (config.tc_laser_color_inner>>8)&0xff;
1127 + lbi = config.tc_laser_color_inner&0xff;
1128 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1129 + ui_do_label(&button, "Laser inner color", 14.0f, -1);
1130 + render_rgb_sliders(&left_view, &button, lri, lgi, lbi, true);
1131 + config.tc_laser_color_inner = (lri<<16) + (lgi<<8) + lbi;
1133 + lro = config.tc_laser_color_outer>>16;
1134 + lgo = (config.tc_laser_color_outer>>8)&0xff;
1135 + lbo = config.tc_laser_color_outer&0xff;
1136 + ui_hsplit_t(&right_view, 20.0f, &button, &right_view);
1137 + ui_do_label(&button, "Laser outer color", 14.0f, -1);
1138 + render_rgb_sliders(&right_view, &button, lro, lgo, lbo, true);
1139 + config.tc_laser_color_outer = (lro<<16) + (lgo<<8) + lbo;
1141 + { RECT lbut, rbut;
1142 + RECT screen = *ui_screen();
1143 + ui_hsplit_t(&left_view, 20.0f, &lbut, &left_view);
1144 + ui_hsplit_t(&right_view, 20.0f, &rbut, &right_view);
1145 + // calculate world screen mapping
1146 + float points[4];
1147 + mapscreen_to_world(0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, gfx_screenaspect(), 1.0f, points);
1148 + points[2] = points[2] - points[0];
1149 + points[3] = points[3] - points[1];
1150 + points[0] = 0.0f;
1151 + points[1] = 0.0f;
1152 + // factor between world and menu screen mappings
1153 + float fact_x, fact_y;
1154 + fact_x = (points[2]-points[0])/screen.w;
1155 + fact_y = (points[3]-points[1])/screen.h;
1156 + struct NETOBJ_LASER laser;
1157 + // we want to draw a beam from under the center of one sliders section to the center of the other sliders section
1158 + laser.from_x = (lbut.x + lbut.w/2)*fact_x;
1159 + laser.from_y = (lbut.y + lbut.h/2)*fact_y;
1160 + laser.x = (rbut.x + rbut.w/2)*fact_x;
1161 + laser.y = (rbut.y + rbut.h/2)*fact_y;
1162 + laser.start_tick = client_tick() + client_intratick();
1163 + // apply world screen mapping (beam is bigger in menu mapping)
1164 + gfx_mapscreen(points[0], points[1], points[2], points[3]);
1165 + // draw laser
1166 + ITEMS::render_laser(&laser);
1167 + // restore menu screen mapping
1168 + gfx_mapscreen(screen.x, screen.y, screen.w, screen.h); }
1170 + ui_hsplit_t(&left_view, 20.0f, 0, &left_view);
1171 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1172 + ui_do_label(&button, "HUD/Flag", 16.0f, -1);
1174 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1175 + if(ui_do_button(&config.tc_hud_match, "Make HUD match tees colors", config.tc_hud_match, &button, ui_draw_checkbox, 0))
1176 + config.tc_hud_match ^= 1;
1178 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1179 + if(ui_do_button(&config.tc_colored_flags, "Make flags match tees colors", config.tc_colored_flags, &button, ui_draw_checkbox, 0))
1180 + config.tc_colored_flags ^= 1;
1182 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1183 + if(ui_do_button(&config.tc_speedmeter, "Display speed meter", config.tc_speedmeter, &button, ui_draw_checkbox, 0))
1184 + config.tc_speedmeter ^= 1;
1186 + ui_hsplit_t(&left_view, 20.0f, &button, &left_view);
1187 + ui_vsplit_l(&button, 15.0f, 0, &button);
1188 + if(ui_do_button(&config.tc_speedmeter_accel, "Speed meter show acceleration", config.tc_speedmeter_accel, &button, ui_draw_checkbox, 0))
1189 + config.tc_speedmeter_accel ^= 1;
1191 + ui_hsplit_t(&right_view, 20.0f, 0, &right_view);
1192 + ui_hsplit_t(&right_view, 20.0f, &button, &right_view);
1193 + ui_do_label(&button, "Others", 16.0f, -1);
1195 + ui_hsplit_t(&right_view, 20.0f, &button, &right_view);
1196 + if(ui_do_button(&config.tc_disable_chat, "Disable chat", config.tc_disable_chat, &button, ui_draw_checkbox, 0))
1197 + config.tc_disable_chat ^= 1;
1199 + ui_hsplit_t(&right_view, 20.0f, &button, &right_view);
1200 + if(ui_do_button(&config.tc_hide_carrying, "Hide flag while carrying it", config.tc_hide_carrying, &button, ui_draw_checkbox, 0))
1201 + config.tc_hide_carrying ^= 1;
1203 + ui_hsplit_t(&right_view, 20.0f, &button, &right_view);
1204 + if(ui_do_button(&config.tc_autodemo, "Enable automatic demo recording", config.tc_autodemo, &button, ui_draw_checkbox, 0))
1205 + config.tc_autodemo ^= 1;
1207 + ui_hsplit_t(&right_view, 20.0f, &button, &right_view);
1208 + if(ui_do_button(&config.tc_autoscreen, "Enable end game automatic screenshot", config.tc_autoscreen, &button, ui_draw_checkbox, 0))
1209 + config.tc_autoscreen ^= 1;
1212 +void MENUS::render_settings_teecomp_about(RECT main_view)
1214 + RECT button;
1216 + ui_hsplit_t(&main_view, 52.0f, &button, &main_view);
1217 + ui_do_label(&button, "TeeComp", 48.0f, 0);
1218 + ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
1219 + ui_vsplit_r(&button, button.w/3, 0, &button);
1220 + ui_do_label(&button, "Version "TEECOMP_VERSION, 14.0f, -1);
1221 + ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
1222 + ui_vsplit_r(&button, button.w/3, 0, &button);
1223 + ui_do_label(&button, "For Teeworlds "GAME_VERSION, 14.0f, -1);
1224 + ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
1225 + ui_vsplit_r(&button, button.w/3, 0, &button);
1226 + ui_do_label(&button, "Compiled "__DATE__" "__TIME__, 14.0f, -1);
1228 + ui_hsplit_t(&main_view, 40.0f, 0, &main_view);
1229 + ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
1230 + ui_do_label(&button, "By Alban 'spl0k' FERON", 14.0f, 0);
1231 + ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
1232 + ui_do_label(&button, "http://spl0k.unreal-design.com/", 14.0f, 0);
1234 + ui_hsplit_t(&main_view, 20.0f, 0, &main_view);
1235 + ui_hsplit_t(&main_view, 22.0f, &button, &main_view);
1236 + ui_do_label(&button, "Special thanks to:", 16.0f, 0);
1237 + ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
1238 + ui_do_label(&button, "Sd`", 14.0f, 0);
1239 + ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
1240 + ui_do_label(&button, "Tho", 14.0f, 0);
1241 + ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
1242 + ui_do_label(&button, "Eve", 14.0f, 0);
1243 + ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
1244 + ui_do_label(&button, "some other MonkeyStyle members", 14.0f, 0);
1245 + ui_hsplit_t(&main_view, 20.0f, &button, &main_view);
1246 + ui_do_label(&button, "and the Teeworlds.com community", 14.0f, 0);
1248 + ui_hsplit_b(&main_view, 10.0f, &main_view, &button);
1249 + ui_do_label(&button, "so you can set while u set while u set options", 10.0f, -1);
1250 + ui_hsplit_b(&main_view, 10.0f, &main_view, &button);
1251 + ui_do_label(&button, "Yo dawg I herd you like tabs so we put tabs in yo tabs in yo tabs", 10.0f, -1);
1254 diff -Nru teeworlds-0.5.2-src/src/game/client/components/nameplates.cpp teeworlds-0.5.2-teecomp/src/game/client/components/nameplates.cpp
1255 --- teeworlds-0.5.2-src/src/game/client/components/nameplates.cpp 2009-10-26 19:04:31.000000000 +0100
1256 +++ teeworlds-0.5.2-teecomp/src/game/client/components/nameplates.cpp 2009-10-27 19:06:18.000000000 +0100
1257 @@ -7,6 +7,8 @@
1258 #include "nameplates.hpp"
1259 #include "controls.hpp"
1261 +#include <game/client/teecomp.hpp>
1263 void NAMEPLATES::render_nameplate(
1264 const NETOBJ_CHARACTER *prev_char,
1265 const NETOBJ_CHARACTER *player_char,
1266 @@ -25,9 +27,32 @@
1267 if(config.cl_nameplates_always == 0)
1268 a = clamp(1-powf(distance(gameclient.controls->target_pos, position)/200.0f,16.0f), 0.0f, 1.0f);
1270 - const char *name = gameclient.clients[player_info->cid].name;
1271 + char name[256];
1272 + if(!config.tc_nameplate_score)
1273 + str_format(name, 256, "%s", gameclient.clients[player_info->cid].name);
1274 + else
1275 + str_format(name, 256, "%s (%d)", gameclient.clients[player_info->cid].name, player_info->score);
1276 float tw = gfx_text_width(0, 28.0f, name, -1);
1277 - gfx_text_color(1,1,1,a);
1278 + if(config.tc_nameplate_shadow)
1280 + gfx_text_color(0,0,0,a);
1281 + gfx_text(0, position.x-tw/2.0f+2, position.y-60+2, 28.0f, name, -1);
1283 + bool is_teamplay;
1284 + is_teamplay = gameclient.snap.gameobj && gameclient.snap.gameobj->flags&GAMEFLAG_TEAMS;
1285 + if(config.tc_colored_nameplates&1 && is_teamplay)
1287 + vec3 col = TeecompUtils::getTeamColor(
1288 + gameclient.clients[player_info->cid].team,
1289 + gameclient.snap.local_info->team,
1290 + config.tc_colored_nameplates_team1,
1291 + config.tc_colored_nameplates_team2,
1292 + config.tc_colored_nameplates&2);
1293 + gfx_text_color(col.r, col.g, col.b, a);
1295 + else // FFA or no colored plates
1296 + gfx_text_color(1,1,1,a);
1298 gfx_text(0, position.x-tw/2.0f, position.y-60, 28.0f, name, -1);
1300 if(config.debug) // render client id when in debug aswell
1301 diff -Nru teeworlds-0.5.2-src/src/game/client/components/scoreboard.cpp teeworlds-0.5.2-teecomp/src/game/client/components/scoreboard.cpp
1302 --- teeworlds-0.5.2-src/src/game/client/components/scoreboard.cpp 2009-10-26 19:04:31.000000000 +0100
1303 +++ teeworlds-0.5.2-teecomp/src/game/client/components/scoreboard.cpp 2009-10-27 19:06:18.000000000 +0100
1304 @@ -6,8 +6,10 @@
1305 #include <game/client/animstate.hpp>
1306 #include <game/client/render.hpp>
1307 #include <game/client/components/motd.hpp>
1308 +#include <game/client/components/teecomp_stats.hpp>
1309 #include "scoreboard.hpp"
1311 +#include <game/client/teecomp.hpp>
1313 SCOREBOARD::SCOREBOARD()
1315 @@ -231,11 +233,20 @@
1316 (gameclient.snap.flags[1] && gameclient.snap.flags[1]->carried_by == info->cid))
1318 gfx_blend_normal();
1319 - gfx_texture_set(data->images[IMAGE_GAME].id);
1320 + if(config.tc_colored_flags)
1321 + gfx_texture_set(data->images[IMAGE_GAME_GRAY].id);
1322 + else
1323 + gfx_texture_set(data->images[IMAGE_GAME].id);
1324 gfx_quads_begin();
1326 if(info->team == 0) select_sprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
1327 else select_sprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
1328 + if(config.tc_colored_flags)
1330 + vec3 col = TeecompUtils::getTeamColor(1-info->team, gameclient.snap.local_info->team,
1331 + config.tc_colored_tees_team1, config.tc_colored_tees_team2, config.tc_colored_tees_method);
1332 + gfx_setcolor(col.r, col.g, col.b, 1.0f);
1335 float size = 64.0f;
1336 gfx_quads_drawTL(x+55, y-15, size/2, size);
1337 @@ -270,6 +281,10 @@
1338 if(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over)
1339 do_scoreboard = true;
1341 + // we're looking at the stats, don't show the scoreboard
1342 + if(gameclient.teecomp_stats->is_active())
1343 + do_scoreboard = false;
1345 if(!do_scoreboard)
1346 return;
1348 @@ -293,20 +308,39 @@
1349 else
1352 + char text[32];
1353 if(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over)
1355 - const char *text = "DRAW!";
1356 + str_copy(text, "DRAW!", sizeof(text));
1357 if(gameclient.snap.gameobj->teamscore_red > gameclient.snap.gameobj->teamscore_blue)
1358 - text = "Red Team Wins!";
1360 + if(gameclient.snap.local_info->team == 1 && config.tc_colored_tees_method == 1)
1361 + str_format(text, sizeof(text), "%s Team Wins!", TeecompUtils::rgb_to_name(config.tc_colored_tees_team2));
1362 + else
1363 + str_format(text, sizeof(text), "%s Team Wins!", TeecompUtils::rgb_to_name(config.tc_colored_tees_team1));
1365 else if(gameclient.snap.gameobj->teamscore_blue > gameclient.snap.gameobj->teamscore_red)
1366 - text = "Blue Team Wins!";
1368 + if(gameclient.snap.local_info->team == 1 && config.tc_colored_tees_method == 1)
1369 + str_format(text, sizeof(text), "%s Team Wins!", TeecompUtils::rgb_to_name(config.tc_colored_tees_team1));
1370 + else
1371 + str_format(text, sizeof(text), "%s Team Wins!", TeecompUtils::rgb_to_name(config.tc_colored_tees_team2));
1374 float w = gfx_text_width(0, 92.0f, text, -1);
1375 gfx_text(0, width/2-w/2, 45, 92.0f, text, -1);
1378 - render_scoreboard(width/2-w-20, 150.0f, w, 0, "Red Team");
1379 - render_scoreboard(width/2 + 20, 150.0f, w, 1, "Blue Team");
1380 + if(gameclient.snap.local_info && gameclient.snap.local_info->team == 1 && config.tc_colored_tees_method == 1)
1381 + str_format(text, sizeof(text), "%s Team", TeecompUtils::rgb_to_name(config.tc_colored_tees_team2));
1382 + else
1383 + str_format(text, sizeof(text), "%s Team", TeecompUtils::rgb_to_name(config.tc_colored_tees_team1));
1384 + render_scoreboard(width/2-w-20, 150.0f, w, 0, text);
1385 + if(gameclient.snap.local_info && gameclient.snap.local_info->team == 1 && config.tc_colored_tees_method == 1)
1386 + str_format(text, sizeof(text), "%s Team", TeecompUtils::rgb_to_name(config.tc_colored_tees_team1));
1387 + else
1388 + str_format(text, sizeof(text), "%s Team", TeecompUtils::rgb_to_name(config.tc_colored_tees_team2));
1389 + render_scoreboard(width/2 + 20, 150.0f, w, 1, text);
1392 render_goals(width/2-w/2, 150+750+25, w);
1393 diff -Nru teeworlds-0.5.2-src/src/game/client/components/teecomp_stats.cpp teeworlds-0.5.2-teecomp/src/game/client/components/teecomp_stats.cpp
1394 --- teeworlds-0.5.2-src/src/game/client/components/teecomp_stats.cpp 1970-01-01 01:00:00.000000000 +0100
1395 +++ teeworlds-0.5.2-teecomp/src/game/client/components/teecomp_stats.cpp 2009-10-27 19:40:12.000000000 +0100
1396 @@ -0,0 +1,531 @@
1397 +#include <engine/e_client_interface.h>
1398 +#include <game/generated/g_protocol.hpp>
1399 +#include <game/generated/gc_data.hpp>
1400 +#include <game/client/gameclient.hpp>
1401 +#include <game/client/animstate.hpp>
1402 +#include <game/client/teecomp.hpp>
1403 +#include "teecomp_stats.hpp"
1405 +TEECOMP_STATS::TEECOMP_STATS()
1407 + on_reset();
1410 +void TEECOMP_STATS::on_reset()
1412 + for(int i=0; i<MAX_CLIENTS; i++)
1413 + gameclient.stats[i].reset();
1414 + mode = 0;
1415 + stats_cid = -1;
1418 +void TEECOMP_STATS::con_key_stats(void *result, void *user_data)
1420 + //((TEECOMP_STATS *)user_data)->active = console_arg_int(result, 0) != 0;
1421 + if(console_arg_int(result, 0) != 0)
1422 + ((TEECOMP_STATS *)user_data)->mode = console_arg_int(result, 1);
1423 + else
1424 + ((TEECOMP_STATS *)user_data)->mode = 0;
1427 +void TEECOMP_STATS::con_key_next(void *result, void *user_data)
1429 + //((TEECOMP_STATS *)user_data)->active = console_arg_int(result, 0) != 0;
1430 + TEECOMP_STATS *stats = (TEECOMP_STATS *)user_data;
1431 + if(stats->mode != 2)
1432 + return;
1434 + if(console_arg_int(result, 0) == 0)
1436 + stats->stats_cid++;
1437 + stats->stats_cid %= MAX_CLIENTS;
1438 + stats->check_stats_cid();
1442 +void TEECOMP_STATS::on_console_init()
1444 + MACRO_REGISTER_COMMAND("+stats", "i", CFGFLAG_CLIENT, con_key_stats, this, "Show stats");
1445 + MACRO_REGISTER_COMMAND("+next_stats", "", CFGFLAG_CLIENT, con_key_next, this, "Next player stats");
1448 +bool TEECOMP_STATS::is_active() {
1449 + return (mode > 0);
1452 +void TEECOMP_STATS::check_stats_cid()
1454 + if(stats_cid == -1)
1455 + stats_cid = gameclient.snap.local_cid;
1457 + int prev = stats_cid;
1458 + while(!gameclient.stats[stats_cid].active)
1460 + stats_cid++;
1461 + stats_cid %= MAX_CLIENTS;
1462 + if(stats_cid == prev)
1464 + stats_cid = -1;
1465 + mode = 0;
1466 + break;
1471 +void TEECOMP_STATS::on_message(int msgtype, void *rawmsg)
1473 + if(msgtype == NETMSGTYPE_SV_KILLMSG)
1475 + NETMSG_SV_KILLMSG *msg = (NETMSG_SV_KILLMSG *)rawmsg;
1476 + GAMECLIENT::CLIENT_STATS *stats = gameclient.stats;
1478 + stats[msg->victim].deaths++;
1479 + if(msg->weapon >= 0)
1480 + stats[msg->victim].deaths_from[msg->weapon]++;
1481 + if(msg->mode_special & 1)
1482 + stats[msg->victim].deaths_carrying++;
1483 + if(msg->victim != msg->killer)
1485 + stats[msg->killer].frags++;
1486 + if(msg->weapon >= 0)
1487 + stats[msg->killer].frags_with[msg->weapon]++;
1488 + if(msg->mode_special & 1)
1489 + stats[msg->killer].carriers_killed++;
1490 + if(msg->mode_special & 2)
1491 + stats[msg->killer].kills_carrying++;
1493 + else
1494 + stats[msg->victim].suicides++;
1496 + else if(msgtype == NETMSGTYPE_SV_CHAT)
1498 + NETMSG_SV_CHAT *msg = (NETMSG_SV_CHAT *)rawmsg;
1499 + if(msg->cid < 0)
1501 + const char *p;
1502 + const char *look_for = "flag was captured by ";
1503 + if(p = str_find_nocase(msg->message, look_for))
1505 + char name[64];
1506 + p += str_length(look_for);
1507 + str_copy(name, p, sizeof(name));
1508 + if(str_comp_nocase(name+str_length(name)-9, " seconds)") == 0)
1510 + char *c = name+str_length(name)-10;
1511 + while(c > name)
1513 + c--;
1514 + if(*c == '(')
1516 + *(c-1) = 0;
1517 + break;
1521 + for(int i=0; i<MAX_CLIENTS; i++)
1523 + if(!gameclient.stats[i].active)
1524 + continue;
1526 + if(str_comp_nocase(gameclient.clients[i].name, name) == 0)
1528 + gameclient.stats[i].flag_captures++;
1529 + break;
1537 +void TEECOMP_STATS::on_render()
1539 + switch(mode)
1541 + case 1:
1542 + render_global_stats();
1543 + break;
1544 + case 2:
1545 + render_individual_stats();
1546 + break;
1550 +void TEECOMP_STATS::render_global_stats()
1552 + if(mode != 1)
1553 + return;
1555 + float width = 400*3.0f*gfx_screenaspect();
1556 + float height = 400*3.0f;
1557 + float w = 450.0f;
1558 + float h = 750.0f;
1560 + const NETOBJ_PLAYER_INFO *players[MAX_CLIENTS] = {0};
1561 + int num_players = 0;
1562 + int i;
1563 + for(i=0; i<snap_num_items(SNAP_CURRENT); i++)
1565 + SNAP_ITEM item;
1566 + const void *data = snap_get_item(SNAP_CURRENT, i, &item);
1568 + if(item.type == NETOBJTYPE_PLAYER_INFO)
1570 + const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
1572 + if(!gameclient.stats[info->cid].active)
1573 + continue;
1575 + players[num_players] = info;
1576 + num_players++;
1580 + for(int i=0; i<6; i++)
1581 + if(config.tc_statboard_infos & (1<<i))
1582 + w += 100;
1583 + if(gameclient.snap.gameobj && gameclient.snap.gameobj->flags&GAMEFLAG_FLAGS && config.tc_statboard_infos&TC_STATS_FLAGS)
1584 + w += 100;
1586 + bool display_weapon[NUM_WEAPONS] = {false};
1587 + if(config.tc_statboard_infos & TC_STATS_WEAPS)
1589 + for(i=0; i<num_players; i++)
1591 + const GAMECLIENT::CLIENT_STATS stats = gameclient.stats[players[i]->cid];
1592 + for(int j=0; j<NUM_WEAPONS; j++)
1593 + display_weapon[j] = display_weapon[j] || stats.frags_with[j] || stats.deaths_from[j];
1595 + for(i=0; i<NUM_WEAPONS; i++)
1596 + if(display_weapon[i])
1597 + w += 120;
1600 + float x = width/2-w/2;
1601 + float y = 200.0f;
1603 + gfx_mapscreen(0, 0, width, height);
1605 + gfx_blend_normal();
1606 + gfx_texture_set(-1);
1607 + gfx_quads_begin();
1608 + gfx_setcolor(0,0,0,0.5f);
1609 + draw_round_rect(x-10.f, y-10.f, w, h, 17.0f);
1610 + gfx_quads_end();
1612 + float tw;
1613 + int px = 525;
1615 + gfx_text(0, x+10, y, 24.0f, "Name", -1);
1616 + const char *headers[] = { "Frags", "Deaths", "Suicides", "Ratio", "Net", "FPM" };
1617 + for(i=0; i<6; i++)
1618 + if(config.tc_statboard_infos & (1<<i))
1620 + tw = gfx_text_width(0, 24.0f, headers[i], -1);
1621 + gfx_text(0, x+px-tw, y, 24.0f, headers[i], -1);
1622 + px += 100;
1625 + if(config.tc_statboard_infos & TC_STATS_WEAPS)
1627 + gfx_texture_set(data->images[IMAGE_GAME].id);
1628 + gfx_quads_begin();
1629 + for(i=0, px-=40; i<NUM_WEAPONS; i++)
1631 + if(!display_weapon[i])
1632 + continue;
1634 + select_sprite(data->weapons.id[i].sprite_body, 0);
1635 + if(i == 0)
1636 + draw_sprite(x+px, y+8, data->weapons.id[i].visual_size*0.8);
1637 + else
1638 + draw_sprite(x+px, y+8, data->weapons.id[i].visual_size);
1639 + px += 120;
1641 + gfx_quads_end();
1642 + px += 40;
1645 + if(gameclient.snap.gameobj && gameclient.snap.gameobj->flags&GAMEFLAG_FLAGS && config.tc_statboard_infos&TC_STATS_FLAGS)
1647 + px -= 40;
1648 + gfx_texture_set(data->images[IMAGE_GAME].id);
1649 + gfx_quads_begin();
1650 + gfx_quads_setrotation(0.78f);
1651 + select_sprite(SPRITE_FLAG_RED);
1652 + draw_sprite(x+px, y+10, 48);
1653 + gfx_quads_end();
1656 + y += 29.0f;
1658 + float font_size = 30.0f;
1659 + float line_height = 50.0f;
1660 + float tee_sizemod = 1.0f;
1661 + float tee_offset = 0.0f;
1663 + if(num_players > 14)
1665 + font_size = 30.0f;
1666 + line_height = 40.0f;
1667 + tee_sizemod = 0.8f;
1668 + tee_offset = -5.0f;
1671 + for(int j=0; j<num_players; j++)
1673 + const NETOBJ_PLAYER_INFO *info = players[j];
1674 + const GAMECLIENT::CLIENT_STATS stats = gameclient.stats[info->cid];
1676 + if(info->local)
1678 + // background so it's easy to find the local player
1679 + gfx_texture_set(-1);
1680 + gfx_quads_begin();
1681 + gfx_setcolor(1,1,1,0.25f);
1682 + draw_round_rect(x, y, w-20, line_height*0.95f, 17.0f);
1683 + gfx_quads_end();
1686 + TEE_RENDER_INFO teeinfo = gameclient.clients[info->cid].render_info;
1687 + teeinfo.size *= tee_sizemod;
1688 + render_tee(ANIMSTATE::get_idle(), &teeinfo, EMOTE_NORMAL, vec2(1,0), vec2(x+28, y+28+tee_offset));
1690 + char buf[128];
1691 + if(config.tc_stat_id)
1693 + str_format(buf, sizeof(buf), "%d", info->cid);
1694 + gfx_text(0, x, y, font_size, buf, -1);
1697 + gfx_text(0, x+64, y, font_size, gameclient.clients[info->cid].name, -1);
1699 + px = 525;
1701 + if(config.tc_statboard_infos & TC_STATS_FRAGS)
1703 + str_format(buf, sizeof(buf), "%d", stats.frags);
1704 + tw = gfx_text_width(0, font_size, buf, -1);
1705 + gfx_text(0, x-tw+px, y, font_size, buf, -1);
1706 + px += 100;
1708 + if(config.tc_statboard_infos & TC_STATS_DEATHS)
1710 + str_format(buf, sizeof(buf), "%d", stats.deaths);
1711 + tw = gfx_text_width(0, font_size, buf, -1);
1712 + gfx_text(0, x-tw+px, y, font_size, buf, -1);
1713 + px += 100;
1715 + if(config.tc_statboard_infos & TC_STATS_SUICIDES)
1717 + str_format(buf, sizeof(buf), "%d", stats.suicides);
1718 + tw = gfx_text_width(0, font_size, buf, -1);
1719 + gfx_text(0, x-tw+px, y, font_size, buf, -1);
1720 + px += 100;
1722 + if(config.tc_statboard_infos & TC_STATS_RATIO)
1724 + if(stats.deaths == 0)
1725 + str_format(buf, sizeof(buf), "--");
1726 + else
1727 + str_format(buf, sizeof(buf), "%.2f", (float)(stats.frags)/stats.deaths);
1728 + tw = gfx_text_width(0, font_size, buf, -1);
1729 + gfx_text(0, x-tw+px, y, font_size, buf, -1);
1730 + px += 100;
1732 + if(config.tc_statboard_infos & TC_STATS_NET)
1734 + str_format(buf, sizeof(buf), "%+d", stats.frags-stats.deaths);
1735 + tw = gfx_text_width(0, font_size, buf, -1);
1736 + gfx_text(0, x-tw+px, y, font_size, buf, -1);
1737 + px += 100;
1739 + if(config.tc_statboard_infos & TC_STATS_FPM)
1741 + float fpm = (float)(stats.frags*60)/((float)(client_tick()-stats.join_date)/client_tickspeed());
1742 + str_format(buf, sizeof(buf), "%.1f", fpm);
1743 + tw = gfx_text_width(0, font_size, buf, -1);
1744 + gfx_text(0, x-tw+px, y, font_size, buf, -1);
1745 + px += 100;
1747 + for(i=0, px=px-40; i<NUM_WEAPONS; i++)
1749 + if(!display_weapon[i])
1750 + continue;
1752 + str_format(buf, sizeof(buf), "%d/%d", stats.frags_with[i], stats.deaths_from[i]);
1753 + tw = gfx_text_width(0, font_size, buf, -1);
1754 + gfx_text(0, x+px-tw/2, y, font_size, buf, -1);
1755 + px += 120;
1757 + if(gameclient.snap.gameobj && gameclient.snap.gameobj->flags&GAMEFLAG_FLAGS && config.tc_statboard_infos&TC_STATS_FLAGS)
1759 + str_format(buf, sizeof(buf), "%d", stats.flag_captures);
1760 + tw = gfx_text_width(0, font_size, buf, -1);
1761 + gfx_text(0, x-tw+px, y, font_size, buf, -1);
1762 + px += 100;
1764 + y += line_height;
1768 +void TEECOMP_STATS::render_individual_stats()
1770 + if(mode != 2)
1771 + return;
1772 + check_stats_cid();
1773 + if(mode != 2)
1774 + return;
1775 + int cid = stats_cid;
1776 + float width = 400*3.0f*gfx_screenaspect();
1777 + float height = 400*3.0f;
1778 + float w = 1200.0f;
1779 + float x = width/2-w/2;
1780 + float y = 100.0f;
1781 + float xo = 200.0f;
1782 + float font_size = 30.0f;
1783 + float line_height = 40.0f;
1784 + const GAMECLIENT::CLIENT_STATS stats = gameclient.stats[cid];
1786 + gfx_mapscreen(0, 0, width, height);
1788 + // header with name and score
1789 + gfx_blend_normal();
1790 + gfx_texture_set(-1);
1791 + gfx_quads_begin();
1792 + gfx_setcolor(0,0,0,0.5f);
1793 + draw_round_rect(x-10.f, y-10.f, w, 120.0f, 17.0f);
1794 + gfx_quads_end();
1796 + TEE_RENDER_INFO teeinfo = gameclient.clients[cid].render_info;
1797 + teeinfo.size *= 1.5f;
1798 + render_tee(ANIMSTATE::get_idle(), &teeinfo, EMOTE_NORMAL, vec2(1,0), vec2(x+xo+32, y+36));
1799 + gfx_text(0, x+xo+128, y, 48.0f, gameclient.clients[cid].name, -1);
1801 + char buf[64];
1802 + if(config.tc_stat_id)
1804 + str_format(buf, sizeof(buf), "%d", cid);
1805 + gfx_text(0, x+xo, y, font_size, buf, -1);
1808 + str_format(buf, sizeof(buf), "Score: %d", gameclient.snap.player_infos[cid]->score);
1809 + gfx_text(0, x+xo, y+64, font_size, buf, -1);
1810 + int seconds = (float)(client_tick()-stats.join_date)/client_tickspeed();
1811 + str_format(buf, sizeof(buf), "Time played: %02d:%02d", seconds/60, seconds%60);
1812 + gfx_text(0, x+xo+256, y+64, font_size, buf, -1);
1814 + y += 150.0f;
1816 + // Frags, etc. stats
1817 + gfx_blend_normal();
1818 + gfx_texture_set(-1);
1819 + gfx_quads_begin();
1820 + gfx_setcolor(0,0,0,0.5f);
1821 + draw_round_rect(x-10.f, y-10.f, w, 100.0f, 17.0f);
1822 + gfx_quads_end();
1824 + gfx_texture_set(data->images[IMAGE_EMOTICONS].id);
1825 + gfx_quads_begin();
1826 + gfx_setcolor(1.0f,1.0f,1.0f,1.0f);
1827 + select_sprite(SPRITE_DEADTEE);
1828 + gfx_quads_draw(x+xo/2, y+40, 128, 128);
1829 + gfx_quads_end();
1831 + str_format(buf, sizeof(buf), "Frags: %d", stats.frags);
1832 + gfx_text(0, x+xo, y, font_size, buf, -1);
1833 + str_format(buf, sizeof(buf), "Deaths: %d", stats.deaths);
1834 + gfx_text(0, x+xo+200.0f, y, font_size, buf, -1);
1835 + str_format(buf, sizeof(buf), "Suicides: %d", stats.suicides);
1836 + gfx_text(0, x+xo+400.0f, y, font_size, buf, -1);
1837 + y += line_height;
1839 + if(stats.deaths == 0)
1840 + str_format(buf, sizeof(buf), "Ratio: --");
1841 + else
1842 + str_format(buf, sizeof(buf), "Ratio: %.2f", (float)(stats.frags)/stats.deaths);
1843 + gfx_text(0, x+xo, y, font_size, buf, -1);
1844 + str_format(buf, sizeof(buf), "Net: %d", stats.frags-stats.deaths);
1845 + gfx_text(0, x+xo+200.0f, y, font_size, buf, -1);
1846 + float fpm = (float)(stats.frags*60)/((float)(client_tick()-stats.join_date)/client_tickspeed());
1847 + str_format(buf, sizeof(buf), "FPM: %.1f", fpm);
1848 + gfx_text(0, x+xo+400.0f, y, font_size, buf, -1);
1849 + y+= line_height + 30.0f;
1851 + // Weapon stats
1852 + bool display_weapon[NUM_WEAPONS] = {false};
1853 + int num_weaps = 0;
1854 + for(int i=0; i<NUM_WEAPONS; i++)
1855 + if(stats.frags_with[i] || stats.deaths_from[i])
1857 + display_weapon[i] = true;
1858 + num_weaps++;
1861 + if(num_weaps)
1863 + gfx_blend_normal();
1864 + gfx_texture_set(-1);
1865 + gfx_quads_begin();
1866 + gfx_setcolor(0,0,0,0.5f);
1867 + draw_round_rect(x-10.f, y-10.f, w, line_height*(1+num_weaps)+20.0f, 17.0f);
1868 + gfx_quads_end();
1870 + gfx_text(0, x+xo, y, font_size, "Frags", -1);
1871 + gfx_text(0, x+xo+200.0f, y, font_size, "Deaths", -1);
1872 + y += line_height;
1874 + for(int i=0; i<NUM_WEAPONS; i++)
1876 + if(!display_weapon[i])
1877 + continue;
1879 + gfx_texture_set(data->images[IMAGE_GAME].id);
1880 + gfx_quads_begin();
1881 + select_sprite(data->weapons.id[i].sprite_body, 0);
1882 + draw_sprite(x+xo/2, y+24, data->weapons.id[i].visual_size);
1883 + gfx_quads_end();
1885 + str_format(buf, sizeof(buf), "%d", stats.frags_with[i]);
1886 + gfx_text(0, x+xo, y, font_size, buf, -1);
1887 + str_format(buf, sizeof(buf), "%d", stats.deaths_from[i]);
1888 + gfx_text(0, x+xo+200.0f, y, font_size, buf, -1);
1889 + y += line_height;
1891 + y += 30.0f;
1894 + // Flag stats
1895 + if(gameclient.snap.gameobj && gameclient.snap.gameobj->flags&GAMEFLAG_FLAGS)
1897 + gfx_blend_normal();
1898 + gfx_texture_set(-1);
1899 + gfx_quads_begin();
1900 + gfx_setcolor(0,0,0,0.5f);
1901 + draw_round_rect(x-10.f, y-10.f, w, line_height*5+20.0f, 17.0f);
1902 + gfx_quads_end();
1904 + gfx_texture_set(data->images[IMAGE_GAME].id);
1905 + gfx_quads_begin();
1906 + select_sprite(SPRITE_FLAG_RED);
1907 + draw_sprite(x+xo/2, y+100.0f, 192);
1908 + gfx_quads_end();
1910 + str_format(buf, sizeof(buf), "Grabs: %d", stats.flag_grabs);
1911 + gfx_text(0, x+xo, y, font_size, buf, -1);
1912 + y += line_height;
1913 + str_format(buf, sizeof(buf), "Captures: %d", stats.flag_captures);
1914 + gfx_text(0, x+xo, y, font_size, buf, -1);
1915 + y += line_height;
1916 + str_format(buf, sizeof(buf), "Kills holding flag: %d", stats.kills_carrying);
1917 + gfx_text(0, x+xo, y, font_size, buf, -1);
1918 + y += line_height;
1919 + str_format(buf, sizeof(buf), "Deaths with flag: %d", stats.deaths_carrying);
1920 + gfx_text(0, x+xo, y, font_size, buf, -1);
1921 + y += line_height;
1922 + str_format(buf, sizeof(buf), "Carriers killed: %d", stats.carriers_killed);
1923 + gfx_text(0, x+xo, y, font_size, buf, -1);
1924 + y += line_height;
1928 diff -Nru teeworlds-0.5.2-src/src/game/client/components/teecomp_stats.hpp teeworlds-0.5.2-teecomp/src/game/client/components/teecomp_stats.hpp
1929 --- teeworlds-0.5.2-src/src/game/client/components/teecomp_stats.hpp 1970-01-01 01:00:00.000000000 +0100
1930 +++ teeworlds-0.5.2-teecomp/src/game/client/components/teecomp_stats.hpp 2009-10-27 19:06:18.000000000 +0100
1931 @@ -0,0 +1,22 @@
1932 +#include <game/client/component.hpp>
1934 +class TEECOMP_STATS: public COMPONENT
1936 +private:
1937 + int mode;
1938 + int stats_cid;
1939 + static void con_key_stats(void *result, void *user_data);
1940 + static void con_key_next(void *result, void *user_data);
1941 + void render_global_stats();
1942 + void render_individual_stats();
1943 + void check_stats_cid();
1945 +public:
1946 + TEECOMP_STATS();
1947 + virtual void on_reset();
1948 + virtual void on_console_init();
1949 + virtual void on_render();
1950 + virtual void on_message(int msgtype, void *rawmsg);
1951 + bool is_active();
1954 diff -Nru teeworlds-0.5.2-src/src/game/client/gameclient.cpp teeworlds-0.5.2-teecomp/src/game/client/gameclient.cpp
1955 --- teeworlds-0.5.2-src/src/game/client/gameclient.cpp 2009-10-26 19:04:31.000000000 +0100
1956 +++ teeworlds-0.5.2-teecomp/src/game/client/gameclient.cpp 2009-10-27 19:06:18.000000000 +0100
1957 @@ -35,6 +35,9 @@
1958 #include "components/skins.hpp"
1959 #include "components/sounds.hpp"
1960 #include "components/voting.hpp"
1961 +#include "components/teecomp_stats.hpp"
1963 +#include <game/client/teecomp.hpp>
1965 GAMECLIENT gameclient;
1967 @@ -59,6 +62,7 @@
1968 static EMOTICON emoticon;
1969 static DAMAGEIND damageind;
1970 static VOTING voting;
1971 +static TEECOMP_STATS teecomp_stats;
1973 static PLAYERS players;
1974 static NAMEPLATES nameplates;
1975 @@ -115,6 +119,7 @@
1976 damageind = &::damageind;
1977 mapimages = &::mapimages;
1978 voting = &::voting;
1979 + teecomp_stats = &::teecomp_stats;
1981 // make a list of all the systems, make sure to add them in the corrent render order
1982 all.add(skins);
1983 @@ -144,6 +149,7 @@
1984 all.add(&broadcast);
1985 all.add(&debughud);
1986 all.add(&scoreboard);
1987 + all.add(teecomp_stats);
1988 all.add(motd);
1989 all.add(menus);
1990 all.add(console);
1991 @@ -233,6 +239,75 @@
1992 dbg_msg("", "%f.2ms", ((end-start)*1000)/(float)time_freq());
1994 servermode = SERVERMODE_PURE;
1996 + // Teecomp grayscale flags
1997 + gfx_unload_texture(data->images[IMAGE_GAME_GRAY].id); // Already loaded with full color, unload
1998 + data->images[IMAGE_GAME_GRAY].id = -1;
2000 + IMAGE_INFO info;
2001 + if(!gfx_load_png(&info, data->images[IMAGE_GAME_GRAY].filename))
2002 + return;
2004 + unsigned char *d = (unsigned char *)info.data;
2005 + int step = info.format == IMG_RGBA ? 4 : 3;
2007 + for(int i=0; i < info.width*info.height; i++)
2009 + int v = (d[i*step]+d[i*step+1]+d[i*step+2])/3;
2010 + d[i*step] = v;
2011 + d[i*step+1] = v;
2012 + d[i*step+2] = v;
2015 + int freq[256];
2016 + int org_weight;
2017 + int new_weight;
2018 + int flag_x = 384;
2019 + int flag_y = 256;
2020 + int flag_w = 128;
2021 + int flag_h = 256;
2022 + int pitch = info.width*4;
2024 + for(int f=0; f<2; f++)
2026 + org_weight = 0;
2027 + new_weight = 192;
2028 + for(int i=0; i<256; i++)
2029 + freq[i] = 0;
2031 + // find most common frequence
2032 + for(int y=flag_y; y<flag_y+flag_h; y++)
2033 + for(int x=flag_x+flag_w*f; x<flag_x+flag_w*(1+f); x++)
2035 + if(d[y*pitch+x*4+3] > 128)
2036 + freq[d[y*pitch+x*4]]++;
2039 + for(int i = 1; i < 256; i++)
2041 + if(freq[org_weight] < freq[i])
2042 + org_weight = i;
2045 + // reorder
2046 + int inv_org_weight = 255-org_weight;
2047 + int inv_new_weight = 255-new_weight;
2048 + for(int y=flag_y; y<flag_y+flag_h; y++)
2049 + for(int x=flag_x+flag_w*f; x<flag_x+flag_w*(1+f); x++)
2051 + int v = d[y*pitch+x*4];
2052 + if(v <= org_weight*1.25f) // modified for contrast
2053 + v = (int)(((v/(float)org_weight) * new_weight));
2054 + else
2055 + v = (int)(((v-org_weight)/(float)inv_org_weight)*inv_new_weight + new_weight);
2056 + d[y*pitch+x*4] = v;
2057 + d[y*pitch+x*4+1] = v;
2058 + d[y*pitch+x*4+2] = v;
2062 + data->images[IMAGE_GAME_GRAY].id = gfx_load_texture_raw(info.width, info.height, info.format, info.data, info.format, 0);
2063 + mem_free(info.data);
2066 void GAMECLIENT::on_save()
2067 @@ -246,7 +321,7 @@
2068 // handle mouse movement
2069 int x=0, y=0;
2070 inp_mouse_relative(&x, &y);
2071 - if(x || y)
2072 + if(x || y || !freeview)
2074 for(int h = 0; h < input.num; h++)
2076 @@ -277,7 +352,31 @@
2078 int GAMECLIENT::on_snapinput(int *data)
2080 - return controls->snapinput(data);
2081 + int val = controls->snapinput(data);
2082 + if(val && snap.spectate)
2084 + NETOBJ_PLAYER_INPUT *inp = (NETOBJ_PLAYER_INPUT *)data;
2085 + static bool last_fire = false, last_hook = false;
2087 + if(inp->fire&1 && !last_fire)
2089 + find_next_spectable_cid();
2090 + last_fire = true;
2092 + else if(!(inp->fire&1) && last_fire)
2093 + last_fire = false;
2095 + if(inp->hook && !last_hook)
2097 + freeview = !freeview;
2098 + if(!freeview)
2099 + find_next_spectable_cid();
2100 + last_hook = true;
2102 + else if(!inp->hook && last_hook)
2103 + last_hook = false;
2105 + return val;
2108 void GAMECLIENT::on_connected()
2109 @@ -299,6 +398,13 @@
2111 // send the inital info
2112 send_info(true);
2114 + freeview = true;
2115 + spectate_cid = -1;
2116 + last_game_over = false;
2117 + last_warmup = false;
2118 + last_flag_carrier[0] = -1;
2119 + last_flag_carrier[1] = -1;
2122 void GAMECLIENT::on_reset()
2123 @@ -318,7 +424,9 @@
2124 clients[i].skin_info.texture = gameclient.skins->get(0)->color_texture;
2125 clients[i].skin_info.color_body = vec4(1,1,1,1);
2126 clients[i].skin_info.color_feet = vec4(1,1,1,1);
2127 - clients[i].update_render_info();
2128 + clients[i].update_render_info(i);
2130 + stats[i].reset();
2133 for(int i = 0; i < all.num; i++)
2134 @@ -343,8 +451,41 @@
2135 vec2(snap.local_prev_character->x, snap.local_prev_character->y),
2136 vec2(snap.local_character->x, snap.local_character->y), client_intratick());
2138 + if(spectate_cid == -1)
2139 + freeview = true;
2140 + if(snap.spectate && !freeview)
2142 + if(!snap.characters[spectate_cid].active || clients[spectate_cid].team == -1)
2144 + freeview = true;
2145 + return;
2147 + spectate_pos = mix(
2148 + vec2(snap.characters[spectate_cid].prev.x, snap.characters[spectate_cid].prev.y),
2149 + vec2(snap.characters[spectate_cid].cur.x, snap.characters[spectate_cid].cur.y), client_intratick());
2153 +void GAMECLIENT::find_next_spectable_cid()
2155 + int next = spectate_cid+1;
2156 + next %= MAX_CLIENTS;
2157 + int prev = next;
2158 + while(!snap.characters[next].active || clients[next].team == -1)
2160 + next++;
2161 + next %= MAX_CLIENTS;
2162 + if(next == prev)
2164 + freeview = true;
2165 + spectate_cid = -1;
2166 + return;
2169 + spectate_cid = next;
2170 + if(freeview)
2171 + freeview = false;
2174 static void evolve(NETOBJ_CHARACTER *character, int tick)
2176 @@ -473,6 +614,9 @@
2177 // then change the state
2178 for(int i = 0; i < all.num; i++)
2179 all.components[i]->on_statechange(new_state, old_state);
2181 + if(new_state == CLIENTSTATE_ONLINE && config.tc_autodemo)
2182 + teecomp_demo_start();
2186 @@ -570,6 +714,10 @@
2188 snap.team_size[0] = snap.team_size[1] = 0;
2190 + // TeeComp.
2191 + for(int i=0; i<MAX_CLIENTS; i++)
2192 + stats[i].active = false;
2194 int num = snap_num_items(SNAP_CURRENT);
2195 for(int i = 0; i < num; i++)
2197 @@ -613,9 +761,8 @@
2198 clients[cid].skin_info.color_feet = vec4(1,1,1,1);
2201 - clients[cid].update_render_info();
2202 + clients[cid].update_render_info(cid);
2203 gameclient.snap.num_players++;
2206 else if(item.type == NETOBJTYPE_PLAYER_INFO)
2208 @@ -635,7 +782,10 @@
2210 // calculate team-balance
2211 if(info->team != -1)
2213 snap.team_size[info->team]++;
2214 + stats[info->cid].active = true;
2218 else if(item.type == NETOBJTYPE_CHARACTER)
2219 @@ -654,9 +804,46 @@
2222 else if(item.type == NETOBJTYPE_GAME)
2224 snap.gameobj = (NETOBJ_GAME *)data;
2225 + if(snap.gameobj->game_over != last_game_over)
2227 + if(!last_game_over)
2228 + on_game_over();
2229 + else
2230 + on_game_restart();
2231 + last_game_over = snap.gameobj->game_over;
2233 + if((snap.gameobj->warmup > 0) != last_warmup)
2235 + if(last_warmup)
2236 + on_warmup_end();
2237 + last_warmup = snap.gameobj->warmup > 0;
2240 else if(item.type == NETOBJTYPE_FLAG)
2241 - snap.flags[item.id%2] = (const NETOBJ_FLAG *)data;
2243 + int fid = item.id%2;
2244 + snap.flags[fid] = (const NETOBJ_FLAG *)data;
2245 + if(snap.flags[fid]->carried_by != last_flag_carrier[fid])
2247 + if(snap.flags[fid]->carried_by >= 0)
2248 + on_flag_grab(fid);
2249 + last_flag_carrier[fid] = snap.flags[fid]->carried_by;
2254 + // TeeComp
2255 + for(int i=0; i<MAX_CLIENTS; i++)
2257 + if(stats[i].active && !stats[i].was_active)
2259 + stats[i].reset(); // Client connected, reset stats.
2260 + stats[i].active = true;
2261 + stats[i].join_date = client_tick();
2263 + stats[i].was_active = stats[i].active;
2267 @@ -690,7 +877,7 @@
2269 // update render info
2270 for(int i = 0; i < MAX_CLIENTS; i++)
2271 - clients[i].update_render_info();
2272 + clients[i].update_render_info(i);
2275 void GAMECLIENT::on_predict()
2276 @@ -817,21 +1004,105 @@
2277 predicted_tick = client_predtick();
2280 -void GAMECLIENT::CLIENT_DATA::update_render_info()
2281 +void GAMECLIENT::on_game_over()
2283 + if(config.tc_autoscreen && !demorec_isplaying())
2284 + gfx_screenshot();
2287 +void GAMECLIENT::on_game_restart()
2289 + if(!demorec_isplaying() && config.tc_autodemo && demorec_isrecording())
2291 + demorec_record_stop();
2292 + teecomp_demo_start();
2294 + for(int i=0; i<MAX_CLIENTS; i++)
2295 + stats[i].reset();
2298 +void GAMECLIENT::on_warmup_end()
2300 + for(int i=0; i<MAX_CLIENTS; i++)
2301 + stats[i].reset();
2304 +void GAMECLIENT::on_flag_grab(int id)
2306 + stats[snap.flags[id]->carried_by].flag_grabs++;
2309 +void GAMECLIENT::CLIENT_STATS::reset()
2311 + join_date = 0;
2312 + active = false;
2313 + was_active = false;
2314 + frags = 0;
2315 + deaths = 0;
2316 + suicides = 0;
2317 + for(int j=0; j<NUM_WEAPONS; j++)
2319 + frags_with[j] = 0;
2320 + deaths_from[j] = 0;
2322 + flag_grabs = 0;
2323 + flag_captures = 0;
2324 + carriers_killed = 0;
2325 + kills_carrying = 0;
2326 + deaths_carrying = 0;
2329 +void GAMECLIENT::CLIENT_DATA::update_render_info(int cid)
2331 render_info = skin_info;
2333 // force team colors
2334 if(gameclient.snap.gameobj && gameclient.snap.gameobj->flags&GAMEFLAG_TEAMS)
2336 - const int team_colors[2] = {65387, 10223467};
2337 - if(team >= 0 || team <= 1)
2338 + int local_team;
2339 + if(gameclient.snap.local_info)
2340 + local_team = gameclient.snap.local_info->team;
2341 + else // local_info null when joining a server
2342 + local_team = 0;
2344 + if(team != -1)
2346 + const char* forced_skin;
2347 + int sid = skin_id;
2348 + if(cid != gameclient.snap.local_cid && TeecompUtils::get_forced_skin_name(team, local_team, forced_skin))
2349 + sid = max(0, gameclient.skins->find(forced_skin));
2351 + if(TeecompUtils::get_force_dm_colors(team, local_team))
2353 + render_info.texture = gameclient.skins->get(sid)->org_texture;
2354 + render_info.color_body = vec4(1,1,1,1);
2355 + render_info.color_feet = vec4(1,1,1,1);
2357 + else
2359 + render_info.texture = gameclient.skins->get(sid)->color_texture;
2360 + vec3 col = TeecompUtils::getTeamColor(team, local_team, config.tc_colored_tees_team1,
2361 + config.tc_colored_tees_team2, config.tc_colored_tees_method);
2362 + render_info.color_body = vec4(col.r, col.g, col.b, 1.0f);
2363 + render_info.color_feet = vec4(col.r, col.g, col.b, 1.0f);
2366 + else
2368 render_info.texture = gameclient.skins->get(skin_id)->color_texture;
2369 - render_info.color_body = gameclient.skins->get_color(team_colors[team]);
2370 - render_info.color_feet = gameclient.skins->get_color(team_colors[team]);
2371 + render_info.color_body = vec4(1,1,1,1);
2372 + render_info.color_feet = vec4(1,1,1,1);
2375 + else if(config.tc_force_skin_team1 && cid != gameclient.snap.local_cid) // Force DM skin
2377 + const SKINS::SKIN* skin;
2378 + skin = gameclient.skins->get(max(0, gameclient.skins->find(config.tc_forced_skin1)));
2379 + if(use_custom_color)
2380 + render_info.texture = skin->color_texture;
2381 + else
2382 + render_info.texture = skin->org_texture;
2386 void GAMECLIENT::send_switch_team(int team)
2387 diff -Nru teeworlds-0.5.2-src/src/game/client/gameclient.hpp teeworlds-0.5.2-teecomp/src/game/client/gameclient.hpp
2388 --- teeworlds-0.5.2-src/src/game/client/gameclient.hpp 2009-10-26 19:04:31.000000000 +0100
2389 +++ teeworlds-0.5.2-teecomp/src/game/client/gameclient.hpp 2009-10-27 19:06:18.000000000 +0100
2390 @@ -112,11 +112,37 @@
2392 float angle;
2394 - void update_render_info();
2395 + void update_render_info(int cid);
2398 CLIENT_DATA clients[MAX_CLIENTS];
2400 + // TeeComp vars
2401 + struct CLIENT_STATS
2403 + int join_date;
2404 + bool active;
2405 + bool was_active;
2407 + int frags_with[NUM_WEAPONS];
2408 + int deaths_from[NUM_WEAPONS];
2409 + int frags;
2410 + int deaths;
2411 + int suicides;
2413 + int flag_grabs;
2414 + int flag_captures;
2415 + int carriers_killed;
2416 + int kills_carrying;
2417 + int deaths_carrying;
2419 + void reset();
2420 + };
2421 + CLIENT_STATS stats[MAX_CLIENTS];
2422 + bool freeview;
2423 + int spectate_cid;
2424 + vec2 spectate_pos;
2426 void on_reset();
2428 // hooks
2429 @@ -131,6 +157,16 @@
2430 void on_predict();
2431 int on_snapinput(int *data);
2433 + // TeeComp hooks
2434 + bool last_game_over;
2435 + bool last_warmup;
2436 + int last_flag_carrier[2];
2437 + void on_game_over();
2438 + void on_game_restart();
2439 + void on_warmup_end();
2440 + void on_flag_grab(int id);
2441 + void find_next_spectable_cid();
2443 // actions
2444 // TODO: move these
2445 void send_switch_team(int team);
2446 @@ -153,6 +189,7 @@
2447 class MOTD *motd;
2448 class MAPIMAGES *mapimages;
2449 class VOTING *voting;
2450 + class TEECOMP_STATS *teecomp_stats;
2453 extern GAMECLIENT gameclient;
2454 diff -Nru teeworlds-0.5.2-src/src/game/client/teecomp.cpp teeworlds-0.5.2-teecomp/src/game/client/teecomp.cpp
2455 --- teeworlds-0.5.2-src/src/game/client/teecomp.cpp 1970-01-01 01:00:00.000000000 +0100
2456 +++ teeworlds-0.5.2-teecomp/src/game/client/teecomp.cpp 2009-10-27 19:06:18.000000000 +0100
2457 @@ -0,0 +1,143 @@
2458 +#include "teecomp.hpp"
2459 +#include <engine/e_config.h>
2460 +#include <base/math.hpp>
2461 +#include <base/system.h>
2463 +vec3 TeecompUtils::getTeamColor(int for_team, int local_team, int color1, int color2, int method)
2465 + vec3 c1((color1>>16)/255.0f, ((color1>>8)&0xff)/255.0f, (color1&0xff)/255.0f);
2466 + vec3 c2((color2>>16)/255.0f, ((color2>>8)&0xff)/255.0f, (color2&0xff)/255.0f);
2468 + // Team based colors or spectating
2469 + if(!method || local_team == -1)
2471 + if(for_team == 0)
2472 + return c1;
2473 + return c2;
2476 + // Enemy based colors
2477 + if(for_team == local_team)
2478 + return c1;
2479 + return c2;
2482 +bool TeecompUtils::get_forced_skin_name(int for_team, int local_team, const char*& skin_name)
2484 + // Team based colors or spectating
2485 + if(!config.tc_forced_skins_method || local_team == -1)
2487 + if(for_team == 0)
2489 + skin_name = config.tc_forced_skin1;
2490 + return config.tc_force_skin_team1;
2492 + skin_name = config.tc_forced_skin2;
2493 + return config.tc_force_skin_team2;
2496 + // Enemy based colors
2497 + if(for_team == local_team)
2499 + skin_name = config.tc_forced_skin1;
2500 + return config.tc_force_skin_team1;
2502 + skin_name = config.tc_forced_skin2;
2503 + return config.tc_force_skin_team2;
2506 +bool TeecompUtils::get_force_dm_colors(int for_team, int local_team)
2508 + if(!config.tc_colored_tees_method || local_team == -1)
2510 + if(for_team == 0)
2511 + return config.tc_dm_colors_team1;
2512 + return config.tc_dm_colors_team2;
2515 + if(for_team == local_team)
2516 + return config.tc_dm_colors_team1;
2517 + return config.tc_dm_colors_team2;
2520 +void TeecompUtils::reset_config()
2522 + #define MACRO_CONFIG_INT(name, def, min, max, flags, desc) config.name = def;
2523 + #define MACRO_CONFIG_STR(name, len, def, flags, desc) str_copy(config.name, def, len);
2524 + #include "../teecomp_vars.hpp"
2525 + #undef MACRO_CONFIG_INT
2526 + #undef MACRO_CONFIG_STR
2529 +static vec3 rgb_to_hsl(vec3 rgb)
2531 + float r = rgb.r;
2532 + float g = rgb.g;
2533 + float b = rgb.b;
2535 + float vMin = min(min(r, g), b);
2536 + float vMax = max(max(r, g), b);
2537 + float dMax = vMax - vMin;
2539 + float h;
2540 + float s;
2541 + float l = (vMax + vMin) / 2.0f;
2543 + if(dMax == 0.0f)
2545 + h = 0.0f;
2546 + s = 0.0f;
2548 + else
2550 + if(l < 0.5f)
2551 + s = dMax / (vMax + vMin);
2552 + else
2553 + s = dMax / (2 - vMax - vMin);
2555 + float dR = (((vMax - r) / 6.0f) + (dMax / 2.0f)) / dMax;
2556 + float dG = (((vMax - g) / 6.0f) + (dMax / 2.0f)) / dMax;
2557 + float dB = (((vMax - b) / 6.0f) + (dMax / 2.0f)) / dMax;
2559 + if(r == vMax)
2560 + h = dB - dG;
2561 + else if(g == vMax)
2562 + h = (1.0f/3.0f) + dR - dB;
2563 + else if(b == vMax)
2564 + h = (2.0f/3.0f) + dG - dR;
2566 + if(h < 0.0f)
2567 + h += 1.0f;
2568 + if(h > 1.0f)
2569 + h -= 1.0f;
2572 + return vec3(h*360, s, l);
2575 +const char* TeecompUtils::rgb_to_name(int rgb)
2577 + vec3 rgb_v((rgb>>16)/255.0f, ((rgb>>8)&0xff)/255.0f, (rgb&0xff)/255.0f);
2578 + vec3 hsl = rgb_to_hsl(rgb_v);
2580 + if(hsl.l < 0.2f)
2581 + return "Black";
2582 + if(hsl.l > 0.9f)
2583 + return "White";
2584 + if(hsl.s < 0.1f)
2585 + return "Gray";
2586 + if(hsl.h < 20)
2587 + return "Red";
2588 + if(hsl.h < 45)
2589 + return "Orange";
2590 + if(hsl.h < 70)
2591 + return "Yellow";
2592 + if(hsl.h < 155)
2593 + return "Green";
2594 + if(hsl.h < 260)
2595 + return "Blue";
2596 + if(hsl.h < 335)
2597 + return "Purple";
2598 + return "Red";
2601 diff -Nru teeworlds-0.5.2-src/src/game/client/teecomp.hpp teeworlds-0.5.2-teecomp/src/game/client/teecomp.hpp
2602 --- teeworlds-0.5.2-src/src/game/client/teecomp.hpp 1970-01-01 01:00:00.000000000 +0100
2603 +++ teeworlds-0.5.2-teecomp/src/game/client/teecomp.hpp 2009-10-27 19:06:18.000000000 +0100
2604 @@ -0,0 +1,28 @@
2605 +#ifndef __TEECOMP_HPP_
2606 +#define __TEECOMP_HPP_
2608 +#include <base/vmath.hpp>
2610 +enum {
2611 + TC_STATS_FRAGS=1,
2612 + TC_STATS_DEATHS=2,
2613 + TC_STATS_SUICIDES=4,
2614 + TC_STATS_RATIO=8,
2615 + TC_STATS_NET=16,
2616 + TC_STATS_FPM=32,
2617 + TC_STATS_WEAPS=64,
2618 + TC_STATS_FLAGS=128
2621 +class TeecompUtils
2623 +public:
2624 + static vec3 getTeamColor(int for_team, int local_team, int color1, int color2, int method);
2625 + static bool get_forced_skin_name(int for_team, int local_team, const char*& skin_name);
2626 + static bool get_force_dm_colors(int for_team, int local_team);
2627 + static void reset_config();
2628 + static const char* rgb_to_name(int rgb);
2631 +#endif
2633 diff -Nru teeworlds-0.5.2-src/src/game/teecomp_vars.hpp teeworlds-0.5.2-teecomp/src/game/teecomp_vars.hpp
2634 --- teeworlds-0.5.2-src/src/game/teecomp_vars.hpp 1970-01-01 01:00:00.000000000 +0100
2635 +++ teeworlds-0.5.2-teecomp/src/game/teecomp_vars.hpp 2009-10-27 19:06:18.000000000 +0100
2636 @@ -0,0 +1,33 @@
2637 +MACRO_CONFIG_INT(tc_nameplate_shadow, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Enable name plate shadow")
2638 +MACRO_CONFIG_INT(tc_nameplate_score, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Display score on name plates")
2639 +MACRO_CONFIG_INT(tc_colored_nameplates, 0, 0, 3, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Enable colored name plates")
2640 +MACRO_CONFIG_INT(tc_colored_nameplates_team1, 16739179, 0, 16777215, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Red team/team mates name plate color")
2641 +MACRO_CONFIG_INT(tc_colored_nameplates_team2, 7053311, 0, 16777215, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Blue team/enemies name plate color")
2643 +MACRO_CONFIG_INT(tc_colored_tees_method, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Enable enemy based skin colors")
2644 +MACRO_CONFIG_INT(tc_dm_colors_team1, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Use DM colors for red team/team mates")
2645 +MACRO_CONFIG_INT(tc_dm_colors_team2, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Use DM colors for blue team/enemies")
2646 +MACRO_CONFIG_INT(tc_colored_tees_team1, 16739179, 0, 16777215, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Red team/team mates color")
2647 +MACRO_CONFIG_INT(tc_colored_tees_team2, 7053311, 0, 16777215, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Blue team/enemies color")
2649 +MACRO_CONFIG_INT(tc_forced_skins_method, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Enable enemy based forced skins")
2650 +MACRO_CONFIG_INT(tc_force_skin_team1, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Force a skin for red team/your team/DM matchs")
2651 +MACRO_CONFIG_INT(tc_force_skin_team2, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Force a skin for blue team/opponents")
2652 +MACRO_CONFIG_STR(tc_forced_skin1, 64, "default", CFGFLAG_CLIENT|CFGFLAG_SAVE, "Forced skin for red/mates/DM matchs")
2653 +MACRO_CONFIG_STR(tc_forced_skin2, 64, "default", CFGFLAG_CLIENT|CFGFLAG_SAVE, "Forced skin for blue/opponents")
2655 +MACRO_CONFIG_INT(tc_hud_match, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Make HUD match tees' colors")
2656 +MACRO_CONFIG_INT(tc_speedmeter, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Display speed meter")
2657 +MACRO_CONFIG_INT(tc_speedmeter_accel, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Speed meter shows acceleration")
2659 +MACRO_CONFIG_INT(tc_autodemo, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Enable auto demo recording")
2660 +MACRO_CONFIG_INT(tc_autoscreen, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Enable auto screenshot")
2662 +MACRO_CONFIG_INT(tc_colored_flags, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Make flags colors match tees colors")
2663 +MACRO_CONFIG_INT(tc_hide_carrying, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Hide the flag if you're carrying it")
2665 +MACRO_CONFIG_INT(tc_statboard_infos, 235, 1, 255, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Mask of infos to display on the global statboard")
2666 +MACRO_CONFIG_INT(tc_stat_id, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Show player id in statboards")
2667 +MACRO_CONFIG_INT(tc_disable_chat, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Disable chat")
2668 +MACRO_CONFIG_INT(tc_laser_color_inner, 8355839, 0, 16777215, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Inner color of laser")
2669 +MACRO_CONFIG_INT(tc_laser_color_outer, 1250112, 0, 16777215, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Outer color of laser")
2670 diff -Nru teeworlds-0.5.2-src/src/game/variables.hpp teeworlds-0.5.2-teecomp/src/game/variables.hpp
2671 --- teeworlds-0.5.2-src/src/game/variables.hpp 2009-10-26 19:04:31.000000000 +0100
2672 +++ teeworlds-0.5.2-teecomp/src/game/variables.hpp 2009-10-27 19:06:18.000000000 +0100
2673 @@ -44,6 +44,9 @@
2675 MACRO_CONFIG_INT(gfx_noclip, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Disable clipping")
2677 +/* TeeComp */
2678 +#include "teecomp_vars.hpp"
2680 /* server */
2681 MACRO_CONFIG_INT(sv_warmup, 0, 0, 0, CFGFLAG_SERVER, "Number of seconds to do warpup before round starts")
2682 MACRO_CONFIG_STR(sv_motd, 900, "", CFGFLAG_SERVER, "Message of the day to display for the clients")
2683 diff -Nru teeworlds-0.5.2-src/src/game/version.hpp teeworlds-0.5.2-teecomp/src/game/version.hpp
2684 --- teeworlds-0.5.2-src/src/game/version.hpp 2009-10-26 19:04:31.000000000 +0100
2685 +++ teeworlds-0.5.2-teecomp/src/game/version.hpp 2009-11-10 17:14:50.000000000 +0100
2686 @@ -2,3 +2,4 @@
2687 #include "generated/nethash.c"
2688 #define GAME_VERSION "0.5.2"
2689 #define GAME_NETVERSION "0.5 " GAME_NETVERSION_HASH
2690 +#define TEECOMP_VERSION "0.7.0"