Merge branch 'master' into terencehill/bot_ai
authorterencehill <piuntn@gmail.com>
Tue, 17 Jul 2018 15:19:59 +0000 (17:19 +0200)
committerterencehill <piuntn@gmail.com>
Tue, 17 Jul 2018 15:19:59 +0000 (17:19 +0200)
73 files changed:
.tx/merge-base
check-translations.sh
common.de.po
common.de_CH.po
common.fr.po
common.he.po
gfx/hud/default/as_defend.tga [new file with mode: 0644]
gfx/hud/default/as_destroy.tga [new file with mode: 0644]
gfx/hud/luma/as_defend.tga [new file with mode: 0644]
gfx/hud/luma/as_destroy.tga [new file with mode: 0644]
gfx/hud/luma/ok_weapon_rail.tga
gfx/hud/luma/ok_weapon_shotgun.tga
gfx/hud/luma/ok_weapon_smg.tga
languages.txt
qcsrc/client/commands/cl_cmd.qc
qcsrc/client/csqcmodel_hooks.qc
qcsrc/client/hud/hud.qc
qcsrc/client/hud/panel/ammo.qc
qcsrc/client/hud/panel/centerprint.qc
qcsrc/client/hud/panel/modicons.qc
qcsrc/client/hud/panel/powerups.qc
qcsrc/client/hud/panel/quickmenu.qc
qcsrc/client/hud/panel/radar.qc
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/client/hud/panel/weapons.qc
qcsrc/client/main.qc
qcsrc/client/mapvoting.qc
qcsrc/client/miscfunctions.qc
qcsrc/client/player_skeleton.qc
qcsrc/client/teamradar.qc
qcsrc/client/view.qc
qcsrc/client/weapons/projectile.qc
qcsrc/common/command/command.qh
qcsrc/common/effects/all.inc
qcsrc/common/gamemodes/gamemode/assault/assault.qc
qcsrc/common/gamemodes/gamemode/clanarena/clanarena.qc
qcsrc/common/gamemodes/gamemode/ctf/ctf.qc
qcsrc/common/gamemodes/gamemode/domination/domination.qc
qcsrc/common/gamemodes/gamemode/freezetag/freezetag.qc
qcsrc/common/gamemodes/gamemode/invasion/invasion.qc
qcsrc/common/gamemodes/gamemode/keyhunt/keyhunt.qc
qcsrc/common/gamemodes/gamemode/nexball/nexball.qc
qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qc
qcsrc/common/gamemodes/gamemode/race/race.qc
qcsrc/common/gamemodes/gamemode/tdm/tdm.qc
qcsrc/common/gamemodes/sv_rules.qh
qcsrc/common/mutators/mutator/overkill/okrpc.qc
qcsrc/common/sounds/sound.qh
qcsrc/common/t_items.qc
qcsrc/common/teams.qh
qcsrc/common/turrets/sv_turrets.qc
qcsrc/common/vehicles/cl_vehicles.qc
qcsrc/common/vehicles/sv_vehicles.qc
qcsrc/lib/i18n.qh
qcsrc/lib/oo.qh
qcsrc/server/bot/default/bot.qc
qcsrc/server/client.qc
qcsrc/server/command/cmd.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_world.qc
qcsrc/server/g_world.qh
qcsrc/server/mutators/events.qh
qcsrc/server/player.qc
qcsrc/server/player.qh
qcsrc/server/scores_rules.qc
qcsrc/server/teamplay.qc
qcsrc/server/teamplay.qh
qcsrc/server/weapons/selection.qc
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/weaponsystem.qc

index ca7140deb4f39043ced90c760624d498c0f1b2a1..22200e07fbaa96b1573a6e7d479516e053fabd01 100644 (file)
@@ -1 +1 @@
-Wed Jun 20 07:24:25 CEST 2018
+Sat Jul 14 07:24:18 CEST 2018
index 5e2ad5a54a1e099e1c33e88261fe1bf45857db8d..6a55b5ef732f3dff77418a4c06ead7660a8b2a6b 100755 (executable)
@@ -101,11 +101,11 @@ if [ x"$mode" = x"txt" ]; then
                                if [ "$p" -lt 50 ]; then
                                        continue
                                fi
-                               item="$l $l \"$l\" 0%"
+                               item="$l \"$l\" \"$l\" 0%"
                        fi
                        printf "%s\n" "$item" | sed -e "s/[0-9][0-9]*%/$p%/"
                done
-       } | tr '"' '\t' | sort -k3 | tr '\t' '"'
+       } | LC_ALL=C sort -t '"' -k4,4
 fi
 
 if [ x"$mode" = x"po" ]; then
index f248daf3c81d93d5dc60c1ff11f49083d0c378a0..2423e3782526671792bb23d8d4049a07e7971f1f 100644 (file)
@@ -3,7 +3,7 @@
 # This file is distributed under the same license as the PACKAGE package.
 #
 # Translators:
-# Wuzzy <almikes@aol.com>, 2016-2017
+# Wuzzy <almikes@aol.com>, 2016-2018
 # Brot Brot <noah.schluessel@gmail.com>, 2015
 # cvcxc <hans.andersen72@yahoo.com>, 2013
 # divVerent <divVerent@xonotic.org>, 2011,2013
@@ -24,7 +24,7 @@ msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2017-07-09 00:35+0200\n"
-"PO-Revision-Date: 2017-09-23 19:12+0000\n"
+"PO-Revision-Date: 2018-07-13 16:04+0000\n"
 "Last-Translator: Wuzzy <almikes@aol.com>\n"
 "Language-Team: German (http://www.transifex.com/team-xonotic/xonotic/"
 "language/de/)\n"
@@ -48,7 +48,7 @@ msgstr "^1Konnte nicht nach %s schreiben\n"
 
 #: qcsrc/client/hud/panel/chat.qc:82
 msgid "^3Player^7: This is the chat area."
-msgstr "^3Player^7: Dies ist der Chat-Bereich."
+msgstr "^3Spieler^7: Dies ist der Chat-Bereich."
 
 #: qcsrc/client/hud/panel/engineinfo.qc:69
 #, c-format
@@ -210,7 +210,7 @@ msgstr "^3Doppelklicke ^7ein Panel für Panel-spezifische Optionen."
 
 #: qcsrc/client/hud/panel/infomessages.qc:227
 msgid "^3CTRL ^7to disable collision testing, ^3SHIFT ^7and"
-msgstr "^3STRG^7, um Kollisionstests zu deaktivieren, ^3SHIFT ^7und"
+msgstr "^3CTRL^7, um Kollisionstests zu deaktivieren, ^3SHIFT ^7und"
 
 #: qcsrc/client/hud/panel/infomessages.qc:228
 msgid "^3ALT ^7+ ^3ARROW KEYS ^7for fine adjustments."
@@ -222,7 +222,7 @@ msgstr "Persönliche Bestzeit"
 
 #: qcsrc/client/hud/panel/modicons.qc:576
 msgid "Server best"
-msgstr "Server Bestzeit"
+msgstr "Server-Bestzeit"
 
 #: qcsrc/client/hud/panel/notify.qc:115 qcsrc/client/hud/panel/notify.qc:116
 #: qcsrc/client/hud/panel/score.qc:59
@@ -285,7 +285,7 @@ msgstr "freier Gegenstand %x^7 (l:%y^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:804
 msgid "QMCMD^free item, icon"
-msgstr "freier Gegenstand, icon"
+msgstr "freier Gegenstand, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:805
 msgid "QMCMD^took item (l:%l^7)"
@@ -293,7 +293,7 @@ msgstr "Gegenstand genommen (l:%l^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:805
 msgid "QMCMD^took item, icon"
-msgstr "Gegenstand genommen, icon"
+msgstr "Gegenstand genommen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:806
 msgid "QMCMD^negative"
@@ -309,7 +309,7 @@ msgstr "brauche Hilfe (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:808
 msgid "QMCMD^need help, icon"
-msgstr "brauche Hilfe, icon"
+msgstr "brauche Hilfe, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:809
 msgid "QMCMD^enemy seen (l:%y^7)"
@@ -317,7 +317,7 @@ msgstr "Gegner gesehen (l:%y^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:809
 msgid "QMCMD^enemy seen, icon"
-msgstr "Gegner gesehen, icon"
+msgstr "Gegner gesehen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:810
 msgid "QMCMD^flag seen (l:%y^7)"
@@ -325,7 +325,7 @@ msgstr "Flagge gesehen (l:%y^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:810
 msgid "QMCMD^flag seen, icon"
-msgstr "Flagge gesehen, icon"
+msgstr "Flagge gesehen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:811
 msgid "QMCMD^defending (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
@@ -333,7 +333,7 @@ msgstr "verteidigen (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:811
 msgid "QMCMD^defending, icon"
-msgstr "verteidigen, icon"
+msgstr "verteidigen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:812
 msgid "QMCMD^roaming (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
@@ -341,7 +341,7 @@ msgstr "wandernd (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:812
 msgid "QMCMD^roaming, icon"
-msgstr "wandernd, icon"
+msgstr "wandernd, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:813
 msgid "QMCMD^attacking (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
@@ -349,7 +349,7 @@ msgstr "angreifen (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:813
 msgid "QMCMD^attacking, icon"
-msgstr "angreifen, Iion"
+msgstr "angreifen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:814
 msgid "QMCMD^killed flagcarrier (l:%y^7)"
@@ -357,7 +357,7 @@ msgstr "Flaggenträger getötet (l:%y^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:814
 msgid "QMCMD^killed flagcarrier, icon"
-msgstr "Flaggenträger getötet, icon"
+msgstr "Flaggenträger getötet, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:815
 #, c-format
@@ -366,11 +366,11 @@ msgstr "Flagge fallen gelassen (l:%d^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:815
 msgid "QMCMD^dropped flag, icon"
-msgstr "Flagge fallen gelassen, icon"
+msgstr "Flagge fallen gelassen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:816
 msgid "QMCMD^drop weapon, icon"
-msgstr "Waffe wegwerfen, icon"
+msgstr "Waffe wegwerfen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:816
 msgid "QMCMD^dropped weapon %w^7 (l:%l^7)"
@@ -378,7 +378,7 @@ msgstr "Waffe fallen gelassen %w^7 (l:%l^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:817
 msgid "QMCMD^drop flag/key, icon"
-msgstr "Flagge/Schlüssel fallen gelassen, icon"
+msgstr "Flagge/Schlüssel fallen gelassen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:817
 msgid "QMCMD^dropped flag/key %w^7 (l:%l^7)"
@@ -694,7 +694,7 @@ msgstr "ticks"
 msgid ""
 "You can modify the scoreboard using the ^2scoreboard_columns_set command.\n"
 msgstr ""
-"Du kannst die Tabelle mit dem ^2scoreboard_columns_set-Befehl ändern.\n"
+"Du kannst die Punktetafel mit dem ^2scoreboard_columns_set-Befehl ändern.\n"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:296
 msgid "^3|---------------------------------------------------------------|\n"
@@ -792,7 +792,7 @@ msgstr "^3capzeit^7                  Zeit des schnellsten Captures (CTF)\n"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:319
 msgid "^3fckills^7                  Number of flag carrier kills\n"
-msgstr "^3fckills^7                  Anzahl der getöteten Flaggen-Träger\n"
+msgstr "^3fckills^7                  Anzahl der getöteten Flaggenträger\n"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:320
 msgid "^3returns^7                  Number of flag returns\n"
@@ -950,7 +950,7 @@ msgstr "Platzierungen"
 #: qcsrc/client/hud/panel/scoreboard.qc:1519
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:43
 msgid "Scoreboard"
-msgstr "Tabelle"
+msgstr "Punktetafel"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1584
 #, c-format
@@ -1022,7 +1022,7 @@ msgstr "Du bist tot, warte ^3%s^7 bis zum Respawn"
 #: qcsrc/client/hud/panel/scoreboard.qc:1707
 #, c-format
 msgid "You are dead, press ^2%s^7 to respawn"
-msgstr "Du bist tot, drücke ^2%s^7 um neu zu spawnen"
+msgstr "Du bist tot, drücke ^2%s^7, um neu zu spawnen"
 
 #: qcsrc/client/hud/panel/vote.qc:24
 msgid "^1You must answer before entering hud configure mode\n"
@@ -1070,11 +1070,11 @@ msgstr "Keine Munition mehr"
 
 #: qcsrc/client/hud/panel/weapons.qc:534
 msgid "Don't have"
-msgstr "Nicht vorhanden"
+msgstr "Hast du nicht"
 
 #: qcsrc/client/hud/panel/weapons.qc:538
 msgid "Unavailable"
-msgstr "Nicht verfügbar"
+msgstr "Fehlend"
 
 #: qcsrc/client/main.qc:1014
 msgid " qu/s"
@@ -1384,11 +1384,11 @@ msgstr "Vielleicht klappt es beim nächsten Mal!"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1172
 msgid "Tubular! Press \"Next Level\" to continue!"
-msgstr "Großartig! Drücke „Nächter Level“ zum Fortfahren!"
+msgstr "Großartig! Drücke „Nächstes Level“ zum Fortfahren!"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1174
 msgid "Wicked! Press \"Next Level\" to continue!"
-msgstr "Wahnsinn! Klicke \"Nächstes Level\" um weiter zu spielen!"
+msgstr "Wahnsinn! Drücke „Nächstes Level“ zum Fortfahren!"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1177
 msgid "Press the space bar to change your currently selected tile"
@@ -1419,7 +1419,7 @@ msgstr "Speichern"
 #: qcsrc/common/minigames/minigame/pp.qc:438
 #: qcsrc/common/minigames/minigame/ttt.qc:319
 msgid "Draw"
-msgstr "Zeichnen"
+msgstr "Unentschieden"
 
 #: qcsrc/common/minigames/minigame/c4.qc:378
 #: qcsrc/common/minigames/minigame/nmm.qc:601
@@ -1521,7 +1521,7 @@ msgstr "Nächstes Spiel"
 #: qcsrc/common/minigames/minigame/ps.qc:478
 #, c-format
 msgid "Pieces left: %s"
-msgstr "Verbleibende Spielfiguren: %s"
+msgstr "Figuren: %s"
 
 #: qcsrc/common/minigames/minigame/ps.qc:488
 msgid "No more valid moves"
@@ -2626,7 +2626,7 @@ msgstr "^BGDu hast ^F1%s^BG%s fallengelassen"
 #: qcsrc/common/notifications/all.inc:698
 #, c-format
 msgid "^BGYou got the ^F1%s"
-msgstr "^BG^F1%s^K1 erhalten"
+msgstr "^F1%s^BG erhalten"
 
 #: qcsrc/common/notifications/all.inc:385
 #: qcsrc/common/notifications/all.inc:699
@@ -2734,12 +2734,12 @@ msgstr "^BGTeam ^TC^TT^BG hielt den Ball zu lange fest"
 #: qcsrc/common/notifications/all.inc:412
 #, c-format
 msgid "^BG%s^BG captured %s^BG control point"
-msgstr "^BG%s^BG hat den Kontrollpunkt von %s^BG erobert"
+msgstr "^BG%s^BG hat einen Kontrollpunkt erobert: %s^BG"
 
 #: qcsrc/common/notifications/all.inc:413
 #, c-format
 msgid "^TC^TT^BG team %s^BG control point has been destroyed by %s"
-msgstr "^TC^TT^BGDer Kontrollpunkt vom Team %s^BG wurde von %s zerstört"
+msgstr "^TC^TT^BGEin Kontrollpunkt vom Team %s^BG wurde von %s zerstört"
 
 #: qcsrc/common/notifications/all.inc:414
 msgid "^TC^TT^BG generator has been destroyed"
@@ -2759,7 +2759,7 @@ msgstr "^BG%s^K1 hat Unsichtbarkeit aufgesammelt"
 #: qcsrc/common/notifications/all.inc:418
 #, c-format
 msgid "^BG%s^K1 picked up Shield"
-msgstr "^BG%s^K1 hat das Schild aufgenommen"
+msgstr "^BG%s^K1 hat den Schild aufgenommen"
 
 #: qcsrc/common/notifications/all.inc:419
 #, c-format
@@ -3596,7 +3596,7 @@ msgstr "^K1Deine Medizin-Granate ist ein wenig defekt"
 
 #: qcsrc/common/notifications/all.inc:644
 msgid "^K1You are respawning for running out of ammo..."
-msgstr "^K1Du wirst wiederbelebt weil du keine Munition mehr hast …"
+msgstr "^K1Du wirst wiederbelebt, weil du keine Munition mehr hast …"
 
 #: qcsrc/common/notifications/all.inc:644
 msgid "^K1You were killed for running out of ammo..."
@@ -3913,12 +3913,12 @@ msgstr "^F2Aktive Waffe: ^F1%s"
 #: qcsrc/common/notifications/all.inc:733
 #, c-format
 msgid "^BGYou captured %s^BG control point"
-msgstr "^BGDu hast den Kontrollpunkt von %s^BG erobert"
+msgstr "^BGDu hast einen Kontrollpunkt erobert: %s^BG"
 
 #: qcsrc/common/notifications/all.inc:734
 #, c-format
 msgid "^TC^TT^BG team captured %s^BG control point"
-msgstr "Team ^TC^TT^BG hat %ss^BG Kontrollpunkt erobert"
+msgstr "Team ^TC^TT^BG hat einen Kontrollpunkt erobert: %s^BG"
 
 #: qcsrc/common/notifications/all.inc:735
 msgid "^BGThis control point currently cannot be captured"
@@ -4019,7 +4019,7 @@ msgstr "^F2Ein Schild umgibt dich"
 
 #: qcsrc/common/notifications/all.inc:754
 msgid "^F2Shield has worn off"
-msgstr "^F2Das Schild ist wieder verschwunden"
+msgstr "^F2Der Schild ist wieder verschwunden"
 
 #: qcsrc/common/notifications/all.inc:756
 msgid "^F2You are on speed"
@@ -5257,7 +5257,7 @@ msgstr "Schriftgröße:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qh:6
 msgid "Centerprint Panel"
-msgstr "Nachrichten-Panel"
+msgstr "Zentralanzeigen-Panel"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:15
 msgid "Chat entries:"
@@ -5355,7 +5355,7 @@ msgstr "Beim Zuschauen zeigen"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:18
 msgid "PNL^Enabled even playing in warmup"
-msgstr "Auch in der Aufwärmphase zeigen"
+msgstr "Auch in Aufwärmphase zeigen"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:29
 msgid "Reduced"
@@ -5363,7 +5363,7 @@ msgstr "Reduziert"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:32
 msgid "Text/icon ratio:"
-msgstr "Text/Icon-Verhältnis:"
+msgstr "Text-/Icon-Verhältnis:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:35
 msgid "Hide spawned items"
@@ -5407,7 +5407,7 @@ msgstr "Eintrags-Ausblendung:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_notification.qh:6
 msgid "Notification Panel"
-msgstr "Anzeige-Panel"
+msgstr "Nachrichten-Panel"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:15
 #: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:14
@@ -5421,11 +5421,11 @@ msgstr "Panel anzeigen"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:17
 msgid "Panel enabled even observing"
-msgstr "Panel auch beim Zuschauen anzeigen"
+msgstr "Auch beim Zuschauen zeigen"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:18
 msgid "Panel enabled only in Race/CTS"
-msgstr "Panel nur in Rennen und CTS-Rennen anzeigen"
+msgstr "Nur in Rennen und CTS-Rennen zeigen"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:24
 msgid "Status bar"
@@ -5536,7 +5536,7 @@ msgstr "Rundenzeit-Panel"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:16
 msgid "Panel enabled in teamgames"
-msgstr "Panel in Team-Spieltypen aktivieren"
+msgstr "Panel in Teamspielen aktivieren"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:23
 msgid "Radar:"
@@ -6317,13 +6317,11 @@ msgstr "Spielmechanik-Mutatoren:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:160
 msgid "Enable dodging"
-msgstr ""
-"Ausweichmodus: Es ist möglich rasch zur Seite zu springen (spezielle "
-"Bewegung)"
+msgstr "Ausweichmanöver aktivieren"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:167
 msgid "All players are almost invisible"
-msgstr "Tarnmodus: Alle Spieler sind fast unsichtbar"
+msgstr "Alle Spieler sind fast unsichtbar"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:174
 msgid "Only possible to inflict damage on your enemy while he's airborne"
@@ -6333,15 +6331,15 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:178
 msgid "Damage done to your enemy gets added to your own health"
 msgstr ""
-"Vampirmodus: Der Schaden, dem du anderen Spielern zufügst, wird deiner "
-"eigenen Lebensenergie hinzugefügt"
+"Der Schaden, dem du anderen Spielern zufügst, wird deiner eigenen "
+"Lebensenergie hinzugefügt"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:183
 msgid ""
 "Amount of health below which your player gets stunned because of blood loss"
 msgstr ""
-"Blutverlust: Aktiviere diesen Modus und stelle den Wert der Lebensenergie, "
-"bei der Spieler auf Grund von Blutverlust betäubt wirken, ein"
+"Aktiviere diesen Modus und stelle den Wert der Lebensenergie, bei der "
+"Spieler auf Grund von Blutverlust betäubt wirken, ein"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:192
 msgid "Make things fall to the ground slower, lower value means lower gravity"
@@ -6390,10 +6388,9 @@ msgid ""
 "Selecting a weapon arena will give all players that weapon at spawn as well "
 "as unlimited ammo, and disable all other weapon pickups."
 msgstr ""
-"Waffen-Arenen: Die Auswahl einer Waffen-Arena führt dazu, dass jeder Spieler "
-"mit der gewählten Waffe startet. Diese hat unendlich viel Munition, andere "
-"Waffen sind nicht vorhanden – Spezielle Waffen-Arenen: Spieler starten mit "
-"allen Waffen und unendlich viel Munition"
+"Die Auswahl einer Waffen-Arena führt dazu, dass jeder Spieler mit der "
+"gewählten Waffe startet. Diese hat unendlich viel Munition, andere Waffen "
+"sind nicht vorhanden."
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:255
 msgid "Most weapons"
@@ -6617,7 +6614,7 @@ msgstr "Musikplayer"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:48
 msgid "Auto record demos"
-msgstr "Wiederholungen automatisch aufzeichnen"
+msgstr "Wiederholungen autom. aufzeichnen"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:57
 msgid "Timedemo"
@@ -6708,7 +6705,7 @@ msgstr "Alle entfernen"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:43
 msgid "Auto screenshot scoreboard"
-msgstr "Screenshot der Tabelle automatisch anfertigen"
+msgstr "Auto-Screenshot der Punktetafel"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:63
 msgid "Open in the viewer"
@@ -7419,7 +7416,7 @@ msgstr "Scharf"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:163
 msgid "Decals"
-msgstr "Einschusslöcher"
+msgstr "Dekore"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:164
 msgid "Enable decals (bullet holes and blood) (default: enabled)"
@@ -7717,7 +7714,7 @@ msgstr "Dezimalstellen im Respawn-Countdown anzeigen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:57
 msgid "Show accuracy underneath scoreboard"
-msgstr "Trefferquote unter Tabelle anzeigen"
+msgstr "Trefferquote unter Punktetafel anzeigen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:61
 msgid "Waypoints"
@@ -7824,7 +7821,7 @@ msgstr "Um den HUD-Editor zu starten, muss ein Spiel gestartet werden."
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc:23
 msgid "Do you wish to start a local game to set up the HUD?"
-msgstr "Willst du ein lokales Spiel starten, um das HUD zu editieren?"
+msgstr "Willst du ein lokales Spiel starten, um das HUD zu bearbeiten?"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:24
 msgid "Frag Information"
@@ -7840,7 +7837,7 @@ msgstr "Amokläufe nur anzeigen, wenn sie Achievements sind"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:34
 msgid "Show spree information in centerprints"
-msgstr "Amoklauf-Informationen in Centerprints anzeigen"
+msgstr "Amoklauf-Infos in Zentralanzeige zeigen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:38
 msgid "Show spree information in death messages"
@@ -7872,7 +7869,7 @@ msgstr "In separater Zeile anzeigen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:58
 msgid "Add extra frag information to centerprint when available"
-msgstr "Zusätzliche Frag-Informationen in Centerprint anzeigen, wenn verfügbar"
+msgstr "Zusätzliche Frag-Infos in Zentralanzeige zeigen, wenn verfügbar"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:62
 msgid "Add frag location to death messages when available"
@@ -7914,7 +7911,7 @@ msgstr "Powerup-Nachrichten"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:89
 msgid "Weapon centerprint notifications"
-msgstr "Waffen-Centerprint-Nachrichten"
+msgstr "Waffen-Zentralanzeigen-Nachrichten"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:92
 msgid "Weapon info message notifications"
@@ -7995,7 +7992,7 @@ msgstr "Nur in Nicht-Teamspielen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:60
 msgid "Body fading:"
-msgstr "Ausblenden von Leichen:"
+msgstr "Leichenausblendung:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:63
 msgid "Gibs:"
@@ -8290,7 +8287,7 @@ msgstr "Auto-Springen"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:99
 msgid "Jetpack on jump:"
-msgstr "Jetpack aktiveren durch Springen:"
+msgstr "Jetpack bei Sprung:"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:101
 msgid "JPJUMP^Disabled"
@@ -8395,7 +8392,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
 msgid "Server queries/s:"
-msgstr "Server Anfragen/Sekunde:"
+msgstr "Serveranfragen/s:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
 msgid "Downloads:"
@@ -8589,11 +8586,12 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:10
 msgid "While connected language changes will be applied only to the menu,"
 msgstr ""
-"Während du verbunden bist, werden Sprachänderungen nur auf das Menü angewandt"
+"Während du verbunden bist, werden Sprachänderungen nur auf das Menü "
+"angewandt;"
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:12
 msgid "full language changes will take effect starting from the next game"
-msgstr "Volle Sprachänderungen finden erst nach dem Neustart des Spiels statt"
+msgstr "volle Sprachänderungen finden erst nach dem Neustart des Spiels statt."
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:16
 msgid "Disconnect now"
@@ -8940,7 +8938,7 @@ msgstr "Einzelspieler"
 #: qcsrc/menu/xonotic/dialog_singleplayer.qh:7
 msgid "Play the singleplayer campaign or instant action matches against bots"
 msgstr ""
-"Spiele die Einzelspieler-Kampagne oder habe Instant-Action Spiele gegen Bots"
+"Spiele die Einzelspieler-Kampagne oder spiele ein Schnellspiel gegen Bots"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer_winner.qh:7
 msgid "Winner"
@@ -9492,7 +9490,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/util.qc:780
 msgid "Use default"
-msgstr "Standard verwenden"
+msgstr "Standard"
 
 #: qcsrc/menu/xonotic/util.qc:800
 msgid "Team Color:"
index d5c87645f5f5fca211aba727c93dcf7eaa11a7e5..2c2c96b5dace8b9b653ec744dc4139c7baba613c 100644 (file)
@@ -3,7 +3,7 @@
 # This file is distributed under the same license as the PACKAGE package.
 #
 # Translators:
-# Wuzzy <almikes@aol.com>, 2016-2017
+# Wuzzy <almikes@aol.com>, 2016-2018
 # Brot Brot <noah.schluessel@gmail.com>, 2015
 # cvcxc <hans.andersen72@yahoo.com>, 2013
 # divVerent <divVerent@xonotic.org>, 2011,2013
@@ -24,7 +24,7 @@ msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2017-07-09 00:35+0200\n"
-"PO-Revision-Date: 2017-09-23 19:12+0000\n"
+"PO-Revision-Date: 2018-07-13 16:04+0000\n"
 "Last-Translator: Wuzzy <almikes@aol.com>\n"
 "Language-Team: German (http://www.transifex.com/team-xonotic/xonotic/"
 "language/de/)\n"
@@ -48,7 +48,7 @@ msgstr "^1Konnte nicht nach %s schreiben\n"
 
 #: qcsrc/client/hud/panel/chat.qc:82
 msgid "^3Player^7: This is the chat area."
-msgstr "^3Player^7: Dies ist der Chat-Bereich."
+msgstr "^3Spieler^7: Dies ist der Chat-Bereich."
 
 #: qcsrc/client/hud/panel/engineinfo.qc:69
 #, c-format
@@ -210,7 +210,7 @@ msgstr "^3Doppelklicke ^7ein Panel für Panel-spezifische Optionen."
 
 #: qcsrc/client/hud/panel/infomessages.qc:227
 msgid "^3CTRL ^7to disable collision testing, ^3SHIFT ^7and"
-msgstr "^3STRG^7, um Kollisionstests zu deaktivieren, ^3SHIFT ^7und"
+msgstr "^3CTRL^7, um Kollisionstests zu deaktivieren, ^3SHIFT ^7und"
 
 #: qcsrc/client/hud/panel/infomessages.qc:228
 msgid "^3ALT ^7+ ^3ARROW KEYS ^7for fine adjustments."
@@ -222,7 +222,7 @@ msgstr "Persönliche Bestzeit"
 
 #: qcsrc/client/hud/panel/modicons.qc:576
 msgid "Server best"
-msgstr "Server Bestzeit"
+msgstr "Server-Bestzeit"
 
 #: qcsrc/client/hud/panel/notify.qc:115 qcsrc/client/hud/panel/notify.qc:116
 #: qcsrc/client/hud/panel/score.qc:59
@@ -285,7 +285,7 @@ msgstr "freier Gegenstand %x^7 (l:%y^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:804
 msgid "QMCMD^free item, icon"
-msgstr "freier Gegenstand, icon"
+msgstr "freier Gegenstand, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:805
 msgid "QMCMD^took item (l:%l^7)"
@@ -293,7 +293,7 @@ msgstr "Gegenstand genommen (l:%l^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:805
 msgid "QMCMD^took item, icon"
-msgstr "Gegenstand genommen, icon"
+msgstr "Gegenstand genommen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:806
 msgid "QMCMD^negative"
@@ -309,7 +309,7 @@ msgstr "brauche Hilfe (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:808
 msgid "QMCMD^need help, icon"
-msgstr "brauche Hilfe, icon"
+msgstr "brauche Hilfe, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:809
 msgid "QMCMD^enemy seen (l:%y^7)"
@@ -317,7 +317,7 @@ msgstr "Gegner gesehen (l:%y^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:809
 msgid "QMCMD^enemy seen, icon"
-msgstr "Gegner gesehen, icon"
+msgstr "Gegner gesehen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:810
 msgid "QMCMD^flag seen (l:%y^7)"
@@ -325,7 +325,7 @@ msgstr "Flagge gesehen (l:%y^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:810
 msgid "QMCMD^flag seen, icon"
-msgstr "Flagge gesehen, icon"
+msgstr "Flagge gesehen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:811
 msgid "QMCMD^defending (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
@@ -333,7 +333,7 @@ msgstr "verteidigen (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:811
 msgid "QMCMD^defending, icon"
-msgstr "verteidigen, icon"
+msgstr "verteidigen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:812
 msgid "QMCMD^roaming (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
@@ -341,7 +341,7 @@ msgstr "wandernd (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:812
 msgid "QMCMD^roaming, icon"
-msgstr "wandernd, icon"
+msgstr "wandernd, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:813
 msgid "QMCMD^attacking (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
@@ -349,7 +349,7 @@ msgstr "angreifen (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:813
 msgid "QMCMD^attacking, icon"
-msgstr "angreifen, Iion"
+msgstr "angreifen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:814
 msgid "QMCMD^killed flagcarrier (l:%y^7)"
@@ -357,7 +357,7 @@ msgstr "Flaggenträger getötet (l:%y^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:814
 msgid "QMCMD^killed flagcarrier, icon"
-msgstr "Flaggenträger getötet, icon"
+msgstr "Flaggenträger getötet, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:815
 #, c-format
@@ -366,11 +366,11 @@ msgstr "Flagge fallen gelassen (l:%d^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:815
 msgid "QMCMD^dropped flag, icon"
-msgstr "Flagge fallen gelassen, icon"
+msgstr "Flagge fallen gelassen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:816
 msgid "QMCMD^drop weapon, icon"
-msgstr "Waffe wegwerfen, icon"
+msgstr "Waffe wegwerfen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:816
 msgid "QMCMD^dropped weapon %w^7 (l:%l^7)"
@@ -378,7 +378,7 @@ msgstr "Waffe fallen gelassen %w^7 (l:%l^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:817
 msgid "QMCMD^drop flag/key, icon"
-msgstr "Flagge/Schlüssel fallen gelassen, icon"
+msgstr "Flagge/Schlüssel fallen gelassen, Icon"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:817
 msgid "QMCMD^dropped flag/key %w^7 (l:%l^7)"
@@ -694,7 +694,7 @@ msgstr "ticks"
 msgid ""
 "You can modify the scoreboard using the ^2scoreboard_columns_set command.\n"
 msgstr ""
-"Du kannst die Tabelle mit dem ^2scoreboard_columns_set-Befehl ändern.\n"
+"Du kannst die Punktetafel mit dem ^2scoreboard_columns_set-Befehl ändern.\n"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:296
 msgid "^3|---------------------------------------------------------------|\n"
@@ -792,7 +792,7 @@ msgstr "^3capzeit^7                  Zeit des schnellsten Captures (CTF)\n"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:319
 msgid "^3fckills^7                  Number of flag carrier kills\n"
-msgstr "^3fckills^7                  Anzahl der getöteten Flaggen-Träger\n"
+msgstr "^3fckills^7                  Anzahl der getöteten Flaggenträger\n"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:320
 msgid "^3returns^7                  Number of flag returns\n"
@@ -950,7 +950,7 @@ msgstr "Platzierungen"
 #: qcsrc/client/hud/panel/scoreboard.qc:1519
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:43
 msgid "Scoreboard"
-msgstr "Tabelle"
+msgstr "Punktetafel"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1584
 #, c-format
@@ -1022,7 +1022,7 @@ msgstr "Du bist tot, warte ^3%s^7 bis zum Respawn"
 #: qcsrc/client/hud/panel/scoreboard.qc:1707
 #, c-format
 msgid "You are dead, press ^2%s^7 to respawn"
-msgstr "Du bist tot, drücke ^2%s^7 um neu zu spawnen"
+msgstr "Du bist tot, drücke ^2%s^7, um neu zu spawnen"
 
 #: qcsrc/client/hud/panel/vote.qc:24
 msgid "^1You must answer before entering hud configure mode\n"
@@ -1070,11 +1070,11 @@ msgstr "Keine Munition mehr"
 
 #: qcsrc/client/hud/panel/weapons.qc:534
 msgid "Don't have"
-msgstr "Nicht vorhanden"
+msgstr "Hast du nicht"
 
 #: qcsrc/client/hud/panel/weapons.qc:538
 msgid "Unavailable"
-msgstr "Nicht verfügbar"
+msgstr "Fehlend"
 
 #: qcsrc/client/main.qc:1014
 msgid " qu/s"
@@ -1384,11 +1384,11 @@ msgstr "Vielleicht klappt es beim nächsten Mal!"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1172
 msgid "Tubular! Press \"Next Level\" to continue!"
-msgstr "Grossartig! Drücke „Nächter Level“ zum Fortfahren!"
+msgstr "Grossartig! Drücke „Nächstes Level“ zum Fortfahren!"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1174
 msgid "Wicked! Press \"Next Level\" to continue!"
-msgstr "Wahnsinn! Klicke \"Nächstes Level\" um weiter zu spielen!"
+msgstr "Wahnsinn! Drücke „Nächstes Level“ zum Fortfahren!"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1177
 msgid "Press the space bar to change your currently selected tile"
@@ -1419,7 +1419,7 @@ msgstr "Speichern"
 #: qcsrc/common/minigames/minigame/pp.qc:438
 #: qcsrc/common/minigames/minigame/ttt.qc:319
 msgid "Draw"
-msgstr "Zeichnen"
+msgstr "Unentschieden"
 
 #: qcsrc/common/minigames/minigame/c4.qc:378
 #: qcsrc/common/minigames/minigame/nmm.qc:601
@@ -1521,7 +1521,7 @@ msgstr "Nächstes Spiel"
 #: qcsrc/common/minigames/minigame/ps.qc:478
 #, c-format
 msgid "Pieces left: %s"
-msgstr "Verbleibende Spielfiguren: %s"
+msgstr "Figuren: %s"
 
 #: qcsrc/common/minigames/minigame/ps.qc:488
 msgid "No more valid moves"
@@ -2626,7 +2626,7 @@ msgstr "^BGDu hast ^F1%s^BG%s fallengelassen"
 #: qcsrc/common/notifications/all.inc:698
 #, c-format
 msgid "^BGYou got the ^F1%s"
-msgstr "^BG^F1%s^K1 erhalten"
+msgstr "^F1%s^BG erhalten"
 
 #: qcsrc/common/notifications/all.inc:385
 #: qcsrc/common/notifications/all.inc:699
@@ -2734,12 +2734,12 @@ msgstr "^BGTeam ^TC^TT^BG hielt den Ball zu lange fest"
 #: qcsrc/common/notifications/all.inc:412
 #, c-format
 msgid "^BG%s^BG captured %s^BG control point"
-msgstr "^BG%s^BG hat den Kontrollpunkt von %s^BG erobert"
+msgstr "^BG%s^BG hat einen Kontrollpunkt erobert: %s^BG"
 
 #: qcsrc/common/notifications/all.inc:413
 #, c-format
 msgid "^TC^TT^BG team %s^BG control point has been destroyed by %s"
-msgstr "^TC^TT^BGDer Kontrollpunkt vom Team %s^BG wurde von %s zerstört"
+msgstr "^TC^TT^BGEin Kontrollpunkt vom Team %s^BG wurde von %s zerstört"
 
 #: qcsrc/common/notifications/all.inc:414
 msgid "^TC^TT^BG generator has been destroyed"
@@ -2759,7 +2759,7 @@ msgstr "^BG%s^K1 hat Unsichtbarkeit aufgesammelt"
 #: qcsrc/common/notifications/all.inc:418
 #, c-format
 msgid "^BG%s^K1 picked up Shield"
-msgstr "^BG%s^K1 hat das Schild aufgenommen"
+msgstr "^BG%s^K1 hat den Schild aufgenommen"
 
 #: qcsrc/common/notifications/all.inc:419
 #, c-format
@@ -3597,7 +3597,7 @@ msgstr "^K1Deine Medizin-Granate ist ein wenig defekt"
 
 #: qcsrc/common/notifications/all.inc:644
 msgid "^K1You are respawning for running out of ammo..."
-msgstr "^K1Du wirst wiederbelebt weil du keine Munition mehr hast …"
+msgstr "^K1Du wirst wiederbelebt, weil du keine Munition mehr hast …"
 
 #: qcsrc/common/notifications/all.inc:644
 msgid "^K1You were killed for running out of ammo..."
@@ -3914,12 +3914,12 @@ msgstr "^F2Aktive Waffe: ^F1%s"
 #: qcsrc/common/notifications/all.inc:733
 #, c-format
 msgid "^BGYou captured %s^BG control point"
-msgstr "^BGDu hast den Kontrollpunkt von %s^BG erobert"
+msgstr "^BGDu hast einen Kontrollpunkt erobert: %s^BG"
 
 #: qcsrc/common/notifications/all.inc:734
 #, c-format
 msgid "^TC^TT^BG team captured %s^BG control point"
-msgstr "Team ^TC^TT^BG hat %ss^BG Kontrollpunkt erobert"
+msgstr "Team ^TC^TT^BG hat einen Kontrollpunkt erobert: %s^BG"
 
 #: qcsrc/common/notifications/all.inc:735
 msgid "^BGThis control point currently cannot be captured"
@@ -4020,7 +4020,7 @@ msgstr "^F2Ein Schild umgibt dich"
 
 #: qcsrc/common/notifications/all.inc:754
 msgid "^F2Shield has worn off"
-msgstr "^F2Das Schild ist wieder verschwunden"
+msgstr "^F2Der Schild ist wieder verschwunden"
 
 #: qcsrc/common/notifications/all.inc:756
 msgid "^F2You are on speed"
@@ -5258,7 +5258,7 @@ msgstr "Schriftgrösse:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qh:6
 msgid "Centerprint Panel"
-msgstr "Nachrichten-Panel"
+msgstr "Zentralanzeigen-Panel"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:15
 msgid "Chat entries:"
@@ -5356,7 +5356,7 @@ msgstr "Beim Zuschauen zeigen"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:18
 msgid "PNL^Enabled even playing in warmup"
-msgstr "Auch in der Aufwärmphase zeigen"
+msgstr "Auch in Aufwärmphase zeigen"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:29
 msgid "Reduced"
@@ -5364,7 +5364,7 @@ msgstr "Reduziert"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:32
 msgid "Text/icon ratio:"
-msgstr "Text/Icon-Verhältnis:"
+msgstr "Text-/Icon-Verhältnis:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:35
 msgid "Hide spawned items"
@@ -5408,7 +5408,7 @@ msgstr "Eintrags-Ausblendung:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_notification.qh:6
 msgid "Notification Panel"
-msgstr "Anzeige-Panel"
+msgstr "Nachrichten-Panel"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:15
 #: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:14
@@ -5422,11 +5422,11 @@ msgstr "Panel anzeigen"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:17
 msgid "Panel enabled even observing"
-msgstr "Panel auch beim Zuschauen anzeigen"
+msgstr "Auch beim Zuschauen zeigen"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:18
 msgid "Panel enabled only in Race/CTS"
-msgstr "Panel nur in Rennen und CTS-Rennen anzeigen"
+msgstr "Nur in Rennen und CTS-Rennen zeigen"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:24
 msgid "Status bar"
@@ -5537,7 +5537,7 @@ msgstr "Rundenzeit-Panel"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:16
 msgid "Panel enabled in teamgames"
-msgstr "Panel in Team-Spieltypen aktivieren"
+msgstr "Panel in Teamspielen aktivieren"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:23
 msgid "Radar:"
@@ -6318,13 +6318,11 @@ msgstr "Spielmechanik-Mutatoren:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:160
 msgid "Enable dodging"
-msgstr ""
-"Ausweichmodus: Es ist möglich rasch zur Seite zu springen (spezielle "
-"Bewegung)"
+msgstr "Ausweichmanöver aktivieren"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:167
 msgid "All players are almost invisible"
-msgstr "Tarnmodus: Alle Spieler sind fast unsichtbar"
+msgstr "Alle Spieler sind fast unsichtbar"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:174
 msgid "Only possible to inflict damage on your enemy while he's airborne"
@@ -6334,15 +6332,15 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:178
 msgid "Damage done to your enemy gets added to your own health"
 msgstr ""
-"Vampirmodus: Der Schaden, dem du anderen Spielern zufügst, wird deiner "
-"eigenen Lebensenergie hinzugefügt"
+"Der Schaden, dem du anderen Spielern zufügst, wird deiner eigenen "
+"Lebensenergie hinzugefügt"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:183
 msgid ""
 "Amount of health below which your player gets stunned because of blood loss"
 msgstr ""
-"Blutverlust: Aktiviere diesen Modus und stelle den Wert der Lebensenergie, "
-"bei der Spieler auf Grund von Blutverlust betäubt wirken, ein"
+"Aktiviere diesen Modus und stelle den Wert der Lebensenergie, bei der "
+"Spieler auf Grund von Blutverlust betäubt wirken, ein"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:192
 msgid "Make things fall to the ground slower, lower value means lower gravity"
@@ -6391,10 +6389,9 @@ msgid ""
 "Selecting a weapon arena will give all players that weapon at spawn as well "
 "as unlimited ammo, and disable all other weapon pickups."
 msgstr ""
-"Waffen-Arenen: Die Auswahl einer Waffen-Arena führt dazu, dass jeder Spieler "
-"mit der gewählten Waffe startet. Diese hat unendlich viel Munition, andere "
-"Waffen sind nicht vorhanden – Spezielle Waffen-Arenen: Spieler starten mit "
-"allen Waffen und unendlich viel Munition"
+"Die Auswahl einer Waffen-Arena führt dazu, dass jeder Spieler mit der "
+"gewählten Waffe startet. Diese hat unendlich viel Munition, andere Waffen "
+"sind nicht vorhanden."
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:255
 msgid "Most weapons"
@@ -6618,7 +6615,7 @@ msgstr "Musikplayer"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:48
 msgid "Auto record demos"
-msgstr "Wiederholungen automatisch aufzeichnen"
+msgstr "Wiederholungen autom. aufzeichnen"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:57
 msgid "Timedemo"
@@ -6709,7 +6706,7 @@ msgstr "Alle entfernen"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:43
 msgid "Auto screenshot scoreboard"
-msgstr "Screenshot der Tabelle automatisch anfertigen"
+msgstr "Auto-Screenshot der Punktetafel"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:63
 msgid "Open in the viewer"
@@ -7420,7 +7417,7 @@ msgstr "Scharf"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:163
 msgid "Decals"
-msgstr "Einschusslöcher"
+msgstr "Dekore"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:164
 msgid "Enable decals (bullet holes and blood) (default: enabled)"
@@ -7718,7 +7715,7 @@ msgstr "Dezimalstellen im Respawn-Countdown anzeigen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:57
 msgid "Show accuracy underneath scoreboard"
-msgstr "Trefferquote unter Tabelle anzeigen"
+msgstr "Trefferquote unter Punktetafel anzeigen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:61
 msgid "Waypoints"
@@ -7825,7 +7822,7 @@ msgstr "Um den HUD-Editor zu starten, muss ein Spiel gestartet werden."
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc:23
 msgid "Do you wish to start a local game to set up the HUD?"
-msgstr "Willst du ein lokales Spiel starten, um das HUD zu editieren?"
+msgstr "Willst du ein lokales Spiel starten, um das HUD zu bearbeiten?"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:24
 msgid "Frag Information"
@@ -7841,7 +7838,7 @@ msgstr "Amokläufe nur anzeigen, wenn sie Achievements sind"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:34
 msgid "Show spree information in centerprints"
-msgstr "Amoklauf-Informationen in Centerprints anzeigen"
+msgstr "Amoklauf-Infos in Zentralanzeige zeigen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:38
 msgid "Show spree information in death messages"
@@ -7873,7 +7870,7 @@ msgstr "In separater Zeile anzeigen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:58
 msgid "Add extra frag information to centerprint when available"
-msgstr "Zusätzliche Frag-Informationen in Centerprint anzeigen, wenn verfügbar"
+msgstr "Zusätzliche Frag-Infos in Zentralanzeige zeigen, wenn verfügbar"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:62
 msgid "Add frag location to death messages when available"
@@ -7915,7 +7912,7 @@ msgstr "Powerup-Nachrichten"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:89
 msgid "Weapon centerprint notifications"
-msgstr "Waffen-Centerprint-Nachrichten"
+msgstr "Waffen-Zentralanzeigen-Nachrichten"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:92
 msgid "Weapon info message notifications"
@@ -7996,7 +7993,7 @@ msgstr "Nur in Nicht-Teamspielen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:60
 msgid "Body fading:"
-msgstr "Ausblenden von Leichen:"
+msgstr "Leichenausblendung:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:63
 msgid "Gibs:"
@@ -8291,7 +8288,7 @@ msgstr "Auto-Springen"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:99
 msgid "Jetpack on jump:"
-msgstr "Jetpack aktiveren durch Springen:"
+msgstr "Jetpack bei Sprung:"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:101
 msgid "JPJUMP^Disabled"
@@ -8396,7 +8393,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
 msgid "Server queries/s:"
-msgstr "Server Anfragen/Sekunde:"
+msgstr "Serveranfragen/s:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
 msgid "Downloads:"
@@ -8590,11 +8587,12 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:10
 msgid "While connected language changes will be applied only to the menu,"
 msgstr ""
-"Während du verbunden bist, werden Sprachänderungen nur auf das Menü angewandt"
+"Während du verbunden bist, werden Sprachänderungen nur auf das Menü "
+"angewandt;"
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:12
 msgid "full language changes will take effect starting from the next game"
-msgstr "Volle Sprachänderungen finden erst nach dem Neustart des Spiels statt"
+msgstr "volle Sprachänderungen finden erst nach dem Neustart des Spiels statt."
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:16
 msgid "Disconnect now"
@@ -8941,7 +8939,7 @@ msgstr "Einzelspieler"
 #: qcsrc/menu/xonotic/dialog_singleplayer.qh:7
 msgid "Play the singleplayer campaign or instant action matches against bots"
 msgstr ""
-"Spiele die Einzelspieler-Kampagne oder habe Instant-Action Spiele gegen Bots"
+"Spiele die Einzelspieler-Kampagne oder spiele ein Schnellspiel gegen Bots"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer_winner.qh:7
 msgid "Winner"
@@ -9493,7 +9491,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/util.qc:780
 msgid "Use default"
-msgstr "Standard verwenden"
+msgstr "Standard"
 
 #: qcsrc/menu/xonotic/util.qc:800
 msgid "Team Color:"
index 84391e6114ea7ba0d9010dd5dee41ed46820185b..4a3b837d1c3bbf8cfff28783d13ac3688d437ee2 100644 (file)
 # RedGuff <domsau2@yahoo.fr>, 2014
 # Yannick Le Guen <leguen.yannick@gmail.com>, 2013
 # Hugo Locurcio, 2013
-# Yannick Le Guen <leguen.yannick@gmail.com>, 2013-2017
+# Yannick Le Guen <leguen.yannick@gmail.com>, 2013-2018
 msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2017-07-09 00:35+0200\n"
-"PO-Revision-Date: 2017-09-14 13:32+0000\n"
+"PO-Revision-Date: 2018-07-08 09:28+0000\n"
 "Last-Translator: Yannick Le Guen <leguen.yannick@gmail.com>\n"
 "Language-Team: French (http://www.transifex.com/team-xonotic/xonotic/"
 "language/fr/)\n"
@@ -3086,12 +3086,12 @@ msgstr ""
 #: qcsrc/common/notifications/all.inc:484
 #, c-format
 msgid "^BG%s%s^K1 was sniped by ^BG%s^K1's Machine Gun%s%s"
-msgstr "^BG%s%s^K1 a été abattu par la Mitrailleuse de ^BG%s^K1%s%s"
+msgstr "^BG%s%s^K1 a été abattu par la Mitraillette de ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:485
 #, c-format
 msgid "^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s%s"
-msgstr "^BG%s%s^K1 a été criblé de balles par la Mitrailleuse de ^BG%s^K1%s%s"
+msgstr "^BG%s%s^K1 a été criblé de balles par la Mitraillette de ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:486
 #: qcsrc/common/notifications/all.inc:790
@@ -4631,7 +4631,7 @@ msgstr "Grappin"
 
 #: qcsrc/common/weapons/weapon/machinegun.qc:17
 msgid "MachineGun"
-msgstr "Mitrailleuse"
+msgstr "Mitraillette"
 
 #: qcsrc/common/weapons/weapon/minelayer.qc:17
 msgid "Mine Layer"
index 593e684a646c9714c90d90cbf02bf197633a270b..6aa36e0816d98228fe28624b55ca4e0c79bf5594 100644 (file)
@@ -3,13 +3,14 @@
 # This file is distributed under the same license as the PACKAGE package.
 #
 # Translators:
+# nad le <nadavlevi726@gmail.com>, 2018
 msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2017-07-09 00:35+0200\n"
-"PO-Revision-Date: 2017-07-05 15:06+0000\n"
-"Last-Translator: divVerent <divVerent@xonotic.org>\n"
+"PO-Revision-Date: 2018-07-10 10:55+0000\n"
+"Last-Translator: nad le <nadavlevi726@gmail.com>\n"
 "Language-Team: Hebrew (http://www.transifex.com/team-xonotic/xonotic/"
 "language/he/)\n"
 "Language: he\n"
@@ -65,12 +66,12 @@ msgstr ""
 #: qcsrc/client/hud/panel/infomessages.qc:102
 #: qcsrc/client/hud/panel/infomessages.qc:106
 msgid "next weapon"
-msgstr ""
+msgstr "נשק הבא"
 
 #: qcsrc/client/hud/panel/infomessages.qc:102
 #: qcsrc/client/hud/panel/infomessages.qc:106
 msgid "previous weapon"
-msgstr ""
+msgstr "נשק קודם"
 
 #: qcsrc/client/hud/panel/infomessages.qc:106
 #, c-format
@@ -100,7 +101,7 @@ msgstr ""
 #: qcsrc/client/hud/panel/infomessages.qc:111
 #: qcsrc/menu/xonotic/keybinder.qc:94
 msgid "server info"
-msgstr ""
+msgstr "מידע על השרת"
 
 #: qcsrc/client/hud/panel/infomessages.qc:124
 msgid "^1Match has already begun"
@@ -140,7 +141,7 @@ msgstr ""
 #: qcsrc/client/hud/panel/infomessages.qc:175
 #: qcsrc/menu/xonotic/keybinder.qc:91
 msgid "ready"
-msgstr ""
+msgstr "מוכן"
 
 #: qcsrc/client/hud/panel/infomessages.qc:162
 #, c-format
@@ -172,7 +173,7 @@ msgstr ""
 #: qcsrc/client/hud/panel/infomessages.qc:199
 #: qcsrc/menu/xonotic/keybinder.qc:102
 msgid "team menu"
-msgstr ""
+msgstr "תפריט צוות"
 
 #: qcsrc/client/hud/panel/infomessages.qc:209
 msgid "^1Spectating this player:"
@@ -225,7 +226,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/quickmenu.qc:636
 msgid "Continue..."
-msgstr ""
+msgstr "המשך..."
 
 #: qcsrc/client/hud/panel/quickmenu.qc:794
 #: qcsrc/client/hud/panel/quickmenu.qc:798
@@ -500,12 +501,12 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/racetimer.qc:61
 msgid "Start line"
-msgstr ""
+msgstr "קו התחלה"
 
 #: qcsrc/client/hud/panel/racetimer.qc:63
 #: qcsrc/client/hud/panel/racetimer.qc:67
 msgid "Finish line"
-msgstr ""
+msgstr "קו סיום"
 
 #: qcsrc/client/hud/panel/racetimer.qc:65
 #, c-format
@@ -1010,7 +1011,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:16
 #: qcsrc/menu/xonotic/dialog_uid2name.qc:15
 msgid "Yes"
-msgstr ""
+msgstr "כן"
 
 #: qcsrc/client/hud/panel/vote.qc:127 qcsrc/menu/xonotic/dialog_firstrun.qc:83
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc:21
@@ -1020,7 +1021,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:17
 #: qcsrc/menu/xonotic/dialog_uid2name.qc:17
 msgid "No"
-msgstr ""
+msgstr "לא"
 
 #: qcsrc/client/hud/panel/weapons.qc:530
 msgid "Out of ammo"
@@ -1032,7 +1033,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/weapons.qc:538
 msgid "Unavailable"
-msgstr ""
+msgstr "לא זמין"
 
 #: qcsrc/client/main.qc:1014
 msgid " qu/s"
@@ -1078,7 +1079,7 @@ msgstr ""
 
 #: qcsrc/client/mapvoting.qc:365
 msgid "Vote for a map"
-msgstr ""
+msgstr "הצבע למפה"
 
 #: qcsrc/client/mapvoting.qc:382
 #, c-format
@@ -1181,11 +1182,11 @@ msgstr ""
 
 #: qcsrc/common/mapinfo.qh:126
 msgid "Race"
-msgstr ""
+msgstr "מרוץ"
 
 #: qcsrc/common/mapinfo.qh:126
 msgid "Race against other players to the finish line"
-msgstr ""
+msgstr "התחרה נגד שחקנים אחרים לקו הסיום"
 
 #: qcsrc/common/mapinfo.qh:160
 msgid "Race CTS"
@@ -1205,7 +1206,7 @@ msgstr ""
 
 #: qcsrc/common/mapinfo.qh:220
 msgid "Capture the Flag"
-msgstr ""
+msgstr "תפוס את הדגל"
 
 #: qcsrc/common/mapinfo.qh:220
 msgid ""
@@ -1308,7 +1309,7 @@ msgstr ""
 
 #: qcsrc/common/minigames/cl_minigames_hud.qc:403
 msgid "Exit Menu"
-msgstr ""
+msgstr "צא מהתפריט"
 
 #: qcsrc/common/minigames/cl_minigames_hud.qc:415
 #: qcsrc/menu/xonotic/dialog_multiplayer.qc:16
@@ -1317,7 +1318,7 @@ msgstr ""
 
 #: qcsrc/common/minigames/cl_minigames_hud.qc:418
 msgid "Join"
-msgstr ""
+msgstr "הצטרף"
 
 #: qcsrc/common/minigames/cl_minigames_hud.qc:489
 msgid "Minigames"
@@ -1345,7 +1346,7 @@ msgstr ""
 
 #: qcsrc/common/minigames/minigame/bd.qc:1404
 msgid "Next Level"
-msgstr ""
+msgstr "שלב הבא"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1405
 msgid "Restart"
@@ -1358,7 +1359,7 @@ msgstr ""
 #: qcsrc/common/minigames/minigame/bd.qc:1407
 #: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:37
 msgid "Save"
-msgstr ""
+msgstr "שמור"
 
 #: qcsrc/common/minigames/minigame/c4.qc:373
 #: qcsrc/common/minigames/minigame/pp.qc:438
@@ -1414,15 +1415,15 @@ msgstr ""
 
 #: qcsrc/common/minigames/minigame/pong.qc:651
 msgid "Start Match"
-msgstr ""
+msgstr "התחל משחק"
 
 #: qcsrc/common/minigames/minigame/pong.qc:652
 msgid "Add AI player"
-msgstr ""
+msgstr "הוסף שחקן מחשב"
 
 #: qcsrc/common/minigames/minigame/pong.qc:653
 msgid "Remove AI player"
-msgstr ""
+msgstr "הסר שחקן מחשב"
 
 #: qcsrc/common/minigames/minigame/pp.qc:443
 #: qcsrc/common/minigames/minigame/ttt.qc:324
@@ -1451,7 +1452,7 @@ msgstr ""
 #: qcsrc/common/minigames/minigame/pp.qc:582
 #: qcsrc/common/minigames/minigame/ttt.qc:665
 msgid "Next Match"
-msgstr ""
+msgstr "משחק הבא"
 
 #: qcsrc/common/minigames/minigame/ps.qc:478
 #, c-format
@@ -1464,7 +1465,7 @@ msgstr ""
 
 #: qcsrc/common/minigames/minigame/ps.qc:491
 msgid "Well done, you win!"
-msgstr ""
+msgstr "כל הכבוד, ניצחת!"
 
 #: qcsrc/common/minigames/minigame/ps.qc:494
 msgid "Jump a piece over another to capture it"
@@ -1477,7 +1478,7 @@ msgstr ""
 #: qcsrc/common/monsters/monster/mage.qh:17
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:18
 msgid "Mage"
-msgstr ""
+msgstr "קוסם"
 
 #: qcsrc/common/monsters/monster/mage.qh:29
 msgid "Mage spike"
@@ -1491,7 +1492,7 @@ msgstr ""
 #: qcsrc/common/monsters/monster/spider.qh:17
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:16
 msgid "Spider"
-msgstr ""
+msgstr "עכביש"
 
 #: qcsrc/common/monsters/monster/spider.qh:28
 msgid "Spider attack"
@@ -1509,11 +1510,11 @@ msgstr ""
 #: qcsrc/common/monsters/monster/zombie.qh:17
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:15
 msgid "Zombie"
-msgstr ""
+msgstr "זומבי"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:15
 msgid "Ammo"
-msgstr ""
+msgstr "תחמושת"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:24
 msgid "Resistance"
@@ -1522,7 +1523,7 @@ msgstr ""
 #: qcsrc/common/mutators/mutator/buffs/all.inc:33
 #: qcsrc/common/mutators/mutator/instagib/items.qh:94
 msgid "Speed"
-msgstr ""
+msgstr "מהירות"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:43
 msgid "Medic"
@@ -1610,7 +1611,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:109
 #: qcsrc/menu/xonotic/util.qc:775
 msgid "Color:"
-msgstr ""
+msgstr "צבע:"
 
 #: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:47
 msgid "Draw damage numbers for friendly fire"
@@ -1781,7 +1782,7 @@ msgstr ""
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:45
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:48
 msgid "Ball"
-msgstr ""
+msgstr "כדור"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:46
 msgid "Ball carrier"
@@ -1798,19 +1799,19 @@ msgstr ""
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:57
 msgid "Weapon"
-msgstr ""
+msgstr "נשק"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:59
 msgid "Monster"
-msgstr ""
+msgstr "מפלצת"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:61
 msgid "Vehicle"
-msgstr ""
+msgstr "רכב"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:62
 msgid "Intruder!"
-msgstr ""
+msgstr "פולש!"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:64
 msgid "Tagged"
@@ -4332,7 +4333,7 @@ msgstr ""
 
 #: qcsrc/common/turrets/turret/plasma_weapon.qh:7
 msgid "Plasma"
-msgstr ""
+msgstr "פלזמה"
 
 #: qcsrc/common/turrets/turret/tesla.qh:13
 #: qcsrc/common/turrets/turret/tesla_weapon.qh:7
@@ -4462,7 +4463,7 @@ msgstr ""
 
 #: qcsrc/common/weapons/weapon/shotgun.qc:17
 msgid "Shotgun"
-msgstr ""
+msgstr "שוטגן"
 
 #: qcsrc/common/weapons/weapon/tuba.qc:17
 #, no-c-format
@@ -4712,7 +4713,7 @@ msgstr ""
 
 #: qcsrc/menu/command/menu_cmd.qc:79
 msgid "Available options:\n"
-msgstr ""
+msgstr "אפשרויות זמינות:\n"
 
 #: qcsrc/menu/command/menu_cmd.qc:128
 msgid "Invalid command. For a list of supported commands, try menu_cmd help.\n"
@@ -4745,7 +4746,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/credits.qc:48
 msgid "Website"
-msgstr ""
+msgstr "אתר"
 
 #: qcsrc/menu/xonotic/credits.qc:53
 msgid "Stats"
@@ -4925,7 +4926,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/cvarlist.qc:93
 msgid "private"
-msgstr ""
+msgstr "פרטי"
 
 #: qcsrc/menu/xonotic/cvarlist.qc:95
 msgid "engine setting"
@@ -4946,7 +4947,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_credits.qh:7
 msgid "Credits"
-msgstr ""
+msgstr "קרדיטים"
 
 #: qcsrc/menu/xonotic/dialog_credits.qh:8
 msgid "The Xonotic credits"
@@ -4962,7 +4963,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:45
 #: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:28
 msgid "Name:"
-msgstr ""
+msgstr "שם:"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:53
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:60
@@ -4983,11 +4984,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:88
 msgid "Save settings"
-msgstr ""
+msgstr "שמור הגדרות"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qh:6
 msgid "Welcome"
-msgstr ""
+msgstr "ברוך הבא"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:16
 msgid "Ammunition display:"
@@ -5021,7 +5022,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:33
 #: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:18
 msgid "Left"
-msgstr ""
+msgstr "שמאל"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:32
 #: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:32
@@ -5032,7 +5033,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:34
 #: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:20
 msgid "Right"
-msgstr ""
+msgstr "ימין"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qh:6
 msgid "Ammo Panel"
@@ -5059,7 +5060,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:19
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:71
 msgid "Center"
-msgstr ""
+msgstr "מרכז"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:35
 msgid "Font scale:"
@@ -5075,7 +5076,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:18
 msgid "Chat size:"
-msgstr ""
+msgstr "גודל צ'אט:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:22
 msgid "Chat lifetime:"
@@ -5265,15 +5266,15 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:37
 msgid "Speed:"
-msgstr ""
+msgstr "מהירות:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:38
 msgid "Include vertical speed"
-msgstr ""
+msgstr "כלול מהירות אנכית"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:49
 msgid "Speed unit:"
-msgstr ""
+msgstr "יחידת מידה למהירות:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:51
 msgid "qu/s"
@@ -5297,7 +5298,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:57
 msgid "Show"
-msgstr ""
+msgstr "הצג"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:60
 msgid "Top speed"
@@ -5419,7 +5420,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_score.qc:15
 msgid "Score:"
-msgstr ""
+msgstr "ניקוד:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_score.qc:18
 msgid "Rankings:"
@@ -5470,7 +5471,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:139
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:55
 msgid "Never"
-msgstr ""
+msgstr "לעולם לא"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:24
 #, c-format
@@ -5515,7 +5516,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:54
 msgid "Number"
-msgstr ""
+msgstr "מספר"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:55
 msgid "Bind"
@@ -5556,14 +5557,14 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:25
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:35
 msgid "Filter:"
-msgstr ""
+msgstr "מסנן:"
 
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:30
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:53
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:44
 msgid "Refresh"
-msgstr ""
+msgstr "רענן"
 
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:33
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:30
@@ -5581,7 +5582,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:48
 #: qcsrc/menu/xonotic/util.qc:767
 msgid "Background:"
-msgstr ""
+msgstr "רקע:"
 
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:50
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:62
@@ -5662,7 +5663,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:13
 msgid "Monster:"
-msgstr ""
+msgstr "מפלצת:"
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:22
 #: qcsrc/menu/xonotic/dialog_sandboxtools.qc:20
@@ -5672,7 +5673,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:23
 #: qcsrc/menu/xonotic/serverlist.qc:268
 msgid "Remove"
-msgstr ""
+msgstr "הסר"
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:25
 msgid "Move target:"
@@ -5696,7 +5697,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:31
 msgid "Colors:"
-msgstr ""
+msgstr "צבעים:"
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:33
 #: qcsrc/menu/xonotic/dialog_sandboxtools.qc:39
@@ -5709,7 +5710,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer.qc:14
 msgid "Servers"
-msgstr ""
+msgstr "שרתים"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer.qc:15
 msgid "Find servers to play on"
@@ -5743,12 +5744,12 @@ msgstr ""
 #: qcsrc/menu/xonotic/util.qc:785 qcsrc/menu/xonotic/util.qc:794
 #: qcsrc/menu/xonotic/util.qc:802 qcsrc/menu/xonotic/util.qc:814
 msgid "Default"
-msgstr ""
+msgstr "ברירת מחדל"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:48
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Unlimited"
-msgstr ""
+msgstr "לא מוגבל"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:65
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:66
@@ -5789,7 +5790,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:70
 msgid "Lives:"
-msgstr ""
+msgstr "חיים:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:71
 msgid "Laps:"
@@ -5805,11 +5806,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
 msgid "Gametype"
-msgstr ""
+msgstr "סוג משחק"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:102
 msgid "Time limit:"
-msgstr ""
+msgstr "הגבלת זמן:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:104
 msgid "Timelimit in minutes that when hit, will end the match"
@@ -5827,7 +5828,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "1 minute"
-msgstr ""
+msgstr "דקה אחת"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
 msgid "TIMLIM^Infinite"
@@ -5835,19 +5836,19 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Teams:"
-msgstr ""
+msgstr "צוותים:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "2 teams"
-msgstr ""
+msgstr "2 צוותים"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "3 teams"
-msgstr ""
+msgstr "3 צוותים"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "4 teams"
-msgstr ""
+msgstr "4 צוותים"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:140
 msgid "Player slots:"
@@ -5881,15 +5882,15 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Beginner"
-msgstr ""
+msgstr "מתחיל"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "You will win"
-msgstr ""
+msgstr "אתה תנצח"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:155
 msgid "You can win"
-msgstr ""
+msgstr "אתה יכול לנצח"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:156
 msgid "You might win"
@@ -5897,27 +5898,27 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:157
 msgid "Advanced"
-msgstr ""
+msgstr "מתקדם"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:158
 msgid "Expert"
-msgstr ""
+msgstr "מומחה"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:159
 msgid "Pro"
-msgstr ""
+msgstr "מקצוען"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:160
 msgid "Assassin"
-msgstr ""
+msgstr "מתנקש"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
 msgid "Unhuman"
-msgstr ""
+msgstr "לא אנושי"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:162
 msgid "Godlike"
-msgstr ""
+msgstr "דמוי אל"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:178
 msgid "Mutators..."
@@ -5955,7 +5956,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:217
 msgid "Add all"
-msgstr ""
+msgstr "הוסף הכל"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:218
 msgid "Add every available map to your selection"
@@ -5963,7 +5964,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:221
 msgid "Remove all"
-msgstr ""
+msgstr "הסר הכל"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
 msgid "Remove all the maps from your selection"
@@ -5975,20 +5976,20 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:58
 msgid "Title:"
-msgstr ""
+msgstr "כותרת:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:64
 msgid "Author:"
-msgstr ""
+msgstr "מחבר:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:70
 msgid "Game types:"
-msgstr ""
+msgstr "סוגי משחק:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:93
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:296
 msgid "Close"
-msgstr ""
+msgstr "סגור"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:96
 msgid "MAP^Play"
@@ -6044,7 +6045,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:75
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:282
 msgid "No start weapons"
-msgstr ""
+msgstr "ללא נשקי התחלה"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:77
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:195
@@ -6073,7 +6074,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:89
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:229
 msgid "Weapons stay"
-msgstr ""
+msgstr "נשקים נשארים"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:91
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:184
@@ -6129,7 +6130,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:178
 msgid "Damage done to your enemy gets added to your own health"
-msgstr ""
+msgstr "נזק שנעשה לאויב שלך מתווסף לחיים שלך"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:183
 msgid ""
@@ -6182,11 +6183,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:255
 msgid "Most weapons"
-msgstr ""
+msgstr "רוב הנשקים"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:260
 msgid "All weapons"
-msgstr ""
+msgstr "כל הנשקים"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:264
 msgid "Special arenas:"
@@ -6255,11 +6256,11 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:67
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:223
 msgid "Address:"
-msgstr ""
+msgstr "כתובת:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:78
 msgid "Info..."
-msgstr ""
+msgstr "מידע..."
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:79
 msgid "Show more information about the currently highlighted server"
@@ -6268,7 +6269,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:84
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:303
 msgid "Join!"
-msgstr ""
+msgstr "הצטרף!"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:154
 #: qcsrc/menu/xonotic/serverlist.qc:1061
@@ -6282,7 +6283,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:161
 msgid "Official"
-msgstr ""
+msgstr "רשמי"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:169
 msgid "N/A (auth library missing, can't connect)"
@@ -6294,7 +6295,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:177
 msgid "Not supported (can't connect)"
-msgstr ""
+msgstr "לא נתמך(לא יכול להתחבר)"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:179
 msgid "Not supported (won't encrypt)"
@@ -6330,11 +6331,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:231
 msgid "Gametype:"
-msgstr ""
+msgstr "סוג משחק:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:236
 msgid "Map:"
-msgstr ""
+msgstr "מפה:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:241
 msgid "Mod:"
@@ -6342,16 +6343,16 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:246
 msgid "Version:"
-msgstr ""
+msgstr "גרסה:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:251
 msgid "Settings:"
-msgstr ""
+msgstr "הגדרות:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:258
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:290
 msgid "Players:"
-msgstr ""
+msgstr "שחקנים:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:263
 msgid "Bots:"
@@ -6375,7 +6376,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qh:7
 msgid "Server Information"
-msgstr ""
+msgstr "מידע על השרת"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:25
 msgid "Demos"
@@ -6412,12 +6413,12 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc:15
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc:15
 msgid "Do you really wish to disconnect now?"
-msgstr ""
+msgstr "אתה באמת רוצה להתנתק עכשיו?"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qh:6
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qh:6
 msgid "Disconnect"
-msgstr ""
+msgstr "התנתק"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc:13
 msgid "Timing a demo will disconnect you from the current match."
@@ -6445,7 +6446,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:55
 msgid "Random order"
-msgstr ""
+msgstr "סדר אקראי"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:60
 msgid "MUSICPL^Stop"
@@ -6485,19 +6486,19 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:139
 msgid "Reset"
-msgstr ""
+msgstr "אפס"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:144
 msgid "Previous"
-msgstr ""
+msgstr "קודם"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:147
 msgid "Next"
-msgstr ""
+msgstr "הבא"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:152
 msgid "Slide show"
-msgstr ""
+msgstr "מצגת שקופיות"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:34
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:21
@@ -6510,7 +6511,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:48
 msgid "Name"
-msgstr ""
+msgstr "שם"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:77
 msgid "Model"
@@ -6538,38 +6539,38 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:145
 msgid "Country"
-msgstr ""
+msgstr "מדינה"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:159
 msgid "Gender:"
-msgstr ""
+msgstr "מין:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:161
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:174
 msgid "Undisclosed"
-msgstr ""
+msgstr "לא ידוע"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:162
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:172
 msgid "Female"
-msgstr ""
+msgstr "נקבה"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:163
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:173
 msgid "Male"
-msgstr ""
+msgstr "זכר"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:166
 msgid "Gender"
-msgstr ""
+msgstr "מין"
 
 #: qcsrc/menu/xonotic/dialog_quit.qc:11
 msgid "Are you sure you want to quit?"
-msgstr ""
+msgstr "אתה בטוח שברצונך לצאת?"
 
 #: qcsrc/menu/xonotic/dialog_quit.qc:15
 msgid "Back to work..."
-msgstr ""
+msgstr "בחזרה לעבודה..."
 
 #: qcsrc/menu/xonotic/dialog_quit.qc:17
 msgid "I got some more fragging to do!"
@@ -6577,7 +6578,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_quit.qh:7
 msgid "Quit the game"
-msgstr ""
+msgstr "צא מהמשחק"
 
 #: qcsrc/menu/xonotic/dialog_sandboxtools.qc:15
 msgid "Model:"
@@ -6585,15 +6586,15 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_sandboxtools.qc:21
 msgid "Remove *"
-msgstr ""
+msgstr "הסר *"
 
 #: qcsrc/menu/xonotic/dialog_sandboxtools.qc:23
 msgid "Copy *"
-msgstr ""
+msgstr "העתק *"
 
 #: qcsrc/menu/xonotic/dialog_sandboxtools.qc:24
 msgid "Paste"
-msgstr ""
+msgstr "הדבק"
 
 #: qcsrc/menu/xonotic/dialog_sandboxtools.qc:26
 msgid "Bone:"
@@ -6693,7 +6694,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_sandboxtools.qc:81
 msgid "Show help"
-msgstr ""
+msgstr "הצג עזרה"
 
 #: qcsrc/menu/xonotic/dialog_sandboxtools.qc:82
 msgid "* is the object you are facing"
@@ -6709,23 +6710,23 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings.qc:19
 msgid "Effects"
-msgstr ""
+msgstr "אפקטים"
 
 #: qcsrc/menu/xonotic/dialog_settings.qc:20
 msgid "Audio"
-msgstr ""
+msgstr "שמע"
 
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Game"
-msgstr ""
+msgstr "משחק"
 
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Input"
-msgstr ""
+msgstr "קלט"
 
 #: qcsrc/menu/xonotic/dialog_settings.qc:24
 msgid "User"
-msgstr ""
+msgstr "משתמש"
 
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 #: qcsrc/menu/xonotic/keybinder.qc:105
@@ -6734,11 +6735,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings.qh:6
 msgid "Settings"
-msgstr ""
+msgstr "הגדרות"
 
 #: qcsrc/menu/xonotic/dialog_settings.qh:7
 msgid "Change the game settings"
-msgstr ""
+msgstr "שנה את הגדרות המשחק"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
@@ -6746,7 +6747,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:35
 msgid "Music:"
-msgstr ""
+msgstr "מוזיקה:"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:43
 msgid "VOL^Ambient:"
@@ -6754,7 +6755,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:50
 msgid "Info:"
-msgstr ""
+msgstr "מידע:"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:57
 msgid "Items:"
@@ -6766,7 +6767,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:71
 msgid "Player:"
-msgstr ""
+msgstr "שחקן:"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:78
 msgid "Shots:"
@@ -6774,11 +6775,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:85
 msgid "Voice:"
-msgstr ""
+msgstr "קול:"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:93
 msgid "Weapons:"
-msgstr ""
+msgstr "נשקים:"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:99
 msgid "New style sound attenuation"
@@ -6842,7 +6843,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:123
 msgid "Stereo"
-msgstr ""
+msgstr "סטראו"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:124
 msgid "2.1"
@@ -6900,7 +6901,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:149
 msgid "Menu sounds"
-msgstr ""
+msgstr "צלילי תפריט"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:150
 msgid "Play sounds when clicking menu items"
@@ -6924,7 +6925,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:160
 msgid "5 minutes"
-msgstr ""
+msgstr "5 דקות"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:161
 msgid "WRN^Both"
@@ -6940,17 +6941,17 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:168
 msgid "Sometimes"
-msgstr ""
+msgstr "לפעמים"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:169
 msgid "Often"
-msgstr ""
+msgstr "לעתים קרובות"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:170
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:141
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:57
 msgid "Always"
-msgstr ""
+msgstr "תמיד"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:176
 msgid "Debug info about sounds"
@@ -7180,7 +7181,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:169
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:253
 msgid "Distance:"
-msgstr ""
+msgstr "מרחק"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:172
 msgid "Decals further away than this will not be drawn (default: 300)"
@@ -7188,7 +7189,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:176
 msgid "Time:"
-msgstr ""
+msgstr "זמן:"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:179
 msgid "Time in seconds before decals fade away (default: 2)"
@@ -7264,7 +7265,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:212
 msgid "Use normal maps"
-msgstr ""
+msgstr "השתמש במפות רגילות"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:213
 msgid "Enable use of directional shading on textures (default: enabled)"
@@ -7312,7 +7313,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:239
 msgid "Particles"
-msgstr ""
+msgstr "חלקיקים"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:240
 msgid "Spawnpoint effects"
@@ -7324,7 +7325,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:246
 msgid "Quality:"
-msgstr ""
+msgstr "איכות:"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:249
 msgid ""
@@ -7355,11 +7356,11 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:81
 #: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:97
 msgid "Size:"
-msgstr ""
+msgstr "גודל:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:64
 msgid "By health"
-msgstr ""
+msgstr "לפי חיים"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:76
 msgid "Use rings to indicate weapon status"
@@ -7455,7 +7456,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:74
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:124
 msgid "Fontsize:"
-msgstr ""
+msgstr "גודל גופן:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:80
 msgid "Edge offset:"
@@ -7467,7 +7468,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:94
 msgid "Damage"
-msgstr ""
+msgstr "נזק"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:96
 msgid "Overlay:"
@@ -7487,11 +7488,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:114
 msgid "Show names above players"
-msgstr ""
+msgstr "הצג שמות מעל שחקנים"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:130
 msgid "Max distance:"
-msgstr ""
+msgstr "מרחק מקסימלי:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:136
 msgid "Decolorize:"
@@ -7597,7 +7598,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:65
 msgid "Gamemode Settings"
-msgstr ""
+msgstr "אפשרויות מצב משחק"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:67
 msgid "Display capture times in Capture The Flag"
@@ -7611,7 +7612,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:91
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:133
 msgid "Other"
-msgstr ""
+msgstr "אחר"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:78
 msgid "Display console messages in the top left corner"
@@ -7655,7 +7656,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qh:7
 msgid "Messages"
-msgstr ""
+msgstr "הודעות"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:30
 msgid "Items"
@@ -7696,7 +7697,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:49
 #: qcsrc/menu/xonotic/serverlist.qc:767
 msgid "Players"
-msgstr ""
+msgstr "שחקנים"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:51
 msgid "Force player models to mine"
@@ -7768,7 +7769,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:51
 msgid "3rd person perspective"
-msgstr ""
+msgstr "נקודת מבט מגוף שלישי"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:55
 msgid "Back distance"
@@ -7913,7 +7914,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qh:7
 #: qcsrc/menu/xonotic/keybinder.qc:43
 msgid "Weapons"
-msgstr ""
+msgstr "נשקים"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:33
 msgid "Key Bindings"
@@ -7925,19 +7926,19 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:41
 msgid "Edit..."
-msgstr ""
+msgstr "ערוך..."
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:47
 msgid "Clear"
-msgstr ""
+msgstr "נקה"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:52
 msgid "Reset all"
-msgstr ""
+msgstr "אפס הכל"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:57
 msgid "Mouse"
-msgstr ""
+msgstr "עכבר"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:59
 msgid "Sensitivity:"
@@ -8013,7 +8014,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:114
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:119
 msgid "Use joystick input"
-msgstr ""
+msgstr "התשתמש בקלט מג'ויסטיק"
 
 #: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:31
 msgid "Command when pressed:"
@@ -8025,7 +8026,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:40
 msgid "Cancel"
-msgstr ""
+msgstr "בטל"
 
 #: qcsrc/menu/xonotic/dialog_settings_input_userbind.qh:7
 msgid "User defined key bind"
@@ -8048,7 +8049,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
 msgid "Network"
-msgstr ""
+msgstr "רשת"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
 msgid "Client UDP port:"
@@ -8060,11 +8061,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
 msgid "Bandwidth:"
-msgstr ""
+msgstr "רוחב פס:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
 msgid "Specify your network speed"
-msgstr ""
+msgstr "צין את מהירות הרשת שלך"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
 msgid "56k"
@@ -8100,7 +8101,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
 msgid "Downloads:"
-msgstr ""
+msgstr "הורדות:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
 msgid "Maximum number of concurrent HTTP/FTP downloads"
@@ -8108,7 +8109,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:56
 msgid "Download speed:"
-msgstr ""
+msgstr "מהירות הורדה:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Local latency:"
@@ -8148,7 +8149,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
 msgid "Target:"
-msgstr ""
+msgstr "מטרה:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
 msgid "TRGT^Disabled"
@@ -8168,7 +8169,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:129
 msgid "Show frames per second"
-msgstr ""
+msgstr "הצג פריימים לשנייה"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:130
 msgid "Show your rendered frames per second"
@@ -8206,7 +8207,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:147
 msgid "Enable developer mode"
-msgstr ""
+msgstr "אפשר מצב מפתח"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:151
 msgid "Advanced settings..."
@@ -8235,23 +8236,23 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:49
 msgid "Type:"
-msgstr ""
+msgstr "סוג:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:53
 msgid "Value:"
-msgstr ""
+msgstr "ערך:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:70
 msgid "Description:"
-msgstr ""
+msgstr "תיאור:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qh:7
 msgid "Advanced settings"
-msgstr ""
+msgstr "אפשרויות מתקדמות"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:11
 msgid "Are you sure you want to reset all settings?"
-msgstr ""
+msgstr "האם אתה בטוח שברצונך לאפס את כל ההגדרות?"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:13
 msgid "This will create a backup config in your data directory"
@@ -8263,11 +8264,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:64
 msgid "Text Language"
-msgstr ""
+msgstr "שפת טקסט"
 
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:69
 msgid "Set language"
-msgstr ""
+msgstr "קבע שפה"
 
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:74
 msgid "Disable gore effects and harsh language"
@@ -8289,11 +8290,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:16
 msgid "Disconnect now"
-msgstr ""
+msgstr "התנתק עכשיו"
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:17
 msgid "Switch language"
-msgstr ""
+msgstr "החלף שפה"
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qh:6
 msgid "Warning"
@@ -8361,7 +8362,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:59
 msgid "Full screen"
-msgstr ""
+msgstr "מסך מלא"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Vertical Synchronization"
@@ -8611,7 +8612,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_singleplayer_winner.qh:7
 msgid "Winner"
-msgstr ""
+msgstr "מנצח"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:32
 msgid "join 'best' team (auto-select)"
@@ -8623,27 +8624,27 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:37
 msgid "red"
-msgstr ""
+msgstr "אדום"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:38
 msgid "blue"
-msgstr ""
+msgstr "כחול"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:39
 msgid "yellow"
-msgstr ""
+msgstr "צהוב"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:40
 msgid "pink"
-msgstr ""
+msgstr "ורוד"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:43
 msgid "spectate"
-msgstr ""
+msgstr "צפה"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qh:7
 msgid "Team Selection"
-msgstr ""
+msgstr "בחירת צוות"
 
 #: qcsrc/menu/xonotic/dialog_uid2name.qc:10
 msgid "Allow player statistics to use your nickname?"
@@ -8667,7 +8668,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/keybinder.qc:30
 msgid "forward"
-msgstr ""
+msgstr "קדימה"
 
 #: qcsrc/menu/xonotic/keybinder.qc:31
 msgid "backpedal"
@@ -8739,7 +8740,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/keybinder.qc:80
 msgid "screen shot"
-msgstr ""
+msgstr "צילום מסך"
 
 #: qcsrc/menu/xonotic/keybinder.qc:81
 msgid "maximize radar"
@@ -8771,11 +8772,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/keybinder.qc:89
 msgid "vote YES"
-msgstr ""
+msgstr "הצבע כן"
 
 #: qcsrc/menu/xonotic/keybinder.qc:90
 msgid "vote NO"
-msgstr ""
+msgstr "הצבע לא"
 
 #: qcsrc/menu/xonotic/keybinder.qc:93
 msgid "Client"
@@ -8787,11 +8788,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/keybinder.qc:96
 msgid "disconnect"
-msgstr ""
+msgstr "התנתק"
 
 #: qcsrc/menu/xonotic/keybinder.qc:97
 msgid "quit"
-msgstr ""
+msgstr "צא"
 
 #: qcsrc/menu/xonotic/keybinder.qc:101
 msgid "auto-join team"
@@ -8865,7 +8866,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.qc:765
 msgid "Map"
-msgstr ""
+msgstr "מפה"
 
 #: qcsrc/menu/xonotic/serverlist.qc:766
 msgid "Type"
@@ -9008,7 +9009,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/slider_resolution.qc:115
 msgid "Screen resolution"
-msgstr ""
+msgstr "רזולוציית מסך"
 
 #: qcsrc/menu/xonotic/slider_sbfadetime.qc:13
 msgid "PART^Slow"
@@ -9024,51 +9025,51 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/statslist.qc:29
 msgid "January"
-msgstr ""
+msgstr "ינואר"
 
 #: qcsrc/menu/xonotic/statslist.qc:30
 msgid "February"
-msgstr ""
+msgstr "פברואר"
 
 #: qcsrc/menu/xonotic/statslist.qc:31
 msgid "March"
-msgstr ""
+msgstr "מרץ"
 
 #: qcsrc/menu/xonotic/statslist.qc:32
 msgid "April"
-msgstr ""
+msgstr "אפריל"
 
 #: qcsrc/menu/xonotic/statslist.qc:33
 msgid "May"
-msgstr ""
+msgstr "מאי"
 
 #: qcsrc/menu/xonotic/statslist.qc:34
 msgid "June"
-msgstr ""
+msgstr "יוני"
 
 #: qcsrc/menu/xonotic/statslist.qc:35
 msgid "July"
-msgstr ""
+msgstr "יולי"
 
 #: qcsrc/menu/xonotic/statslist.qc:36
 msgid "August"
-msgstr ""
+msgstr "אוגוסט"
 
 #: qcsrc/menu/xonotic/statslist.qc:37
 msgid "September"
-msgstr ""
+msgstr "ספטמבר"
 
 #: qcsrc/menu/xonotic/statslist.qc:38
 msgid "October"
-msgstr ""
+msgstr "אוקטובר"
 
 #: qcsrc/menu/xonotic/statslist.qc:39
 msgid "November"
-msgstr ""
+msgstr "נובמבר"
 
 #: qcsrc/menu/xonotic/statslist.qc:40
 msgid "December"
-msgstr ""
+msgstr "דצמבר"
 
 #: qcsrc/menu/xonotic/statslist.qc:96
 msgid "Joined:"
@@ -9145,7 +9146,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/util.qc:780
 msgid "Use default"
-msgstr ""
+msgstr "השתמש בברירת מחדל"
 
 #: qcsrc/menu/xonotic/util.qc:800
 msgid "Team Color:"
diff --git a/gfx/hud/default/as_defend.tga b/gfx/hud/default/as_defend.tga
new file mode 100644 (file)
index 0000000..5aca85e
Binary files /dev/null and b/gfx/hud/default/as_defend.tga differ
diff --git a/gfx/hud/default/as_destroy.tga b/gfx/hud/default/as_destroy.tga
new file mode 100644 (file)
index 0000000..7c779a1
Binary files /dev/null and b/gfx/hud/default/as_destroy.tga differ
diff --git a/gfx/hud/luma/as_defend.tga b/gfx/hud/luma/as_defend.tga
new file mode 100644 (file)
index 0000000..5aca85e
Binary files /dev/null and b/gfx/hud/luma/as_defend.tga differ
diff --git a/gfx/hud/luma/as_destroy.tga b/gfx/hud/luma/as_destroy.tga
new file mode 100644 (file)
index 0000000..7c779a1
Binary files /dev/null and b/gfx/hud/luma/as_destroy.tga differ
index e2e83ae7588ba17ef77aa1f1278f29a69901111a..b90d291fb40646d6ffdbcd7e5845b3835b63c12c 100644 (file)
Binary files a/gfx/hud/luma/ok_weapon_rail.tga and b/gfx/hud/luma/ok_weapon_rail.tga differ
index f5fb92e13ee7bcc11b2809755883a44531fe0b18..b0e7bf9327d5d95350ed74ec1f7589171882963b 100644 (file)
Binary files a/gfx/hud/luma/ok_weapon_shotgun.tga and b/gfx/hud/luma/ok_weapon_shotgun.tga differ
index 5aee32ab545a47884f50cd00ce4248e8cb35ab3c..cb26a1657dd0f04c2775e9d9323327885a5cc918 100644 (file)
Binary files a/gfx/hud/luma/ok_weapon_smg.tga and b/gfx/hud/luma/ok_weapon_smg.tga differ
index 65ce9094219c56f80574f2735befda22cf3c46bd..e16e0b878637b50dd21f71c361f88866b5c54379 100644 (file)
@@ -1,25 +1,25 @@
-ko    Korean "한국의" 33%
-ast   Asturian "Asturianu" 73%
+ast   "Asturian" "Asturianu" 73%
+de    "German" "Deutsch" 99%
+de_CH "German (Switzerland)" "Deutsch (Schweiz)" 99%
+en    "English" "English" 100%
+en_AU "English (Australia)" "English (Australia)" 86%
+es    "Spanish" "Español" 99%
+fr    "French" "Français" 99%
+ga    "Irish" "Irish" 35%
+it    "Italian" "Italiano" 99%
+hu    "Hungarian" "Magyar" 55%
+nl    "Dutch" "Nederlands" 70%
+pl    "Polish" "Polski" 81%
+pt    "Portuguese" "Português" 98%
+pt_BR "Portuguese (Brazil)" "Português (Brasil)" 99%
+ro    "Romanian" "Romana" 83%
+fi    "Finnish" "Suomi" 33%
+el    "Greek" "Ελληνική" 33%
+be    "Belarusian" "Беларуская" 61%
+bg    "Bulgarian" "Български" 68%
+ru    "Russian" "Русский" 99%
+sr    "Serbian" "Српски" 71%
+uk    "Ukrainian" "Українська" 57%
 zh_CN "Chinese (China)" "中文" 62%
-de    German "Deutsch"
-de_CH German "Deutsch (Schweiz)"
-en    English "English"
-en_AU English "English (Australia)" 86%
-es    Spanish "Español" 99%
-fr    French "Français"
-ga    Irish "Irish" 35%
-it    Italian "Italiano"
-hu    Hungarian "Magyar" 55%
-nl    Dutch "Nederlands" 70%
-pl    Polish "Polski" 81%
-pt    Portuguese "Português"
-pt_BR pt_BR "pt_BR" 99%
-ro    Romanian "Romana" 83%
-fi    Finnish "Suomi" 33%
 zh_TW "Chinese (Taiwan)" "國語" 68%
-el    Greek "Ελληνική" 33%
-be    Belarusian "Беларуская" 61%
-bg    Bulgarian "Български" 68%
-ru    Russian "Русский"
-sr    Serbian "Српски" 71%
-uk    Ukrainian "Українська" 57%
+ko    "Korean" "한국의" 33%
index 1a6a9f88419d8cccc098c2fb78f6e925dc9bf5b7..c4b1ec041126310346a099b3f6b87546097df94a 100644 (file)
@@ -43,7 +43,7 @@ void DrawDebugModel(entity this)
 
 void LocalCommand_blurtest(int request)
 {
-    TC(int, request);
+       TC(int, request);
        // Simple command to work with postprocessing temporarily... possibly completely pointless, the glsl shader is used for a real feature now...
        // Anyway, to enable it, just compile the client with -DBLURTEST and then you can use the command.
 
@@ -79,7 +79,7 @@ void LocalCommand_blurtest(int request)
 
 void LocalCommand_boxparticles(int request, int argc)
 {
-    TC(int, request); TC(int, argc);
+       TC(int, request); TC(int, argc);
        switch (request)
        {
                case CMD_REQUEST_COMMAND:
@@ -135,7 +135,7 @@ void LocalCommand_boxparticles(int request, int argc)
 
 void LocalCommand_create_scrshot_ent(int request)
 {
-    TC(int, request);
+       TC(int, request);
        switch (request)
        {
                case CMD_REQUEST_COMMAND:
@@ -175,7 +175,7 @@ void LocalCommand_create_scrshot_ent(int request)
 
 void LocalCommand_debugmodel(int request, int argc)
 {
-    TC(int, request); TC(int, argc);
+       TC(int, request); TC(int, argc);
        switch (request)
        {
                case CMD_REQUEST_COMMAND:
@@ -205,7 +205,7 @@ void LocalCommand_debugmodel(int request, int argc)
 
 void LocalCommand_handlevote(int request, int argc)
 {
-    TC(int, request); TC(int, argc);
+       TC(int, request); TC(int, argc);
        switch (request)
        {
                case CMD_REQUEST_COMMAND:
@@ -255,7 +255,7 @@ void LocalCommand_handlevote(int request, int argc)
 
 void LocalCommand_hud(int request, int argc)
 {
-    TC(int, request); TC(int, argc);
+       TC(int, request); TC(int, argc);
        switch (request)
        {
                case CMD_REQUEST_COMMAND:
@@ -351,7 +351,7 @@ void LocalCommand_hud(int request, int argc)
 
 void LocalCommand_localprint(int request, int argc)
 {
-    TC(int, request); TC(int, argc);
+       TC(int, request); TC(int, argc);
        switch (request)
        {
                case CMD_REQUEST_COMMAND:
@@ -378,7 +378,7 @@ void LocalCommand_localprint(int request, int argc)
 
 void LocalCommand_mv_download(int request, int argc)
 {
-    TC(int, request); TC(int, argc);
+       TC(int, request); TC(int, argc);
        switch (request)
        {
                case CMD_REQUEST_COMMAND:
@@ -405,7 +405,7 @@ void LocalCommand_mv_download(int request, int argc)
 
 void LocalCommand_sendcvar(int request, int argc)
 {
-    TC(int, request); TC(int, argc);
+       TC(int, request); TC(int, argc);
        switch (request)
        {
                case CMD_REQUEST_COMMAND:
index d8f6d26a33895e91fd40fb6a8d1b42e723de8575..035ba2a1647c29a2445ca54d73022670536cfed3 100644 (file)
@@ -362,7 +362,7 @@ void CSQCPlayer_AnimDecide_PostUpdate(entity this, bool isnew)
 }
 int CSQCPlayer_FallbackFrame(entity this, int f)
 {
-    TC(int, f);
+       TC(int, f);
        if(frameduration(this.modelindex, f) > 0)
                return f; // goooooood
        if(frameduration(this.modelindex, 1) <= 0)
index 2b8eed95f7705578fc5ae34a083e8187c0f45a0b..2becced8e0cbcda94ad910946fc4480939b21856 100644 (file)
@@ -75,14 +75,14 @@ vector HUD_Get_Num_Color (float hp, float maxvalue)
 
 float HUD_GetRowCount(int item_count, vector size, float item_aspect)
 {
-    TC(int, item_count);
+       TC(int, item_count);
        float aspect = size_y / size_x;
        return bound(1, floor((sqrt(4 * item_aspect * aspect * item_count + aspect * aspect) + aspect + 0.5) / 2), item_count);
 }
 
 vector HUD_GetTableSize_BestItemAR(int item_count, vector psize, float item_aspect)
 {
-    TC(int, item_count);
+       TC(int, item_count);
        float columns, rows;
        float ratio, best_ratio = 0;
        float best_columns = 1, best_rows = 1;
@@ -180,7 +180,7 @@ void HUD_Panel_LoadCvars()
 //basically the same code of draw_ButtonPicture and draw_VertButtonPicture for the menu
 void HUD_Panel_DrawProgressBar(vector theOrigin, vector theSize, string pic, float length_ratio, bool vertical, float baralign, vector theColor, float theAlpha, int drawflag)
 {
-    TC(bool, vertical); TC(int, drawflag);
+       TC(bool, vertical); TC(int, drawflag);
        if(!length_ratio || !theAlpha)
                return;
        if(length_ratio > 1)
@@ -287,7 +287,7 @@ void HUD_Panel_DrawProgressBar(vector theOrigin, vector theSize, string pic, flo
 
 void HUD_Panel_DrawHighlight(vector pos, vector mySize, vector color, float theAlpha, int drawflag)
 {
-    TC(int, drawflag);
+       TC(int, drawflag);
        if(!theAlpha)
                return;
 
@@ -308,7 +308,7 @@ void HUD_Panel_DrawHighlight(vector pos, vector mySize, vector color, float theA
 
 void DrawNumIcon_expanding(vector myPos, vector mySize, float theTime, string icon, bool vertical, int icon_right_align, vector color, float theAlpha, float fadelerp)
 {
-    TC(bool, vertical); TC(int, icon_right_align);
+       TC(bool, vertical); TC(int, icon_right_align);
        vector newPos = '0 0 0', newSize = '0 0 0';
        vector picpos, numpos;
 
@@ -388,7 +388,7 @@ void DrawNumIcon_expanding(vector myPos, vector mySize, float theTime, string ic
 
 void DrawNumIcon(vector myPos, vector mySize, float theTime, string icon, bool vertical, int icon_right_align, vector color, float theAlpha)
 {
-    TC(bool, vertical); TC(int, icon_right_align);
+       TC(bool, vertical); TC(int, icon_right_align);
        DrawNumIcon_expanding(myPos, mySize, theTime, icon, vertical, icon_right_align, color, theAlpha, 0);
 }
 
index 01ce50cdbb6f87e03291c9f57232dc683aff76c9..ce700586caad1efe174acea70a0a85f06b2a0ced 100644 (file)
@@ -22,7 +22,7 @@ void DrawNadeProgressBar(vector myPos, vector mySize, float progress, vector col
 
 void DrawAmmoItem(vector myPos, vector mySize, int ammoType, bool isCurrent, bool isInfinite)
 {
-    TC(bool, isCurrent); TC(bool, isInfinite);
+       TC(bool, isCurrent); TC(bool, isInfinite);
        if(ammoType == RESOURCE_NONE)
                return;
 
index f8f70c8189e671de3cb01fd3d4c4a8aab3e7745a..90a496e0d175962f8dae41d4f75beec0346010b9 100644 (file)
@@ -20,7 +20,7 @@ bool centerprint_showing;
 
 void centerprint_generic(int new_id, string strMessage, float duration, int countdown_num)
 {
-    TC(int, new_id); TC(int, countdown_num);
+       TC(int, new_id); TC(int, countdown_num);
        //printf("centerprint_generic(%d, '%s^7', %d, %d);\n", new_id, strMessage, duration, countdown_num);
        int i, j;
 
@@ -94,7 +94,7 @@ void centerprint_generic(int new_id, string strMessage, float duration, int coun
 
 void centerprint_kill(int id)
 {
-    TC(int, id);
+       TC(int, id);
        centerprint_generic(id, "", 0, 0);
 }
 
index 89b8a8c188b4a981774ed1c173b98e8215c62a78..87e4a7fb251af875266a9ea72c82cdd6449e1f91 100644 (file)
@@ -13,7 +13,7 @@ bool mod_active; // is there any active mod icon?
 
 void DrawCAItem(vector myPos, vector mySize, float aspect_ratio, int layout, int i)
 {
-    TC(int, layout); TC(int, i);
+       TC(int, layout); TC(int, i);
        int stat = -1;
        string pic = "";
        vector color = '0 0 0';
@@ -626,7 +626,7 @@ void HUD_Mod_Race(vector pos, vector mySize)
 
 void DrawDomItem(vector myPos, vector mySize, float aspect_ratio, int layout, int i)
 {
-    TC(int, layout); TC(int, i);
+       TC(int, layout); TC(int, i);
        float stat = -1;
        string pic = "";
        vector color = '0 0 0';
index dd574cf9b039c4b69d6654792a36525e7c54ba57..947bfd53b3ee1075063b72a489ece3b981811753 100644 (file)
@@ -47,7 +47,7 @@ void addPowerupItem(string name, string icon, vector color, float currentTime, f
 
 int getPowerupItemAlign(int align, int column, int row, int columns, int rows, bool isVertical)
 {
-    TC(int, align); TC(int, column); TC(int, row); TC(int, columns); TC(int, rows); TC(bool, isVertical);
+       TC(int, align); TC(int, column); TC(int, row); TC(int, columns); TC(int, rows); TC(bool, isVertical);
        if(align < 2)
                return align;
 
index 29f69b3d4d9c506efc1676f48055af6c13011c4e..98b15ee9537257443d0a19d06dba2beed6ce4c4a 100644 (file)
@@ -43,7 +43,7 @@ float QuickMenu_TimeOut;
 // if s1 is not empty s will be displayed as command otherwise as submenu
 void QuickMenu_Page_LoadEntry(int i, string s, string s1)
 {
-    TC(int, i);
+       TC(int, i);
        //LOG_INFOF("^xc80 entry %d: %s, %s\n", i, s, s1);
        strcpy(QuickMenu_Page_Description[i], s);
        strcpy(QuickMenu_Page_Command[i], s1);
@@ -51,7 +51,7 @@ void QuickMenu_Page_LoadEntry(int i, string s, string s1)
 
 void QuickMenu_Page_ClearEntry(int i)
 {
-    TC(int, i);
+       TC(int, i);
        strfree(QuickMenu_Page_Description[i]);
        strfree(QuickMenu_Page_Command[i]);
        QuickMenu_Page_Command_Type[i] = 0;
@@ -225,7 +225,7 @@ bool QuickMenu_IsOpened()
 
 bool HUD_Quickmenu_PlayerListEntries_Create(string cmd, int teamplayers, bool without_me)
 {
-    TC(int, teamplayers); TC(bool, without_me);
+       TC(int, teamplayers); TC(bool, without_me);
        int i;
        for(i = 0; i < QUICKMENU_MAXLINES; ++i)
                QuickMenu_Page_ClearEntry(i);
@@ -250,7 +250,7 @@ bool HUD_Quickmenu_PlayerListEntries_Create(string cmd, int teamplayers, bool wi
 int QuickMenu_Buffer_Index_Prev;
 bool QuickMenu_Page_Load(string target_submenu, bool new_page)
 {
-    TC(bool, new_page);
+       TC(bool, new_page);
        string s = string_null, cmd = string_null, z_submenu;
 
        if (new_page == 0)
@@ -361,7 +361,7 @@ bool QuickMenu_Page_Load(string target_submenu, bool new_page)
 
 bool QuickMenu_ActionForNumber(int num)
 {
-    TC(int, num);
+       TC(int, num);
        if (!QuickMenu_IsLastPage)
        {
                if (num < 0 || num >= QUICKMENU_MAXLINES)
@@ -389,7 +389,7 @@ bool QuickMenu_ActionForNumber(int num)
 
 void QuickMenu_Page_ActiveEntry(int entry_num)
 {
-    TC(int, entry_num);
+       TC(int, entry_num);
        QuickMenu_Page_ActivatedEntry = entry_num;
        QuickMenu_Page_ActivatedEntry_Time = time + 0.1;
        if(QuickMenu_Page_Command[QuickMenu_Page_ActivatedEntry])
@@ -407,7 +407,7 @@ void QuickMenu_Page_ActiveEntry(int entry_num)
 
 bool QuickMenu_InputEvent(int bInputType, float nPrimary, float nSecondary)
 {
-    TC(int, bInputType);
+       TC(int, bInputType);
        // we only care for keyboard events
        if(bInputType == 2)
                return false;
@@ -748,7 +748,7 @@ void HUD_QuickMenu()
 
 void HUD_Quickmenu_PlayerListEntries(string cmd, int teamplayers, bool without_me)
 {
-    TC(int, teamplayers); TC(bool, without_me);
+       TC(int, teamplayers); TC(bool, without_me);
        entity pl;
        if(teamplayers && !team_count)
                return;
index bd94520d4e4292972e51277c0f27d6fc7fd7cd75..65073d9fed09700f5c8aebc6dfd6c322f6a05294 100644 (file)
@@ -19,7 +19,7 @@ bool HUD_Radar_Clickable()
 
 void HUD_Radar_Show_Maximized(bool doshow, bool clickable)
 {
-    TC(bool, doshow);
+       TC(bool, doshow);
        hud_panel_radar_maximized = doshow;
        hud_panel_radar_temp_hidden = 0;
 
@@ -56,7 +56,7 @@ void HUD_Radar_Hide_Maximized()
 
 float HUD_Radar_InputEvent(int bInputType, float nPrimary, float nSecondary)
 {
-    TC(int, bInputType);
+       TC(int, bInputType);
        if(!hud_panel_radar_maximized || !hud_panel_radar_mouse ||
                autocvar__hud_configure || mv_active)
                return false;
index 91d9f6f70d9757635c97ffe4136d504e325925dd..32ccccfca3355dedfa235c20e96f316ee61ed2b4 100644 (file)
@@ -175,7 +175,7 @@ void Scoreboard_UpdatePlayerTeams()
 
 int Scoreboard_CompareScore(int vl, int vr, int f)
 {
-    TC(int, vl); TC(int, vr); TC(int, f);
+       TC(int, vl); TC(int, vr); TC(int, f);
        if(f & SFL_ZERO_IS_WORST)
        {
                if(vl == 0 && vr != 0)
@@ -381,7 +381,7 @@ void Cmd_Scoreboard_Help()
 
 void Cmd_Scoreboard_SetFields(int argc)
 {
-    TC(int, argc);
+       TC(int, argc);
        int i, slash;
        string str, pattern;
        bool have_name = false, have_primary = false, have_secondary = false, have_separator = false;
@@ -716,7 +716,7 @@ float sbt_fixcolumnwidth_marginlen;
 
 string Scoreboard_FixColumnWidth(int i, string str)
 {
-    TC(int, i);
+       TC(int, i);
        float f;
        vector sz;
 
@@ -840,7 +840,7 @@ vector Scoreboard_DrawHeader(vector pos, vector rgb, bool other_players)
 
 void Scoreboard_DrawItem(vector item_pos, vector rgb, entity pl, bool is_self, int pl_number)
 {
-    TC(bool, is_self); TC(int, pl_number);
+       TC(bool, is_self); TC(int, pl_number);
        string str;
        bool is_spec = (entcs_GetTeam(pl.sv_entnum) == NUM_SPECTATOR);
 
index 5d75c7dd2a4182fe19d9a4ec67d2940a3d877174..8bf11cf1ac93d3994840bb64b96bac5ce993317d 100644 (file)
@@ -11,7 +11,7 @@
 entity weaponorder[Weapons_MAX];
 void weaponorder_swap(int i, int j, entity pass)
 {
-    TC(int, i); TC(int, j);
+       TC(int, i); TC(int, j);
        entity h = weaponorder[i];
        weaponorder[i] = weaponorder[j];
        weaponorder[j] = h;
@@ -20,7 +20,7 @@ void weaponorder_swap(int i, int j, entity pass)
 string weaponorder_cmp_str;
 int weaponorder_cmp(int i, int j, entity pass)
 {
-    TC(int, i); TC(int, j);
+       TC(int, i); TC(int, j);
        int ai = strstrofs(weaponorder_cmp_str, sprintf(" %d ", weaponorder[i].m_id), 0);
        int aj = strstrofs(weaponorder_cmp_str, sprintf(" %d ", weaponorder[j].m_id), 0);
        return aj - ai; // the string is in REVERSE order (higher prio at the right is what we want, but higher prio first is the string)
index 218df18a474fc47746e8a928f77e164ecece995f..863905a3d32fd4fb5ec1b4c9ae9e2d2dbf45df31 100644 (file)
@@ -230,7 +230,7 @@ void Shutdown()
 .float has_team;
 float SetTeam(entity o, int Team)
 {
-    TC(int, Team);
+       TC(int, Team);
        devassert_once(Team);
        entity tm;
        if(teamplay)
index 8412bd757964ffdec471381121b8a923af5a152c..03e94dc7f304238bc916443bc4a6fbef512d7bc7 100644 (file)
@@ -43,7 +43,7 @@ int n_ssdirs;
 
 string MapVote_FormatMapItem(int id, string map, float _count, float maxwidth, vector fontsize)
 {
-    TC(int, id);
+       TC(int, id);
        string pre, post;
        pre = sprintf("%d. ", id+1);
        if(mv_detail)
@@ -64,7 +64,7 @@ string MapVote_FormatMapItem(int id, string map, float _count, float maxwidth, v
 
 vector MapVote_RGB(int id)
 {
-    TC(int, id);
+       TC(int, id);
        if(!(mv_flags[id] & GTV_AVAILABLE))
                return '1 1 1';
        if(id == mv_ownvote)
@@ -77,7 +77,7 @@ vector MapVote_RGB(int id)
 
 void GameTypeVote_DrawGameTypeItem(vector pos, float maxh, float tsize, string gtype, string pic, float _count, int id)
 {
-    TC(int, id);
+       TC(int, id);
        // Find the correct alpha
        float alpha;
        if(!(mv_flags_start[id] & GTV_AVAILABLE))
@@ -189,7 +189,7 @@ void GameTypeVote_DrawGameTypeItem(vector pos, float maxh, float tsize, string g
 
 void MapVote_DrawMapItem(vector pos, float isize, float tsize, string map, string pic, float _count, int id)
 {
-    TC(int, id);
+       TC(int, id);
        vector img_size = '0 0 0';
        string label;
        float text_size;
@@ -264,7 +264,7 @@ void MapVote_DrawMapItem(vector pos, float isize, float tsize, string map, strin
 
 void MapVote_DrawAbstain(vector pos, float isize, float tsize, float _count, int id)
 {
-    TC(int, id);
+       TC(int, id);
        vector rgb;
        float text_size;
        string label;
@@ -281,7 +281,7 @@ void MapVote_DrawAbstain(vector pos, float isize, float tsize, float _count, int
 
 vector MapVote_GridVec(vector gridspec, int i, int m)
 {
-    TC(int, i); TC(int, m);
+       TC(int, i); TC(int, m);
        int r = i % m;
        return
                '1 0 0' * (gridspec.x * r)
@@ -491,7 +491,7 @@ void MapVote_Draw()
 
 void Cmd_MapVote_MapDownload(int argc)
 {
-    TC(int, argc);
+       TC(int, argc);
        entity pak;
 
        if(argc != 2 || !mv_pk3list)
@@ -522,7 +522,7 @@ void Cmd_MapVote_MapDownload(int argc)
 
 void MapVote_CheckPK3(string pic, string pk3, int id)
 {
-    TC(int, id);
+       TC(int, id);
        entity pak;
        pak = spawn();
        pak.netname = pk3;
@@ -544,7 +544,7 @@ void MapVote_CheckPK3(string pic, string pk3, int id)
 
 void MapVote_CheckPic(string pic, string pk3, int id)
 {
-    TC(int, id);
+       TC(int, id);
        // never try to retrieve a pic for the "don't care" 'map'
        if(mv_abstain && id == mv_num_maps - 1)
                return;
@@ -587,7 +587,7 @@ void MapVote_ReadMask()
 
 void MapVote_ReadOption(int i)
 {
-    TC(int, i);
+       TC(int, i);
        string map = strzone(ReadString());
        string pk3 = strzone(ReadString());
        int j = bound(0, ReadByte(), n_ssdirs - 1);
@@ -604,7 +604,7 @@ void MapVote_ReadOption(int i)
 
 void GameTypeVote_ReadOption(int i)
 {
-    TC(int, i);
+       TC(int, i);
        string gt = strzone(ReadString());
 
        mv_maps[i] = gt;
@@ -711,13 +711,13 @@ void MapVote_Init()
 
 void MapVote_SendChoice(int index)
 {
-    TC(int, index);
+       TC(int, index);
        localcmd(strcat("\nimpulse ", ftos(index+1), "\n"));
 }
 
 int MapVote_MoveLeft(int pos)
 {
-    TC(int, pos);
+       TC(int, pos);
        int imp;
        if ( pos < 0 )
                imp = mv_num_maps - 1;
@@ -729,7 +729,7 @@ int MapVote_MoveLeft(int pos)
 }
 int MapVote_MoveRight(int pos)
 {
-    TC(int, pos);
+       TC(int, pos);
        int imp;
        if ( pos < 0 )
                imp = 0;
@@ -741,7 +741,7 @@ int MapVote_MoveRight(int pos)
 }
 int MapVote_MoveUp(int pos)
 {
-    TC(int, pos);
+       TC(int, pos);
        int imp;
        if ( pos < 0 )
                imp = mv_num_maps - 1;
@@ -761,7 +761,7 @@ int MapVote_MoveUp(int pos)
 }
 int MapVote_MoveDown(int pos)
 {
-    TC(int, pos);
+       TC(int, pos);
        int imp;
        if ( pos < 0 )
                imp = 0;
@@ -778,7 +778,7 @@ int MapVote_MoveDown(int pos)
 
 float MapVote_InputEvent(int bInputType, float nPrimary, float nSecondary)
 {
-    TC(int, bInputType);
+       TC(int, bInputType);
        float imp;
 
        if (!mv_active)
index 01409280a4a4c9f535cf18e6c0f7f21b2eb1d8b0..360305601a8b71cfdd345436f213f9eafb5e50ee 100644 (file)
@@ -121,7 +121,7 @@ void RemoveTeam(entity Team)
 
 entity GetTeam(int Team, bool add)
 {
-    TC(int, Team); TC(bool, add);
+       TC(int, Team); TC(bool, add);
        int num = (Team == NUM_SPECTATOR) ? 16 : Team;
        if(teamslots[num])
                return teamslots[num];
@@ -553,7 +553,7 @@ void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector
 /** engine callback */
 void URI_Get_Callback(int id, int status, string data)
 {
-    TC(int, id); TC(int, status);
+       TC(int, id); TC(int, status);
        if(url_URI_Get_Callback(id, status, data))
        {
                // handled
index bb1b6f919b840c78a2bca6d339245e5b057acbc1..d9c9ab14210353a5490d4e9dc5deadde59763577 100644 (file)
@@ -83,7 +83,7 @@ void skeleton_markbones(entity e)
 
 void skel_set_boneabs(float s, int bone, vector absorg)
 {
-    TC(int, bone);
+       TC(int, bone);
        vector absang = fixedvectoangles2(v_forward, v_up);
 
        vector parentorg = skel_get_boneabs(s, skel_get_boneparent(s, bone));
@@ -113,7 +113,7 @@ void free_skeleton_from_frames(entity e)
 
 void skeleton_from_frames(entity e, bool is_dead)
 {
-    TC(bool, is_dead);
+       TC(bool, is_dead);
        float m = e.modelindex;
        if(!e.skeletonindex)
        {
index c5f1c2fb4b1468b1b50bf997f366987ce675c83f..5d40dbe04eeefb986630eb8c0dc0c8e5c09bf712 100644 (file)
@@ -149,7 +149,7 @@ void draw_teamradar_icon(vector coord, entity icon, entity pingdata, vector rgb,
 
 void draw_teamradar_link(vector start, vector end, int colors)
 {
-    TC(int, colors);
+       TC(int, colors);
        vector c0, c1, norm;
 
        start = teamradar_texcoord_to_2dcoord(teamradar_3dcoord_to_texcoord(start));
index 2538299475c3b43980a56483ca0995470d5fff97..a7fbe136825b960bb2718fc518183d5d259d8e47 100644 (file)
@@ -1568,7 +1568,7 @@ int lasthud;
 float vh_notice_time;
 void CSQC_UpdateView(entity this, float w, float h)
 {
-    TC(int, w); TC(int, h);
+       TC(int, w); TC(int, h);
        entity e;
        float fov;
        float f;
index 41b97694496616fa4de17b8f73aa2c163cb2fa6d..f4871e7fc6194803adf7fa2a8b9ec1276abc06c3 100644 (file)
@@ -171,7 +171,7 @@ void Projectile_Draw(entity this)
 
 void loopsound(entity e, int ch, Sound samp, float vol, float attn)
 {
-    TC(int, ch);
+       TC(int, ch);
        if (e.silent)
                return;
 
index 349d492da82b4169113ecde8989e764f06690f22..26308b89db807514f60b36ea236b14ccbc32fd9c 100644 (file)
@@ -8,6 +8,6 @@ CLASS(Command, Object)
        ATTRIB(Command, m_description, string);
        METHOD(Command, m_invokecmd, void(Command this, int request, entity caller, int arguments, string command))
        {
-        TC(Command, this);
+               TC(Command, this);
        }
 ENDCLASS(Command)
index 6439a49bb21ce32c6c64bbc8814f37dbb8f5520d..3b534ab781d0f7d8a4614a4534fe4f208a28899d 100644 (file)
@@ -258,6 +258,6 @@ entity EFFECT_ROCKETMINSTA_LASER(int teamid)
         case NUM_TEAM_4:    e = EFFECT_ROCKETMINSTA_LASER_PINK; break;
         default:            e = EFFECT_ROCKETMINSTA_LASER_NEUTRAL; break;
     }
-    if (particleeffectnum(e) < 0 || Team_TeamToNumber(teamid) == -1) { e = EFFECT_TR_NEXUIZPLASMA; }
+    if (particleeffectnum(e) < 0 || !Team_IsValidTeam(teamid)) { e = EFFECT_TR_NEXUIZPLASMA; }
     return e;
 }
index 710f03095b5402c0e837ec8e3e8867576067b9bd..bc048563e83e837df8cf5cc3301e35b9391085e3 100644 (file)
@@ -606,10 +606,10 @@ MUTATOR_HOOKFUNCTION(as, PlayHitsound)
        return (frag_victim.classname == "func_assault_destructible");
 }
 
-MUTATOR_HOOKFUNCTION(as, CheckAllowedTeams)
+MUTATOR_HOOKFUNCTION(as, TeamBalance_CheckAllowedTeams)
 {
        // assault always has 2 teams
-       c1 = c2 = 0;
+       M_ARGV(0, float) = BIT(0) | BIT(1);
        return true;
 }
 
index f4aea4357ddfc3fecd65e3feabafda49890c72e1..a81a23a51cef6363a1b219a49206806fb096fc34 100644 (file)
@@ -7,53 +7,64 @@ bool autocvar_g_ca_spectate_enemies;
 
 void CA_count_alive_players()
 {
-       total_players = redalive = bluealive = yellowalive = pinkalive = 0;
-       FOREACH_CLIENT(IS_PLAYER(it), {
-               switch(it.team)
+       total_players = 0;
+       for (int i = 1; i <= NUM_TEAMS; ++i)
+       {
+               Team_SetNumberOfAlivePlayers(Team_GetTeamFromIndex(i), 0);
+       }
+       FOREACH_CLIENT(IS_PLAYER(it) && Entity_HasValidTeam(it),
+       {
+               ++total_players;
+               if (IS_DEAD(it))
                {
-                       case NUM_TEAM_1: ++total_players; if(!IS_DEAD(it)) ++redalive; break;
-                       case NUM_TEAM_2: ++total_players; if(!IS_DEAD(it)) ++bluealive; break;
-                       case NUM_TEAM_3: ++total_players; if(!IS_DEAD(it)) ++yellowalive; break;
-                       case NUM_TEAM_4: ++total_players; if(!IS_DEAD(it)) ++pinkalive; break;
+                       continue;
                }
+               entity team_ = Entity_GetTeam(it);
+               int num_alive = Team_GetNumberOfAlivePlayers(team_);
+               ++num_alive;
+               Team_SetNumberOfAlivePlayers(team_, num_alive);
        });
-       FOREACH_CLIENT(IS_REAL_CLIENT(it), {
-               STAT(REDALIVE, it) = redalive;
-               STAT(BLUEALIVE, it) = bluealive;
-               STAT(YELLOWALIVE, it) = yellowalive;
-               STAT(PINKALIVE, it) = pinkalive;
+       FOREACH_CLIENT(IS_REAL_CLIENT(it),
+       {
+               STAT(REDALIVE, it) = Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(
+                       1));
+               STAT(BLUEALIVE, it) = Team_GetNumberOfAlivePlayers(
+                       Team_GetTeamFromIndex(2));
+               STAT(YELLOWALIVE, it) = Team_GetNumberOfAlivePlayers(
+                       Team_GetTeamFromIndex(3));
+               STAT(PINKALIVE, it) = Team_GetNumberOfAlivePlayers(
+                       Team_GetTeamFromIndex(4));
        });
 }
 
-float CA_GetWinnerTeam()
+int CA_GetWinnerTeam()
 {
-       float winner_team = 0;
-       if(redalive >= 1)
-               winner_team = NUM_TEAM_1;
-       if(bluealive >= 1)
+       int winner_team = 0;
+       if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(1)) >= 1)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_2;
+               winner_team = NUM_TEAM_1;
        }
-       if(yellowalive >= 1)
+       for (int i = 2; i <= NUM_TEAMS; ++i)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_3;
+               if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) >= 1)
+               {
+                       if (winner_team != 0)
+                       {
+                               return 0;
+                       }
+                       winner_team = Team_IndexToTeam(i);
+               }
        }
-       if(pinkalive >= 1)
+       if (winner_team)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_4;
-       }
-       if(winner_team)
                return winner_team;
+       }
        return -1; // no player left
 }
 
 void nades_Clear(entity player);
 
-#define CA_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0))
-#define CA_ALIVE_TEAMS_OK() (CA_ALIVE_TEAMS() == NumTeams(ca_teams))
+#define CA_ALIVE_TEAMS_OK() (Team_GetNumberOfAliveTeams() == NumTeams(ca_teams))
 float CA_CheckWinner()
 {
        if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
@@ -69,8 +80,10 @@ float CA_CheckWinner()
        }
 
        CA_count_alive_players();
-       if(CA_ALIVE_TEAMS() > 1)
+       if (Team_GetNumberOfAliveTeams() > 1)
+       {
                return 0;
+       }
 
        int winner_team = CA_GetWinnerTeam();
        if(winner_team > 0)
@@ -119,14 +132,14 @@ bool CA_CheckTeams()
                return false;
        }
        int missing_teams_mask = 0;
-       if(ca_teams & BIT(0))
-               missing_teams_mask += (!redalive) * 1;
-       if(ca_teams & BIT(1))
-               missing_teams_mask += (!bluealive) * 2;
-       if(ca_teams & BIT(2))
-               missing_teams_mask += (!yellowalive) * 4;
-       if(ca_teams & BIT(3))
-               missing_teams_mask += (!pinkalive) * 8;
+       for (int i = 1; i <= NUM_TEAMS; ++i)
+       {
+               if ((ca_teams & Team_IndexToBit(i)) &&
+                       (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) == 0))
+               {
+                       missing_teams_mask |= Team_IndexToBit(i);
+               }
+       }
        if(prev_missing_teams_mask != missing_teams_mask)
        {
                Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
@@ -232,9 +245,10 @@ MUTATOR_HOOKFUNCTION(ca, reset_map_global)
        return true;
 }
 
-MUTATOR_HOOKFUNCTION(ca, CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
+MUTATOR_HOOKFUNCTION(ca, TeamBalance_CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
 {
        M_ARGV(0, float) = ca_teams;
+       return true;
 }
 
 entity ca_LastPlayerForTeam(entity this)
index 855b043375c55568d6d92d4ec5da15bd98841a82..13d89c1be13c3c3f6537ee0f0592ee883f906c05 100644 (file)
@@ -2503,11 +2503,9 @@ MUTATOR_HOOKFUNCTION(ctf, HavocBot_ChooseRole)
        return true;
 }
 
-MUTATOR_HOOKFUNCTION(ctf, CheckAllowedTeams)
+MUTATOR_HOOKFUNCTION(ctf, TeamBalance_CheckAllowedTeams)
 {
-       //M_ARGV(0, float) = ctf_teams;
        M_ARGV(1, string) = "ctf_team";
-       return true;
 }
 
 MUTATOR_HOOKFUNCTION(ctf, SpectateCopy)
@@ -2733,7 +2731,6 @@ spawnfunc(team_CTL_bluelolly)  { spawnfunc_item_flag_team2(this);    }
 // scoreboard setup
 void ctf_ScoreRules(int teams)
 {
-       CheckAllowedTeams(NULL);
        GameRules_scoring(teams, SFL_SORT_PRIO_PRIMARY, 0, {
         field_team(ST_CTF_CAPS, "caps", SFL_SORT_PRIO_PRIMARY);
         field(SP_CTF_CAPS, "caps", SFL_SORT_PRIO_SECONDARY);
index e27a701c1591820393ac11e5efbb6829be271867..b8f08a5a1e09b35f28aa9d3e4ae6b852cd59d196 100644 (file)
@@ -297,47 +297,55 @@ void dom_controlpoint_setup(entity this)
        WaypointSprite_SpawnFixed(WP_DomNeut, this.origin + '0 0 32', this, sprite, RADARICON_DOMPOINT);
 }
 
-float total_controlpoints;
+int total_control_points;
 void Domination_count_controlpoints()
 {
-       total_controlpoints = redowned = blueowned = yellowowned = pinkowned = 0;
+       total_control_points = 0;
+       for (int i = 1; i <= NUM_TEAMS; ++i)
+       {
+               Team_SetNumberOfControlPoints(Team_GetTeamFromIndex(i), 0);
+       }
        IL_EACH(g_dompoints, true,
        {
-               ++total_controlpoints;
-               redowned += (it.goalentity.team == NUM_TEAM_1);
-               blueowned += (it.goalentity.team == NUM_TEAM_2);
-               yellowowned += (it.goalentity.team == NUM_TEAM_3);
-               pinkowned += (it.goalentity.team == NUM_TEAM_4);
+               ++total_control_points;
+               if (!Entity_HasValidTeam(it.goalentity))
+               {
+                       continue;
+               }
+               entity team_ = Entity_GetTeam(it.goalentity);
+               int num_control_points = Team_GetNumberOfControlPoints(team_);
+               ++num_control_points;
+               Team_SetNumberOfControlPoints(team_, num_control_points);
        });
 }
 
-float Domination_GetWinnerTeam()
+int Domination_GetWinnerTeam()
 {
-       float winner_team = 0;
-       if(redowned == total_controlpoints)
-               winner_team = NUM_TEAM_1;
-       if(blueowned == total_controlpoints)
+       int winner_team = 0;
+       if (Team_GetNumberOfControlPoints(Team_GetTeamFromIndex(1)) ==
+               total_control_points)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_2;
+               winner_team = NUM_TEAM_1;
        }
-       if(yellowowned == total_controlpoints)
+       for (int i = 2; i <= NUM_TEAMS; ++i)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_3;
+               if (Team_GetNumberOfControlPoints(Team_GetTeamFromIndex(i)) ==
+                       total_control_points)
+               {
+                       if (winner_team != 0)
+                       {
+                               return 0;
+                       }
+                       winner_team = Team_IndexToTeam(i);
+               }
        }
-       if(pinkowned == total_controlpoints)
+       if (winner_team)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_4;
-       }
-       if(winner_team)
                return winner_team;
+       }
        return -1; // no control points left?
 }
 
-#define DOM_OWNED_CONTROLPOINTS() ((redowned > 0) + (blueowned > 0) + (yellowowned > 0) + (pinkowned > 0))
-#define DOM_OWNED_CONTROLPOINTS_OK() (DOM_OWNED_CONTROLPOINTS() < total_controlpoints)
 float Domination_CheckWinner()
 {
        if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
@@ -417,7 +425,7 @@ void havocbot_role_dom(entity this)
        }
 }
 
-MUTATOR_HOOKFUNCTION(dom, CheckAllowedTeams)
+MUTATOR_HOOKFUNCTION(dom, TeamBalance_CheckAllowedTeams)
 {
        // fallback?
        M_ARGV(0, float) = domination_teams;
@@ -428,12 +436,9 @@ MUTATOR_HOOKFUNCTION(dom, CheckAllowedTeams)
        {
                if(head.netname != "")
                {
-                       switch(head.team)
+                       if (Team_IsValidTeam(head.team))
                        {
-                               case NUM_TEAM_1: c1 = 0; break;
-                               case NUM_TEAM_2: c2 = 0; break;
-                               case NUM_TEAM_3: c3 = 0; break;
-                               case NUM_TEAM_4: c4 = 0; break;
+                               M_ARGV(0, float) |= Team_TeamToBit(head.team);
                        }
                }
 
@@ -584,10 +589,10 @@ void ScoreRules_dom(int teams)
 }
 
 // code from here on is just to support maps that don't have control point and team entities
-void dom_spawnteam (string teamname, float teamcolor, string pointmodel, float pointskin, Sound capsound, string capnarration, string capmessage)
+void dom_spawnteam(string teamname, float teamcolor, string pointmodel, float pointskin, Sound capsound, string capnarration, string capmessage)
 {
-    TC(Sound, capsound);
-    entity e = new_pure(dom_team);
+       TC(Sound, capsound);
+       entity e = new_pure(dom_team);
        e.netname = strzone(teamname);
        e.cnt = teamcolor;
        e.model = pointmodel;
@@ -621,7 +626,7 @@ void dom_spawnpoint(vector org)
 // spawn some default teams if the map is not set up for domination
 void dom_spawnteams(int teams)
 {
-    TC(int, teams);
+       TC(int, teams);
        dom_spawnteam(Team_ColoredFullName(NUM_TEAM_1), NUM_TEAM_1-1, "models/domination/dom_red.md3", 0, SND_DOM_CLAIM, "", "Red team has captured a control point");
        dom_spawnteam(Team_ColoredFullName(NUM_TEAM_2), NUM_TEAM_2-1, "models/domination/dom_blue.md3", 0, SND_DOM_CLAIM, "", "Blue team has captured a control point");
        if(teams >= 3)
@@ -644,14 +649,9 @@ void dom_DelayedInit(entity this) // Do this check with a delay so we can wait f
                dom_spawnteams(domination_teams);
        }
 
-       CheckAllowedTeams(NULL);
-       //domination_teams = ((c4>=0) ? 4 : (c3>=0) ? 3 : 2);
-
-       int teams = 0;
-       if(c1 >= 0) teams |= BIT(0);
-       if(c2 >= 0) teams |= BIT(1);
-       if(c3 >= 0) teams |= BIT(2);
-       if(c4 >= 0) teams |= BIT(3);
+       entity balance = TeamBalance_CheckAllowedTeams(NULL);
+       int teams = TeamBalance_GetAllowedTeams(balance);
+       TeamBalance_Destroy(balance);
        domination_teams = teams;
 
        domination_roundbased = autocvar_g_domination_roundbased;
index 4d9175574b80ec79db6207523fb5fb7cc75ec5a4..6919518b8340ff1e65fa1f16d615eaed9eb7582b 100644 (file)
@@ -2,6 +2,7 @@
 
 // TODO: sv_freezetag
 #ifdef SVQC
+
 #include <server/resources.qh>
 
 float autocvar_g_freezetag_frozen_maxtime;
@@ -13,27 +14,40 @@ float autocvar_g_freezetag_warmup;
 
 void freezetag_count_alive_players()
 {
-       total_players = redalive = bluealive = yellowalive = pinkalive = 0;
-       FOREACH_CLIENT(IS_PLAYER(it), {
-               switch(it.team)
+       total_players = 0;
+       for (int i = 1; i <= NUM_TEAMS; ++i)
+       {
+               Team_SetNumberOfAlivePlayers(Team_GetTeamFromIndex(i), 0);
+       }
+       FOREACH_CLIENT(IS_PLAYER(it) && Entity_HasValidTeam(it),
+       {
+               ++total_players;
+               if ((GetResourceAmount(it, RESOURCE_HEALTH) < 1) ||
+                       (STAT(FROZEN, it) == 1))
                {
-                       case NUM_TEAM_1: ++total_players; if(STAT(FROZEN, it) != 1 && GetResourceAmount(it, RESOURCE_HEALTH) >= 1) ++redalive; break;
-                       case NUM_TEAM_2: ++total_players; if(STAT(FROZEN, it) != 1 && GetResourceAmount(it, RESOURCE_HEALTH) >= 1) ++bluealive; break;
-                       case NUM_TEAM_3: ++total_players; if(STAT(FROZEN, it) != 1 && GetResourceAmount(it, RESOURCE_HEALTH) >= 1) ++yellowalive; break;
-                       case NUM_TEAM_4: ++total_players; if(STAT(FROZEN, it) != 1 && GetResourceAmount(it, RESOURCE_HEALTH) >= 1) ++pinkalive; break;
+                       continue;
                }
+               entity team_ = Entity_GetTeam(it);
+               int num_alive = Team_GetNumberOfAlivePlayers(team_);
+               ++num_alive;
+               Team_SetNumberOfAlivePlayers(team_, num_alive);
        });
-       FOREACH_CLIENT(IS_REAL_CLIENT(it), {
-               STAT(REDALIVE, it) = redalive;
-               STAT(BLUEALIVE, it) = bluealive;
-               STAT(YELLOWALIVE, it) = yellowalive;
-               STAT(PINKALIVE, it) = pinkalive;
+       FOREACH_CLIENT(IS_REAL_CLIENT(it),
+       {
+               STAT(REDALIVE, it) = Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(
+                       1));
+               STAT(BLUEALIVE, it) = Team_GetNumberOfAlivePlayers(
+                       Team_GetTeamFromIndex(2));
+               STAT(YELLOWALIVE, it) = Team_GetNumberOfAlivePlayers(
+                       Team_GetTeamFromIndex(3));
+               STAT(PINKALIVE, it) = Team_GetNumberOfAlivePlayers(
+                       Team_GetTeamFromIndex(4));
        });
 
        eliminatedPlayers.SendFlags |= 1;
 }
-#define FREEZETAG_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0))
-#define FREEZETAG_ALIVE_TEAMS_OK() (FREEZETAG_ALIVE_TEAMS() == NumTeams(freezetag_teams))
+
+#define FREEZETAG_ALIVE_TEAMS_OK() (Team_GetNumberOfAliveTeams() == NumTeams(freezetag_teams))
 
 float freezetag_CheckTeams()
 {
@@ -53,14 +67,14 @@ float freezetag_CheckTeams()
                return 0;
        }
        int missing_teams_mask = 0;
-       if(freezetag_teams & BIT(0))
-               missing_teams_mask += (!redalive) * 1;
-       if(freezetag_teams & BIT(1))
-               missing_teams_mask += (!bluealive) * 2;
-       if(freezetag_teams & BIT(2))
-               missing_teams_mask += (!yellowalive) * 4;
-       if(freezetag_teams & BIT(3))
-               missing_teams_mask += (!pinkalive) * 8;
+       for (int i = 1; i <= NUM_TEAMS; ++i)
+       {
+               if ((freezetag_teams & Team_IndexToBit(i)) &&
+                       (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) == 0))
+               {
+                       missing_teams_mask |= Team_IndexToBit(i);
+               }
+       }
        if(prev_missing_teams_mask != missing_teams_mask)
        {
                Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
@@ -69,28 +83,28 @@ float freezetag_CheckTeams()
        return 0;
 }
 
-float freezetag_getWinnerTeam()
+int freezetag_getWinnerTeam()
 {
-       float winner_team = 0;
-       if(redalive >= 1)
-               winner_team = NUM_TEAM_1;
-       if(bluealive >= 1)
+       int winner_team = 0;
+       if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(1)) >= 1)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_2;
+               winner_team = NUM_TEAM_1;
        }
-       if(yellowalive >= 1)
+       for (int i = 2; i <= NUM_TEAMS; ++i)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_3;
+               if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) >= 1)
+               {
+                       if (winner_team != 0)
+                       {
+                               return 0;
+                       }
+                       winner_team = Team_IndexToTeam(i);
+               }
        }
-       if(pinkalive >= 1)
+       if (winner_team)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_4;
-       }
-       if(winner_team)
                return winner_team;
+       }
        return -1; // no player left
 }
 
@@ -112,8 +126,10 @@ float freezetag_CheckWinner()
                return 1;
        }
 
-       if(FREEZETAG_ALIVE_TEAMS() > 1)
+       if (Team_GetNumberOfAliveTeams() > 1)
+       {
                return 0;
+       }
 
        int winner_team = freezetag_getWinnerTeam();
        if(winner_team > 0)
@@ -559,9 +575,10 @@ MUTATOR_HOOKFUNCTION(ft, HavocBot_ChooseRole)
        return true;
 }
 
-MUTATOR_HOOKFUNCTION(ft, CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
+MUTATOR_HOOKFUNCTION(ft, TeamBalance_CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
 {
        M_ARGV(0, float) = freezetag_teams;
+       return true;
 }
 
 MUTATOR_HOOKFUNCTION(ft, SetWeaponArena)
index 3dff701959ef82c11f8f7e205daa3abfeb6af14b..00e2241c6866bf051135f891c3edb9433251b919 100644 (file)
@@ -548,9 +548,10 @@ MUTATOR_HOOKFUNCTION(inv, CheckRules_World)
        return true;
 }
 
-MUTATOR_HOOKFUNCTION(inv, CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
+MUTATOR_HOOKFUNCTION(inv, TeamBalance_CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
 {
        M_ARGV(0, float) = invasion_teams;
+       return true;
 }
 
 MUTATOR_HOOKFUNCTION(inv, AllowMobButcher)
@@ -561,7 +562,6 @@ MUTATOR_HOOKFUNCTION(inv, AllowMobButcher)
 
 void invasion_ScoreRules(int inv_teams)
 {
-       if(inv_teams) { CheckAllowedTeams(NULL); }
        GameRules_score_enabled(false);
        GameRules_scoring(inv_teams, 0, 0, {
            if (inv_teams) {
index 00eb886d5336b274398bb0739a51f9c6d8d1a78c..5af4c45b7ddc9b7752f5aee5eb8a0c194efe08e5 100644 (file)
@@ -1264,9 +1264,10 @@ MUTATOR_HOOKFUNCTION(kh, MatchEnd)
        kh_finalize();
 }
 
-MUTATOR_HOOKFUNCTION(kh, CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
+MUTATOR_HOOKFUNCTION(kh, TeamBalance_CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
 {
        M_ARGV(0, float) = kh_teams;
+       return true;
 }
 
 MUTATOR_HOOKFUNCTION(kh, SpectateCopy)
index 487012aa50902e7a834fdd708a7c0e45bb2928cc..89c53a82abc22eb1b7b4b8fc1a8784e8f5b6ea23 100644 (file)
@@ -635,7 +635,7 @@ void SpawnGoal(entity this)
 
        EXACTTRIGGER_INIT;
 
-       if(this.team != GOAL_OUT && Team_TeamToNumber(this.team) != -1)
+       if(this.team != GOAL_OUT && Team_IsValidTeam(this.team))
        {
                entity wp = WaypointSprite_SpawnFixed(WP_NbGoal, (this.absmin + this.absmax) * 0.5, this, sprite, RADARICON_NONE);
                wp.colormod = ((this.team) ? Team_ColorRGB(this.team) : '1 0.5 0');
@@ -920,7 +920,7 @@ MUTATOR_HOOKFUNCTION(nb, ItemTouch)
        return MUT_ITEMTOUCH_CONTINUE;
 }
 
-MUTATOR_HOOKFUNCTION(nb, CheckAllowedTeams)
+MUTATOR_HOOKFUNCTION(nb, TeamBalance_CheckAllowedTeams)
 {
        M_ARGV(1, string) = "nexball_team";
        return true;
index 9b175f179a7cc6ff0dc95de64cd6a4564c80fac0..6d719eb977c512997131382e30a0698e0fcd14c0 100644 (file)
@@ -1113,46 +1113,52 @@ int total_generators;
 void Onslaught_count_generators()
 {
        entity e;
-       total_generators = redowned = blueowned = yellowowned = pinkowned = 0;
+       total_generators = 0;
+       for (int i = 1; i <= NUM_TEAMS; ++i)
+       {
+               Team_SetNumberOfControlPoints(Team_GetTeamFromIndex(i), 0);
+       }
        for(e = ons_worldgeneratorlist; e; e = e.ons_worldgeneratornext)
        {
                ++total_generators;
-               redowned += (e.team == NUM_TEAM_1 && GetResourceAmount(e, RESOURCE_HEALTH) > 0);
-               blueowned += (e.team == NUM_TEAM_2 && GetResourceAmount(e, RESOURCE_HEALTH) > 0);
-               yellowowned += (e.team == NUM_TEAM_3 && GetResourceAmount(e, RESOURCE_HEALTH) > 0);
-               pinkowned += (e.team == NUM_TEAM_4 && GetResourceAmount(e, RESOURCE_HEALTH) > 0);
+               if (GetResourceAmount(e, RESOURCE_HEALTH) < 1)
+               {
+                       continue;
+               }
+               entity team_ = Entity_GetTeam(e);
+               int num_control_points = Team_GetNumberOfControlPoints(team_);
+               ++num_control_points;
+               Team_SetNumberOfControlPoints(team_, num_control_points);
        }
 }
 
 int Onslaught_GetWinnerTeam()
 {
        int winner_team = 0;
-       if(redowned > 0)
-               winner_team = NUM_TEAM_1;
-       if(blueowned > 0)
+       if (Team_GetNumberOfControlPoints(Team_GetTeamFromIndex(1)) >= 1)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_2;
+               winner_team = NUM_TEAM_1;
        }
-       if(yellowowned > 0)
+       for (int i = 2; i <= NUM_TEAMS; ++i)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_3;
+               if (Team_GetNumberOfControlPoints(Team_GetTeamFromIndex(i)) >= 1)
+               {
+                       if (winner_team != 0)
+                       {
+                               return 0;
+                       }
+                       winner_team = Team_IndexToTeam(i);
+               }
        }
-       if(pinkowned > 0)
+       if (winner_team)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_4;
-       }
-       if(winner_team)
                return winner_team;
+       }
        return -1; // no generators left?
 }
 
 void nades_Clear(entity e);
 
-#define ONS_OWNED_GENERATORS() ((redowned > 0) + (blueowned > 0) + (yellowowned > 0) + (pinkowned > 0))
-#define ONS_OWNED_GENERATORS_OK() (ONS_OWNED_GENERATORS() > 1)
 bool Onslaught_CheckWinner()
 {
        if ((autocvar_timelimit && time > game_starttime + autocvar_timelimit * 60) || (round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0))
@@ -1198,8 +1204,10 @@ bool Onslaught_CheckWinner()
 
        Onslaught_count_generators();
 
-       if(ONS_OWNED_GENERATORS_OK())
+       if (Team_GetNumberOfTeamsWithControlPoints() > 1)
+       {
                return 0;
+       }
 
        int winner_team = Onslaught_GetWinnerTeam();
 
@@ -1897,17 +1905,14 @@ MUTATOR_HOOKFUNCTION(ons, HavocBot_ChooseRole)
        return true;
 }
 
-MUTATOR_HOOKFUNCTION(ons, CheckAllowedTeams)
+MUTATOR_HOOKFUNCTION(ons, TeamBalance_CheckAllowedTeams)
 {
        // onslaught is special
        for(entity tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext)
        {
-               switch(tmp_entity.team)
+               if (Team_IsValidTeam(tmp_entity.team))
                {
-                       case NUM_TEAM_1: c1 = 0; break;
-                       case NUM_TEAM_2: c2 = 0; break;
-                       case NUM_TEAM_3: c3 = 0; break;
-                       case NUM_TEAM_4: c4 = 0; break;
+                       M_ARGV(0, float) |= Team_TeamToBit(tmp_entity.team);
                }
        }
 
@@ -2137,12 +2142,9 @@ spawnfunc(onslaught_generator)
 // scoreboard setup
 void ons_ScoreRules()
 {
-       CheckAllowedTeams(NULL);
-       int teams = 0;
-       if(c1 >= 0) teams |= BIT(0);
-       if(c2 >= 0) teams |= BIT(1);
-       if(c3 >= 0) teams |= BIT(2);
-       if(c4 >= 0) teams |= BIT(3);
+       entity balance = TeamBalance_CheckAllowedTeams(NULL);
+       int teams = TeamBalance_GetAllowedTeams(balance);
+       TeamBalance_Destroy(balance);
        GameRules_scoring(teams, SFL_SORT_PRIO_PRIMARY, 0, {
            field_team(ST_ONS_CAPS, "destroyed", SFL_SORT_PRIO_PRIMARY);
            field(SP_ONS_CAPS, "caps", SFL_SORT_PRIO_SECONDARY);
index c98e1b6a898ce0a309e69d079b5a43a0a84f883f..aaf83cb39bc9af705a4111bff581efed9b6dc5f6 100644 (file)
@@ -366,9 +366,10 @@ MUTATOR_HOOKFUNCTION(rc, ForbidPlayerScore_Clear)
                return true; // in qualifying, you don't lose score by observing
 }
 
-MUTATOR_HOOKFUNCTION(rc, CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
+MUTATOR_HOOKFUNCTION(rc, TeamBalance_CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
 {
        M_ARGV(0, float) = race_teams;
+       return true;
 }
 
 MUTATOR_HOOKFUNCTION(rc, Scores_CountFragsRemaining)
index 39e5fec1e19cd62fd7783252c3c5d81ea97ba89c..cf328902bf3aa866fef2bfad25846b5adf672605 100644 (file)
@@ -53,10 +53,9 @@ void tdm_DelayedInit(entity this)
        }
 }
 
-MUTATOR_HOOKFUNCTION(tdm, CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
+MUTATOR_HOOKFUNCTION(tdm, TeamBalance_CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
 {
        M_ARGV(1, string) = "tdm_team";
-       return true;
 }
 
 MUTATOR_HOOKFUNCTION(tdm, Scores_CountFragsRemaining)
index 979477cbafab6c676c4fdc7cabfeedf43134725b..ca1b6f8e74649e80c2b1ebe8c180871c00cef75e 100644 (file)
@@ -2,7 +2,6 @@
 
 // TODO: find a better location for these?
 float total_players;
-float redalive, bluealive, yellowalive, pinkalive;
 
 // todo: accept the number of teams as a parameter
 void GameRules_teams(bool value);
index 37d82e22ef72d9f1579d4056349bcf39f61d012a..3174fa7ff31ee4006231c4f45fbba5395619fe74 100644 (file)
@@ -2,12 +2,20 @@
 
 #ifdef SVQC
 
+.float m_chainsaw_damage; // accumulated damage of the missile as it passes trough enemies
+
 void W_OverkillRocketPropelledChainsaw_Explode(entity this, entity directhitentity)
 {
        this.event_damage = func_null;
        this.takedamage = DAMAGE_NO;
 
-       RadiusDamage(this, this.realowner, WEP_CVAR_PRI(okrpc, damage), WEP_CVAR_PRI(okrpc, edgedamage), WEP_CVAR_PRI(okrpc, radius), NULL, NULL, WEP_CVAR_PRI(okrpc, force), this.projectiledeathtype, this.weaponentity_fld, directhitentity);
+       float explosion_damage = RadiusDamage(this, this.realowner, WEP_CVAR_PRI(okrpc, damage), WEP_CVAR_PRI(okrpc, edgedamage), WEP_CVAR_PRI(okrpc, radius), NULL, NULL, WEP_CVAR_PRI(okrpc, force), this.projectiledeathtype, this.weaponentity_fld, directhitentity);
+       if (explosion_damage > 0 && this.m_chainsaw_damage > 0)
+       {
+               // if chainsaw hit something, it removed fired damage (so that direct hit is 100%)
+               // now that we also damaged something by explosion we'd go over 100% so let's add the fired damage back
+               accuracy_add(this.realowner, DEATH_WEAPONOF(this.projectiledeathtype).m_id, WEP_CVAR(okrpc, damage), 0);
+       }
 
        delete(this);
 }
@@ -53,8 +61,22 @@ void W_OverkillRocketPropelledChainsaw_Think(entity this)
        vector mydir = normalize(this.velocity);
 
        tracebox(this.origin, this.mins, this.maxs, this.origin + mydir * (2 * myspeed_accel), MOVE_NORMAL, this);
-       if(IS_PLAYER(trace_ent))
+       if (IS_PLAYER(trace_ent))
+       {
+               if (accuracy_isgooddamage(this.realowner, trace_ent))
+               {
+                       if (this.m_chainsaw_damage == 0) // first hit
+                       {
+                               // The fired damage of the explosion is already counted in the statistics (when launching the chainsaw).
+                               // We remove it here so that a direct hit that passes through and doesn't damage anything by the explosion later is still 100%.
+                               float fired_damage = WEP_CVAR_PRI(okrpc, damage2) - WEP_CVAR_PRI(okrpc, damage);
+                               float hit_damage = WEP_CVAR_PRI(okrpc, damage2);
+                               accuracy_add(this.realowner, DEATH_WEAPONOF(this.projectiledeathtype).m_id, fired_damage, hit_damage);
+                       }
+                       this.m_chainsaw_damage += WEP_CVAR_PRI(okrpc, damage2);
+               }
                Damage(trace_ent, this, this.realowner, WEP_CVAR_PRI(okrpc, damage2), this.projectiledeathtype, this.weaponentity_fld, this.origin, normalize(this.origin - trace_ent.origin) * WEP_CVAR_PRI(okrpc, force));
+       }
 
        this.velocity = mydir * (myspeed + (WEP_CVAR_PRI(okrpc, speedaccel) * sys_frametime));
 
@@ -106,6 +128,7 @@ void W_OverkillRocketPropelledChainsaw_Attack (Weapon thiswep, entity actor, .en
        SUB_SetFade (flash, time, 0.1);
        flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
        W_AttachToShotorg(actor, weaponentity, flash, '5 0 0');
+       missile.m_chainsaw_damage = 0;
 
        MUTATOR_CALLHOOK(EditProjectile, actor, missile);
 }
index d46ac9eafc7c36cccbeb07c7d302fe9b25f250d3..49cfb4488c9e478f7bf90dddf95c7787a143d62e 100644 (file)
@@ -128,7 +128,7 @@ CLASS(Sound, Object)
        }
        METHOD(Sound, sound_precache, void(Sound this))
        {
-           TC(Sound, this);
+               TC(Sound, this);
                string s = _Sound_fixpath(this.sound_str());
                if (!s) return;
                profile(sprintf("precache_sound(\"%s\")", s));
index 140b619c5ec09cae3f8c62fcf1e87bb6c4b61c2b..28ea1add9f998c8b52f9f463d6e7ca8bc73f50d2 100644 (file)
@@ -613,14 +613,18 @@ float adjust_respawntime(float normal_respawntime) {
                return normal_respawntime;
        }
 
-       CheckAllowedTeams(NULL);
-       GetTeamCounts(NULL);
+       entity balance = TeamBalance_CheckAllowedTeams(NULL);
+       TeamBalance_GetTeamCounts(balance, NULL);
        int players = 0;
-       if (c1 != -1) players += c1;
-       if (c2 != -1) players += c2;
-       if (c3 != -1) players += c3;
-       if (c4 != -1) players += c4;
-
+       for (int i = 1; i <= NUM_TEAMS; ++i)
+       {
+               if (TeamBalance_IsTeamAllowed(balance, i))
+               {
+                       players += TeamBalance_GetNumberOfPlayers(balance, i);
+               }
+       }
+       TeamBalance_Destroy(balance);
+       
        if (players >= 2) {
                return normal_respawntime * (r / (players + o) + l);
        } else {
index 57d644c0448549e13bff834f7cb6fd289d983cc3..1a2e1b1766febc7cb404dbe5e02f03bf1b2a7e71 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+const int NUM_TEAMS = 4; ///< Number of teams in the game.
+
 #ifdef TEAMNUMBERS_THAT_ARENT_STUPID
 const int NUM_TEAM_1 = 1;  // red
 const int NUM_TEAM_2 = 2; // blue
@@ -125,12 +127,12 @@ float Team_ColorToTeam(string team_color)
        return -1;
 }
 
-/// \brief Returns whether team is valid.
-/// \param[in] team_ Team to check.
+/// \brief Returns whether team value is valid.
+/// \param[in] team_num Team to check.
 /// \return True if team is valid, false otherwise.
-bool Team_IsValidTeam(int team_)
+bool Team_IsValidTeam(int team_num)
 {
-       switch (team_)
+       switch (team_num)
        {
                case NUM_TEAM_1:
                case NUM_TEAM_2:
@@ -143,12 +145,12 @@ bool Team_IsValidTeam(int team_)
        return false;
 }
 
-/// \brief Returns whether team number is valid.
-/// \param[in] number Team number to check.
-/// \return True if team number is valid, false otherwise.
-bool Team_IsValidNumber(int number)
+/// \brief Returns whether the team index is valid.
+/// \param[in] index Team index to check.
+/// \return True if team index is valid, false otherwise.
+bool Team_IsValidIndex(int index)
 {
-       switch (number)
+       switch (index)
        {
                case 1:
                case 2:
@@ -161,36 +163,60 @@ bool Team_IsValidNumber(int number)
        return false;
 }
 
-float Team_NumberToTeam(float number)
+/// \brief Converts team index into team value.
+/// \param[in] index Team index to convert.
+/// \return Team value.
+int Team_IndexToTeam(int index)
 {
-       switch(number)
+       switch (index)
        {
                case 1: return NUM_TEAM_1;
                case 2: return NUM_TEAM_2;
                case 3: return NUM_TEAM_3;
                case 4: return NUM_TEAM_4;
        }
-
        return -1;
 }
 
-float Team_TeamToNumber(float teamid)
+/// \brief Converts team value into team index.
+/// \param[in] team_num Team value to convert.
+/// \return Team index.
+int Team_TeamToIndex(int team_num)
 {
-       switch(teamid)
+       switch (team_num)
        {
                case NUM_TEAM_1: return 1;
                case NUM_TEAM_2: return 2;
                case NUM_TEAM_3: return 3;
                case NUM_TEAM_4: return 4;
        }
-
        return -1;
 }
 
+/// \brief Converts team value into bit value that is used in team bitmasks.
+/// \param[in] team_num Team value to convert.
+/// \return Team bit.
+int Team_TeamToBit(int team_num)
+{
+       if (!Team_IsValidTeam(team_num))
+       {
+               return 0;
+       }
+       return BIT(Team_TeamToIndex(team_num) - 1);
+}
+
+/// \brief Converts team index into bit value that is used in team bitmasks.
+/// \param[in] index Team index to convert.
+/// \return Team bit.
+int Team_IndexToBit(int index)
+{
+       return BIT(index - 1);
+}
+
 
 // legacy aliases for shitty code
-#define TeamByColor(teamid) (Team_TeamToNumber(teamid) - 1)
-#define ColorByTeam(number) Team_NumberToTeam(number + 1)
+#define TeamByColor(teamid) (Team_TeamToIndex(teamid) - 1)
+#define ColorByTeam(number) Team_IndexToTeam(number + 1)
 
 // useful aliases
 #define Team_ColorName_Lower(teamid) strtolower(Team_ColorName(teamid))
@@ -203,8 +229,8 @@ float Team_TeamToNumber(float teamid)
 #define Team_FullName(teamid) strcat(Team_ColorName(teamid), " ", NAME_TEAM, "^7")
 #define Team_ColoredFullName(teamid) strcat(Team_ColorCode(teamid), Team_ColorName(teamid), " ", NAME_TEAM, "^7")
 
-#define Team_NumberToFullName(number) Team_FullName(Team_NumberToTeam(number))
-#define Team_NumberToColoredFullName(number) Team_ColoredFullName(Team_NumberToTeam(number))
+#define Team_IndexToFullName(index) Team_FullName(Team_IndexToTeam(index))
+#define Team_IndexToColoredFullName(index) Team_ColoredFullName(Team_IndexToTeam(index))
 
 // replace these flags in a string with the strings provided
 #define TCR(input,type,team) strreplace("^TC", COL_TEAM_##team, strreplace("^TT", strtoupper(type##_TEAM_##team), input))
index b68aca16feddd93b6ea01b555b49aa6b17d2c53a..95ee419815a14a0741644b8a84ddcf6bd5ea3b97 100644 (file)
@@ -474,7 +474,7 @@ void turret_projectile_damage(entity this, entity inflictor, entity attacker, fl
 
 entity turret_projectile(entity actor, Sound _snd, float _size, float _health, float _death, float _proj_type, float _cull, float _cli_anim)
 {
-    TC(Sound, _snd);
+       TC(Sound, _snd);
        entity proj;
 
        sound (actor, CH_WEAPON_A, _snd, VOL_BASE, ATTEN_NORM);
index 51ac4bee45f3e035b19fc9895abfbce066e639e6..06c8484ff8eec45d17be6d3f18e0caaa6d1f2c5b 100644 (file)
@@ -21,7 +21,7 @@ float alarm2time;
 
 void vehicle_alarm(entity e, int ch, Sound s0und)
 {
-    TC(Sound, s0und);
+       TC(Sound, s0und);
        if(!autocvar_cl_vehicles_alarm)
                return;
 
index 214109c97b5fcbb8a45e4f73ddc46972b065f6c5..716dfe8d0c130225041502345a182873aa7c111f 100644 (file)
@@ -251,7 +251,7 @@ entity vehicles_projectile(entity this, string _mzlfx, Sound _mzlsound,
                                                   int _deahtype, float _projtype, float _health,
                                                   bool _cull, bool _clianim, entity _owner)
 {
-    TC(Sound, _mzlsound);
+       TC(Sound, _mzlsound);
        entity proj;
 
        proj = spawn();
index 3dfac622464a1144ed74096703108d0e9afa8251..841486f5837a9150cf730d77ef23a7d9c8443ca5 100644 (file)
@@ -45,14 +45,14 @@ ERASEABLE
 string CTX(string s)
 {
 #if CTX_CACHE
-               string c = HM_gets(CTX_cache, s);
-               if (c != "") return c;
+       string c = HM_gets(CTX_cache, s);
+       if (c != "") return c;
 #endif
        int p = strstrofs(s, "^", 0);
        string ret = (p < 0) ? s : substring(s, p + 1, -1);
 #if CTX_CACHE
-        LOG_DEBUGF("CTX(\"%s\")", s);
-               HM_sets(CTX_cache, s, ret);
+       LOG_DEBUGF("CTX(\"%s\")", s);
+       HM_sets(CTX_cache, s, ret);
 #endif
        return ret;
 }
index b22ff791501c9a990c93e5d9c7f3dabc2c35f661..e482d7d9ac9b1afab49ae9279ced927e0aa5ce4e 100644 (file)
@@ -326,7 +326,7 @@ CLASS(Object)
     #define remove(this) delete(this)
        METHOD(Object, describe, string(Object this))
        {
-           TC(Object, this);
+               TC(Object, this);
                string s = _("No description");
                if (cvar("developer"))
                {
@@ -340,7 +340,7 @@ CLASS(Object)
        }
        METHOD(Object, display, void(Object this, void(string name, string icon) returns))
        {
-           TC(Object, this);
+               TC(Object, this);
                returns(sprintf("entity %i", this), "nopreview_map");
        }
 ENDCLASS(Object)
index b3a143b9a7b02a6142dd7019694df6521957e153..f03bdfc74db470c44ba0927aef9383dd079d7bf1 100644 (file)
@@ -434,15 +434,15 @@ void bot_clientconnect(entity this)
        else if(this.bot_forced_team==4)
                this.team = NUM_TEAM_4;
        else
-               JoinBestTeam(this, true);
+               TeamBalance_JoinBestTeam(this, true);
 
        havocbot_setupbot(this);
 }
 
 void bot_removefromlargestteam()
 {
-       CheckAllowedTeams(NULL);
-       GetTeamCounts(NULL);
+       entity balance = TeamBalance_CheckAllowedTeams(NULL);
+       TeamBalance_GetTeamCounts(balance, NULL);
 
        entity best = NULL;
        float besttime = 0;
@@ -461,12 +461,10 @@ void bot_removefromlargestteam()
 
                int thiscount = 0;
 
-               switch(it.team)
+               if (Team_IsValidTeam(it.team))
                {
-                       case NUM_TEAM_1: thiscount = c1; break;
-                       case NUM_TEAM_2: thiscount = c2; break;
-                       case NUM_TEAM_3: thiscount = c3; break;
-                       case NUM_TEAM_4: thiscount = c4; break;
+                       thiscount = TeamBalance_GetNumberOfPlayers(balance,
+                               Team_TeamToIndex(it.team));
                }
 
                if(thiscount > bestcount)
@@ -481,6 +479,7 @@ void bot_removefromlargestteam()
                        best = it;
                }
        });
+       TeamBalance_Destroy(balance);
        if(!bcount)
                return; // no bots to remove
        currentbots = currentbots - 1;
index 9214900f36af170cce29422d8735673e91ff5779..53a203eb9dfee4fc835efdef4d4663be0f0f21c8 100644 (file)
@@ -287,10 +287,8 @@ void PutObserverInServer(entity this)
        if (mutator_returnvalue) {
            // mutator prevents resetting teams+score
        } else {
-               int oldteam = this.team;
-               this.team = -1;  // move this as it is needed to log the player spectating in eventlog
-               MUTATOR_CALLHOOK(Player_ChangedTeam, this, oldteam, this.team);
-        this.frags = FRAGS_SPECTATOR;
+               Player_SetTeamIndex(this, -1);
+               this.frags = FRAGS_SPECTATOR;
         PlayerScore_Clear(this);  // clear scores when needed
     }
 
@@ -302,7 +300,7 @@ void PutObserverInServer(entity this)
                        Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_CHAT_NOSPECTATORS);
 
                if(!CS(this).just_joined)
-                       LogTeamchange(this.playerid, -1, 4);
+                       LogTeamchange(this.playerid, -1, TEAM_CHANGE_SPECTATOR);
                else
                        CS(this).just_joined = false;
        }
@@ -521,7 +519,7 @@ void PutPlayerInServer(entity this)
        accuracy_resend(this);
 
        if (this.team < 0)
-               JoinBestTeam(this, true);
+               TeamBalance_JoinBestTeam(this, true);
 
        entity spot = SelectSpawnPoint(this, false);
        if (!spot) {
@@ -915,7 +913,7 @@ void ClientKill_Now_TeamChange(entity this)
 {
        if(this.killindicator_teamchange == -1)
        {
-               JoinBestTeam( this, true );
+               TeamBalance_JoinBestTeam(this, true);
        }
        else if(this.killindicator_teamchange == -2)
        {
@@ -1175,6 +1173,76 @@ void ClientPreConnect(entity this)
 }
 #endif
 
+string GetClientVersionMessage(entity this)
+{
+       if (CS(this).version_mismatch) {
+               if(CS(this).version < autocvar_gameversion) {
+                       return strcat("This is Xonotic ", autocvar_g_xonoticversion,
+                               "\n^3Your client version is outdated.\n\n\n### YOU WON'T BE ABLE TO PLAY ON THIS SERVER ###\n\n\nPlease update!!!^8");
+               } else {
+                       return strcat("This is Xonotic ", autocvar_g_xonoticversion,
+                               "\n^3This server is using an outdated Xonotic version.\n\n\n ### THIS SERVER IS INCOMPATIBLE AND THUS YOU CANNOT JOIN ###.^8");
+               }
+       } else {
+               return strcat("Welcome to Xonotic ", autocvar_g_xonoticversion);
+       }
+}
+
+string getwelcomemessage(entity this)
+{
+       MUTATOR_CALLHOOK(BuildMutatorsPrettyString, "");
+       string modifications = M_ARGV(0, string);
+
+       if(g_weaponarena)
+       {
+               if(g_weaponarena_random)
+                       modifications = strcat(modifications, ", ", ftos(g_weaponarena_random), " of ", g_weaponarena_list, " Arena");
+               else
+                       modifications = strcat(modifications, ", ", g_weaponarena_list, " Arena");
+       }
+       else if(cvar("g_balance_blaster_weaponstartoverride") == 0)
+               modifications = strcat(modifications, ", No start weapons");
+       if(cvar("sv_gravity") < stof(cvar_defstring("sv_gravity")))
+               modifications = strcat(modifications, ", Low gravity");
+       if(g_weapon_stay && !g_cts)
+               modifications = strcat(modifications, ", Weapons stay");
+       if(g_jetpack)
+               modifications = strcat(modifications, ", Jet pack");
+       if(autocvar_g_powerups == 0)
+               modifications = strcat(modifications, ", No powerups");
+       if(autocvar_g_powerups > 0)
+               modifications = strcat(modifications, ", Powerups");
+       modifications = substring(modifications, 2, strlen(modifications) - 2);
+
+       string versionmessage = GetClientVersionMessage(this);
+       string s = strcat(versionmessage, "^8\n^8\nmatch type is ^1", gamemode_name, "^8\n");
+
+       if(modifications != "")
+               s = strcat(s, "^8\nactive modifications: ^3", modifications, "^8\n");
+
+       if(cache_lastmutatormsg != autocvar_g_mutatormsg)
+       {
+               strcpy(cache_lastmutatormsg, autocvar_g_mutatormsg);
+               strcpy(cache_mutatormsg, cache_lastmutatormsg);
+       }
+
+       if (cache_mutatormsg != "") {
+               s = strcat(s, "\n\n^8special gameplay tips: ^7", cache_mutatormsg);
+       }
+
+       string mutator_msg = "";
+       MUTATOR_CALLHOOK(BuildGameplayTipsString, mutator_msg);
+       mutator_msg = M_ARGV(0, string);
+
+       s = strcat(s, mutator_msg); // trust that the mutator will do proper formatting
+
+       string motd = autocvar_sv_motd;
+       if (motd != "") {
+               s = strcat(s, "\n\n^8MOTD: ^7", strreplace("\\n", "\n", motd));
+       }
+       return s;
+}
+
 /**
 =============
 ClientConnect
@@ -1230,7 +1298,7 @@ void ClientConnect(entity this)
 
        int playerid_save = this.playerid;
        this.playerid = 0; // silent
-       JoinBestTeam(this, false); // if the team number is valid, keep it
+       TeamBalance_JoinBestTeam(this, false); // if the team number is valid, keep it
        this.playerid = playerid_save;
 
        TRANSMUTE(Observer, this);
@@ -1246,7 +1314,7 @@ void ClientConnect(entity this)
        if (autocvar_sv_eventlog)
                GameLogEcho(strcat(":join:", ftos(this.playerid), ":", ftos(etof(this)), ":", ((IS_REAL_CLIENT(this)) ? this.netaddress : "bot"), ":", playername(this, false)));
 
-       LogTeamchange(this.playerid, this.team, 1);
+       LogTeamchange(this.playerid, this.team, TEAM_CHANGE_CONNECT);
 
        CS(this).just_joined = true;  // stop spamming the eventlog with additional lines when the client connects
 
@@ -1266,12 +1334,9 @@ void ClientConnect(entity this)
        // notify about available teams
        if (teamplay)
        {
-               CheckAllowedTeams(this);
-               int t = 0;
-               if (c1 >= 0) t |= BIT(0);
-               if (c2 >= 0) t |= BIT(1);
-               if (c3 >= 0) t |= BIT(2);
-               if (c4 >= 0) t |= BIT(3);
+               entity balance = TeamBalance_CheckAllowedTeams(this);
+               int t = TeamBalance_GetAllowedTeams(balance);
+               TeamBalance_Destroy(balance);
                stuffcmd(this, sprintf("set _teams_available %d\n", t));
        }
        else
@@ -1523,7 +1588,7 @@ void DebugPrintToChatTeam(int team_num, string text)
 
 void play_countdown(entity this, float finished, Sound samp)
 {
-    TC(Sound, samp);
+       TC(Sound, samp);
        if(IS_REAL_CLIENT(this))
                if(floor(finished - time - frametime) != floor(finished - time))
                        if(finished - time < 6)
@@ -1803,7 +1868,7 @@ spectate mode routines
 
 void SpectateCopy(entity this, entity spectatee)
 {
-    TC(Client, this); TC(Client, spectatee);
+       TC(Client, this); TC(Client, spectatee);
 
        MUTATOR_CALLHOOK(SpectateCopy, spectatee, this);
        PS(this) = PS(spectatee);
@@ -2056,7 +2121,7 @@ void Join(entity this)
 
        if(!this.team_selected)
        if(autocvar_g_campaign || autocvar_g_balance_teams)
-               JoinBestTeam(this, true);
+               TeamBalance_JoinBestTeam(this, true);
 
        if(autocvar_g_campaign)
                campaign_bots_may_start = true;
@@ -2067,7 +2132,9 @@ void Join(entity this)
 
        if(IS_PLAYER(this))
        if(teamplay && this.team != -1)
-               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(this.team, INFO_JOIN_PLAY_TEAM), this.netname);
+       {
+               //Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(this.team, INFO_JOIN_PLAY_TEAM), this.netname);
+       }
        else
                Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_JOIN_PLAY, this.netname);
        this.team_selected = false;
index 9b7a0f6574fb78cf3636d8325b4bb7479f59ae47..0e6781e374120ba2c964ff7edd444715cb13b729 100644 (file)
@@ -394,13 +394,16 @@ void ClientCommand_selectteam(entity caller, float request, float argc)
                        if ((selection != -1) && autocvar_g_balance_teams &&
                                autocvar_g_balance_teams_prevent_imbalance)
                        {
-                               CheckAllowedTeams(caller);
-                               GetTeamCounts(caller);
-                               if ((BIT(Team_TeamToNumber(selection) - 1) & FindBestTeams(caller, false)) == 0)
+                               entity balance = TeamBalance_CheckAllowedTeams(caller);
+                               TeamBalance_GetTeamCounts(balance, caller);
+                               if ((Team_IndexToBit(Team_TeamToIndex(selection)) &
+                                       TeamBalance_FindBestTeams(balance, caller, false)) == 0)
                                {
                                        Send_Notification(NOTIF_ONE, caller, MSG_INFO, INFO_TEAMCHANGE_LARGERTEAM);
+                                       TeamBalance_Destroy(balance);
                                        return;
                                }
+                               TeamBalance_Destroy(balance);
                        }
                        ClientKill_TeamChange(caller, selection);
                        if (!IS_PLAYER(caller))
index 1076225d82acaf1e89a00432927c4c95b8593c34..9ba78c32a0546cce999d177a6649adfa8e0f42fb 100644 (file)
@@ -1057,6 +1057,7 @@ void GameCommand_moveplayer(float request, float argc)
 
                                                                // find the team to move the player to
                                                                team_id = Team_ColorToTeam(destination);
+                                                               entity balance;
                                                                if (team_id == client.team)  // already on the destination team
                                                                {
                                                                        // keep the forcing undone
@@ -1065,30 +1066,72 @@ void GameCommand_moveplayer(float request, float argc)
                                                                }
                                                                else if (team_id == 0)  // auto team
                                                                {
-                                                                       CheckAllowedTeams(client);
-                                                                       team_id = Team_NumberToTeam(FindSmallestTeam(client, false));
+                                                                       balance = TeamBalance_CheckAllowedTeams(client);
+                                                                       team_id = Team_IndexToTeam(TeamBalance_FindBestTeam(balance, client, false));
                                                                }
                                                                else
                                                                {
-                                                                       CheckAllowedTeams(client);
+                                                                       balance = TeamBalance_CheckAllowedTeams(client);
                                                                }
                                                                client.team_forced = save;
 
                                                                // Check to see if the destination team is even available
                                                                switch (team_id)
                                                                {
-                                                                       case NUM_TEAM_1: if (c1 == -1) { LOG_INFO("Sorry, can't move player to red team if it doesn't exist."); return; } break;
-                                                                       case NUM_TEAM_2: if (c2 == -1) { LOG_INFO("Sorry, can't move player to blue team if it doesn't exist."); return; } break;
-                                                                       case NUM_TEAM_3: if (c3 == -1) { LOG_INFO("Sorry, can't move player to yellow team if it doesn't exist."); return; } break;
-                                                                       case NUM_TEAM_4: if (c4 == -1) { LOG_INFO("Sorry, can't move player to pink team if it doesn't exist."); return; } break;
-
-                                                                       default: LOG_INFO("Sorry, can't move player here if team ", destination, " doesn't exist.");
+                                                                       case NUM_TEAM_1:
+                                                                       {
+                                                                               if (!TeamBalance_IsTeamAllowed(balance, 1))
+                                                                               {
+                                                                                       LOG_INFO("Sorry, can't move player to red team if it doesn't exist.");
+                                                                                       TeamBalance_Destroy(balance);
+                                                                                       return;
+                                                                               }
+                                                                               TeamBalance_Destroy(balance);
+                                                                               break;
+                                                                       }
+                                                                       case NUM_TEAM_2:
+                                                                       {
+                                                                               if (!TeamBalance_IsTeamAllowed(balance, 2))
+                                                                               {
+                                                                                       LOG_INFO("Sorry, can't move player to blue team if it doesn't exist.");
+                                                                                       TeamBalance_Destroy(balance);
+                                                                                       return;
+                                                                               }
+                                                                               TeamBalance_Destroy(balance);
+                                                                               break;
+                                                                       }
+                                                                       case NUM_TEAM_3:
+                                                                       {
+                                                                               if (!TeamBalance_IsTeamAllowed(balance, 3))
+                                                                               {
+                                                                                       LOG_INFO("Sorry, can't move player to yellow team if it doesn't exist.");
+                                                                                       TeamBalance_Destroy(balance);
+                                                                                       return;
+                                                                               }
+                                                                               TeamBalance_Destroy(balance);
+                                                                               break;
+                                                                       }
+                                                                       case NUM_TEAM_4:
+                                                                       {
+                                                                               if (!TeamBalance_IsTeamAllowed(balance, 4))
+                                                                               {
+                                                                                       LOG_INFO("Sorry, can't move player to pink team if it doesn't exist.");
+                                                                                       TeamBalance_Destroy(balance);
+                                                                                       return;
+                                                                               }
+                                                                               TeamBalance_Destroy(balance);
+                                                                               break;
+                                                                       }
+                                                                       default:
+                                                                       {
+                                                                               LOG_INFO("Sorry, can't move player here if team ", destination, " doesn't exist.");
                                                                                return;
+                                                                       }
                                                                }
 
                                                                // If so, lets continue and finally move the player
                                                                client.team_forced = 0;
-                                                               if (MoveToTeam(client, team_id, 6))
+                                                               if (MoveToTeam(client, Team_TeamToIndex(team_id), 6))
                                                                {
                                                                        successful = strcat(successful, (successful ? ", " : ""), playername(client, false));
                                                                        LOG_INFO("Player ", ftos(GetFilteredNumber(t)), " (", playername(client, false), ") has been moved to the ", Team_ColoredFullName(team_id), "^7.");
@@ -1279,16 +1322,23 @@ void GameCommand_shuffleteams(float request)
                        });
 
                        int number_of_teams = 0;
-                       CheckAllowedTeams(NULL);
-                       if (c1 >= 0) number_of_teams = max(1, number_of_teams);
-                       if (c2 >= 0) number_of_teams = max(2, number_of_teams);
-                       if (c3 >= 0) number_of_teams = max(3, number_of_teams);
-                       if (c4 >= 0) number_of_teams = max(4, number_of_teams);
+                       entity balance = TeamBalance_CheckAllowedTeams(NULL);
+                       for (int i = 1; i <= NUM_TEAMS; ++i)
+                       {
+                               if (TeamBalance_IsTeamAllowed(balance, i))
+                               {
+                                       number_of_teams = max(i, number_of_teams);
+                               }
+                       }
+                       TeamBalance_Destroy(balance);
 
                        int team_index = 0;
                        FOREACH_CLIENT_RANDOM(IS_PLAYER(it) || it.caplayer, {
-                               int target_team_number = Team_NumberToTeam(team_index + 1);
-                               if (it.team != target_team_number) MoveToTeam(it, target_team_number, 6);
+                               int target_team_index = team_index + 1;
+                               if (Entity_GetTeamIndex(it) != target_team_index)
+                               {
+                                       MoveToTeam(it, target_team_index, 6);
+                               }
                                team_index = (team_index + 1) % number_of_teams;
                        });
 
index 5f034f12f88534e9f644eeba88bed1351246ecb2..b990888e6a1e2fa6e49974e3507067cfe11b3220 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "../g_damage.qh"
 #include "../g_world.qh"
+#include "../teamplay.qh"
 #include "../race.qh"
 #include "../round_handler.qh"
 #include "../scores.qh"
index 4c23aaeb3b956f6706b8dcea57db48f1c4231f01..d2a695aeb988c274df6e478527ae09cfbee8f753 100644 (file)
@@ -27,8 +27,6 @@ float bots_would_leave;
 void UpdateFrags(entity player, int f);
 .float totalfrags;
 
-float team1_score, team2_score, team3_score, team4_score;
-
 // flag set on worldspawn so that the code knows if it is dedicated or not
 float server_is_dedicated;
 
@@ -231,8 +229,6 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
 // WEAPONTODO
 #define DMG_NOWEP (weaponentities[0])
 
-float lockteams;
-
 float sv_maxidle;
 float sv_maxidle_spectatorsareidle;
 int sv_maxidle_slots;
index 38284c30decd8a5b3adae3fbebe9039ef7e560ef..a25ae5bec9f878d9ba5feca5a6bb2f7e7c55bae6 100644 (file)
@@ -35,7 +35,7 @@ void UpdateFrags(entity player, int f)
        GameRules_scoring_add_team(player, SCORE, f);
 }
 
-void GiveFrags (entity attacker, entity targ, float f, int deathtype, .entity weaponentity)
+void GiveFrags(entity attacker, entity targ, float f, int deathtype, .entity weaponentity)
 {
        // TODO route through PlayerScores instead
        if(game_stopped) return;
@@ -566,7 +566,7 @@ void Unfreeze(entity targ)
        MUTATOR_CALLHOOK(Unfreeze, targ);
 }
 
-void Damage (entity targ, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
+void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
 {
        float complainteamdamage = 0;
        float mirrordamage = 0;
@@ -1040,9 +1040,9 @@ float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector in
                                                }
 
                                                if(targ == directhitentity || DEATH_ISSPECIAL(deathtype))
-                                                       Damage (targ, inflictor, attacker, finaldmg, deathtype, weaponentity, nearest, force);
+                                                       Damage(targ, inflictor, attacker, finaldmg, deathtype, weaponentity, nearest, force);
                                                else
-                                                       Damage (targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, weaponentity, nearest, force);
+                                                       Damage(targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, weaponentity, nearest, force);
                                        }
                                }
                        }
@@ -1058,9 +1058,9 @@ float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector in
        return total_damage_to_creatures;
 }
 
-float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype, .entity weaponentity, entity directhitentity)
+float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype, .entity weaponentity, entity directhitentity)
 {
-       return RadiusDamageForSource (inflictor, (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5), inflictor.velocity, attacker, coredamage, edgedamage, rad, cantbe, mustbe, false, forceintensity, deathtype, weaponentity, directhitentity);
+       return RadiusDamageForSource(inflictor, (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5), inflictor.velocity, attacker, coredamage, edgedamage, rad, cantbe, mustbe, false, forceintensity, deathtype, weaponentity, directhitentity);
 }
 
 bool Heal(entity targ, entity inflictor, float amount, float limit)
index 26a4cfb08685c3d16f58f8acd5416d693ed65b18..038936ee49282bff375700dd76159197aea86d8f 100644 (file)
@@ -16,6 +16,7 @@
 #include <server/mutators/_mod.qh>
 #include "race.qh"
 #include "scores.qh"
+#include "scores_rules.qh"
 #include "teamplay.qh"
 #include "weapons/weaponstats.qh"
 #include "../common/constants.qh"
@@ -578,6 +579,58 @@ STATIC_INIT_EARLY(maxclients)
        }
 }
 
+void default_delayedinit(entity this)
+{
+       if(!scores_initialized)
+               ScoreRules_generic();
+}
+
+void InitGameplayMode()
+{
+       VoteReset();
+
+       // find out good world mins/maxs bounds, either the static bounds found by looking for solid, or the mapinfo specified bounds
+       get_mi_min_max(1);
+       // assign reflectively to avoid "assignment to world" warning
+       int done = 0; for (int i = 0, n = numentityfields(); i < n; ++i) {
+           string k = entityfieldname(i); vector v = (k == "mins") ? mi_min : (k == "maxs") ? mi_max : '0 0 0';
+           if (v) {
+            putentityfieldstring(i, world, sprintf("%v", v));
+            if (++done == 2) break;
+        }
+       }
+       // currently, NetRadiant's limit is 131072 qu for each side
+       // distance from one corner of a 131072qu cube to the opposite corner is approx. 227023 qu
+       // set the distance according to map size but don't go over the limit to avoid issues with float precision
+       // in case somebody makes extremely large maps
+       max_shot_distance = min(230000, vlen(world.maxs - world.mins));
+
+       MapInfo_LoadMapSettings(mapname);
+       GameRules_teams(false);
+
+       if (!cvar_value_issafe(world.fog))
+       {
+               LOG_INFO("The current map contains a potentially harmful fog setting, ignored");
+               world.fog = string_null;
+       }
+       if(MapInfo_Map_fog != "")
+               if(MapInfo_Map_fog == "none")
+                       world.fog = string_null;
+               else
+                       world.fog = strzone(MapInfo_Map_fog);
+       clientstuff = strzone(MapInfo_Map_clientstuff);
+
+       MapInfo_ClearTemps();
+
+       gamemode_name = MapInfo_Type_ToText(MapInfo_LoadedGametype);
+
+       cache_mutatormsg = strzone("");
+       cache_lastmutatormsg = strzone("");
+
+       InitializeEntity(NULL, default_delayedinit, INITPRIO_GAMETYPE_FALLBACK);
+}
+
+void Map_MarkAsRecent(string m);
 float world_already_spawned;
 spawnfunc(worldspawn)
 {
@@ -1646,10 +1699,11 @@ float WinningCondition_Scores(float limit, float leadlimit)
 
        if(teamplay)
        {
-               team1_score = TeamScore_GetCompareValue(NUM_TEAM_1);
-               team2_score = TeamScore_GetCompareValue(NUM_TEAM_2);
-               team3_score = TeamScore_GetCompareValue(NUM_TEAM_3);
-               team4_score = TeamScore_GetCompareValue(NUM_TEAM_4);
+               for (int i = 1; i < 5; ++i)
+               {
+                       Team_SetTeamScore(Team_GetTeamFromIndex(i),
+                               TeamScore_GetCompareValue(Team_IndexToTeam(i)));
+               }
        }
 
        ClearWinners();
@@ -1719,30 +1773,32 @@ float WinningCondition_RanOutOfSpawns()
        if(!some_spawn_has_been_used)
                return WINNING_NO;
 
-       team1_score = team2_score = team3_score = team4_score = 0;
-
-       FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it), {
-               switch(it.team)
+       for (int i = 1; i < 5; ++i)
+       {
+               Team_SetTeamScore(Team_GetTeamFromIndex(i), 0);
+       }
+       
+       FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it),
+       {
+               if (Team_IsValidTeam(it.team))
                {
-                       case NUM_TEAM_1: team1_score = 1; break;
-                       case NUM_TEAM_2: team2_score = 1; break;
-                       case NUM_TEAM_3: team3_score = 1; break;
-                       case NUM_TEAM_4: team4_score = 1; break;
+                       Team_SetTeamScore(Team_GetTeam(it.team), 1);
                }
        });
 
        IL_EACH(g_spawnpoints, true,
        {
-               switch(it.team)
+               if (Team_IsValidTeam(it.team))
                {
-                       case NUM_TEAM_1: team1_score = 1; break;
-                       case NUM_TEAM_2: team2_score = 1; break;
-                       case NUM_TEAM_3: team3_score = 1; break;
-                       case NUM_TEAM_4: team4_score = 1; break;
+                       Team_SetTeamScore(Team_GetTeam(it.team), 1);
                }
        });
 
        ClearWinners();
+       float team1_score = Team_GetTeamScore(Team_GetTeamFromIndex(1));
+       float team2_score = Team_GetTeamScore(Team_GetTeamFromIndex(2));
+       float team3_score = Team_GetTeamScore(Team_GetTeamFromIndex(3));
+       float team4_score = Team_GetTeamScore(Team_GetTeamFromIndex(4));
        if(team1_score + team2_score + team3_score + team4_score == 0)
        {
                checkrules_equality = true;
@@ -1752,20 +1808,28 @@ float WinningCondition_RanOutOfSpawns()
        {
                float t, i;
                if(team1_score)
-                       t = NUM_TEAM_1;
+                       t = 1;
                else if(team2_score)
-                       t = NUM_TEAM_2;
+                       t = 2;
                else if(team3_score)
-                       t = NUM_TEAM_3;
+                       t = 3;
                else // if(team4_score)
-                       t = NUM_TEAM_4;
-               CheckAllowedTeams(NULL);
+                       t = 4;
+               entity balance = TeamBalance_CheckAllowedTeams(NULL);
                for(i = 0; i < MAX_TEAMSCORE; ++i)
                {
-                       if(t != NUM_TEAM_1) if(c1 >= 0) TeamScore_AddToTeam(NUM_TEAM_1, i, -1000);
-                       if(t != NUM_TEAM_2) if(c2 >= 0) TeamScore_AddToTeam(NUM_TEAM_2, i, -1000);
-                       if(t != NUM_TEAM_3) if(c3 >= 0) TeamScore_AddToTeam(NUM_TEAM_3, i, -1000);
-                       if(t != NUM_TEAM_4) if(c4 >= 0) TeamScore_AddToTeam(NUM_TEAM_4, i, -1000);
+                       for (int j = 1; j <= NUM_TEAMS; ++j)
+                       {
+                               if (t == j)
+                               {
+                                       continue;
+                               }
+                               if (!TeamBalance_IsTeamAllowed(balance, j))
+                               {
+                                       continue;
+                               }
+                               TeamScore_AddToTeam(Team_IndexToTeam(j), i, -1000);
+                       }
                }
 
                AddWinners(team, t);
index c0c35589a865f476ea08d006f5f43c2ab7996ac6..da950f18575e28a410fbed9955b90a0a5ced4ed7 100644 (file)
@@ -5,6 +5,9 @@ float checkrules_suddendeathwarning;
 float checkrules_suddendeathend;
 float checkrules_overtimesadded; //how many overtimes have been already added
 
+string cache_mutatormsg;
+string cache_lastmutatormsg;
+
 const int WINNING_NO = 0; // no winner, but time limits may terminate the game
 const int WINNING_YES = 1; // winner found
 const int WINNING_NEVER = 2; // no winner, enter overtime if time limit is reached
index a4cf9df8ef30cc5e6554f4403112a28723a07e84..58e9ca127dabb4fb3183616f7815885fcfafa861 100644 (file)
@@ -137,40 +137,51 @@ MUTATOR_HOOKABLE(GiveFragsForKill, EV_GiveFragsForKill);
 /** called when the match ends */
 MUTATOR_HOOKABLE(MatchEnd, EV_NO_ARGS);
 
-/** allows adjusting allowed teams */
-#define EV_CheckAllowedTeams(i, o) \
+/** Allows adjusting allowed teams. Return true to use the bitmask value and set
+ * non-empty string to use team entity name. Both behaviors can be active at the
+ * same time and will stack allowed teams.
+ */
+#define EV_TeamBalance_CheckAllowedTeams(i, o) \
     /** mask of teams      */ i(float, MUTATOR_ARGV_0_float) \
     /**/                      o(float, MUTATOR_ARGV_0_float) \
     /** team entity name   */ i(string, MUTATOR_ARGV_1_string) \
     /**/                      o(string, MUTATOR_ARGV_1_string) \
     /** player checked     */ i(entity, MUTATOR_ARGV_2_entity) \
     /**/
-MUTATOR_HOOKABLE(CheckAllowedTeams, EV_CheckAllowedTeams);
+MUTATOR_HOOKABLE(TeamBalance_CheckAllowedTeams,
+       EV_TeamBalance_CheckAllowedTeams);
 
 /** return true to manually override team counts */
-MUTATOR_HOOKABLE(GetTeamCounts, EV_NO_ARGS);
+MUTATOR_HOOKABLE(TeamBalance_GetTeamCounts, EV_NO_ARGS);
 
-/** allow overriding of team counts */
-#define EV_GetTeamCount(i, o) \
-    /** team to count                   */ i(float, MUTATOR_ARGV_0_float) \
+/** allows overriding of team counts */
+#define EV_TeamBalance_GetTeamCount(i, o) \
+    /** team index to count             */ i(float, MUTATOR_ARGV_0_float) \
     /** player to ignore                */ i(entity, MUTATOR_ARGV_1_entity) \
-    /** number of players in a team     */ i(float, MUTATOR_ARGV_2_float) \
-    /**/                                   o(float, MUTATOR_ARGV_2_float) \
-    /** number of bots in a team        */ i(float, MUTATOR_ARGV_3_float) \
-    /**/                                   o(float, MUTATOR_ARGV_3_float) \
-    /** lowest scoring human in a team  */ i(entity, MUTATOR_ARGV_4_entity) \
-    /**/                                   o(entity, MUTATOR_ARGV_4_entity) \
-    /** lowest scoring bot in a team    */ i(entity, MUTATOR_ARGV_5_entity) \
-    /**/                                   o(entity, MUTATOR_ARGV_5_entity) \
-    /**/
-MUTATOR_HOOKABLE(GetTeamCount, EV_GetTeamCount);
-
-/** allows overriding best teams */
-#define EV_FindBestTeams(i, o) \
+    /** number of players in a team     */ o(float, MUTATOR_ARGV_2_float) \
+    /** number of bots in a team        */ o(float, MUTATOR_ARGV_3_float) \
+    /**/
+MUTATOR_HOOKABLE(TeamBalance_GetTeamCount, EV_TeamBalance_GetTeamCount);
+
+/** allows overriding the teams that will make the game most balanced if the
+ *  player joins any of them.
+ */
+#define EV_TeamBalance_FindBestTeams(i, o) \
     /** player checked   */ i(entity, MUTATOR_ARGV_0_entity) \
     /** bitmask of teams */ o(float, MUTATOR_ARGV_1_float) \
     /**/
-MUTATOR_HOOKABLE(FindBestTeams, EV_FindBestTeams);
+MUTATOR_HOOKABLE(TeamBalance_FindBestTeams, EV_TeamBalance_FindBestTeams);
+
+/** Called during autobalance. Return true to override the player that will be
+switched. */
+#define EV_TeamBalance_GetPlayerForTeamSwitch(i, o) \
+    /** source team index      */ i(int, MUTATOR_ARGV_0_int) \
+    /** destination team index */ i(int, MUTATOR_ARGV_1_int) \
+    /** is looking for bot     */ i(bool, MUTATOR_ARGV_2_bool) \
+    /** player to switch       */ o(entity, MUTATOR_ARGV_3_entity) \
+    /**/
+MUTATOR_HOOKABLE(TeamBalance_GetPlayerForTeamSwitch,
+       EV_TeamBalance_GetPlayerForTeamSwitch);
 
 /** copies variables for spectating "spectatee" to "this" */
 #define EV_SpectateCopy(i, o) \
@@ -1041,9 +1052,9 @@ MUTATOR_HOOKABLE(MonsterModel, EV_MonsterModel);
  * Called before player changes their team. Return true to block team change.
  */
 #define EV_Player_ChangeTeam(i, o) \
-    /** player */         i(entity, MUTATOR_ARGV_0_entity) \
-       /** current team */   i(float, MUTATOR_ARGV_1_float) \
-       /** new team */       i(float, MUTATOR_ARGV_2_float) \
+    /** player */             i(entity, MUTATOR_ARGV_0_entity) \
+    /** current team index */ i(float, MUTATOR_ARGV_1_float) \
+    /** new team index */     i(float, MUTATOR_ARGV_2_float) \
     /**/
 MUTATOR_HOOKABLE(Player_ChangeTeam, EV_Player_ChangeTeam);
 
@@ -1051,9 +1062,9 @@ MUTATOR_HOOKABLE(Player_ChangeTeam, EV_Player_ChangeTeam);
  * Called after player has changed their team.
  */
 #define EV_Player_ChangedTeam(i, o) \
-    /** player */         i(entity, MUTATOR_ARGV_0_entity) \
-       /** old team */       i(float, MUTATOR_ARGV_1_float) \
-       /** current team */   i(float, MUTATOR_ARGV_2_float) \
+    /** player */             i(entity, MUTATOR_ARGV_0_entity) \
+    /** old team index */     i(float, MUTATOR_ARGV_1_float) \
+    /** current team index */ i(float, MUTATOR_ARGV_2_float) \
     /**/
 MUTATOR_HOOKABLE(Player_ChangedTeam, EV_Player_ChangedTeam);
 
index 5bd4b59894e964fcd6b0850a3f67232c8f38a79c..3755da96386ed98e6b10f9a754185a7f6b487951 100644 (file)
@@ -675,21 +675,6 @@ bool PlayerHeal(entity targ, entity inflictor, float amount, float limit)
        return true;
 }
 
-bool MoveToTeam(entity client, int team_colour, int type)
-{
-       int lockteams_backup = lockteams;  // backup any team lock
-       lockteams = 0;  // disable locked teams
-       TeamchangeFrags(client);  // move the players frags
-       if (!SetPlayerTeamSimple(client, team_colour))
-       {
-               return false;
-       }
-       Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE.m_id, DMG_NOWEP, client.origin, '0 0 0');  // kill the player
-       lockteams = lockteams_backup;  // restore the team lock
-       LogTeamchange(client.playerid, client.team, type);
-       return true;
-}
-
 /**
  * message "": do not say, just test flood control
  * return value:
index 8c9bac9b62aaa8e94ea4a594e33f6b680f67d74c..1c38a9fbebf3012b1d87029e26659457d7548a1c 100644 (file)
@@ -30,13 +30,6 @@ void calculate_player_respawn_time(entity this);
 
 void ClientKill_Now_TeamChange(entity this);
 
-/// \brief Moves player to the specified team.
-/// \param[in,out] client Client to move.
-/// \param[in] team_colour Color of the team.
-/// \param[in] type ???
-/// \return True on success, false otherwise.
-bool MoveToTeam(entity client, float team_colour, float type);
-
 void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force);
 
 bool PlayerHeal(entity targ, entity inflictor, float amount, float limit);
index 160b5df5e4cfb21c279b96c39d28dbe6965b27d4..39dbd49a35ddc630c85c849624330e1785d30d01 100644 (file)
@@ -17,8 +17,6 @@ int NumTeams(int teams)
 int AvailableTeams()
 {
        return NumTeams(ScoreRules_teams);
-       // NOTE: this method is unreliable, as forced teams set the c* globals to weird values
-       //return boolean(c1 >= 0) + boolean(c2 >= 0) + boolean(c3 >= 0) + boolean(c4 >= 0);
 }
 
 // NOTE: ST_constants may not be >= MAX_TEAMSCORE
@@ -64,12 +62,11 @@ void ScoreRules_basics_end()
 void ScoreRules_generic()
 {
     int teams = 0;
-       if (teamplay) {
-               CheckAllowedTeams(NULL);
-               if (c1 >= 0) teams |= BIT(0);
-               if (c2 >= 0) teams |= BIT(1);
-               if (c3 >= 0) teams |= BIT(2);
-               if (c4 >= 0) teams |= BIT(3);
+       if (teamplay)
+       {
+               entity balance = TeamBalance_CheckAllowedTeams(NULL);
+               teams = TeamBalance_GetAllowedTeams(balance);
+               TeamBalance_Destroy(balance);
        }
        GameRules_scoring(teams, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, {});
 }
index b0d9e0992eb921c204451f24b48877010c082369..25acdd3e01595b82a8f584c44bb8f8a72bf1e2d0 100644 (file)
 #include <common/gamemodes/_mod.qh>
 #include "../common/teams.qh"
 
-void TeamchangeFrags(entity e)
+/// \brief Describes a state of team balance entity.
+enum
 {
-       PlayerScore_Clear(e);
-}
+       TEAM_BALANCE_UNINITIALIZED, ///< The team balance has not been initialized.
+       /// \brief TeamBalance_CheckAllowedTeams has been called.
+       TEAM_BALANCE_TEAMS_CHECKED,
+       /// \brief TeamBalance_GetTeamCounts has been called.
+       TEAM_BALANCE_TEAM_COUNTS_FILLED
+};
 
-void LogTeamchange(float player_id, float team_number, float type)
-{
-       if(!autocvar_sv_eventlog)
-               return;
+/// \brief Indicates that the player is not allowed to join a team.
+const int TEAM_NOT_ALLOWED = -1;
 
-       if(player_id < 1)
-               return;
+.int m_team_balance_state; ///< Holds the state of the team balance entity.
+.entity m_team_balance_team[NUM_TEAMS]; ///< ???
 
-       GameLogEcho(strcat(":team:", ftos(player_id), ":", ftos(team_number), ":", ftos(type)));
-}
+.float m_team_score; ///< The score of the team.
+.int m_num_players; ///< Number of players (both humans and bots) in a team.
+.int m_num_bots; ///< Number of bots in a team.
+.int m_num_players_alive; ///< Number of alive players in a team.
+.int m_num_control_points; ///< Number of control points owned by a team.
+
+entity g_team_entities[NUM_TEAMS]; ///< Holds global team entities.
 
-void default_delayedinit(entity this)
+STATIC_INIT(g_team_entities)
 {
-       if(!scores_initialized)
-               ScoreRules_generic();
+       for (int i = 0; i < NUM_TEAMS; ++i)
+       {
+               g_team_entities[i] = spawn();
+       }
 }
 
-void InitGameplayMode()
+entity Team_GetTeamFromIndex(int index)
 {
-       VoteReset();
-
-       // find out good world mins/maxs bounds, either the static bounds found by looking for solid, or the mapinfo specified bounds
-       get_mi_min_max(1);
-       // assign reflectively to avoid "assignment to world" warning
-       int done = 0; for (int i = 0, n = numentityfields(); i < n; ++i) {
-           string k = entityfieldname(i); vector v = (k == "mins") ? mi_min : (k == "maxs") ? mi_max : '0 0 0';
-           if (v) {
-            putentityfieldstring(i, world, sprintf("%v", v));
-            if (++done == 2) break;
-        }
-       }
-       // currently, NetRadiant's limit is 131072 qu for each side
-       // distance from one corner of a 131072qu cube to the opposite corner is approx. 227023 qu
-       // set the distance according to map size but don't go over the limit to avoid issues with float precision
-       // in case somebody makes extremely large maps
-       max_shot_distance = min(230000, vlen(world.maxs - world.mins));
-
-       MapInfo_LoadMapSettings(mapname);
-       GameRules_teams(false);
-
-       if (!cvar_value_issafe(world.fog))
-       {
-               LOG_INFO("The current map contains a potentially harmful fog setting, ignored");
-               world.fog = string_null;
-       }
-       if(MapInfo_Map_fog != "")
-               if(MapInfo_Map_fog == "none")
-                       world.fog = string_null;
-               else
-                       world.fog = strzone(MapInfo_Map_fog);
-       clientstuff = strzone(MapInfo_Map_clientstuff);
-
-       MapInfo_ClearTemps();
-
-       gamemode_name = MapInfo_Type_ToText(MapInfo_LoadedGametype);
-
-       cache_mutatormsg = strzone("");
-       cache_lastmutatormsg = strzone("");
-
-       InitializeEntity(NULL, default_delayedinit, INITPRIO_GAMETYPE_FALLBACK);
+       if (!Team_IsValidIndex(index))
+       {
+               LOG_FATALF("Team_GetTeamFromIndex: Index is invalid: %f", index);
+       }
+       return g_team_entities[index - 1];
 }
 
-string GetClientVersionMessage(entity this)
+entity Team_GetTeam(int team_num)
 {
-       if (CS(this).version_mismatch) {
-               if(CS(this).version < autocvar_gameversion) {
-                       return strcat("This is Xonotic ", autocvar_g_xonoticversion,
-                               "\n^3Your client version is outdated.\n\n\n### YOU WON'T BE ABLE TO PLAY ON THIS SERVER ###\n\n\nPlease update!!!^8");
-               } else {
-                       return strcat("This is Xonotic ", autocvar_g_xonoticversion,
-                               "\n^3This server is using an outdated Xonotic version.\n\n\n ### THIS SERVER IS INCOMPATIBLE AND THUS YOU CANNOT JOIN ###.^8");
-               }
-       } else {
-               return strcat("Welcome to Xonotic ", autocvar_g_xonoticversion);
+       if (!Team_IsValidTeam(team_num))
+       {
+               LOG_FATALF("Team_GetTeam: Value is invalid: %f", team_num);
        }
+       return g_team_entities[Team_TeamToIndex(team_num) - 1];
 }
 
-string getwelcomemessage(entity this)
+float Team_GetTeamScore(entity team_ent)
 {
-       MUTATOR_CALLHOOK(BuildMutatorsPrettyString, "");
-       string modifications = M_ARGV(0, string);
+       return team_ent.m_team_score;
+}
 
-       if(g_weaponarena)
-       {
-               if(g_weaponarena_random)
-                       modifications = strcat(modifications, ", ", ftos(g_weaponarena_random), " of ", g_weaponarena_list, " Arena"); // TODO: somehow get this into the mutator
-               else
-                       modifications = strcat(modifications, ", ", g_weaponarena_list, " Arena");
-       }
-       else if(cvar("g_balance_blaster_weaponstartoverride") == 0)
-               modifications = strcat(modifications, ", No start weapons");
-       if(cvar("sv_gravity") < stof(cvar_defstring("sv_gravity")))
-               modifications = strcat(modifications, ", Low gravity");
-       if(g_weapon_stay && !g_cts)
-               modifications = strcat(modifications, ", Weapons stay");
-       if(g_jetpack)
-               modifications = strcat(modifications, ", Jetpack");
-       if(autocvar_g_powerups == 0)
-               modifications = strcat(modifications, ", No powerups");
-       if(autocvar_g_powerups > 0)
-               modifications = strcat(modifications, ", Powerups");
-       modifications = substring(modifications, 2, strlen(modifications) - 2);
+void Team_SetTeamScore(entity team_ent, float score)
+{
+       team_ent.m_team_score = score;
+}
 
-       string versionmessage = GetClientVersionMessage(this);
-       string s = strcat(versionmessage, "^8\n^8\nmatch type is ^1", gamemode_name, "^8\n");
+int Team_GetNumberOfAlivePlayers(entity team_ent)
+{
+       return team_ent.m_num_players_alive;
+}
 
-       if(modifications != "")
-               s = strcat(s, "^8\nactive modifications: ^3", modifications, "^8\n");
+void Team_SetNumberOfAlivePlayers(entity team_ent, int number)
+{
+       team_ent.m_num_players_alive = number;
+}
 
-       if(cache_lastmutatormsg != autocvar_g_mutatormsg)
+int Team_GetNumberOfAliveTeams()
+{
+       int result = 0;
+       for (int i = 0; i < NUM_TEAMS; ++i)
        {
-               strcpy(cache_lastmutatormsg, autocvar_g_mutatormsg);
-               strcpy(cache_mutatormsg, cache_lastmutatormsg);
-       }
-
-       if (cache_mutatormsg != "") {
-               s = strcat(s, "\n\n^8special gameplay tips: ^7", cache_mutatormsg);
+               if (g_team_entities[i].m_num_players_alive > 0)
+               {
+                       ++result;
+               }
        }
+       return result;
+}
 
-       string mutator_msg = "";
-       MUTATOR_CALLHOOK(BuildGameplayTipsString, mutator_msg);
-       mutator_msg = M_ARGV(0, string);
+int Team_GetNumberOfControlPoints(entity team_ent)
+{
+       return team_ent.m_num_control_points;
+}
 
-       s = strcat(s, mutator_msg); // trust that the mutator will do proper formatting
+void Team_SetNumberOfControlPoints(entity team_ent, int number)
+{
+       team_ent.m_num_control_points = number;
+}
 
-       string motd = autocvar_sv_motd;
-       if (motd != "") {
-               s = strcat(s, "\n\n^8MOTD: ^7", strreplace("\\n", "\n", motd));
+int Team_GetNumberOfTeamsWithControlPoints()
+{
+       int result = 0;
+       for (int i = 0; i < NUM_TEAMS; ++i)
+       {
+               if (g_team_entities[i].m_num_control_points > 0)
+               {
+                       ++result;
+               }
        }
-       return s;
+       return result;
 }
 
 void setcolor(entity this, int clr)
@@ -162,6 +131,26 @@ void setcolor(entity this, int clr)
 #endif
 }
 
+bool Entity_HasValidTeam(entity this)
+{
+       return Team_IsValidTeam(this.team);
+}
+
+int Entity_GetTeamIndex(entity this)
+{
+       return Team_TeamToIndex(this.team);
+}
+
+entity Entity_GetTeam(entity this)
+{
+       int index = Entity_GetTeamIndex(this);
+       if (!Team_IsValidIndex(index))
+       {
+               return NULL;
+       }
+       return Team_GetTeamFromIndex(index);
+}
+
 void SetPlayerColors(entity player, float _color)
 {
        float pants = _color & 0x0F;
@@ -176,748 +165,720 @@ void SetPlayerColors(entity player, float _color)
        }
 }
 
-void KillPlayerForTeamChange(entity player)
+bool Player_SetTeamIndex(entity player, int index)
 {
-       if (IS_DEAD(player))
+       int new_team = Team_IndexToTeam(index);
+       if (player.team == new_team)
        {
-               return;
+               if (new_team != -1)
+               {
+                       // This is important when players join the game and one of their
+                       // color matches the team color while other doesn't. For example
+                       // [BOT]Lion.
+                       SetPlayerColors(player, new_team - 1);
+               }
+               return true;
        }
-       if (MUTATOR_CALLHOOK(Player_ChangeTeamKill, player) == true)
+       int old_index = Team_TeamToIndex(player.team);
+       if (MUTATOR_CALLHOOK(Player_ChangeTeam, player, old_index, index) == true)
        {
-               return;
+               // Mutator has blocked team change.
+               return false;
        }
-       Damage(player, player, player, 100000, DEATH_TEAMCHANGE.m_id, DMG_NOWEP, player.origin,
-               '0 0 0');
+       if (new_team == -1)
+       {
+               player.team = -1;
+       }
+       else
+       {
+               SetPlayerColors(player, new_team - 1);
+       }
+       MUTATOR_CALLHOOK(Player_ChangedTeam, player, old_index, index);
+       return true;
 }
 
-bool SetPlayerTeamSimple(entity player, int team_num)
+bool SetPlayerTeam(entity player, int team_index, int type)
 {
-       if (player.team == team_num)
+       int old_team_index = Entity_GetTeamIndex(player);
+       if (!Player_SetTeamIndex(player, team_index))
        {
-               // This is important when players join the game and one of their color
-               // matches the team color while other doesn't. For example [BOT]Lion.
-               SetPlayerColors(player, team_num - 1);
-               return true;
+               return false;
        }
-       if (MUTATOR_CALLHOOK(Player_ChangeTeam, player, Team_TeamToNumber(
-               player.team), Team_TeamToNumber(team_num)) == true)
+       LogTeamchange(player.playerid, player.team, type);
+       if (team_index != old_team_index)
        {
-               // Mutator has blocked team change.
-               return false;
+               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(player.team,
+                       INFO_JOIN_PLAY_TEAM), player.netname);
+               KillPlayerForTeamChange(player);
        }
-       int old_team = player.team;
-       SetPlayerColors(player, team_num - 1);
-       MUTATOR_CALLHOOK(Player_ChangedTeam, player, old_team, player.team);
        return true;
 }
 
-bool SetPlayerTeam(entity player, int destination_team, int source_team,
-       bool no_print)
+bool MoveToTeam(entity client, int team_index, int type)
 {
-       int team_num = Team_NumberToTeam(destination_team);
-       if (!SetPlayerTeamSimple(player, team_num))
+       //PrintToChatAll(sprintf("MoveToTeam: %s, %f", client.netname, team_index));
+       int lockteams_backup = lockteams;  // backup any team lock
+       lockteams = 0;  // disable locked teams
+       PlayerScore_Clear(client);
+       if (!SetPlayerTeam(client, team_index, type))
        {
+               lockteams = lockteams_backup;  // restore the team lock
                return false;
        }
-       LogTeamchange(player.playerid, player.team, 3);  // log manual team join
-       if (no_print)
+       lockteams = lockteams_backup;  // restore the team lock
+       return true;
+}
+
+void KillPlayerForTeamChange(entity player)
+{
+       if (IS_DEAD(player))
        {
-               return true;
+               return;
        }
-       bprint(playername(player, false), "^7 has changed from ", Team_NumberToColoredFullName(source_team), "^7 to ", Team_NumberToColoredFullName(destination_team), "\n");
-       return true;
+       if (MUTATOR_CALLHOOK(Player_ChangeTeamKill, player) == true)
+       {
+               return;
+       }
+       Damage(player, player, player, 100000, DEATH_TEAMCHANGE.m_id, DMG_NOWEP,
+               player.origin, '0 0 0');
 }
 
-// set c1...c4 to show what teams are allowed
-void CheckAllowedTeams(entity for_whom)
+void LogTeamchange(float player_id, float team_number, int type)
 {
-       int teams_mask = 0;
+       if(!autocvar_sv_eventlog)
+               return;
 
-       c1 = c2 = c3 = c4 = -1;
-       num_bots_team1 = num_bots_team2 = num_bots_team3 = num_bots_team4 = 0;
+       if(player_id < 1)
+               return;
 
-       string teament_name = string_null;
+       GameLogEcho(strcat(":team:", ftos(player_id), ":", ftos(team_number), ":", ftos(type)));
+}
 
-       bool mutator_returnvalue = MUTATOR_CALLHOOK(CheckAllowedTeams, teams_mask, teament_name, for_whom);
+entity TeamBalance_CheckAllowedTeams(entity for_whom)
+{
+       entity balance = spawn();
+       for (int i = 0; i < NUM_TEAMS; ++i)
+       {
+               entity team_ent = balance.m_team_balance_team[i] = spawn();
+               team_ent.m_team_score = g_team_entities[i].m_team_score;
+               team_ent.m_num_players = TEAM_NOT_ALLOWED;
+               team_ent.m_num_bots = 0;
+       }
+       setthink(balance, TeamBalance_Destroy);
+       
+       int teams_mask = 0;     
+       string teament_name = string_null;
+       bool mutator_returnvalue = MUTATOR_CALLHOOK(TeamBalance_CheckAllowedTeams,
+               teams_mask, teament_name, for_whom);
        teams_mask = M_ARGV(0, float);
        teament_name = M_ARGV(1, string);
-
-       if(!mutator_returnvalue)
+       if (mutator_returnvalue)
        {
-               if(teams_mask & BIT(0)) c1 = 0;
-               if(teams_mask & BIT(1)) c2 = 0;
-               if(teams_mask & BIT(2)) c3 = 0;
-               if(teams_mask & BIT(3)) c4 = 0;
+               for (int i = 0; i < NUM_TEAMS; ++i)
+               {
+                       if (teams_mask & BIT(i))
+                       {
+                               balance.m_team_balance_team[i].m_num_players = 0;
+                       }
+               }
        }
 
-       // find out what teams are allowed if necessary
-       if(teament_name)
+       if (teament_name)
        {
                entity head = find(NULL, classname, teament_name);
-               while(head)
+               while (head)
                {
-                       switch(head.team)
+                       if (Team_IsValidTeam(head.team))
                        {
-                               case NUM_TEAM_1: c1 = 0; break;
-                               case NUM_TEAM_2: c2 = 0; break;
-                               case NUM_TEAM_3: c3 = 0; break;
-                               case NUM_TEAM_4: c4 = 0; break;
+                               TeamBalance_GetTeam(balance, head.team).m_num_players = 0;
                        }
-
                        head = find(head, classname, teament_name);
                }
        }
 
        // TODO: Balance quantity of bots across > 2 teams when bot_vs_human is set (and remove next line)
-       if(AvailableTeams() == 2)
-       if(autocvar_bot_vs_human && for_whom)
+       if (AvailableTeams() == 2)
+       if (autocvar_bot_vs_human && for_whom)
        {
-               if(autocvar_bot_vs_human > 0)
+               if (autocvar_bot_vs_human > 0)
                {
                        // find last team available
-
-                       if(IS_BOT_CLIENT(for_whom))
+                       if (IS_BOT_CLIENT(for_whom))
                        {
-                               if(c4 >= 0) { c3 = c2 = c1 = -1; }
-                               else if(c3 >= 0) { c4 = c2 = c1 = -1; }
-                               else { c4 = c3 = c1 = -1; }
+                               if (TeamBalance_IsTeamAllowedInternal(balance, 4))
+                               {
+                                       TeamBalance_BanTeamsExcept(balance, 4);
+                               }
+                               else if (TeamBalance_IsTeamAllowedInternal(balance, 3))
+                               {
+                                       TeamBalance_BanTeamsExcept(balance, 3);
+                               }
+                               else
+                               {
+                                       TeamBalance_BanTeamsExcept(balance, 2);
+                               }
                                // no further cases, we know at least 2 teams exist
                        }
                        else
                        {
-                               if(c1 >= 0) { c2 = c3 = c4 = -1; }
-                               else if(c2 >= 0) { c1 = c3 = c4 = -1; }
-                               else { c1 = c2 = c4 = -1; }
+                               if (TeamBalance_IsTeamAllowedInternal(balance, 1))
+                               {
+                                       TeamBalance_BanTeamsExcept(balance, 1);
+                               }
+                               else if (TeamBalance_IsTeamAllowedInternal(balance, 2))
+                               {
+                                       TeamBalance_BanTeamsExcept(balance, 2);
+                               }
+                               else
+                               {
+                                       TeamBalance_BanTeamsExcept(balance, 3);
+                               }
                                // no further cases, bots have one of the teams
                        }
                }
                else
                {
                        // find first team available
-
-                       if(IS_BOT_CLIENT(for_whom))
+                       if (IS_BOT_CLIENT(for_whom))
                        {
-                               if(c1 >= 0) { c2 = c3 = c4 = -1; }
-                               else if(c2 >= 0) { c1 = c3 = c4 = -1; }
-                               else { c1 = c2 = c4 = -1; }
+                               if (TeamBalance_IsTeamAllowedInternal(balance, 1))
+                               {
+                                       TeamBalance_BanTeamsExcept(balance, 1);
+                               }
+                               else if (TeamBalance_IsTeamAllowedInternal(balance, 2))
+                               {
+                                       TeamBalance_BanTeamsExcept(balance, 2);
+                               }
+                               else
+                               {
+                                       TeamBalance_BanTeamsExcept(balance, 3);
+                               }
                                // no further cases, we know at least 2 teams exist
                        }
                        else
                        {
-                               if(c4 >= 0) { c3 = c2 = c1 = -1; }
-                               else if(c3 >= 0) { c4 = c2 = c1 = -1; }
-                               else { c4 = c3 = c1 = -1; }
+                               if (TeamBalance_IsTeamAllowedInternal(balance, 4))
+                               {
+                                       TeamBalance_BanTeamsExcept(balance, 4);
+                               }
+                               else if (TeamBalance_IsTeamAllowedInternal(balance, 3))
+                               {
+                                       TeamBalance_BanTeamsExcept(balance, 3);
+                               }
+                               else
+                               {
+                                       TeamBalance_BanTeamsExcept(balance, 2);
+                               }
                                // no further cases, bots have one of the teams
                        }
                }
        }
 
-       if(!for_whom)
-               return;
+       if (!for_whom)
+       {
+               balance.m_team_balance_state = TEAM_BALANCE_TEAMS_CHECKED;
+               return balance;
+       }
 
        // if player has a forced team, ONLY allow that one
-       if(for_whom.team_forced == NUM_TEAM_1 && c1 >= 0)
-               c2 = c3 = c4 = -1;
-       else if(for_whom.team_forced == NUM_TEAM_2 && c2 >= 0)
-               c1 = c3 = c4 = -1;
-       else if(for_whom.team_forced == NUM_TEAM_3 && c3 >= 0)
-               c1 = c2 = c4 = -1;
-       else if(for_whom.team_forced == NUM_TEAM_4 && c4 >= 0)
-               c1 = c2 = c3 = -1;
+       for (int i = 1; i <= NUM_TEAMS; ++i)
+       {
+               if (for_whom.team_forced == Team_IndexToTeam(i) &&
+                       TeamBalance_IsTeamAllowedInternal(balance, i))
+               {
+                       TeamBalance_BanTeamsExcept(balance, i);
+               }
+               break;
+       }
+       balance.m_team_balance_state = TEAM_BALANCE_TEAMS_CHECKED;
+       return balance;
 }
 
-float PlayerValue(entity p)
+void TeamBalance_Destroy(entity balance)
 {
-       return 1;
-       // FIXME: it always returns 1...
+       if (balance == NULL)
+       {
+               return;
+       }
+       for (int i = 0; i < NUM_TEAMS; ++i)
+       {
+               delete(balance.(m_team_balance_team[i]));
+       }
+       delete(balance);
 }
 
-// c1...c4 should be set to -1 (not allowed) or 0 (allowed).
-// teams that are allowed will now have their player counts stored in c1...c4
-void GetTeamCounts(entity ignore)
+int TeamBalance_GetAllowedTeams(entity balance)
 {
-       if (MUTATOR_CALLHOOK(GetTeamCounts) == true)
+       if (balance == NULL)
        {
-               if (c1 >= 0)
-               {
-                       MUTATOR_CALLHOOK(GetTeamCount, NUM_TEAM_1, ignore, c1,
-                               num_bots_team1, lowest_human_team1, lowest_bot_team1);
-                       c1 = M_ARGV(2, float);
-                       num_bots_team1 = M_ARGV(3, float);
-                       lowest_human_team1 = M_ARGV(4, entity);
-                       lowest_bot_team1 = M_ARGV(5, entity);
-               }
-               if (c2 >= 0)
-               {
-                       MUTATOR_CALLHOOK(GetTeamCount, NUM_TEAM_2, ignore, c2,
-                               num_bots_team2, lowest_human_team2, lowest_bot_team2);
-                       c2 = M_ARGV(2, float);
-                       num_bots_team2 = M_ARGV(3, float);
-                       lowest_human_team2 = M_ARGV(4, entity);
-                       lowest_bot_team2 = M_ARGV(5, entity);
-               }
-               if (c3 >= 0)
+               LOG_FATAL("TeamBalance_GetAllowedTeams: Team balance entity is NULL.");
+       }
+       if (balance.m_team_balance_state == TEAM_BALANCE_UNINITIALIZED)
+       {
+               LOG_FATAL("TeamBalance_GetAllowedTeams: "
+                       "Team balance entity is not initialized.");
+       }
+       int result = 0;
+       for (int i = 1; i <= NUM_TEAMS; ++i)
+       {
+               if (TeamBalance_IsTeamAllowedInternal(balance, i))
                {
-                       MUTATOR_CALLHOOK(GetTeamCount, NUM_TEAM_3, ignore, c3,
-                               num_bots_team3, lowest_human_team3, lowest_bot_team3);
-                       c3 = M_ARGV(2, float);
-                       num_bots_team3 = M_ARGV(3, float);
-                       lowest_human_team3 = M_ARGV(4, entity);
-                       lowest_bot_team3 = M_ARGV(5, entity);
+                       result |= Team_IndexToBit(i);
                }
-               if (c4 >= 0)
+       }
+       return result;
+}
+
+bool TeamBalance_IsTeamAllowed(entity balance, int index)
+{
+       if (balance == NULL)
+       {
+               LOG_FATAL("TeamBalance_IsTeamAllowed: Team balance entity is NULL.");
+       }
+       if (balance.m_team_balance_state == TEAM_BALANCE_UNINITIALIZED)
+       {
+               LOG_FATAL("TeamBalance_IsTeamAllowed: "
+                       "Team balance entity is not initialized.");
+       }
+       if (!Team_IsValidIndex(index))
+       {
+               LOG_FATALF("TeamBalance_IsTeamAllowed: Team index is invalid: %f",
+                       index);
+       }
+       return TeamBalance_IsTeamAllowedInternal(balance, index);
+}
+
+void TeamBalance_GetTeamCounts(entity balance, entity ignore)
+{
+       if (balance == NULL)
+       {
+               LOG_FATAL("TeamBalance_GetTeamCounts: Team balance entity is NULL.");
+       }
+       if (balance.m_team_balance_state == TEAM_BALANCE_UNINITIALIZED)
+       {
+               LOG_FATAL("TeamBalance_GetTeamCounts: "
+                       "Team balance entity is not initialized.");
+       }
+       if (MUTATOR_CALLHOOK(TeamBalance_GetTeamCounts) == true)
+       {
+               // Mutator has overriden the configuration.
+               for (int i = 1; i <= NUM_TEAMS; ++i)
                {
-                       MUTATOR_CALLHOOK(GetTeamCount, NUM_TEAM_4, ignore,
-                               c4, num_bots_team4, lowest_human_team4, lowest_bot_team4);
-                       c4 = M_ARGV(2, float);
-                       num_bots_team4 = M_ARGV(3, float);
-                       lowest_human_team4 = M_ARGV(4, entity);
-                       lowest_bot_team4 = M_ARGV(5, entity);
+                       entity team_ent = TeamBalance_GetTeamFromIndex(balance, i);
+                       if (TeamBalanceTeam_IsAllowed(team_ent))
+                       {
+                               MUTATOR_CALLHOOK(TeamBalance_GetTeamCount, i, ignore);
+                               team_ent.m_num_players = M_ARGV(2, float);
+                               team_ent.m_num_bots = M_ARGV(3, float);
+                       }
                }
        }
        else
        {
-               float value, bvalue;
-               // now count how many players are on each team already
-               float lowest_human_score1 = FLOAT_MAX;
-               float lowest_bot_score1 = FLOAT_MAX;
-               float lowest_human_score2 = FLOAT_MAX;
-               float lowest_bot_score2 = FLOAT_MAX;
-               float lowest_human_score3 = FLOAT_MAX;
-               float lowest_bot_score3 = FLOAT_MAX;
-               float lowest_human_score4 = FLOAT_MAX;
-               float lowest_bot_score4 = FLOAT_MAX;
+               // Manually count all players.
                FOREACH_CLIENT(true,
                {
-                       float t;
+                       if (it == ignore)
+                       {
+                               continue;
+                       }
+                       int team_num;
                        if (IS_PLAYER(it) || it.caplayer)
                        {
-                               t = it.team;
+                               team_num = it.team;
                        }
                        else if (it.team_forced > 0)
                        {
-                               t = it.team_forced; // reserve the spot
+                               team_num = it.team_forced; // reserve the spot
                        }
                        else
                        {
                                continue;
                        }
-                       if (it == ignore)
+                       if (!Team_IsValidTeam(team_num))
                        {
                                continue;
                        }
-                       value = PlayerValue(it);
-                       if (IS_BOT_CLIENT(it))
-                       {
-                               bvalue = value;
-                       }
-                       else
-                       {
-                               bvalue = 0;
-                       }
-                       if (value == 0)
+                       entity team_ent = TeamBalance_GetTeam(balance, team_num);
+                       if (!TeamBalanceTeam_IsAllowed(team_ent))
                        {
                                continue;
                        }
-                       switch (t)
+                       ++team_ent.m_num_players;
+                       if (IS_BOT_CLIENT(it))
                        {
-                               case NUM_TEAM_1:
-                               {
-                                       if (c1 < 0)
-                                       {
-                                               break;
-                                       }
-                                       c1 += value;
-                                       num_bots_team1 += bvalue;
-                                       float temp_score = PlayerScore_Get(it, SP_SCORE);
-                                       if (!bvalue)
-                                       {
-                                               if (temp_score < lowest_human_score1)
-                                               {
-                                                       lowest_human_team1 = it;
-                                                       lowest_human_score1 = temp_score;
-                                               }
-                                               break;
-                                       }
-                                       if (temp_score < lowest_bot_score1)
-                                       {
-                                               lowest_bot_team1 = it;
-                                               lowest_bot_score1 = temp_score;
-                                       }
-                                       break;
-                               }
-                               case NUM_TEAM_2:
-                               {
-                                       if (c2 < 0)
-                                       {
-                                               break;
-                                       }
-                                       c2 += value;
-                                       num_bots_team2 += bvalue;
-                                       float temp_score = PlayerScore_Get(it, SP_SCORE);
-                                       if (!bvalue)
-                                       {
-                                               if (temp_score < lowest_human_score2)
-                                               {
-                                                       lowest_human_team2 = it;
-                                                       lowest_human_score2 = temp_score;
-                                               }
-                                               break;
-                                       }
-                                       if (temp_score < lowest_bot_score2)
-                                       {
-                                               lowest_bot_team2 = it;
-                                               lowest_bot_score2 = temp_score;
-                                       }
-                                       break;
-                               }
-                               case NUM_TEAM_3:
-                               {
-                                       if (c3 < 0)
-                                       {
-                                               break;
-                                       }
-                                       c3 += value;
-                                       num_bots_team3 += bvalue;
-                                       float temp_score = PlayerScore_Get(it, SP_SCORE);
-                                       if (!bvalue)
-                                       {
-                                               if (temp_score < lowest_human_score3)
-                                               {
-                                                       lowest_human_team3 = it;
-                                                       lowest_human_score3 = temp_score;
-                                               }
-                                               break;
-                                       }
-                                       if (temp_score < lowest_bot_score3)
-                                       {
-                                               lowest_bot_team3 = it;
-                                               lowest_bot_score3 = temp_score;
-                                       }
-                                       break;
-                               }
-                               case NUM_TEAM_4:
-                               {
-                                       if (c4 < 0)
-                                       {
-                                               break;
-                                       }
-                                       c4 += value;
-                                       num_bots_team4 += bvalue;
-                                       float temp_score = PlayerScore_Get(it, SP_SCORE);
-                                       if (!bvalue)
-                                       {
-                                               if (temp_score < lowest_human_score4)
-                                               {
-                                                       lowest_human_team4 = it;
-                                                       lowest_human_score4 = temp_score;
-                                               }
-                                               break;
-                                       }
-                                       if (temp_score < lowest_bot_score4)
-                                       {
-                                               lowest_bot_team4 = it;
-                                               lowest_bot_score4 = temp_score;
-                                       }
-                                       break;
-                               }
+                               ++team_ent.m_num_bots;
                        }
                });
        }
 
        // if the player who has a forced team has not joined yet, reserve the spot
-       if(autocvar_g_campaign)
+       if (autocvar_g_campaign)
        {
-               switch(autocvar_g_campaign_forceteam)
+               if (Team_IsValidIndex(autocvar_g_campaign_forceteam))
                {
-                       case 1: if(c1 == num_bots_team1) ++c1; break;
-                       case 2: if(c2 == num_bots_team2) ++c2; break;
-                       case 3: if(c3 == num_bots_team3) ++c3; break;
-                       case 4: if(c4 == num_bots_team4) ++c4; break;
+                       entity team_ent = TeamBalance_GetTeamFromIndex(balance,
+                               autocvar_g_campaign_forceteam);
+                       if (team_ent.m_num_players == team_ent.m_num_bots)
+                       {
+                               ++team_ent.m_num_players;
+                       }
                }
        }
+       balance.m_team_balance_state = TEAM_BALANCE_TEAM_COUNTS_FILLED;
 }
 
-bool IsTeamSmallerThanTeam(int team_a, int team_b, entity player,
-       bool use_score)
+int TeamBalance_GetNumberOfPlayers(entity balance, int index)
 {
-       if (!Team_IsValidNumber(team_a))
+       if (balance == NULL)
        {
-               LOG_FATALF("IsTeamSmallerThanTeam: team_a is invalid: %f", team_a);
+               LOG_FATAL("TeamBalance_GetNumberOfPlayers: "
+                       "Team balance entity is NULL.");
        }
-       if (!Team_IsValidNumber(team_b))
+       if (balance.m_team_balance_state != TEAM_BALANCE_TEAM_COUNTS_FILLED)
        {
-               LOG_FATALF("IsTeamSmallerThanTeam: team_b is invalid: %f", team_b);
+               LOG_FATAL("TeamBalance_GetNumberOfPlayers: "
+                       "TeamBalance_GetTeamCounts has not been called.");
        }
-       if (team_a == team_b)
+       if (!Team_IsValidIndex(index))
        {
-               return false;
-       }
-       // we assume that CheckAllowedTeams and GetTeamCounts have already been called
-       int num_players_team_a = -1, num_players_team_b = -1;
-       int num_bots_team_a = 0, num_bots_team_b = 0;
-       float score_team_a = 0, score_team_b = 0;
-       switch (team_a)
-       {
-               case 1:
-               {
-                       num_players_team_a = c1;
-                       num_bots_team_a = num_bots_team1;
-                       score_team_a = team1_score;
-                       break;
-               }
-               case 2:
-               {
-                       num_players_team_a = c2;
-                       num_bots_team_a = num_bots_team2;
-                       score_team_a = team2_score;
-                       break;
-               }
-               case 3:
-               {
-                       num_players_team_a = c3;
-                       num_bots_team_a = num_bots_team3;
-                       score_team_a = team3_score;
-                       break;
-               }
-               case 4:
-               {
-                       num_players_team_a = c4;
-                       num_bots_team_a = num_bots_team4;
-                       score_team_a = team4_score;
-                       break;
-               }
+               LOG_FATALF("TeamBalance_GetNumberOfPlayers: Team index is invalid: %f",
+                       index);
        }
-       switch (team_b)
+       return balance.m_team_balance_team[index - 1].m_num_players;
+}
+
+int TeamBalance_FindBestTeam(entity balance, entity player, bool ignore_player)
+{
+       if (balance == NULL)
        {
-               case 1:
-               {
-                       num_players_team_b = c1;
-                       num_bots_team_b = num_bots_team1;
-                       score_team_b = team1_score;
-                       break;
-               }
-               case 2:
-               {
-                       num_players_team_b = c2;
-                       num_bots_team_b = num_bots_team2;
-                       score_team_b = team2_score;
-                       break;
-               }
-               case 3:
-               {
-                       num_players_team_b = c3;
-                       num_bots_team_b = num_bots_team3;
-                       score_team_b = team3_score;
-                       break;
-               }
-               case 4:
-               {
-                       num_players_team_b = c4;
-                       num_bots_team_b = num_bots_team4;
-                       score_team_b = team4_score;
-                       break;
-               }
+               LOG_FATAL("TeamBalance_FindBestTeam: Team balance entity is NULL.");
        }
-       // invalid
-       if (num_players_team_a < 0 || num_players_team_b < 0)
+       if (balance.m_team_balance_state == TEAM_BALANCE_UNINITIALIZED)
        {
-               return false;
+               LOG_FATAL("TeamBalance_FindBestTeam: "
+                       "Team balance entity is not initialized.");
        }
-       if (IS_REAL_CLIENT(player) && bots_would_leave)
+       // count how many players are in each team
+       if (ignore_player)
        {
-               num_players_team_a -= num_bots_team_a;
-               num_players_team_b -= num_bots_team_b;
+               TeamBalance_GetTeamCounts(balance, player);
        }
-       if (!use_score)
+       else
        {
-               return num_players_team_a < num_players_team_b;
+               TeamBalance_GetTeamCounts(balance, NULL);
        }
-       if (num_players_team_a < num_players_team_b)
+       int team_bits = TeamBalance_FindBestTeams(balance, player, true);
+       if (team_bits == 0)
        {
-               return true;
+               LOG_FATALF("TeamBalance_FindBestTeam: No teams available for %s\n",
+                       MapInfo_Type_ToString(MapInfo_CurrentGametype()));
        }
-       if (num_players_team_a > num_players_team_b)
+       RandomSelection_Init();
+       for (int i = 1; i <= NUM_TEAMS; ++i)
        {
-               return false;
+               if (team_bits & Team_IndexToBit(i))
+               {
+                       RandomSelection_AddFloat(i, 1, 1);
+               }
        }
-       return score_team_a < score_team_b;
+       return RandomSelection_chosen_float;
 }
 
-bool IsTeamEqualToTeam(int team_a, int team_b, entity player, bool use_score)
+int TeamBalance_FindBestTeams(entity balance, entity player, bool use_score)
 {
-       if (!Team_IsValidNumber(team_a))
+       if (balance == NULL)
        {
-               LOG_FATALF("IsTeamEqualToTeam: team_a is invalid: %f", team_a);
+               LOG_FATAL("TeamBalance_FindBestTeams: Team balance entity is NULL.");
        }
-       if (!Team_IsValidNumber(team_b))
+       if (balance.m_team_balance_state != TEAM_BALANCE_TEAM_COUNTS_FILLED)
        {
-               LOG_FATALF("IsTeamEqualToTeam: team_b is invalid: %f", team_b);
+               LOG_FATAL("TeamBalance_FindBestTeams: "
+                       "TeamBalance_GetTeamCounts has not been called.");
        }
-       if (team_a == team_b)
+       if (MUTATOR_CALLHOOK(TeamBalance_FindBestTeams, player) == true)
        {
-               return true;
+               return M_ARGV(1, float);
        }
-       // we assume that CheckAllowedTeams and GetTeamCounts have already been called
-       int num_players_team_a = -1, num_players_team_b = -1;
-       int num_bots_team_a = 0, num_bots_team_b = 0;
-       float score_team_a = 0, score_team_b = 0;
-       switch (team_a)
+       int team_bits = 0;
+       int previous_team = 0;
+       for (int i = 1; i <= NUM_TEAMS; ++i)
        {
-               case 1:
+               if (!TeamBalance_IsTeamAllowedInternal(balance, i))
                {
-                       num_players_team_a = c1;
-                       num_bots_team_a = num_bots_team1;
-                       score_team_a = team1_score;
-                       break;
+                       continue;
                }
-               case 2:
+               if (previous_team == 0)
                {
-                       num_players_team_a = c2;
-                       num_bots_team_a = num_bots_team2;
-                       score_team_a = team2_score;
-                       break;
+                       team_bits = Team_IndexToBit(i);
+                       previous_team = i;
+                       continue;
                }
-               case 3:
+               int compare = TeamBalance_CompareTeams(balance, i, previous_team,
+                       player, use_score);
+               if (compare == TEAMS_COMPARE_LESS)
                {
-                       num_players_team_a = c3;
-                       num_bots_team_a = num_bots_team3;
-                       score_team_a = team3_score;
-                       break;
+                       team_bits = Team_IndexToBit(i);
+                       previous_team = i;
+                       continue;
                }
-               case 4:
+               if (compare == TEAMS_COMPARE_EQUAL)
                {
-                       num_players_team_a = c4;
-                       num_bots_team_a = num_bots_team4;
-                       score_team_a = team4_score;
-                       break;
+                       team_bits |= Team_IndexToBit(i);
+                       previous_team = i;
                }
        }
-       switch (team_b)
+       return team_bits;
+}
+
+void TeamBalance_JoinBestTeam(entity this, bool force_best_team)
+{
+       //PrintToChatAll(sprintf("JoinBestTeam: %s, %f", this.netname, force_best_team));
+       // don't join a team if we're not playing a team game
+       if (!teamplay)
+       {
+               return;
+       }
+
+       // find out what teams are available
+       entity balance = TeamBalance_CheckAllowedTeams(this);
+
+       // if we don't care what team they end up on, put them on whatever team they entered as.
+       // if they're not on a valid team, then let other code put them on the smallest team
+       if (!force_best_team)
        {
-               case 1:
+               int selected_team_index = -1;
+               for (int i = 1; i <= NUM_TEAMS; ++i)
                {
-                       num_players_team_b = c1;
-                       num_bots_team_b = num_bots_team1;
-                       score_team_b = team1_score;
-                       break;
-               }
-               case 2:
-               {
-                       num_players_team_b = c2;
-                       num_bots_team_b = num_bots_team2;
-                       score_team_b = team2_score;
-                       break;
-               }
-               case 3:
-               {
-                       num_players_team_b = c3;
-                       num_bots_team_b = num_bots_team3;
-                       score_team_b = team3_score;
-                       break;
+                       if (TeamBalance_IsTeamAllowedInternal(balance, i) &&
+                               (Team_TeamToIndex(this.team) == i))
+                       {
+                               selected_team_index = i;
+                               break;
+                       }
                }
-               case 4:
+               
+               if (Team_IsValidIndex(selected_team_index))
                {
-                       num_players_team_b = c4;
-                       num_bots_team_b = num_bots_team4;
-                       score_team_b = team4_score;
-                       break;
+                       SetPlayerTeam(this, selected_team_index, TEAM_CHANGE_AUTO_RELAXED);
+                       TeamBalance_Destroy(balance);
+                       return;
                }
        }
-       // invalid
-       if (num_players_team_a < 0 || num_players_team_b < 0)
-               return false;
-
-       if (IS_REAL_CLIENT(player) && bots_would_leave)
+       // otherwise end up on the smallest team (handled below)
+       if (this.bot_forced_team)
        {
-               num_players_team_a -= num_bots_team_a;
-               num_players_team_b -= num_bots_team_b;
+               TeamBalance_Destroy(balance);
+               return;
        }
-       if (!use_score)
+       int best_team_index = TeamBalance_FindBestTeam(balance, this, true);
+       int old_team_index = Team_TeamToIndex(this.team);
+       TeamBalance_Destroy(balance);
+       PlayerScore_Clear(this);
+       if (!SetPlayerTeam(this, best_team_index, TEAM_CHANGE_AUTO))
        {
-               return num_players_team_a == num_players_team_b;
+               return;
        }
-       if (num_players_team_a != num_players_team_b)
+       if ((old_team_index != -1) && !IS_BOT_CLIENT(this))
        {
-               return false;
+               TeamBalance_AutoBalanceBots(best_team_index, old_team_index);
        }
-       return score_team_a == score_team_b;
 }
 
-int FindBestTeams(entity player, bool use_score)
+int TeamBalance_CompareTeams(entity balance, int team_index_a, int team_index_b,
+       entity player, bool use_score)
 {
-       if (MUTATOR_CALLHOOK(FindBestTeams, player) == true)
+       if (balance == NULL)
        {
-               return M_ARGV(1, float);
+               LOG_FATAL("TeamBalance_CompareTeams: Team balance entity is NULL.");
        }
-       int team_bits = 0;
-       int previous_team = 0;
-       if (c1 >= 0)
+       if (balance.m_team_balance_state != TEAM_BALANCE_TEAM_COUNTS_FILLED)
        {
-               team_bits = BIT(0);
-               previous_team = 1;
+               LOG_FATAL("TeamBalance_CompareTeams: "
+                       "TeamBalance_GetTeamCounts has not been called.");
        }
-       if (c2 >= 0)
+       if (!Team_IsValidIndex(team_index_a))
        {
-               if (previous_team == 0)
-               {
-                       team_bits = BIT(1);
-                       previous_team = 2;
-               }
-               else if (IsTeamSmallerThanTeam(2, previous_team, player, use_score))
-               {
-                       team_bits = BIT(1);
-                       previous_team = 2;
-               }
-               else if (IsTeamEqualToTeam(2, previous_team, player, use_score))
-               {
-                       team_bits |= BIT(1);
-                       previous_team = 2;
-               }
+               LOG_FATALF("TeamBalance_CompareTeams: team_index_a is invalid: %f",
+                       team_index_a);
        }
-       if (c3 >= 0)
+       if (!Team_IsValidIndex(team_index_b))
        {
-               if (previous_team == 0)