- wget -O data/maps/stormkeep.waypoints https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints
- wget -O data/maps/stormkeep.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints.cache
- make
- - EXPECT=d00c303596d1be0274375bc5b87619d6
+ - EXPECT=585cfa6d62ce59f4854bedfce7c51c20
- HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
| tee /dev/stderr
| grep '^:'
-Wed Jul 5 07:25:00 CEST 2017
+Sat Jul 8 07:24:47 CEST 2017
add_definitions(-DXONOTIC=1)
add_definitions(-DNDEBUG=1)
+add_definitions(-DENABLE_EFFECTINFO=0)
+add_definitions(-DENABLE_DEBUGDRAW=0)
+add_definitions(-DENABLE_DEBUGTRACE=0)
find_package(Git REQUIRED)
-execute_process(
- COMMAND ${GIT_EXECUTABLE} describe --tags --dirty=~
- WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
- OUTPUT_VARIABLE GIT_DESC
- OUTPUT_STRIP_TRAILING_WHITESPACE
-)
+if (DEFINED ENV{VERSION})
+ set(GIT_DESC "$ENV{VERSION}")
+else ()
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} describe --tags --dirty=~
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ OUTPUT_VARIABLE GIT_DESC
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+endif ()
add_definitions(-DWATERMARK=\"${GIT_DESC}\")
set_source_files_properties(
add_executable(csprogs qcsrc/client/progs.inc)
target_compile_definitions(csprogs PRIVATE -DGAMEQC -DCSQC)
-add_dependencies(csprogs gmqcc)
+if (TARGET gmqcc)
+ add_dependencies(csprogs gmqcc)
+endif ()
add_executable(progs qcsrc/server/progs.inc)
target_compile_definitions(progs PRIVATE -DGAMEQC -DSVQC)
-add_dependencies(progs gmqcc)
+if (TARGET gmqcc)
+ add_dependencies(progs gmqcc)
+endif ()
add_executable(menu qcsrc/menu/progs.inc)
target_compile_definitions(menu PRIVATE -DMENUQC)
-add_dependencies(menu gmqcc)
+if (TARGET gmqcc)
+ add_dependencies(menu gmqcc)
+endif ()
function(set_prelude target prelude)
get_target_property(MY_PROJECT_SOURCES target SOURCES)
set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
set g_jetpack_maxspeed_side 1500 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Asturian (http://www.transifex.com/team-xonotic/xonotic/"
"language/ast/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr "Habilitar panel"
-
-#~ msgid "QMCMD^drop gun, icon"
-#~ msgstr "QMCMD^arma soltada, iconu"
-
-#~ msgid ""
-#~ "^F2You have stolen the enemy's vehicle, you are now visible on their "
-#~ "radar!"
-#~ msgstr "^F2¡Robesti'l vehículu enemigu, agora yes visible nel so radar!"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Belarusian (http://www.transifex.com/team-xonotic/xonotic/"
"language/be/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
-msgstr "QMCMD^Чат"
+msgid "Chat"
+msgstr "Чат"
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgid "QMCMD^:-) / nice one"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Bulgarian (http://www.transifex.com/team-xonotic/xonotic/"
"language/bg/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Catalan (http://www.transifex.com/team-xonotic/xonotic/"
"language/ca/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Czech (http://www.transifex.com/team-xonotic/xonotic/language/"
"cs/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 07:47+0000\n"
-"Last-Translator: Mirio <opivy@hotmail.de>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: German (http://www.transifex.com/team-xonotic/xonotic/"
"language/de/)\n"
"Language: de\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr "Chat"
#: qcsrc/client/hud/panel/quickmenu.qc:795
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr "Panel aktivieren"
-
-#~ msgid "QMCMD^killed flag, icon"
-#~ msgstr "Flaggenträger getötet, icon"
-
-#~ msgid "QMCMD^drop gun, icon"
-#~ msgstr "Waffe fallen gelassen, icon"
-
-#~ msgid "QMCMD^dropped gun %w^7 (l:%l^7)"
-#~ msgstr "Waffe fallen gelassen %w^7 (l:%l^7)"
-
-#~ msgid ""
-#~ "^F2You have stolen the enemy's vehicle, you are now visible on their "
-#~ "radar!"
-#~ msgstr ""
-#~ "^F2Du hast das Fahrzeug des Feindes gestohlen, du bist nun auf ihrem "
-#~ "Radar sichtbar!"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 07:47+0000\n"
-"Last-Translator: Mirio <opivy@hotmail.de>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: German (http://www.transifex.com/team-xonotic/xonotic/"
"language/de/)\n"
"Language: de\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr "Chat"
#: qcsrc/client/hud/panel/quickmenu.qc:795
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr "Panel aktivieren"
-
-#~ msgid "QMCMD^killed flag, icon"
-#~ msgstr "Flaggenträger getötet, icon"
-
-#~ msgid "QMCMD^drop gun, icon"
-#~ msgstr "Waffe fallen gelassen, icon"
-
-#~ msgid "QMCMD^dropped gun %w^7 (l:%l^7)"
-#~ msgstr "Waffe fallen gelassen %w^7 (l:%l^7)"
-
-#~ msgid ""
-#~ "^F2You have stolen the enemy's vehicle, you are now visible on their "
-#~ "radar!"
-#~ msgstr ""
-#~ "^F2Du hast das Fahrzeug des Feindes gestohlen, du bist nun auf ihrem "
-#~ "Radar sichtbar!"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Greek (http://www.transifex.com/team-xonotic/xonotic/language/"
"el/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: English (Australia) (http://www.transifex.com/team-xonotic/"
"xonotic/language/en_AU/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
-msgstr "QMCMD^Chat"
+msgid "Chat"
+msgstr "Chat"
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgid "QMCMD^:-) / nice one"
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr "Enable panel"
-
-#~ msgid "QMCMD^killed flag, icon"
-#~ msgstr "QMCMD^killed flag, icon"
-
-#~ msgid "QMCMD^drop gun, icon"
-#~ msgstr "QMCMD^drop gun, icon"
-
-#~ msgid "QMCMD^dropped gun %w^7 (l:%l^7)"
-#~ msgstr "QMCMD^dropped gun %w^7 (l:%l^7)"
-
-#~ msgid ""
-#~ "^F2You have stolen the enemy's vehicle, you are now visible on their "
-#~ "radar!"
-#~ msgstr ""
-#~ "^F2You have stolen the enemy's vehicle, you are now visible on their "
-#~ "radar!"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Esperanto (http://www.transifex.com/team-xonotic/xonotic/"
"language/eo/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-05-25 19:02+0000\n"
-"Last-Translator: Starfire24680 <starfire24680@gmail.com>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Spanish (http://www.transifex.com/team-xonotic/xonotic/"
"language/es/)\n"
"Language: es\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
-msgstr "QMCMD^Chat"
+msgid "Chat"
+msgstr "Chat"
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgid "QMCMD^:-) / nice one"
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr "Activar panel"
-
-#~ msgid "QMCMD^killed flag, icon"
-#~ msgstr "QMCMD^bandera asesinada, icono"
-
-#~ msgid "QMCMD^drop gun, icon"
-#~ msgstr "QMCMD^tirar arma, icono"
-
-#~ msgid "QMCMD^dropped gun %w^7 (l:%l^7)"
-#~ msgstr "QMCMD^arma tirada %w^7 (l:%l^7)"
-
-#~ msgid ""
-#~ "^F2You have stolen the enemy's vehicle, you are now visible on their "
-#~ "radar!"
-#~ msgstr ""
-#~ "^F2¡Has robado un vehículo del enemigo, ahora eres visible en su radar!"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Spanish (Mexico) (http://www.transifex.com/team-xonotic/"
"xonotic/language/es_MX/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Finnish (http://www.transifex.com/team-xonotic/xonotic/"
"language/fi/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-05-21 08:35+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+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"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr "Tchat"
#: qcsrc/client/hud/panel/quickmenu.qc:795
#: qcsrc/client/hud/panel/quickmenu.qc:814
msgid "QMCMD^killed flagcarrier, icon"
-msgstr ""
+msgstr "tué le porteur de drapeau, icône"
#: qcsrc/client/hud/panel/quickmenu.qc:815
#, c-format
#: qcsrc/client/hud/panel/quickmenu.qc:816
msgid "QMCMD^drop weapon, icon"
-msgstr ""
+msgstr "lâché l'arme, icône"
#: qcsrc/client/hud/panel/quickmenu.qc:816
msgid "QMCMD^dropped weapon %w^7 (l:%l^7)"
-msgstr ""
+msgstr "lâché l'arme %w^7 (l:%l^7)"
#: qcsrc/client/hud/panel/quickmenu.qc:817
msgid "QMCMD^drop flag/key, icon"
#: qcsrc/common/notifications/all.inc:788
msgid "^F2Intruder detected, disabling shields!"
-msgstr ""
+msgstr "^F2Intrus détecté, boucliers désactivés !"
#: qcsrc/common/notifications/all.qh:188
msgid "Notification dump command only works with cl_cmd and sv_cmd.\n"
#: qcsrc/menu/xonotic/credits.qc:231
msgid "Irish"
-msgstr ""
+msgstr "Irlandais"
#: qcsrc/menu/xonotic/credits.qc:234
msgid "Italian"
#: qcsrc/menu/xonotic/credits.qc:279
msgid "Scottish Gaelic"
-msgstr ""
+msgstr "Gaélique écossais"
#: qcsrc/menu/xonotic/credits.qc:282
msgid "Serbian"
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr "Afficher le tableau de bord"
-
-#~ msgid "QMCMD^killed flag, icon"
-#~ msgstr "tué le drapeau, icône"
-
-#~ msgid "QMCMD^drop gun, icon"
-#~ msgstr "lâcher l'arme, icône"
-
-#~ msgid "QMCMD^dropped gun %w^7 (l:%l^7)"
-#~ msgstr "lâché l'arme %w^7 (l:%l^7)"
-
-#~ msgid ""
-#~ "^F2You have stolen the enemy's vehicle, you are now visible on their "
-#~ "radar!"
-#~ msgstr ""
-#~ "^F2Vous avez volé le véhicule de l'ennemi, vous êtes maintenant visible "
-#~ "sur leur radar !"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-05-05 03:24+0000\n"
-"Last-Translator: Kevin Scannell <kscanne@gmail.com>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Irish (http://www.transifex.com/team-xonotic/xonotic/language/"
"ga/)\n"
"Language: ga\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr "Comhrá"
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-06-01 21:16+0000\n"
-"Last-Translator: GunChleoc\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Gaelic, Scottish (http://www.transifex.com/team-xonotic/"
"xonotic/language/gd/)\n"
"Language: gd\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr "Cabadaich"
#: qcsrc/client/hud/panel/quickmenu.qc:795
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr ""
-
-#~ msgid "QMCMD^killed flag, icon"
-#~ msgstr "air bratach a mharbhadh, ìomhaigheag"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2013-09-12 16:53+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Hebrew (http://www.transifex.com/team-xonotic/xonotic/"
"language/he/)\n"
"Language: he\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Hungarian (http://www.transifex.com/team-xonotic/xonotic/"
"language/hu/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-07-06 00:29+0000\n"
-"Last-Translator: Antonio <piuntn@gmail.com>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Italian (http://www.transifex.com/team-xonotic/xonotic/"
"language/it/)\n"
"Language: it\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr "Chat"
#: qcsrc/client/hud/panel/quickmenu.qc:795
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr "Abilita pannello"
-
-#~ msgid "QMCMD^killed flag, icon"
-#~ msgstr "ucciso bandiera, icona"
-
-#~ msgid "QMCMD^drop gun, icon"
-#~ msgstr "lascia arma, icona"
-
-#~ msgid "QMCMD^dropped gun %w^7 (l:%l^7)"
-#~ msgstr "lasciata arma %w^7 (l:%l^7)"
-
-#~ msgid ""
-#~ "^F2You have stolen the enemy's vehicle, you are now visible on their "
-#~ "radar!"
-#~ msgstr ""
-#~ "^F2Hai rubato il veicolo del nemico, sei adesso visibile sul loro radar!"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Japanese (Japan) (http://www.transifex.com/team-xonotic/"
"xonotic/language/ja_JP/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2013-09-12 16:53+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Lojban (http://www.transifex.com/team-xonotic/xonotic/"
"language/jbo/)\n"
"Language: jbo\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Kazakh (Cyrillic) (http://www.transifex.com/team-xonotic/"
"xonotic/language/kk@Cyrl/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-05-21 01:14+0000\n"
-"Last-Translator: Kuff Lee <coughingmouse@gmail.com>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Korean (http://www.transifex.com/team-xonotic/xonotic/"
"language/ko/)\n"
"Language: ko\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
-msgstr "QMCMD^채팅"
+msgid "Chat"
+msgstr "채팅"
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgid "QMCMD^:-) / nice one"
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr "제어반 활성화"
-
-#~ msgid "QMCMD^killed flag, icon"
-#~ msgstr "QMCMD^죽인 깃발, 아이콘"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Cornish (http://www.transifex.com/team-xonotic/xonotic/"
"language/kw/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
-msgstr "QMCMD^Keskows"
+msgid "Chat"
+msgstr "Keskows"
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgid "QMCMD^:-) / nice one"
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr ""
-
-#~ msgid "QMCMD^killed flag, icon"
-#~ msgstr "QMCMD^baner ledhys, arwodhik"
-
-#~ msgid "QMCMD^drop gun, icon"
-#~ msgstr "QMCMD^gonn droppyes, arwodhik"
-
-#~ msgid "QMCMD^dropped gun %w^7 (l:%l^7)"
-#~ msgstr "QMCMD^gonn droppyes %w^7 (l:%l^7)"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Macedonian (http://www.transifex.com/team-xonotic/xonotic/"
"language/mk/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-05-14 14:26+0000\n"
-"Last-Translator: Joeke de Graaf <mappack@null.net>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Dutch (http://www.transifex.com/team-xonotic/xonotic/language/"
"nl/)\n"
"Language: nl\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
-msgstr "QMCMD^Chat"
+msgid "Chat"
+msgstr "Chat"
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgid "QMCMD^:-) / nice one"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2013-09-12 16:53+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Norwegian (http://www.transifex.com/team-xonotic/xonotic/"
"language/no/)\n"
"Language: no\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-06-28 19:15+0000\n"
-"Last-Translator: Amadeusz Sławiński <amade@asmblr.net>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Polish (http://www.transifex.com/team-xonotic/xonotic/"
"language/pl/)\n"
"Language: pl\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr "Czat"
#: qcsrc/client/hud/panel/quickmenu.qc:795
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr "Włącz panel"
-
-#~ msgid "QMCMD^drop gun, icon"
-#~ msgstr "upuściłem "
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-05-31 03:15+0000\n"
-"Last-Translator: Jean Trindade Pereira <jean_trindade2@hotmail.com>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Portuguese (http://www.transifex.com/team-xonotic/xonotic/"
"language/pt/)\n"
"Language: pt\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr "Chat"
#: qcsrc/client/hud/panel/quickmenu.qc:795
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr "Habilitar painel"
-
-#~ msgid "QMCMD^killed flag, icon"
-#~ msgstr "Bandeira aniquilada, ícone"
-
-#~ msgid "QMCMD^drop gun, icon"
-#~ msgstr "Largar arma, ícone"
-
-#~ msgid "QMCMD^dropped gun %w^7 (l:%l^7)"
-#~ msgstr "Arma solta %w^7 (l:%l^7)"
-
-#~ msgid ""
-#~ "^F2You have stolen the enemy's vehicle, you are now visible on their "
-#~ "radar!"
-#~ msgstr ""
-#~ "^F2Você roubou o veículo do inimigo, agora você está visível no radar "
-#~ "deles!"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Romanian (http://www.transifex.com/team-xonotic/xonotic/"
"language/ro/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
-msgstr "QMCMD^Conversație"
+msgid "Chat"
+msgstr "Conversație"
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgid "QMCMD^:-) / nice one"
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr "Activare panou"
-
-#~ msgid "QMCMD^killed flag, icon"
-#~ msgstr "QMCMD^omorât steagul, pictogramă"
-
-#~ msgid "QMCMD^drop gun, icon"
-#~ msgstr "QMCMD^scapă arma, pictogramă"
-
-#~ msgid "QMCMD^dropped gun %w^7 (l:%l^7)"
-#~ msgstr "QMCMD^armă scăpată %w^7 (l:%l^7)"
-
-#~ msgid ""
-#~ "^F2You have stolen the enemy's vehicle, you are now visible on their "
-#~ "radar!"
-#~ msgstr "^F2Ai ciordit un vehicul de la inamic, ești urmărit de radarul lor!"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-04-04 21:13+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: Andrei Stepanov\n"
"Language-Team: Russian (http://www.transifex.com/team-xonotic/xonotic/"
"language/ru/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
-msgstr "QMCMD^Чат"
+msgid "Chat"
+msgstr "Чат"
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgid "QMCMD^:-) / nice one"
#: qcsrc/client/hud/panel/quickmenu.qc:814
msgid "QMCMD^killed flagcarrier, icon"
-msgstr ""
+msgstr "QMCMD^убил флагоносца, иконка"
#: qcsrc/client/hud/panel/quickmenu.qc:815
#, c-format
#: qcsrc/client/hud/panel/quickmenu.qc:816
msgid "QMCMD^drop weapon, icon"
-msgstr ""
+msgstr "QMCMD^сбросить оружие, иконка"
#: qcsrc/client/hud/panel/quickmenu.qc:816
msgid "QMCMD^dropped weapon %w^7 (l:%l^7)"
-msgstr ""
+msgstr "QMCMD^сбросил оружие %w^7 (l:%l^7)"
#: qcsrc/client/hud/panel/quickmenu.qc:817
msgid "QMCMD^drop flag/key, icon"
#: qcsrc/common/notifications/all.inc:788
msgid "^F2Intruder detected, disabling shields!"
-msgstr ""
+msgstr "^F2Захватчик обнаружен, отключение щитов!"
#: qcsrc/common/notifications/all.qh:188
msgid "Notification dump command only works with cl_cmd and sv_cmd.\n"
#: qcsrc/menu/xonotic/credits.qc:231
msgid "Irish"
-msgstr ""
+msgstr "Ирландский"
#: qcsrc/menu/xonotic/credits.qc:234
msgid "Italian"
#: qcsrc/menu/xonotic/credits.qc:279
msgid "Scottish Gaelic"
-msgstr ""
+msgstr "Шотландский"
#: qcsrc/menu/xonotic/credits.qc:282
msgid "Serbian"
#: qcsrc/menu/xonotic/util.qh:44
msgid "Enable panel"
msgstr "Включить панель"
-
-#~ msgid "QMCMD^killed flag, icon"
-#~ msgstr "QMCMD^убил флаг, иконка"
-
-#~ msgid "QMCMD^drop gun, icon"
-#~ msgstr "QMCMD^сбросить оружие, иконка"
-
-#~ msgid "QMCMD^dropped gun %w^7 (l:%l^7)"
-#~ msgstr "QMCMD^сбросил оружие %w^7 (l:%l^7)"
-
-#~ msgid ""
-#~ "^F2You have stolen the enemy's vehicle, you are now visible on their "
-#~ "radar!"
-#~ msgstr "^F2Вы угнали вражеский автомобиль и теперь видны на их радарах!"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Albanian (http://www.transifex.com/team-xonotic/xonotic/"
"language/sq/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-06-17 17:00+0000\n"
-"Last-Translator: Марко М. Костић (Marko M. Kostić) <marko.m.kostic@gmail."
-"com>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Serbian (http://www.transifex.com/team-xonotic/xonotic/"
"language/sr/)\n"
"Language: sr\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
-msgstr "QMCMD^Ћаскање"
+msgid "Chat"
+msgstr "Ћаскање"
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgid "QMCMD^:-) / nice one"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Swedish (http://www.transifex.com/team-xonotic/xonotic/"
"language/sv/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Turkish (http://www.transifex.com/team-xonotic/xonotic/"
"language/tr/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Ukrainian (http://www.transifex.com/team-xonotic/xonotic/"
"language/uk/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Uzbek (Latin) (http://www.transifex.com/team-xonotic/xonotic/"
"language/uz@Latn/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
+msgid "Chat"
msgstr ""
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-03-30 05:23+0000\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Chinese (China) (http://www.transifex.com/team-xonotic/"
"xonotic/language/zh_CN/)\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
-msgstr "QMCMD^对话"
+msgid "Chat"
+msgstr "对话"
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgid "QMCMD^:-) / nice one"
msgstr ""
"Project-Id-Version: Xonotic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-07-03 14:35+0200\n"
-"PO-Revision-Date: 2017-04-15 05:02+0000\n"
-"Last-Translator: Arm Coon <armcoon@gmail.com>\n"
+"POT-Creation-Date: 2017-07-09 00:35+0200\n"
+"PO-Revision-Date: 2017-07-09 23:06+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
"Language-Team: Chinese (Taiwan) (http://www.transifex.com/team-xonotic/"
"xonotic/language/zh_TW/)\n"
"Language: zh_TW\n"
#: qcsrc/client/hud/panel/quickmenu.qc:794
#: qcsrc/client/hud/panel/quickmenu.qc:798
-msgid "QMCMD^Chat"
-msgstr "QMCMD^對話"
+msgid "Chat"
+msgstr "對話"
#: qcsrc/client/hud/panel/quickmenu.qc:795
msgid "QMCMD^:-) / nice one"
r_glsl_offsetmapping_lod 1
r_glsl_offsetmapping_reliefmapping 0
r_glsl_offsetmapping_scale 0.02
-// execute effects-normal.cfg to make sure that all effect settings are reset
+
+// create a temporary empty alias for menu_sync so that execution of effects-normal.cfg
+// on game start doesn't show an error message in the console
alias menu_sync "" // will be re-aliased later
// misc
seta cl_damagetext_friendlyfire "1" "Show damage text for friendlyfire too"
seta cl_damagetext_friendlyfire_color "1 0 0" "Damage text color for friendlyfire"
+seta cl_damagetext_2d_pos "0.47 0.53 0" "2D damage text initial position (X and Y between 0 and 1)"
+seta cl_damagetext_2d_alpha_start 1 "2D damage text initial alpha"
+seta cl_damagetext_2d_alpha_lifetime 1.3 "2D damage text lifetime (alpha fading) in seconds"
+seta cl_damagetext_2d_size_lifetime 3 "2D damage text lifetime (size shrinking) in seconds"
+seta cl_damagetext_2d_velocity "-25 0 0" "2D damage text move direction (screen coordinates)"
+seta cl_damagetext_2d_overlap_offset "0 -15 0" "Offset 2D damage text by this much to prevent overlapping (screen coordinates)"
+seta cl_damagetext_2d_close_range 125 "Always use 2D damagetext for hits closer that this"
+seta cl_damagetext_2d_out_of_view 1 "Always use 2D damagetext for hits that occured off-screen"
+
seta cl_vehicles_alarm 1 "Play an alarm sound when the vehicle you are driving is heavily damaged"
seta cl_vehicles_hud_tactical 1
seta cl_vehicles_hudscale 0.5
seta cl_jetpack_jump 1 "Activate jetpack by pressing jump in the air. 0 = Disable, 1 = Stop when touching ground, 2 = Enable"
+seta cl_race_cptimes_showself 1 "Always show your own times as well as the current best on checkpoints in Race/CTS"
+seta cl_race_cptimes_onlyself 0 "Only show your own times on checkpoints in Race/CTS"
+
// must be at the bottom of this file:
set g_bugrigs 0
seta cl_gentle_damage 0 "client side gentle mode (only replaces damage flash); when set to 1, a white flash replaces the blood image, when set to 2, a randomly colored flash is used instead"
set g_jetpack 0 "Jetpack mutator"
+set cl_jetpack_attenuation 2 "jetpack sound attenuation"
set g_running_guns 0 "... or wonder, till it drives you mad, what would have followed if you had."
en English "English"
en_AU English "English (Australia)" 86%
es Spanish "Español" 99%
-fr French "Français" 99%
-it Italian "Italiano" 99%
+fr French "Français" 100%
+it Italian "Italiano" 100%
hu Hungarian "Magyar" 55%
nl Dutch "Nederlands" 70%
pl Polish "Polski" 80%
el Greek "Ελληνική" 33%
be Belarusian "Беларуская" 62%
bg Bulgarian "Български" 68%
-ru Russian "Русский" 99%
+ru Russian "Русский" 100%
sr Serbian "Српски" 71%
uk Ukrainian "Українська" 57%
VER = $(subst *,\*,$(QCCFLAGS_WATERMARK))
NDEBUG ?= 1
XONOTIC ?= 1
+ENABLE_EFFECTINFO ?= 0
+ENABLE_DEBUGDRAW ?= 0
+ENABLE_DEBUGTRACE ?= 0
BUILD_MOD ?=
ifndef ZIP
-DXONOTIC=$(XONOTIC) \
-DWATERMARK="$(QCCFLAGS_WATERMARK)" \
-DNDEBUG=$(NDEBUG) \
+ -DENABLE_EFFECTINFO=$(ENABLE_EFFECTINFO) \
+ -DENABLE_DEBUGDRAW=$(ENABLE_DEBUGDRAW) \
+ -DENABLE_DEBUGTRACE=$(ENABLE_DEBUGTRACE) \
$(if $(BUILD_MOD), -DBUILD_MOD="$(BUILD_MOD)" -I$(BUILD_MOD), ) \
$(QCCDEFS_EXTRA)
float autocvar_crosshair_size;
int autocvar_ekg;
float autocvar_fov;
-float autocvar_g_balance_damagepush_speedfactor;
bool autocvar_hud_cursormode = true;
float autocvar_hud_colorflash_alpha;
bool autocvar_hud_configure_checkcollisions;
string autocvar__cl_playermodel;
float autocvar_cl_deathglow;
bool autocvar_developer_csqcentities;
-float autocvar_g_jetpack_attenuation;
+float autocvar_cl_jetpack_attenuation = 2;
bool autocvar_cl_showspectators;
int autocvar_cl_nade_timer;
bool autocvar_r_drawviewmodel;
+bool autocvar_cl_race_cptimes_onlyself;
+bool autocvar_cl_race_cptimes_showself = false;
}
void CSQCPlayer_ModelAppearance_Apply(entity this, bool islocalplayer)
{
+ if(MUTATOR_CALLHOOK(ForcePlayermodels_Skip, this, islocalplayer))
+ goto skipforcemodels;
+
// FORCEMODEL
// which one is ALWAYS good?
if (!forceplayermodels_goodmodel)
this.colormap = player_localnum + 1;
}
+ LABEL(skipforcemodels)
+
// GLOWMOD AND DEATH FADING
if(this.colormap > 0)
this.glowmod = colormapPaletteColor(((this.colormap >= 1024) ? this.colormap : entcs_GetClientColors(this.colormap - 1)) & 0x0F, true) * 2;
{
if(!this.snd_looping)
{
- sound(this, CH_TRIGGER_SINGLE, SND_JETPACK_FLY, VOL_BASE, autocvar_g_jetpack_attenuation);
+ sound(this, CH_TRIGGER_SINGLE, SND_JETPACK_FLY, VOL_BASE, autocvar_cl_jetpack_attenuation);
this.snd_looping = CH_TRIGGER_SINGLE;
}
}
{
if(this.snd_looping)
{
- sound(this, this.snd_looping, SND_Null, VOL_BASE, autocvar_g_jetpack_attenuation);
+ sound(this, this.snd_looping, SND_Null, VOL_BASE, autocvar_cl_jetpack_attenuation);
this.snd_looping = 0;
}
}
float race_laptime;
float race_checkpointtime;
float race_previousbesttime;
+float race_mypreviousbesttime;
string race_previousbestname;
float race_nextcheckpoint;
float race_nextbesttime;
+float race_mybesttime;
string race_nextbestname;
float race_penaltyaccumulator; // qualifying: total penalty time in tenths
float race_penaltyeventtime; // time when the player got the penalty
#pragma once
#include <common/weapons/_all.qh>
+#include <common/scores.qh>
void Hud_Dynamic_Frame();
void HUD_Main ();
int race_CheckName(string net_name);
-string MakeRaceString(int cp, float mytime, float theirtime, float lapdelta, string theirname);
+string MakeRaceString(int cp, float mytime, float theirtime, float othertime, float lapdelta, string theirname);
int vote_yescount;
int vote_nocount;
#include <common/mapinfo.qh>
#include <common/ent_cs.qh>
+#include <common/scores.qh>
#include <server/mutators/mutator/gamemode_ctf.qh> // TODO: remove
// Mod icons (#10)
void HUD_Mod_Race(vector pos, vector mySize)
{
- mod_active = 1; // race should never hide the mod icons panel
- entity me;
- me = playerslots[player_localnum];
- float score;
- score = me.(scores(ps_primary));
+ entity me = playerslots[player_localnum];
+ float score = me.(scores(ps_primary));
if(!(scores_flags(ps_primary) & SFL_TIME) || teamplay) // race/cts record display on HUD
+ {
+ mod_active = 0; // hide it in this case!
return; // no records in the actual race
+ }
+
+ mod_active = 1;
// clientside personal record
string rr;
}
// race "awards"
- float a;
- a = bound(0, race_status_time - time, 1);
+ float a = bound(0, race_status_time - time, 1);
+ string s = textShortenToWidth(ColorTranslateRGB(race_status_name), squareSize, '1 1 0' * 0.1 * squareSize, stringwidth_colors);
- string s;
- s = textShortenToWidth(ColorTranslateRGB(race_status_name), squareSize, '1 1 0' * 0.1 * squareSize, stringwidth_colors);
-
- float rank;
+ float rank = 0;
if(race_status > 0)
rank = race_CheckName(race_status_name);
- else
- rank = 0;
- string rankname;
- rankname = count_ordinal(rank);
-
- vector namepos;
- namepos = medalPos + '0 0.8 0' * squareSize;
- vector rankpos;
- rankpos = medalPos + '0 0.15 0' * squareSize;
+ string rankname = count_ordinal(rank);
+ vector namepos = medalPos + '0 0.8 0' * squareSize;
+ vector rankpos = medalPos + '0 0.15 0' * squareSize;
if(race_status == 0)
drawpic_aspect_skin(medalPos, "race_newfail", '1 1 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
string tc_title;
string tc_cmd;
- QUICKMENU_SMENU(CTX(_("QMCMD^Chat")), "Chat")
+ QUICKMENU_SMENU(_("Chat"), "Chat")
QUICKMENU_ENTRY_TC(CTX(_("QMCMD^nice one")), "say %s", ":-) / nice one", CTX(_("QMCMD^:-) / nice one")))
QUICKMENU_ENTRY_TC(CTX(_("QMCMD^good game")), "say %s", "good game", CTX(_("QMCMD^good game")))
QUICKMENU_ENTRY_TC(CTX(_("QMCMD^hi / good luck")), "say %s", "hi / good luck and have fun", CTX(_("QMCMD^hi / good luck and have fun")))
- QUICKMENU_SMENU(CTX(_("QMCMD^Chat")), "Chat")
+ QUICKMENU_SMENU(_("Chat"), "Chat")
if(teamplay)
{
// Race timer (#6)
// return the string of the onscreen race timer
-string MakeRaceString(int cp, float mytime, float theirtime, float lapdelta, string theirname)
+string MakeRaceString(int cp, float mytime, float theirtime, float othertime, float lapdelta, string theirname)
{
TC(int, cp);
- string col;
- string timestr;
- string cpname;
- string lapstr;
- lapstr = "";
+ string cpname, lapstr = "", timestr = "", col = "^7", othercol = "^7", othertimestr = "";
+ if(theirname == "" || !autocvar_cl_race_cptimes_showself)
+ othertime = 0; // don't count personal time
if(theirtime == 0) // goal hit
{
col = "^2";
}
+ if(othertime > 0)
+ {
+ othertimestr = strcat("+", ftos_decimals(+othertime, TIME_DECIMALS));
+ othercol = "^1";
+ }
+ else if(othertime == 0)
+ {
+ othertimestr = "+0.0";
+ othercol = "^3";
+ }
+ else
+ {
+ othertimestr = strcat("-", ftos_decimals(-othertime, TIME_DECIMALS));
+ othercol = "^2";
+ }
+
if(lapdelta > 0)
{
lapstr = sprintf(_(" (-%dL)"), lapdelta);
else
timestr = TIME_ENCODED_TOSTRING(TIME_ENCODE(theirtime));
col = "^3";
- }
- else
- {
- col = "^7";
- timestr = "";
+ if(mytime >= othertime)
+ othertimestr = strcat("+", ftos_decimals(mytime - othertime, TIME_DECIMALS));
+ else
+ othertimestr = TIME_ENCODED_TOSTRING(TIME_ENCODE(othertime));
+ othercol = "^7";
}
if(cp == 254)
return strcat(col, cpname);
else if(theirname == "")
return strcat(col, sprintf("%s (%s)", cpname, timestr));
+ else if(othertime)
+ return strcat(col, sprintf("%s %s(%s)%s (%s %s)", cpname, othercol, othertimestr, col, timestr, strcat(ColorTranslateRGB(theirname), col, lapstr)));
else
return strcat(col, sprintf("%s (%s %s)", cpname, timestr, strcat(ColorTranslateRGB(theirname), col, lapstr)));
}
if(race_checkpoint != 254)
{
if(race_time && race_previousbesttime)
- s = MakeRaceString(race_checkpoint, TIME_DECODE(race_time) - TIME_DECODE(race_previousbesttime), 0, 0, race_previousbestname);
+ s = MakeRaceString(race_checkpoint, TIME_DECODE(race_time) - TIME_DECODE(race_previousbesttime), 0, ((race_mypreviousbesttime) ? TIME_DECODE(race_time) - TIME_DECODE(race_mypreviousbesttime) : 0), 0, race_previousbestname);
else
- s = MakeRaceString(race_checkpoint, 0, -1, 0, race_previousbestname);
+ s = MakeRaceString(race_checkpoint, 0, -1, 0, 0, race_previousbestname);
if(race_time)
forcetime = TIME_ENCODED_TOSTRING(race_time);
}
}
else
{
- if(race_laptime && race_nextbesttime && race_nextcheckpoint != 254)
+ if(race_laptime && race_nextcheckpoint != 254)
{
- a = bound(0, 2 - ((race_laptime + TIME_DECODE(race_nextbesttime)) - (time + TIME_DECODE(race_penaltyaccumulator))), 1);
- if(a > 0) // next one?
- s = MakeRaceString(race_nextcheckpoint, (time + TIME_DECODE(race_penaltyaccumulator)) - race_laptime, TIME_DECODE(race_nextbesttime), 0, race_nextbestname);
+ if(race_nextbesttime)
+ {
+ a = bound(0, 2 - ((race_laptime + TIME_DECODE(race_nextbesttime)) - (time + TIME_DECODE(race_penaltyaccumulator))), 1);
+ float a2 = ((race_mybesttime) ? bound(0, 2 - ((race_laptime + TIME_DECODE(race_mybesttime)) - (time + TIME_DECODE(race_penaltyaccumulator))), 1) : 0);
+ if(a > 0) // next one?
+ s = MakeRaceString(race_nextcheckpoint, (time + TIME_DECODE(race_penaltyaccumulator)) - race_laptime, TIME_DECODE(race_nextbesttime), ((a2 > 0) ? TIME_DECODE(race_mybesttime) : 0), 0, race_nextbestname);
+ }
}
}
if(race_mycheckpointtime)
{
a = bound(0, 2 - (time - race_mycheckpointtime), 1);
- s = MakeRaceString(race_mycheckpoint, TIME_DECODE(race_mycheckpointdelta), -(race_mycheckpointenemy == ""), race_mycheckpointlapsdelta, race_mycheckpointenemy);
+ s = MakeRaceString(race_mycheckpoint, TIME_DECODE(race_mycheckpointdelta), -(race_mycheckpointenemy == ""), 0, race_mycheckpointlapsdelta, race_mycheckpointenemy);
str_pos = pos + vec2(0.5 * (mySize.x - stringwidth(s, true, '1 1 0' * 0.2 * mySize.y)), 0.6 * mySize.y);
drawcolorcodedstring(str_pos, s, '1 1 0' * 0.2 * mySize.y, panel_fg_alpha * a, DRAWFLAG_NORMAL);
}
if(race_othercheckpointtime && race_othercheckpointenemy != "")
{
a = bound(0, 2 - (time - race_othercheckpointtime), 1);
- s = MakeRaceString(race_othercheckpoint, -TIME_DECODE(race_othercheckpointdelta), -(race_othercheckpointenemy == ""), race_othercheckpointlapsdelta, race_othercheckpointenemy);
+ s = MakeRaceString(race_othercheckpoint, -TIME_DECODE(race_othercheckpointdelta), -(race_othercheckpointenemy == ""), 0, race_othercheckpointlapsdelta, race_othercheckpointenemy);
str_pos = pos + vec2(0.5 * (mySize.x - stringwidth(s, true, '1 1 0' * 0.2 * mySize.y)), 0.6 * mySize.y);
drawcolorcodedstring(str_pos, s, '1 1 0' * 0.2 * mySize.y, panel_fg_alpha * a, DRAWFLAG_NORMAL);
}
#include "scoreboard.qh"
#include <common/ent_cs.qh>
#include <common/mapinfo.qh>
+#include <common/scores.qh>
// Score (#7)
#include <common/net_linked.qh>
#include <common/mapinfo.qh>
#include <common/minigames/cl_minigames.qh>
+#include <common/scores.qh>
#include <common/stats.qh>
#include <common/teams.qh>
#include <common/minigames/cl_minigames_hud.qh>
#include <common/net_linked.qh>
#include <common/net_notice.qh>
+#include <common/scores.qh>
#include <common/triggers/include.qh>
#include <common/vehicles/all.qh>
#include <lib/csqcmodel/cl_model.qh>
void Spawn_Draw(entity this)
{
+ if(this.alpha <= 0)
+ return;
+
__pointparticles(this.cnt, this.origin + '0 0 28', '0 0 2', bound(0, frametime, 0.1));
}
float alph;
vector org = getpropertyvec(VF_ORIGIN);
if(this.fade_start)
- alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1);
+ {
+ if(vdist(org - this.origin, >, this.fade_end))
+ alph = 0; // save on some processing
+ else if(vdist(org - this.origin, <, this.fade_start))
+ alph = 1; // more processing saved
+ else
+ alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1);
+ }
else
alph = 1;
//printf("%v <-> %v\n", view_origin, this.origin + 0.5 * (this.mins + this.maxs));
if(this.snd_looping > 0)
{
- sound(this, this.snd_looping, SND_Null, VOL_BASE, autocvar_g_jetpack_attenuation);
+ sound(this, this.snd_looping, SND_Null, VOL_BASE, autocvar_cl_jetpack_attenuation);
this.snd_looping = 0;
}
forcefog = strzone(ReadString());
armorblockpercent = ReadByte() / 255.0;
+ damagepush_speedfactor = ReadByte() / 255.0;
serverflags = ReadByte();
race_checkpoint = ReadByte();
race_time = ReadInt24_t();
race_previousbesttime = ReadInt24_t();
+ race_mypreviousbesttime = ReadInt24_t();
if(race_previousbestname)
strunzone(race_previousbestname);
- race_previousbestname = strzone(ReadString());
+ string pbestname = ReadString();
+ if(autocvar_cl_race_cptimes_onlyself)
+ {
+ race_previousbesttime = race_mypreviousbesttime;
+ race_mypreviousbesttime = 0;
+ race_previousbestname = strzone("");
+ }
+ else
+ race_previousbestname = strzone(pbestname);
race_checkpointtime = time;
race_penaltyaccumulator = 0;
race_laptime = time; // valid
}
-
break;
case RACE_NET_CHECKPOINT_CLEAR:
race_nextcheckpoint = ReadByte();
race_nextbesttime = ReadInt24_t();
+ if(b != RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING) // not while spectating (matches server)
+ race_mybesttime = ReadInt24_t();
if(race_nextbestname)
strunzone(race_nextbestname);
- race_nextbestname = strzone(ReadString());
+ string newname = ReadString();
+ if(autocvar_cl_race_cptimes_onlyself && b != RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING)
+ {
+ race_nextbesttime = race_mybesttime;
+ race_mybesttime = 0;
+ race_nextbestname = strzone("");
+ }
+ else
+ race_nextbestname = strzone(newname);
break;
case RACE_NET_CHECKPOINT_HIT_RACE:
race_mycheckpointlapsdelta -= 256;
if(race_mycheckpointenemy)
strunzone(race_mycheckpointenemy);
- race_mycheckpointenemy = strzone(ReadString());
+ int who = ReadByte();
+ if(who)
+ race_mycheckpointenemy = strzone(entcs_GetName(who - 1));
+ else
+ race_mycheckpointenemy = strzone(""); // TODO: maybe string_null works fine here?
break;
case RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT:
race_othercheckpointlapsdelta -= 256;
if(race_othercheckpointenemy)
strunzone(race_othercheckpointenemy);
- race_othercheckpointenemy = strzone(ReadString());
+ int what = ReadByte();
+ if(what)
+ race_othercheckpointenemy = strzone(entcs_GetName(what - 1));
+ else
+ race_othercheckpointenemy = strzone(""); // TODO: maybe string_null works fine here?
break;
case RACE_NET_PENALTY_RACE:
const float ALPHA_MIN_VISIBLE = 0.003;
float armorblockpercent;
+float damagepush_speedfactor;
//hooks
int calledhooks;
return vec;
}
+bool projected_on_screen(vector screen_pos)
+{
+ return screen_pos.z >= 0
+ && screen_pos.x >= 0
+ && screen_pos.y >= 0
+ && screen_pos.x < vid_conwidth
+ && screen_pos.y < vid_conheight;
+}
+
float expandingbox_sizefactor_from_fadelerp(float fadelerp)
{
return 1.2 / (1.2 - fadelerp);
color = color + factor * (acc_col[j+1] - color);
return color;
}
-
/** entity id */ i(entity, MUTATOR_ARGV_0_entity) \
/**/
MUTATOR_HOOKABLE(DrawViewModel, EV_DrawViewModel);
+
+/** Called when updating the view's liquid contents, return true to disable the standard checks and apply your own */
+MUTATOR_HOOKABLE(HUD_Contents, EV_NO_ARGS);
+
+/** Return true to disable player model/color forcing */
+#define EV_ForcePlayermodels_Skip(i, o) \
+ /** entity id */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** is local */ i(bool, MUTATOR_ARGV_1_bool) \
+ /**/
+MUTATOR_HOOKABLE(ForcePlayermodels_Skip, EV_ForcePlayermodels_Skip);
e.csqcmodel_effects = fx;
CSQCModel_Effects_Apply(e);
}
+ if(a >= 0)
{
string name = wep.mdl;
string newname = wep.wr_viewmodel(wep, this);
}
}
+const int MAX_SPECIALCOMMAND = 15;
+vector specialcommand_slots[MAX_SPECIALCOMMAND];
+vector specialcommand_colors[MAX_SPECIALCOMMAND];
+const float SPECIALCOMMAND_SPEED = 150;
+const float SPECIALCOMMAND_TURNSPEED = 2;
+const float SPECIALCOMMAND_SIZE = 0.025;
+const float SPECIALCOMMAND_CHANCE = 0.35;
+float sc_spawntime, sc_changetime;
+vector sc_color = '1 1 1';
+void SpecialCommand()
+{
+ if(!STAT(MOVEVARS_SPECIALCOMMAND))
+ return;
+
+ if(time >= sc_changetime)
+ {
+ sc_changetime = time + 1;
+ sc_color = randomvec() * 1.5;
+ sc_color.x = bound(0.2, sc_color.x, 0.75);
+ sc_color.y = bound(0.2, sc_color.y, 0.75);
+ sc_color.z = bound(0.2, sc_color.z, 0.75);
+ }
+ drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), sc_color, autocvar_hud_colorflash_alpha * bound(0.1, sc_changetime - time, 0.3), DRAWFLAG_ADDITIVE);
+
+ if(!precache_pic("gfx/smile"))
+ return; // damn party poopers
+
+ for(int j = MAX_SPECIALCOMMAND - 1; j >= 0; --j)
+ {
+ vector slot = specialcommand_slots[j];
+ if(slot.y)
+ slot.y += SPECIALCOMMAND_SPEED * frametime;
+ if(slot.z)
+ slot.z = sin(SPECIALCOMMAND_TURNSPEED * M_PI * time);
+ if(slot.y >= vid_conheight)
+ slot = '0 0 0';
+
+ if(slot == '0 0 0')
+ {
+ if(random() <= SPECIALCOMMAND_CHANCE && time > sc_spawntime) // low chance to spawn!
+ {
+ slot.x = bound(0, (random() * vid_conwidth + 1), vid_conwidth);
+ slot.y = 1; // start it off 0 so we can use it
+ slot.z = random();
+ sc_spawntime = time + bound(0.4, random(), 0.75); // prevent spawning another one for this amount of time!
+ vector newcolor = randomvec() * 2;
+ newcolor.x = bound(0.4, newcolor.x, 1);
+ newcolor.y = bound(0.4, newcolor.y, 1);
+ newcolor.z = bound(0.4, newcolor.z, 1);
+ specialcommand_colors[j] = newcolor;
+ }
+ }
+ else
+ {
+ vector splash_size = '0 0 0';
+ splash_size.x = max(vid_conwidth, vid_conheight) * SPECIALCOMMAND_SIZE;
+ splash_size.y = max(vid_conwidth, vid_conheight) * SPECIALCOMMAND_SIZE;
+ drawpic(vec2(slot), "gfx/smile", vec2(splash_size), specialcommand_colors[j], 0.95, DRAWFLAG_NORMAL);
+ //drawrotpic(vec2(slot), slot.z, "gfx/smile", vec2(splash_size), vec2(splash_size) / 2, specialcommand_colors[j], 0.95, DRAWFLAG_NORMAL);
+ }
+
+ specialcommand_slots[j] = slot;
+ }
+}
+
void HUD_Draw(entity this)
{
// if we don't know gametype and scores yet avoid drawing the scoreboard
}
// crosshair goes VERY LAST
+ SpecialCommand();
UpdateDamage();
HUD_Crosshair(this);
HitSound();
// improved polyblend
- if(autocvar_hud_contents)
+ if(autocvar_hud_contents && !MUTATOR_CALLHOOK(HUD_Contents))
{
float contentalpha_temp, incontent, liquidalpha, contentfadetime;
vector liquidcolor;
// draw 2D entities
IL_EACH(g_drawables_2d, it.draw2d, it.draw2d(it));
Draw_ShowNames_All();
-#ifdef DEBUGDRAW
+#if ENABLE_DEBUGDRAW
Debug_Draw();
#endif
}
else // add it to the end of the list if the list doesn't already have it
{
- argc = tokenizebyseparator(cvar_string(original_cvar), " ");
- int i;
- for(i = 0; i < argc; ++i)
- if(argv(i) == tmp_string)
- return; // already in list
+ FOREACH_WORD(cvar_string(original_cvar), it == tmp_string,
+ {
+ return; // already in the list
+ });
- cvar_set(original_cvar, strcat(tmp_string, " ", cvar_string(original_cvar)));
+ cvar_set(original_cvar, cons(cvar_string(original_cvar), tmp_string));
}
return;
}
{
if(argc == 3)
{
- float i;
string original_cvar = argv(1);
string removal = argv(2);
- string tmp_string;
- argc = tokenizebyseparator(cvar_string(original_cvar), " ");
-
- tmp_string = "";
- for(i = 0; i < argc; ++i)
- if(argv(i) != removal)
- tmp_string = strcat(tmp_string, " ", argv(i));
+ string tmp_string = "";
+ FOREACH_WORD(cvar_string(original_cvar), it != removal,
+ {
+ tmp_string = cons(tmp_string, it);
+ });
- tmp_string = substring(tmp_string, 1, strlen(tmp_string) - 1);
cvar_set(original_cvar, tmp_string);
return;
const int RANKINGS_CNT = 15;
-const int SPRITERULE_DEFAULT = 0;
-const int SPRITERULE_TEAMPLAY = 1;
-const int SPRITERULE_SPECTATOR = 2;
-
///////////////////////////
// keys pressed
const int KEY_FORWARD = BIT(0);
// # of maps, I'll use arrays for them :P
const int MAPVOTE_COUNT = 30;
-/**
- * Lower scores are better (e.g. suicides)
- */
-const int SFL_LOWER_IS_BETTER = BIT(0);
-
-/**
- * Don't show zero values as scores
- */
-const int SFL_HIDE_ZERO = BIT(1);
-
-/**
- * Allow a column to be hidden (do not automatically add it even if it is a sorting key)
- */
-const int SFL_ALLOW_HIDE = BIT(4);
-
-/**
- * Display as a rank (with st, nd, rd, th suffix)
- */
-const int SFL_RANK = BIT(5);
-
-/**
- * Display as mm:ss.s, value is stored as 10ths of a second (AND 0 is the worst possible value!)
- */
-const int SFL_TIME = BIT(6);
-
-// not an extra constant yet
-#define SFL_ZERO_IS_WORST SFL_TIME
-
-/**
- * Scoring priority (NOTE: PRIMARY is used for fraglimit)
- */
-const int SFL_SORT_PRIO_SECONDARY = 4;
-const int SFL_SORT_PRIO_PRIMARY = 8;
-const int SFL_SORT_PRIO_MASK = 12;
-
-/*
- * Score indices
- */
-
-#ifdef GAMEQC
-
-#define IS_INCREASING(x) ( (x) & SFL_LOWER_IS_BETTER )
-#define IS_DECREASING(x) ( !((x) & SFL_LOWER_IS_BETTER) )
-
-
-#define MAX_SCORE 64
-
-#define REGISTER_SP(id) REGISTER(Scores, SP, id, m_id, new_pure(PlayerScoreField))
-REGISTRY(Scores, MAX_SCORE);
-#define Scores_from(i) _Scores_from(i, NULL)
-REGISTER_REGISTRY(Scores)
-REGISTRY_SORT(Scores);
-REGISTRY_CHECK(Scores);
-STATIC_INIT(Scores_renumber) { FOREACH(Scores, true, it.m_id = i); }
-
-USING(PlayerScoreField, entity);
-.int _scores[MAX_SCORE];
-.string m_name;
-.int m_flags;
-
-#define scores(this) _scores[(this).m_id]
-#define scores_label(this) ((this).m_name)
-#define scores_flags(this) ((this).m_flags)
-
-REGISTER_SP(END);
-
-REGISTER_SP(PING);
-REGISTER_SP(PL);
-REGISTER_SP(NAME);
-REGISTER_SP(KDRATIO);
-REGISTER_SP(SUM);
-
-REGISTER_SP(SEPARATOR);
-
-REGISTER_SP(SCORE);
-
-REGISTER_SP(DMG);
-REGISTER_SP(DMGTAKEN);
-
-REGISTER_SP(KILLS);
-REGISTER_SP(DEATHS);
-REGISTER_SP(SUICIDES);
-REGISTER_SP(FRAGS);
-
-REGISTER_SP(ELO);
-
-// TODO: move to common mutators
-
-REGISTER_SP(RACE_TIME);
-REGISTER_SP(RACE_LAPS);
-REGISTER_SP(RACE_FASTEST);
-
-//REGISTER_SP(CTS_TIME);
-//REGISTER_SP(CTS_LAPS);
-//REGISTER_SP(CTS_FASTEST);
-
-REGISTER_SP(ASSAULT_OBJECTIVES);
-
-REGISTER_SP(CTF_PICKUPS);
-REGISTER_SP(CTF_FCKILLS);
-REGISTER_SP(CTF_RETURNS);
-REGISTER_SP(CTF_CAPS);
-REGISTER_SP(CTF_CAPTIME);
-REGISTER_SP(CTF_DROPS);
-
-REGISTER_SP(DOM_TAKES);
-REGISTER_SP(DOM_TICKS);
-
-REGISTER_SP(FREEZETAG_REVIVALS);
-
-REGISTER_SP(KEEPAWAY_PICKUPS);
-REGISTER_SP(KEEPAWAY_BCTIME);
-REGISTER_SP(KEEPAWAY_CARRIERKILLS);
-
-REGISTER_SP(KH_PICKUPS);
-REGISTER_SP(KH_CAPS);
-REGISTER_SP(KH_KCKILLS);
-REGISTER_SP(KH_PUSHES);
-REGISTER_SP(KH_DESTROYS);
-REGISTER_SP(KH_LOSSES);
-
-REGISTER_SP(LMS_RANK);
-REGISTER_SP(LMS_LIVES);
-
-REGISTER_SP(NEXBALL_GOALS);
-REGISTER_SP(NEXBALL_FAULTS);
-
-REGISTER_SP(ONS_TAKES);
-REGISTER_SP(ONS_CAPS);
-
-#define MAX_TEAMSCORE 2
-USING(ScoreTeam, string);
-.int _teamscores[MAX_TEAMSCORE];
-#define teamscores(i) _teamscores[i]
-string _teamscores_label[MAX_TEAMSCORE];
-#define teamscores_label(i) _teamscores_label[i]
-int _teamscores_flags[MAX_TEAMSCORE];
-#define teamscores_flags(i) _teamscores_flags[i]
-
-#endif
-
-const int ST_SCORE = 0;
-
-// game mode specific indices are not in common/, but in server/scores_rules.qc!
-
-// WEAPONTODO: move this into separate/new projectile handling code // this sets sounds and other properties of the projectiles in csqc
-const int PROJECTILE_ELECTRO = 1;
-const int PROJECTILE_ROCKET = 2;
-const int PROJECTILE_TAG = 3;
-const int PROJECTILE_CRYLINK = 5;
-const int PROJECTILE_ELECTRO_BEAM = 6;
-const int PROJECTILE_GRENADE = 7;
-const int PROJECTILE_GRENADE_BOUNCING = 8;
-const int PROJECTILE_MINE = 9;
-const int PROJECTILE_BLASTER = 10;
-const int PROJECTILE_HLAC = 11;
-const int PROJECTILE_SEEKER = 12;
-const int PROJECTILE_FLAC = 13;
-const int PROJECTILE_PORTO_RED = 14;
-const int PROJECTILE_PORTO_BLUE = 15;
-const int PROJECTILE_HOOKBOMB = 16;
-const int PROJECTILE_HAGAR = 17;
-const int PROJECTILE_HAGAR_BOUNCING = 18;
-const int PROJECTILE_CRYLINK_BOUNCING = 20;
-const int PROJECTILE_FIREBALL = 21;
-const int PROJECTILE_FIREMINE = 22;
-
-const int PROJECTILE_RAPTORCANNON = 24;
-const int PROJECTILE_RAPTORBOMB = 25;
-const int PROJECTILE_RAPTORBOMBLET = 26;
-const int PROJECTILE_SPIDERROCKET = 27;
-const int PROJECTILE_WAKIROCKET = 28;
-const int PROJECTILE_WAKICANNON = 29;
-
-const int PROJECTILE_BUMBLE_GUN = 30;
-const int PROJECTILE_BUMBLE_BEAM = 31;
-
-const int PROJECTILE_MAGE_SPIKE = 32;
-const int PROJECTILE_SHAMBLER_LIGHTNING = 33;
-
-const int PROJECTILE_ROCKETMINSTA_LASER = 34;
-
-const int PROJECTILE_ARC_BOLT = 35;
-
-// projectile IDs 40-50 reserved
-
-const int PROJECTILE_RPC = 60;
-
const int SPECIES_HUMAN = 0;
const int SPECIES_ROBOT_SOLID = 1;
const int SPECIES_ALIEN = 2;
const int FRAGS_PLAYER_NONSOLID = FRAGS_LMS_LOSER;
// we can use this frags value for both
-// water levels
-const int WATERLEVEL_NONE = 0;
-const int WATERLEVEL_WETFEET = 1;
-const int WATERLEVEL_SWIMMING = 2;
-const int WATERLEVEL_SUBMERGED = 3;
-
// server flags
const int SERVERFLAG_ALLOW_FULLBRIGHT = 1;
const int SERVERFLAG_TEAMPLAY = 2;
const int SERVERFLAG_PLAYERSTATS = 4;
-#ifdef SVQC
-// FIXME/EXPLAINME: why? Mario: because
-vector autocvar_sv_player_maxs = '16 16 45';
-vector autocvar_sv_player_mins = '-16 -16 -24';
-vector autocvar_sv_player_viewoffset = '0 0 35';
-vector autocvar_sv_player_crouch_maxs = '16 16 25';
-vector autocvar_sv_player_crouch_mins = '-16 -16 -24';
-vector autocvar_sv_player_crouch_viewoffset = '0 0 20';
-//vector autocvar_sv_player_headsize = '24 24 12';
-
-// temporary array used to dump weapon and turret settings
-const int MAX_CONFIG_SETTINGS = 256;
-string config_queue[MAX_CONFIG_SETTINGS];
-
-#endif
-
-
// a bit more constant
const vector PL_MAX_CONST = '16 16 45';
const vector PL_MIN_CONST = '-16 -16 -24';
-// spawnpoint prios
-const int SPAWN_PRIO_NEAR_TEAMMATE_FOUND = 200;
-const int SPAWN_PRIO_NEAR_TEAMMATE_SAMETEAM = 100;
-const int SPAWN_PRIO_RACE_PREVIOUS_SPAWN = 50;
-const int SPAWN_PRIO_GOOD_DISTANCE = 10;
-
// gametype vote flags
const int GTV_FORBIDDEN = 0; // Cannot be voted
const int GTV_AVAILABLE = 1; // Can be voted
}
#endif
-#ifdef DEBUGDRAW
+#if ENABLE_DEBUGDRAW
#ifdef GAMEQC
/**
* 0: off
}
}
-#ifdef DEBUGTRACE
+#if ENABLE_DEBUGTRACE
REGISTER_STAT(TRACE_ENT, int)
#ifdef SVQC
bool autocvar_debugtrace;
}
#endif
-#ifdef EFFECTINFO_ENABLED
+#if ENABLE_EFFECTINFO
#include "effectinfo.qc"
#endif
if(it.damageforcescale)
if(vdist(thisforce, !=, 0))
{
- it.velocity = it.velocity + damage_explosion_calcpush(it.damageforcescale * thisforce, it.velocity, autocvar_g_balance_damagepush_speedfactor);
+ it.velocity = it.velocity + damage_explosion_calcpush(it.damageforcescale * thisforce, it.velocity, damagepush_speedfactor);
UNSET_ONGROUND(it);
}
LogNB("stole", attacker);
_sound(toucher, CH_TRIGGER, ball.noise2, VOL_BASE, ATTEN_NORM);
- if(SAME_TEAM(attacker, toucher) && time > attacker.teamkill_complain)
+ if(SAME_TEAM(attacker, toucher) && time > CS(attacker).teamkill_complain)
{
- attacker.teamkill_complain = time + 5;
- attacker.teamkill_soundtime = time + 0.4;
- attacker.teamkill_soundsource = toucher;
+ CS(attacker).teamkill_complain = time + 5;
+ CS(attacker).teamkill_soundtime = time + 0.4;
+ CS(attacker).teamkill_soundsource = toucher;
}
GiveBall(attacker, toucher.ballcarried);
entity paddle = ball.owner.pong_paddles[pteam-1];
if (!paddle)
return false;
- vector near_point = box_nearest(paddle.mins+paddle.origin,
- paddle.maxs+paddle.origin, ball.origin);
+
+#if 1
+ vector near_point = box_nearest(paddle.m_mins+paddle.origin,
+ paddle.m_maxs+paddle.origin, ball.origin);
return vdist(near_point - ball.origin, <=, ball.pong_length);
+#else
+ return boxesoverlap(paddle.m_mins + paddle.origin, paddle.m_maxs + paddle.origin, ball.m_mins + ball.origin, ball.m_maxs + ball.origin);
+#endif
}
// Checks for a goal, when that happes adds scores and resets the ball
if ( this.realowner.minigame_players.pong_keys == PONG_KEY_INCREASE ||
this.realowner.minigame_players.pong_keys == PONG_KEY_DECREASE )
{
- float movement = autocvar_sv_minigames_pong_paddle_speed * think_speed;
+ float pmovement = autocvar_sv_minigames_pong_paddle_speed * think_speed;
float halflen = this.pong_length/2;
if ( this.realowner.minigame_players.pong_keys == PONG_KEY_DECREASE )
- movement *= -1;
+ pmovement *= -1;
if ( this.team > 2 )
- this.origin_x = bound(halflen, this.origin_x+movement, 1-halflen);
+ this.origin_x = bound(halflen, this.origin_x+pmovement, 1-halflen);
else
- this.origin_y = bound(halflen, this.origin_y+movement, 1-halflen);
+ this.origin_y = bound(halflen, this.origin_y+pmovement, 1-halflen);
this.SendFlags |= MINIG_SF_UPDATE;
}
setthink(paddle, pong_paddle_think);
paddle.nextthink = time;
paddle.team = pl_team;
- paddle.mins = pong_team_to_box_halfsize(pl_team,-paddle.pong_length,-1/16);
- paddle.maxs = pong_team_to_box_halfsize(pl_team,paddle.pong_length,1/16);
+ paddle.m_mins = pong_team_to_box_halfsize(pl_team,-paddle.pong_length,-1/16);
+ paddle.m_maxs = pong_team_to_box_halfsize(pl_team,paddle.pong_length,1/16);
if ( real_player == NULL )
pong_ai_spawn(paddle);
(minigame.minigame_flags & ~PONG_STATUS_WAIT);
minigame.SendFlags |= MINIG_SF_UPDATE;
- int i;
entity ball;
- for ( i = 0; i < autocvar_sv_minigames_pong_ball_number; i++ )
+ for ( int j = 0; j < autocvar_sv_minigames_pong_ball_number; j++ )
{
ball = msle_spawn(minigame,"pong_ball");
ball.pong_length = autocvar_sv_minigames_pong_ball_radius;
+ ball.m_mins = vec2(-ball.pong_length, -ball.pong_length);
+ ball.m_maxs = vec2(ball.pong_length, ball.pong_length);
pong_ball_reset(ball);
}
}
case "-moved":
player.pong_keys &= ~PONG_KEY_DECREASE;
return true;
+ case "move":
+ if(argv(1))
+ player.pong_keys = stoi(argv(1));
+ return true;
case "pong_aimore":
{
- int i;
+ // keep declaration here, moving it into for() reverses weapon order
+ // potentially compiler bug
+ int j;
if ( minigame.minigame_flags & PONG_STATUS_WAIT )
- for ( i = 0; i < PONG_MAX_PLAYERS; i++ )
+ for ( j = 0; j < PONG_MAX_PLAYERS; j++ )
+ //for ( int j = 0; j < PONG_MAX_PLAYERS; j++ )
{
- if ( minigame.pong_paddles[i] == NULL )
+ if ( minigame.pong_paddles[j] == NULL )
{
- pong_paddle_spawn(minigame,i+1,NULL);
+ pong_paddle_spawn(minigame,j+1,NULL);
return true;
}
}
if ( minigame.minigame_flags & PONG_STATUS_WAIT )
{
entity paddle;
- int i;
- for ( i = PONG_MAX_PLAYERS-1; i >= 0; i-- )
+ for ( int j = PONG_MAX_PLAYERS-1; j >= 0; j-- )
{
- paddle = minigame.pong_paddles[i];
+ paddle = minigame.pong_paddles[j];
if ( paddle != NULL &&
paddle.realowner.classname == "pong_ai" )
{
- minigame.pong_paddles[i] = NULL;
+ minigame.pong_paddles[j] = NULL;
delete(paddle.realowner);
delete(paddle);
return true;
}
}
+int pong_keys_pressed;
+int pong_keys_pressed_old;
+
// Required function, draw the game board
void pong_hud_board(vector pos, vector mySize)
{
+ if(pong_keys_pressed != pong_keys_pressed_old)
+ minigame_cmd(strcat("move ", itos(pong_keys_pressed)));
+ pong_keys_pressed_old = pong_keys_pressed;
+
minigame_hud_fitsqare(pos, mySize);
minigame_hud_simpleboard(pos,mySize,minigame_texture("pong/board"));
case K_KP_UPARROW:
case K_LEFTARROW:
case K_KP_LEFTARROW:
- minigame_cmd("+moved");
+ //minigame_cmd("+moved");
+ pong_keys_pressed |= PONG_KEY_DECREASE;
return true;
case K_DOWNARROW:
case K_KP_DOWNARROW:
case K_RIGHTARROW:
case K_KP_RIGHTARROW:
- minigame_cmd("+movei");
+ //minigame_cmd("+movei");
+ pong_keys_pressed |= PONG_KEY_INCREASE;
return true;
}
return false;
case K_KP_UPARROW:
case K_LEFTARROW:
case K_KP_LEFTARROW:
- minigame_cmd("-moved");
+ //minigame_cmd("-moved");
+ pong_keys_pressed &= ~PONG_KEY_DECREASE;
return true;
case K_DOWNARROW:
case K_KP_DOWNARROW:
case K_RIGHTARROW:
case K_KP_RIGHTARROW:
- minigame_cmd("-movei");
+ //minigame_cmd("-movei");
+ pong_keys_pressed &= ~PONG_KEY_INCREASE;
return true;
}
return false;
void player_clear_minigame(entity player)
{
- player.active_minigame = NULL;
+ CS(player).active_minigame = NULL;
player.minigame_players = NULL;
if ( IS_PLAYER(player) )
set_movetype(player, MOVETYPE_WALK);
GameLogEcho(strcat(":minigame:part:",minigame_session.netname,":",
ftos(etof(player)),":",player.netname));
minigame_session.minigame_players = p.list_next;
- delete ( p );
+ delete( p );
player_clear_minigame(player);
}
else
int minigame_addplayer(entity minigame_session, entity player)
{
- if ( player.active_minigame )
+ if ( CS(player).active_minigame )
{
- if ( player.active_minigame == minigame_session )
+ if ( CS(player).active_minigame == minigame_session )
return 0;
- minigame_rmplayer(player.active_minigame,player);
+ minigame_rmplayer(CS(player).active_minigame,player);
}
entity player_pointer = new(minigame_player);
int mgteam = minigame_session.minigame_event(minigame_session,"join",player,player_pointer);
player_pointer.team = mgteam;
player_pointer.list_next = minigame_session.minigame_players;
minigame_session.minigame_players = player_pointer;
- player.active_minigame = minigame_session;
+ CS(player).active_minigame = minigame_session;
player.minigame_players = player_pointer;
setcefc(player_pointer, minigame_CheckSend);
Net_LinkEntity(player_pointer, false, 0, minigame_SendEntity);
void part_minigame(entity player )
{
- entity minig = player.active_minigame;
+ entity minig = CS(player).active_minigame;
if ( minig && minig.classname == "minigame" )
minigame_rmplayer(minig,player);
string invite_minigame(entity inviter, entity player)
{
- if ( !inviter || !inviter.active_minigame )
+ if ( !inviter || !CS(inviter).active_minigame )
return "Invalid minigame";
if ( VerifyClientEntity(player, true, false) <= 0 )
return "Invalid player";
if ( inviter == player )
return "You can't invite yourself";
- if ( player.active_minigame == inviter.active_minigame )
+ if ( CS(player).active_minigame == CS(inviter).active_minigame )
return strcat(player.netname," is already playing");
Send_Notification(NOTIF_ONE, player, MSG_INFO, INFO_MINIGAME_INVITE,
- inviter.active_minigame.netname, inviter.netname );
+ CS(inviter).active_minigame.netname, inviter.netname );
- GameLogEcho(strcat(":minigame:invite:",inviter.active_minigame.netname,":",
+ GameLogEcho(strcat(":minigame:invite:",CS(inviter).active_minigame.netname,":",
ftos(etof(player)),":",player.netname));
return "";
entity minigame_find_player(entity client)
{
- if ( ! client.active_minigame )
+ if ( ! CS(client).active_minigame )
return NULL;
entity e;
- for ( e = client.active_minigame.minigame_players; e; e = e.list_next )
+ for ( e = CS(client).active_minigame.minigame_players; e; e = e.list_next )
if ( e.minigame_players == client )
return e;
return NULL;
bool MinigameImpulse(entity this, int imp)
{
- if (!this.active_minigame) return false;
+ if (!CS(this).active_minigame) return false;
entity e = minigame_find_player(this);
- if ( imp && this.active_minigame && e )
+ if ( imp && CS(this).active_minigame && e )
{
- return this.active_minigame.minigame_event(this.active_minigame,"impulse",e,imp);
+ return CS(this).active_minigame.minigame_event(CS(this).active_minigame,"impulse",e,imp);
}
return false;
}
}
else if ( minig_cmd == "end" || minig_cmd == "part" )
{
- if ( caller.active_minigame )
+ if ( CS(caller).active_minigame )
{
part_minigame(caller);
sprint(caller,"Left minigame session\n");
}
else if ( minig_cmd == "invite" && argc > 2 )
{
- if ( caller.active_minigame )
+ if ( CS(caller).active_minigame )
{
entity client = GetIndexedEntity(argc, 2);
string error = invite_minigame(caller,client);
if ( error == "" )
{
sprint(caller,"You have invited ",client.netname,
- " to join your game of ", caller.active_minigame.descriptor.message, "\n");
+ " to join your game of ", CS(caller).active_minigame.descriptor.message, "\n");
}
else
sprint(caller,"Could not invite: ", error, ".\n");
sprint(caller,"You aren't playing any minigame...\n");
return;
}
- else if ( caller.active_minigame )
+ else if ( CS(caller).active_minigame )
{
entity e = minigame_find_player(caller);
string subcommand = substring(command,argv_end_index(0),-1);
int arg_c = tokenize_console(subcommand);
- if ( caller.active_minigame.minigame_event(caller.active_minigame,"cmd",e,arg_c,subcommand) )
+ if ( CS(caller).active_minigame.minigame_event(CS(caller).active_minigame,"cmd",e,arg_c,subcommand) )
return;
}
MODEL(VEH_SPIDERBOT_VIEW, "models/vehicles/spiderbot_cockpit.dpm");
MODEL(CHAT, "models/misc/chatbubble.spr");
+MODEL(CHAT_MINIGAME, "models/sprites/minigame_busy.iqm");
MODEL(0, "models/sprites/0.spr32");
MODEL(1, "models/sprites/1.spr32");
Send_Effect(EFFECT_EXPLOSION_SMALL, this.origin, '0 0 0', 1);
RadiusDamage (this, this.realowner, (autocvar_g_monster_mage_attack_spike_damage), (autocvar_g_monster_mage_attack_spike_damage) * 0.5, (autocvar_g_monster_mage_attack_spike_radius), NULL, NULL, 0, DEATH_MONSTER_MAGE.m_id, directhitentity);
- delete (this);
+ delete(this);
}
void M_Mage_Attack_Spike_Touch(entity this, entity toucher)
return;
}
- if((this.team && DIFF_TEAM(toucher, this))
- || (STAT(FROZEN, toucher))
- || (toucher.vehicle)
- || (time < toucher.buff_shield)
- || (!this.buff_active)
- )
- {
- // can't touch this
+ if(!this.buff_active)
return;
- }
if(MUTATOR_CALLHOOK(BuffTouch, this, toucher))
return;
if(!IS_PLAYER(toucher))
return; // incase mutator changed toucher
+ if((this.team && DIFF_TEAM(toucher, this))
+ || (STAT(FROZEN, toucher))
+ || (toucher.vehicle)
+ || (time < PS(toucher).buff_shield)
+ )
+ {
+ // can't touch this
+ return;
+ }
+
if (toucher.buffs)
{
if (toucher.cvar_cl_buffs_autoreplace && toucher.buffs != this.buffs)
player.buffs = 0;
player.buff_time = 0;
- player.buff_shield = time + 0.5; // prevent picking up buffs immediately
+ PS(player).buff_shield = time + 0.5; // prevent picking up buffs immediately
// reset timers here to prevent them continuing after re-spawn
player.buff_disability_time = 0;
player.buff_disability_effect_time = 0;
Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid);
player.buffs = 0;
- player.buff_shield = time + max(0, autocvar_g_buffs_pickup_delay);
+ PS(player).buff_shield = time + max(0, autocvar_g_buffs_pickup_delay);
//player.buff_time = 0; // already notified
sound(player, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
return true;
else
Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid);
player.buffs = 0;
- player.buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); // always put in a delay, even if small
+ PS(player).buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); // always put in a delay, even if small
}
}
#endif
+float racecar_angle(float forward, float down)
+{
+ if (forward < 0)
+ {
+ forward = -forward;
+ down = -down;
+ }
+
+ float ret = vectoyaw('0 1 0' * down + '1 0 0' * forward);
+
+ float angle_mult = forward / (800 + forward);
+
+ if (ret > 180)
+ return ret * angle_mult + 360 * (1 - angle_mult);
+ else
+ return ret * angle_mult;
+}
+
void RaceCarPhysics(entity this, float dt)
{
// using this move type for "big rigs"
vector rigvel;
vector angles_save = this.angles;
- float accel = bound(-1, this.movement.x / PHYS_MAXSPEED(this), 1);
- float steer = bound(-1, this.movement.y / PHYS_MAXSPEED(this), 1);
+ float accel = bound(-1, PHYS_CS(this).movement.x / PHYS_MAXSPEED(this), 1);
+ float steer = bound(-1, PHYS_CS(this).movement.y / PHYS_MAXSPEED(this), 1);
if (PHYS_BUGRIGS_REVERSE_SPEEDING(this))
{
{
// now set angles_x so that the car points parallel to the surface
this.angles = vectoangles(
- '1 0 0' * v_forward_x * trace_plane_normal_z
+ '1 0 0' * v_forward.x * trace_plane_normal.z
+
- '0 1 0' * v_forward_y * trace_plane_normal_z
+ '0 1 0' * v_forward.y * trace_plane_normal.z
+
- '0 0 1' * -(v_forward_x * trace_plane_normal_x + v_forward_y * trace_plane_normal_y)
+ '0 0 1' * -(v_forward.x * trace_plane_normal.x + v_forward.y * trace_plane_normal.y)
);
SET_ONGROUND(this);
}
if (trace_fraction != 1)
{
this.angles = vectoangles2(
- '1 0 0' * v_forward_x * trace_plane_normal_z
+ '1 0 0' * v_forward.x * trace_plane_normal.z
+
- '0 1 0' * v_forward_y * trace_plane_normal_z
+ '0 1 0' * v_forward.y * trace_plane_normal.z
+
- '0 0 1' * -(v_forward_x * trace_plane_normal_x + v_forward_y * trace_plane_normal_y),
+ '0 0 1' * -(v_forward.x * trace_plane_normal.x + v_forward.y * trace_plane_normal.y),
trace_plane_normal
);
}
{
vector vel_local;
- vel_local_x = v_forward * this.velocity;
- vel_local_y = v_right * this.velocity;
- vel_local_z = v_up * this.velocity;
+ vel_local.x = v_forward * this.velocity;
+ vel_local.y = v_right * this.velocity;
+ vel_local.z = v_up * this.velocity;
- this.angles_x = racecar_angle(vel_local_x, vel_local_z);
- this.angles_z = racecar_angle(-vel_local_y, vel_local_z);
+ this.angles_x = racecar_angle(vel_local.x, vel_local.z);
+ this.angles_z = racecar_angle(-vel_local.y, vel_local.z);
}
// smooth the angles
vf1 = vf1 + v_forward * (1 - f);
vu1 = vu1 + v_up * (1 - f);
smoothangles = vectoangles2(vf1, vu1);
- this.angles_x = -smoothangles_x;
- this.angles_z = smoothangles_z;
+ this.angles_x = -smoothangles.x;
+ this.angles_z = smoothangles.z;
}
#ifdef SVQC
.float campcheck_nextcheck;
.float campcheck_traveled_distance;
+.vector campcheck_prevorigin;
+
MUTATOR_HOOKFUNCTION(campcheck, PlayerDies)
{
entity frag_target = M_ARGV(2, entity);
MUTATOR_HOOKFUNCTION(campcheck, PlayerPreThink)
{
entity player = M_ARGV(0, entity);
+ bool checked = false;
- if(!game_stopped)
- if(!warmup_stage) // don't consider it camping during warmup?
- if(time >= game_starttime)
+ if(autocvar_g_campcheck_interval)
+ if(!game_stopped && !warmup_stage && time >= game_starttime)
if(IS_PLAYER(player))
- if(IS_REAL_CLIENT(player)) // bots may camp, but that's no reason to constantly kill them
if(!IS_DEAD(player))
- if(!forbidWeaponUse(player))
if(!STAT(FROZEN, player))
if(!PHYS_INPUT_BUTTON_CHAT(player))
- if(autocvar_g_campcheck_interval)
+ if(IS_REAL_CLIENT(player)) // bots may camp, but that's no reason to constantly kill them
+ if(!forbidWeaponUse(player))
{
- vector dist;
-
// calculate player movement (in 2 dimensions only, so jumping on one spot doesn't count as movement)
- dist = player.prevorigin - player.origin;
- dist.z = 0;
+ vector dist = vec2(player.campcheck_prevorigin - player.origin);
player.campcheck_traveled_distance += fabs(vlen(dist));
if((autocvar_g_campaign && !campaign_bots_may_start) || (time < game_starttime) || (round_handler_IsActive() && !round_handler_IsRoundStarted()))
player.campcheck_traveled_distance = 0;
}
- return;
+ checked = true;
}
- player.campcheck_nextcheck = time + autocvar_g_campcheck_interval; // one of the above checks failed, so keep the timer up to date
+ if(!checked)
+ player.campcheck_nextcheck = time + autocvar_g_campcheck_interval; // one of the above checks failed, so keep the timer up to date
+
+ player.campcheck_prevorigin = player.origin;
+}
+
+MUTATOR_HOOKFUNCTION(campcheck, CopyBody)
+{
+ entity player = M_ARGV(0, entity);
+ entity clone = M_ARGV(1, entity);
+
+ clone.campcheck_prevorigin = player.campcheck_prevorigin;
}
MUTATOR_HOOKFUNCTION(campcheck, PlayerSpawn)
AUTOCVAR_SAVE(cl_damagetext_size_max_damage, float, 140, "How much damage is considered large");
AUTOCVAR_SAVE(cl_damagetext_alpha_start, float, 1, "Damage text initial alpha");
AUTOCVAR_SAVE(cl_damagetext_alpha_lifetime, float, 3, "Damage text lifetime in seconds");
-AUTOCVAR_SAVE(cl_damagetext_velocity, vector, '0 0 20', "Damage text move direction");
-AUTOCVAR_SAVE(cl_damagetext_offset, vector, '0 -40 0', "Damage text offset");
+AUTOCVAR_SAVE(cl_damagetext_velocity, vector, '0 0 20', "Damage text move direction (world coordinates)");
+AUTOCVAR_SAVE(cl_damagetext_offset, vector, '0 -40 0', "Damage text offset (screen coordinates)");
AUTOCVAR_SAVE(cl_damagetext_accumulate_range, float, 30, "Damage text spawned within this range is accumulated");
AUTOCVAR_SAVE(cl_damagetext_accumulate_alpha_rel, float, 0.65, "Only update existing damage text when it's above this much percentage (0 to 1) of the starting alpha");
AUTOCVAR_SAVE(cl_damagetext_friendlyfire, bool, true, "Show damage text for friendlyfire too");
AUTOCVAR_SAVE(cl_damagetext_friendlyfire_color, vector, '1 0 0', "Damage text color for friendlyfire");
+AUTOCVAR_SAVE(cl_damagetext_2d, bool, true, "Show damagetext in 2D coordinated if the enemy's location is not known");
+AUTOCVAR_SAVE(cl_damagetext_2d_pos, vector, '0.47 0.53 0', "2D damage text initial position (X and Y between 0 and 1)");
+AUTOCVAR_SAVE(cl_damagetext_2d_alpha_start, float, 1, "2D damage text initial alpha");
+AUTOCVAR_SAVE(cl_damagetext_2d_alpha_lifetime, float, 1.3, "2D damage text lifetime (alpha fading) in seconds");
+AUTOCVAR_SAVE(cl_damagetext_2d_size_lifetime, float, 3, "2D damage text lifetime (size shrinking) in seconds");
+AUTOCVAR_SAVE(cl_damagetext_2d_velocity, vector, '-25 0 0', "2D damage text move direction (screen coordinates)");
+AUTOCVAR_SAVE(cl_damagetext_2d_overlap_offset, vector, '0 -15 0', "Offset 2D damage text by this much to prevent overlapping (screen coordinates)");
+AUTOCVAR_SAVE(cl_damagetext_2d_close_range, float, 125, "Always use 2D damagetext for hits closer that this");
+AUTOCVAR_SAVE(cl_damagetext_2d_out_of_view, bool, true, "Always use 2D damagetext for hits that occured off-screen");
+
CLASS(DamageText, Object)
ATTRIB(DamageText, m_color, vector, autocvar_cl_damagetext_color);
ATTRIB(DamageText, m_color_friendlyfire, vector, autocvar_cl_damagetext_friendlyfire_color);
ATTRIB(DamageText, m_size, float, autocvar_cl_damagetext_size_min);
ATTRIB(DamageText, alpha, float, autocvar_cl_damagetext_alpha_start);
- ATTRIB(DamageText, fade_rate, float, 1 / autocvar_cl_damagetext_alpha_lifetime);
- ATTRIB(DamageText, velocity, vector, autocvar_cl_damagetext_velocity);
+ ATTRIB(DamageText, fade_rate, float, 0);
+ ATTRIB(DamageText, m_shrink_rate, float, 0);
ATTRIB(DamageText, m_group, int, 0);
ATTRIB(DamageText, m_friendlyfire, bool, false);
ATTRIB(DamageText, m_healthdamage, int, 0);
ATTRIB(DamageText, m_armordamage, int, 0);
ATTRIB(DamageText, m_potential_damage, int, 0);
ATTRIB(DamageText, m_deathtype, int, 0);
- ATTRIB(DamageText, time_prev, float, time);
+ ATTRIB(DamageText, hit_time, float, 0);
ATTRIB(DamageText, text, string, string_null);
+ ATTRIB(DamageText, m_screen_coords, bool, false);
+
+ STATIC_ATTRIB(DamageText, screen_first, DamageText, NULL);
+ STATIC_ATTRIB(DamageText, screen_count, int, 0);
void DamageText_draw2d(DamageText this) {
- float dt = time - this.time_prev;
- this.time_prev = time;
- setorigin(this, this.origin + dt * this.velocity);
- this.alpha -= dt * this.fade_rate;
- if (this.alpha < 0)
- {
+ float since_hit = time - this.hit_time;
+ float size = this.m_size - since_hit * this.m_shrink_rate * this.m_size;
+ float alpha_ = this.alpha - since_hit * this.fade_rate;
+ if (alpha_ <= 0 || size <= 0) {
delete(this);
return;
}
- vector pos = project_3d_to_2d(this.origin) + autocvar_cl_damagetext_offset;
- if (pos.z >= 0 && this.m_size > 0) {
- pos.z = 0;
+ vector screen_pos;
+ if (this.m_screen_coords) {
+ screen_pos = this.origin + since_hit * autocvar_cl_damagetext_2d_velocity;
+ } else {
+ screen_pos = project_3d_to_2d(this.origin + since_hit * autocvar_cl_damagetext_velocity) + autocvar_cl_damagetext_offset;
+ }
+ if (screen_pos.z >= 0) {
+ screen_pos.z = 0;
vector rgb;
if (this.m_friendlyfire) {
rgb = this.m_color_friendlyfire;
}
vector drawfontscale_save = drawfontscale;
- drawfontscale = (this.m_size / autocvar_cl_damagetext_size_max) * '1 1 0';
- drawcolorcodedstring2_builtin(pos, this.text, autocvar_cl_damagetext_size_max * '1 1 0', rgb, this.alpha, DRAWFLAG_NORMAL);
+ drawfontscale = (size / autocvar_cl_damagetext_size_max) * '1 1 0';
+ drawcolorcodedstring2_builtin(screen_pos, this.text, autocvar_cl_damagetext_size_max * '1 1 0', rgb, alpha_, DRAWFLAG_NORMAL);
drawfontscale = drawfontscale_save;
}
}
this.m_potential_damage = _potential_damage;
this.m_deathtype = _deathtype;
setorigin(this, _origin);
- this.alpha = autocvar_cl_damagetext_alpha_start;
+ if (this.m_screen_coords) {
+ this.alpha = autocvar_cl_damagetext_2d_alpha_start;
+ } else {
+ this.alpha = autocvar_cl_damagetext_alpha_start;
+ }
+ this.hit_time = time;
int health = rint(this.m_healthdamage / DAMAGETEXT_PRECISION_MULTIPLIER);
int armor = rint(this.m_armordamage / DAMAGETEXT_PRECISION_MULTIPLIER);
autocvar_cl_damagetext_size_max);
}
- CONSTRUCTOR(DamageText, int _group, vector _origin, int _health, int _armor, int _potential_damage, int _deathtype, bool _friendlyfire) {
+ CONSTRUCTOR(DamageText, int _group, vector _origin, bool _screen_coords, int _health, int _armor, int _potential_damage, int _deathtype, bool _friendlyfire) {
CONSTRUCT(DamageText);
this.m_group = _group;
this.m_friendlyfire = _friendlyfire;
+ this.m_screen_coords = _screen_coords;
+ if (_screen_coords) {
+ this.fade_rate = 1 / autocvar_cl_damagetext_2d_alpha_lifetime;
+ this.m_shrink_rate = 1 / autocvar_cl_damagetext_2d_size_lifetime;
+ } else {
+ this.fade_rate = 1 / autocvar_cl_damagetext_alpha_lifetime;
+ this.m_shrink_rate = 0;
+ }
DamageText_update(this, _origin, _health, _armor, _potential_damage, _deathtype);
- IL_PUSH(g_drawables_2d, this);
+ IL_PUSH(g_drawables_2d, this);
}
DESTRUCTOR(DamageText) {
if (this.text) strunzone(this.text);
+ if (this == DamageText_screen_first) {
+ // start from 0 offset again, hopefully, others (if any) will have faded away by now
+ DamageText_screen_first = NULL;
+ DamageText_screen_count = 0;
+ }
}
ENDCLASS(DamageText)
NET_HANDLE(damagetext, bool isNew)
{
- int group = ReadShort();
- vector location = vec3(ReadCoord(), ReadCoord(), ReadCoord());
+ int server_entity_index = ReadByte();
int deathtype = ReadInt24_t();
int flags = ReadByte();
bool friendlyfire = flags & DTFLAG_SAMETEAM;
else potential_damage = ReadShort();
return = true;
- if (autocvar_cl_damagetext) {
- if (friendlyfire && !autocvar_cl_damagetext_friendlyfire) {
- return;
- }
+ if (!autocvar_cl_damagetext) return;
+ if (friendlyfire && !autocvar_cl_damagetext_friendlyfire) return;
+
+ int client_entity_index = server_entity_index - 1;
+ entity entcs = entcs_receiver(client_entity_index);
+
+ bool can_use_3d = entcs && entcs.has_origin;
+ bool too_close = vdist(entcs.origin - view_origin, <, autocvar_cl_damagetext_2d_close_range);
+ bool prefer_in_view = autocvar_cl_damagetext_2d_out_of_view && !projected_on_screen(project_3d_to_2d(entcs.origin));
+ bool prefer_2d = spectatee_status != -1 && autocvar_cl_damagetext_2d && (too_close || prefer_in_view);
+
+ if (can_use_3d && !prefer_2d) {
+ // world coords
if (autocvar_cl_damagetext_accumulate_range) {
- for (entity e = findradius(location, autocvar_cl_damagetext_accumulate_range); e; e = e.chain) {
- if (e.instanceOfDamageText && e.m_group == group && e.alpha > autocvar_cl_damagetext_accumulate_alpha_rel * autocvar_cl_damagetext_alpha_start) {
- DamageText_update(e, location, e.m_healthdamage + health, e.m_armordamage + armor, e.m_potential_damage + potential_damage, deathtype);
+ for (entity e = findradius(entcs.origin, autocvar_cl_damagetext_accumulate_range); e; e = e.chain) {
+ if (e.instanceOfDamageText
+ && !e.m_screen_coords // we're using origin for both world coords and screen coords so avoid mismatches
+ && e.m_group == server_entity_index
+ && e.alpha > autocvar_cl_damagetext_accumulate_alpha_rel * autocvar_cl_damagetext_alpha_start) {
+ DamageText_update(e, entcs.origin, e.m_healthdamage + health, e.m_armordamage + armor, e.m_potential_damage + potential_damage, deathtype);
return;
}
}
}
- make_impure(NEW(DamageText, group, location, health, armor, potential_damage, deathtype, friendlyfire));
+ make_impure(NEW(DamageText, server_entity_index, entcs.origin, false, health, armor, potential_damage, deathtype, friendlyfire));
+ } else if (autocvar_cl_damagetext_2d) {
+ // screen coords only
+ vector screen_pos = vec2(vid_conwidth * autocvar_cl_damagetext_2d_pos.x, vid_conheight * autocvar_cl_damagetext_2d_pos.y);
+ IL_EACH(g_drawables_2d, it.instanceOfDamageText && it.m_screen_coords && it.m_group == server_entity_index, {
+ DamageText_update(it, screen_pos, it.m_healthdamage + health, it.m_armordamage + armor, it.m_potential_damage + potential_damage, deathtype);
+ return;
+ });
+
+ // when hitting multiple enemies, dmgtext would overlap
+ if (DamageText_screen_first == NULL) {
+ DamageText dt = NEW(DamageText, server_entity_index, screen_pos, true, health, armor, potential_damage, deathtype, friendlyfire);
+ make_impure(dt);
+ DamageText_screen_first = dt;
+ DamageText_screen_count = 1;
+ } else {
+ screen_pos += autocvar_cl_damagetext_2d_overlap_offset * DamageText_screen_count;
+ DamageText_screen_count++;
+ make_impure(NEW(DamageText, server_entity_index, screen_pos, true, health, armor, potential_damage, deathtype, friendlyfire));
+ }
}
}
const float armor = M_ARGV(3, float);
const int deathtype = M_ARGV(5, int);
const float potential_damage = M_ARGV(6, float);
- const vector location = hit.origin;
FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA(
if (
(SV_DAMAGETEXT_ALL()) ||
msg_entity = it;
WriteHeader(MSG_ONE, damagetext);
- WriteEntity(MSG_ONE, hit);
- WriteCoord(MSG_ONE, location.x);
- WriteCoord(MSG_ONE, location.y);
- WriteCoord(MSG_ONE, location.z);
+ WriteByte(MSG_ONE, etof(hit));
WriteInt24_t(MSG_ONE, deathtype);
WriteByte(MSG_ONE, flags);
#define PHYS_DODGING_WALL autocvar_sv_dodging_wall_dodging
#define PHYS_DODGING_AIR autocvar_sv_dodging_air_dodging
#define PHYS_DODGING_MAXSPEED autocvar_sv_dodging_maxspeed
-#define PHYS_DODGING_PRESSED_KEYS(s) (s).pressedkeys
// we ran out of stats slots! TODO: re-enable this when prediction is available for dodging
#if 0
#ifdef CSQC
#define PHYS_DODGING_FRAMETIME (1 / (frametime <= 0 ? 60 : frametime))
#define PHYS_DODGING_TIMEOUT(s) STAT(DODGING_TIMEOUT)
+ #define PHYS_DODGING_PRESSED_KEYS(s) (s).pressedkeys
#elif defined(SVQC)
#define PHYS_DODGING_FRAMETIME sys_frametime
#define PHYS_DODGING_TIMEOUT(s) s.cvar_cl_dodging_timeout
+ #define PHYS_DODGING_PRESSED_KEYS(s) CS(s).pressedkeys
#endif
#ifdef SVQC
float tap_direction_x = 0;
float tap_direction_y = 0;
bool dodge_detected = false;
+ vector mymovement = PHYS_CS(this).movement;
#define X(COND,BTN,RESULT) \
- if (this.movement_##COND) \
+ if (mymovement_##COND) \
/* is this a state change? */ \
if(!(PHYS_DODGING_PRESSED_KEYS(this) & KEY_##BTN) || frozen_no_doubletap) { \
tap_direction_##RESULT; \
if (this.dodging_action == 1)
{
//disable jump key during dodge accel phase
- if(this.movement_z > 0) { this.movement_z = 0; }
+ if(PHYS_CS(this).movement.z > 0) { PHYS_CS(this).movement_z = 0; }
this.velocity += ((this.dodging_direction_y * velocity_difference) * v_right)
+ ((this.dodging_direction_x * velocity_difference) * v_forward);
PM_dodging_checkpressedkeys(this);
int keys = this.pressedkeys;
- keys = BITSET(keys, KEY_FORWARD, this.movement.x > 0);
- keys = BITSET(keys, KEY_BACKWARD, this.movement.x < 0);
- keys = BITSET(keys, KEY_RIGHT, this.movement.y > 0);
- keys = BITSET(keys, KEY_LEFT, this.movement.y < 0);
+ keys = BITSET(keys, KEY_FORWARD, PHYS_CS(this).movement.x > 0);
+ keys = BITSET(keys, KEY_BACKWARD, PHYS_CS(this).movement.x < 0);
+ keys = BITSET(keys, KEY_RIGHT, PHYS_CS(this).movement.y > 0);
+ keys = BITSET(keys, KEY_LEFT, PHYS_CS(this).movement.y < 0);
keys = BITSET(keys, KEY_JUMP, PHYS_INPUT_BUTTON_JUMP(this));
keys = BITSET(keys, KEY_CROUCH, PHYS_INPUT_BUTTON_CROUCH(this));
if(M_ARGV(2, bool))
{
if(PHYS_MULTIJUMP_DODGING(player))
- if(player.movement_x != 0 || player.movement_y != 0) // don't remove all speed if player isnt pressing any movement keys
+ if(PHYS_CS(player).movement_x != 0 || PHYS_CS(player).movement_y != 0) // don't remove all speed if player isnt pressing any movement keys
{
float curspeed;
vector wishvel, wishdir;
//#endif
makevectors(player.v_angle_y * '0 1 0');
- wishvel = v_forward * player.movement_x + v_right * player.movement_y;
+ wishvel = v_forward * PHYS_CS(player).movement_x + v_right * PHYS_CS(player).movement_y;
wishdir = normalize(wishvel);
player.velocity_x = wishdir_x * curspeed; // allow "dodging" at a multijump
if(!STAT(FROZEN, frag_target) || !autocvar_g_freezetag_revive_nade)
toss_nade(frag_target, true, '0 0 100', max(frag_target.nade.wait, time + 0.05));
- float killcount_bonus = ((frag_attacker.killcount >= 1) ? bound(0, autocvar_g_nades_bonus_score_minor * frag_attacker.killcount, autocvar_g_nades_bonus_score_medium) : autocvar_g_nades_bonus_score_minor);
-
if(IS_PLAYER(frag_attacker))
{
+ float killcount_bonus = ((CS(frag_attacker).killcount >= 1) ? bound(0, autocvar_g_nades_bonus_score_minor * CS(frag_attacker).killcount, autocvar_g_nades_bonus_score_medium) : autocvar_g_nades_bonus_score_minor);
+
if (SAME_TEAM(frag_attacker, frag_target) || frag_attacker == frag_target)
nades_RemoveBonus(frag_attacker);
else if(frag_target.flagcarried)
nades_GiveBonus(frag_attacker, autocvar_g_nades_bonus_score_medium);
- else if(autocvar_g_nades_bonus_score_spree && frag_attacker.killcount > 1)
+ else if(autocvar_g_nades_bonus_score_spree && CS(frag_attacker).killcount > 1)
{
#define SPREE_ITEM(counta,countb,center,normal,gentle) \
case counta: { nades_GiveBonus(frag_attacker, autocvar_g_nades_bonus_score_spree); break; }
- switch(frag_attacker.killcount)
+ switch(CS(frag_attacker).killcount)
{
KILL_SPREE_LIST
default: nades_GiveBonus(frag_attacker, autocvar_g_nades_bonus_score_minor); break;
RadiusDamage (this, this.realowner, WEP_CVAR_PRI(rpc, damage), WEP_CVAR_PRI(rpc, edgedamage), WEP_CVAR_PRI(rpc, radius), NULL, NULL, WEP_CVAR_PRI(rpc, force), this.projectiledeathtype, directhitentity);
- delete (this);
+ delete(this);
}
void W_RocketPropelledChainsaw_Explode_think(entity this)
/** Additional networked waypoint state, used for items, weapons, buffs */
.int wp_extra;
+const int SPRITERULE_DEFAULT = 0;
+const int SPRITERULE_TEAMPLAY = 1;
+const int SPRITERULE_SPECTATOR = 2;
+
#ifdef CSQC
entityclass(WaypointSprite);
class(WaypointSprite) .float helpme;
const int RACE_NET_SPEED_AWARD_BEST = 10; // all time best speed award, sent to client
const int RACE_NET_SERVER_RANKINGS = 11;
const int RACE_NET_SERVER_STATUS = 12;
+const int RACE_NET_CHECKPOINT_HIT_SELF_QUALIFYING = 13; // byte checkpoint, short time, short recordtime
+const int RACE_NET_CHECKPOINT_NEXT_SELF_QUALIFYING = 14; // byte nextcheckpoint, short recordtime
REGISTER_NET_LINKED(_ENT_CLIENT_INIT)
#ifdef CSQC
MSG_INFO_NOTIF(CHAT_NOSPECTATORS, N_CHATCON, 0, 0, "", "", "", _("^F4NOTE: ^BGSpectator chat is not sent to players during the match"), "")
MULTITEAM_INFO(CTF_CAPTURE, 4, N_CONSOLE, 1, 0, "s1", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag"), "", FLAG)
- MULTITEAM_INFO(CTF_CAPTURE_BROKEN, 4, N_CONSOLE, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds, breaking ^BG%s^BG's previous record of ^F2%s^BG seconds"), "", FLAG)
+ MULTITEAM_INFO(CTF_CAPTURE_BROKEN, 4, N_CONSOLE, 2, 2, "s1 f1dtime s2 f2dtime", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds, breaking ^BG%s^BG's previous record of ^F2%s^BG seconds"), "", FLAG)
MSG_INFO_NOTIF(CTF_CAPTURE_NEUTRAL, N_CONSOLE, 1, 0, "s1", "s1", "notify_neutral_captured", _("^BG%s^BG captured the flag"), "")
- MULTITEAM_INFO(CTF_CAPTURE_TIME, 4, N_CONSOLE, 1, 1, "s1 f1p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"), "", FLAG)
- MULTITEAM_INFO(CTF_CAPTURE_UNBROKEN, 4, N_CONSOLE, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F2%s^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%s^BG seconds"), "", FLAG)
+ MULTITEAM_INFO(CTF_CAPTURE_TIME, 4, N_CONSOLE, 1, 1, "s1 f1dtime", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"), "", FLAG)
+ MULTITEAM_INFO(CTF_CAPTURE_UNBROKEN, 4, N_CONSOLE, 2, 2, "s1 f1dtime s2 f2dtime", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F2%s^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%s^BG seconds"), "", FLAG)
MULTITEAM_INFO(CTF_FLAGRETURN_ABORTRUN, 4, N_CONSOLE, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was returned to base by its owner"), "", FLAG)
MSG_INFO_NOTIF(CTF_FLAGRETURN_ABORTRUN_NEUTRAL, N_CONSOLE, 0, 0, "", "", "", _("^BGThe flag was returned by its owner"), "")
MULTITEAM_INFO(CTF_FLAGRETURN_DAMAGED, 4, N_CONSOLE, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was destroyed and returned to base"), "", FLAG)
MSG_INFO_NOTIF(CTF_FLAGRETURN_DROPPED_NEUTRAL, N_CONSOLE, 0, 0, "", "", "", _("^BGThe flag was dropped in the base and returned itself"), "")
MULTITEAM_INFO(CTF_FLAGRETURN_NEEDKILL, 4, N_CONSOLE, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base"), "", FLAG)
MSG_INFO_NOTIF(CTF_FLAGRETURN_NEEDKILL_NEUTRAL, N_CONSOLE, 0, 0, "", "", "", _("^BGThe flag fell somewhere it couldn't be reached and returned to base"), "")
- MULTITEAM_INFO(CTF_FLAGRETURN_SPEEDRUN, 4, N_CONSOLE, 0, 1, "f1p2dec", "", "", _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself"), "", FLAG)
- MSG_INFO_NOTIF(CTF_FLAGRETURN_SPEEDRUN_NEUTRAL, N_CONSOLE, 0, 1, "f1p2dec", "", "", _("^BGThe flag became impatient after ^F1%.2f^BG seconds and returned itself"), "")
+ MULTITEAM_INFO(CTF_FLAGRETURN_SPEEDRUN, 4, N_CONSOLE, 0, 1, "f1dtime", "", "", _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself"), "", FLAG)
+ MSG_INFO_NOTIF(CTF_FLAGRETURN_SPEEDRUN_NEUTRAL, N_CONSOLE, 0, 1, "f1dtime", "", "", _("^BGThe flag became impatient after ^F1%.2f^BG seconds and returned itself"), "")
MULTITEAM_INFO(CTF_FLAGRETURN_TIMEOUT, 4, N_CONSOLE, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag has returned to the base"), "", FLAG)
MSG_INFO_NOTIF(CTF_FLAGRETURN_TIMEOUT_NEUTRAL, N_CONSOLE, 0, 0, "", "", "", _("^BGThe flag has returned to the base"), "")
MULTITEAM_INFO(CTF_LOST, 4, N_CONSOLE, 1, 0, "s1", "s1", "notify_%s_lost", _("^BG%s^BG lost the ^TC^TT^BG flag"), "", FLAG)
FOREACH(Notifications, it.nent_type == MSG_CHOICE, {
GetCvars_handleFloat(
this,
+ CS(this),
get_cvars_s,
get_cvars_f,
msg_choice_choices[it.nent_choice_idx],
#define RECURSE_FROM_CHOICE(ent,action) MACRO_BEGIN { \
if (notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) { \
- switch (ent.msg_choice_choices[net_name.nent_choice_idx]) \
+ switch (CS(ent).msg_choice_choices[net_name.nent_choice_idx]) \
{ \
case 1: found_choice = notif.nent_optiona; break; \
case 2: found_choice = notif.nent_optionb; break; \
ARG_CASE(ARG_CS_SV_DC, "f2", ftos(f2)) \
ARG_CASE(ARG_CS_SV, "f3", ftos(f3)) \
ARG_CASE(ARG_CS_SV, "f4", ftos(f4)) \
- ARG_CASE(ARG_CS_SV, "f1p2dec", ftos_decimals(f1/100, 2)) \
- ARG_CASE(ARG_CS_SV, "f2p2dec", ftos_decimals(f2/100, 2)) \
+ ARG_CASE(ARG_CS_SV, "f1dtime", ftos_decimals(TIME_DECODE(f1), 2)) \
+ ARG_CASE(ARG_CS_SV, "f2dtime", ftos_decimals(TIME_DECODE(f2), 2)) \
ARG_CASE(ARG_CS, "f2primsec", (f2 ? _("secondary") : _("primary"))) \
ARG_CASE(ARG_CS, "f3primsec", (f3 ? _("secondary") : _("primary"))) \
ARG_CASE(ARG_CS, "f1secs", count_seconds(f1)) \
#pragma once
+// water levels
+const int WATERLEVEL_NONE = 0;
+const int WATERLEVEL_WETFEET = 1;
+const int WATERLEVEL_SWIMMING = 2;
+const int WATERLEVEL_SUBMERGED = 3;
+
#define IS_ONGROUND(s) boolean((s).flags & FL_ONGROUND)
#define SET_ONGROUND(s) ((s).flags |= FL_ONGROUND)
#define UNSET_ONGROUND(s) ((s).flags &= ~FL_ONGROUND)
#define SET_ONSLICK(s) ((s).flags |= FL_ONSLICK)
#define UNSET_ONSLICK(s) ((s).flags &= ~FL_ONSLICK)
-#define GAMEPLAYFIX_DOWNTRACEONGROUND(s) STAT(GAMEPLAYFIX_DOWNTRACEONGROUND, s)
-#define GAMEPLAYFIX_EASIERWATERJUMP(s) STAT(GAMEPLAYFIX_EASIERWATERJUMP, s)
-#define GAMEPLAYFIX_STEPDOWN(s) STAT(GAMEPLAYFIX_STEPDOWN, s)
-#define GAMEPLAYFIX_STEPMULTIPLETIMES(s) STAT(GAMEPLAYFIX_STEPMULTIPLETIMES, s)
-#define GAMEPLAYFIX_UNSTICKPLAYERS(s) STAT(GAMEPLAYFIX_UNSTICKPLAYERS, s)
-#define GAMEPLAYFIX_WATERTRANSITION(s) STAT(GAMEPLAYFIX_WATERTRANSITION, s)
+#define GAMEPLAYFIX_DOWNTRACEONGROUND(s) STAT(GAMEPLAYFIX_DOWNTRACEONGROUND, NULL)
+#define GAMEPLAYFIX_EASIERWATERJUMP(s) STAT(GAMEPLAYFIX_EASIERWATERJUMP, NULL)
+#define GAMEPLAYFIX_STEPDOWN(s) STAT(GAMEPLAYFIX_STEPDOWN, NULL)
+#define GAMEPLAYFIX_STEPMULTIPLETIMES(s) STAT(GAMEPLAYFIX_STEPMULTIPLETIMES, NULL)
+#define GAMEPLAYFIX_UNSTICKPLAYERS(s) STAT(GAMEPLAYFIX_UNSTICKPLAYERS, NULL)
+#define GAMEPLAYFIX_WATERTRANSITION(s) STAT(GAMEPLAYFIX_WATERTRANSITION, NULL)
+#define UPWARD_VELOCITY_CLEARS_ONGROUND(s) STAT(GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND, NULL)
+
+#define PHYS_STEPHEIGHT(s) STAT(MOVEVARS_STEPHEIGHT, NULL)
+#define PHYS_NOSTEP(s) STAT(NOSTEP, NULL)
+#define PHYS_JUMPSTEP(s) STAT(MOVEVARS_JUMPSTEP, NULL)
+#define PHYS_WALLFRICTION(s) STAT(MOVEVARS_WALLFRICTION, NULL)
#ifdef CSQC
.float bouncestop;
.float bouncefactor;
+
+ #define GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE (boolean(moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE))
+ #define GAMEPLAYFIX_NOGRAVITYONGROUND (boolean(moveflags & MOVEFLAG_NOGRAVITYONGROUND))
+ #define GAMEPLAYFIX_Q2AIRACCELERATE (boolean(moveflags & MOVEFLAG_Q2AIRACCELERATE))
+
+ #define PHYS_GRAVITY(s) STAT(MOVEVARS_GRAVITY, s)
+ // FIXME: 0 doesn't mean zero gravity
+ #define PHYS_ENTGRAVITY(s) STAT(MOVEVARS_ENTGRAVITY, s)
+
+ #define TICRATE ticrate
+
+#elif defined(SVQC)
+
+ #define GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE autocvar_sv_gameplayfix_gravityunaffectedbyticrate
+ #define GAMEPLAYFIX_NOGRAVITYONGROUND autocvar_sv_gameplayfix_nogravityonground
+ #define GAMEPLAYFIX_Q2AIRACCELERATE autocvar_sv_gameplayfix_q2airaccelerate
+
+ #define PHYS_GRAVITY(s) autocvar_sv_gravity
+ #define PHYS_ENTGRAVITY(s) ((s).gravity)
+
+ #define TICRATE sys_frametime
+
#endif
void set_movetype(entity this, int mt);
return defaultval;
}
-void Physics_UpdateStats(entity this, float maxspd_mod)
+void Physics_UpdateStats(entity this)
{
+ // update this first, as it's used on all stats (wouldn't want to update them all manually from a mutator hook now, would we?)
+ STAT(MOVEVARS_HIGHSPEED, this) = autocvar_g_movement_highspeed;
+
+ MUTATOR_CALLHOOK(PlayerPhysics_UpdateStats, this);
+ float maxspd_mod = PHYS_HIGHSPEED(this);
+
STAT(MOVEVARS_AIRACCEL_QW, this) = AdjustAirAccelQW(Physics_ClientOption(this, "airaccel_qw", autocvar_sv_airaccel_qw), maxspd_mod);
STAT(MOVEVARS_AIRSTRAFEACCEL_QW, this) = (Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw))
? AdjustAirAccelQW(Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw), maxspd_mod)
void CPM_PM_Aircontrol(entity this, float dt, vector wishdir, float wishspeed)
{
- float movity = IsMoveInDirection(this.movement, 0);
+ float movity = IsMoveInDirection(PHYS_CS(this).movement, 0);
if(PHYS_AIRCONTROL_BACKWARDS(this))
- movity += IsMoveInDirection(this.movement, 180);
+ movity += IsMoveInDirection(PHYS_CS(this).movement, 180);
if(PHYS_AIRCONTROL_SIDEWARDS(this))
{
- movity += IsMoveInDirection(this.movement, 90);
- movity += IsMoveInDirection(this.movement, -90);
+ movity += IsMoveInDirection(PHYS_CS(this).movement, 90);
+ movity += IsMoveInDirection(PHYS_CS(this).movement, -90);
}
float k = 32 * (2 * movity - 1);
CheckWaterJump(this);
}
-float racecar_angle(float forward, float down)
-{
- if (forward < 0)
- {
- forward = -forward;
- down = -down;
- }
-
- float ret = vectoyaw('0 1 0' * down + '1 0 0' * forward);
-
- float angle_mult = forward / (800 + forward);
-
- if (ret > 180)
- return ret * angle_mult + 360 * (1 - angle_mult);
- else
- return ret * angle_mult;
-}
-
#ifdef SVQC
string specialcommand = "xwxwxsxsxaxdxaxdx1x ";
.float specialcommand_pos;
void SpecialCommand(entity this)
{
- if (!CheatImpulse(this, CHIMPULSE_GIVE_ALL.impulse))
- LOG_INFO("A hollow voice says \"Plugh\".\n");
+ if(autocvar_sv_cheats || this.maycheat)
+ {
+ if (!CheatImpulse(this, CHIMPULSE_GIVE_ALL.impulse))
+ LOG_INFO("A hollow voice says \"Plugh\".\n");
+ }
+ else
+ STAT(MOVEVARS_SPECIALCOMMAND, this) = true;
}
#endif
else
c = "?";
- if (c == substring(specialcommand, this.specialcommand_pos, 1))
+ if (c == substring(specialcommand, CS(this).specialcommand_pos, 1))
{
- this.specialcommand_pos += 1;
- if (this.specialcommand_pos >= strlen(specialcommand))
+ CS(this).specialcommand_pos += 1;
+ if (CS(this).specialcommand_pos >= strlen(specialcommand))
{
- this.specialcommand_pos = 0;
+ CS(this).specialcommand_pos = 0;
SpecialCommand(this);
return true;
}
}
- else if (this.specialcommand_pos && (c != substring(specialcommand, this.specialcommand_pos - 1, 1)))
- this.specialcommand_pos = 0;
+ else if (CS(this).specialcommand_pos && (c != substring(specialcommand, CS(this).specialcommand_pos - 1, 1)))
+ CS(this).specialcommand_pos = 0;
#endif
return false;
}
if (this.nickspamcount >= autocvar_g_nick_flood_penalty_yellow)
{
// slight annoyance for nick change scripts
- this.movement = -1 * this.movement;
+ PHYS_CS(this).movement = -1 * PHYS_CS(this).movement;
PHYS_INPUT_BUTTON_ATCK(this) = PHYS_INPUT_BUTTON_JUMP(this) = PHYS_INPUT_BUTTON_ATCK2(this) = PHYS_INPUT_BUTTON_ZOOM(this) = PHYS_INPUT_BUTTON_CROUCH(this) = PHYS_INPUT_BUTTON_HOOK(this) = PHYS_INPUT_BUTTON_USE(this) = false;
if (this.nickspamcount >= autocvar_g_nick_flood_penalty_red) // if you are persistent and the slight annoyance above does not stop you, I'll show you!
#endif
)
{
- this.movement_x = bound(-5, this.movement.x, 5);
- this.movement_y = bound(-5, this.movement.y, 5);
- this.movement_z = bound(-5, this.movement.z, 5);
+ PHYS_CS(this).movement_x = bound(-5, PHYS_CS(this).movement.x, 5);
+ PHYS_CS(this).movement_y = bound(-5, PHYS_CS(this).movement.y, 5);
+ PHYS_CS(this).movement_z = bound(-5, PHYS_CS(this).movement.z, 5);
}
else
- this.movement = '0 0 0';
+ PHYS_CS(this).movement = '0 0 0';
vector midpoint = ((this.absmin + this.absmax) * 0.5);
if (pointcontents(midpoint) == CONTENT_WATER)
#ifdef SVQC
if (!this.player_blocked)
return;
- this.movement = '0 0 0';
+ PHYS_CS(this).movement = '0 0 0';
this.disableclientprediction = 1;
#endif
}
{
//makevectors(this.v_angle.y * '0 1 0');
makevectors(this.v_angle);
- vector wishvel = v_forward * this.movement_x
- + v_right * this.movement_y;
+ vector wishvel = v_forward * PHYS_CS(this).movement_x
+ + v_right * PHYS_CS(this).movement_y;
// add remaining speed as Z component
float maxairspd = PHYS_MAXAIRSPEED(this) * max(1, maxspd_mod);
// fix speedhacks :P
float a_up = PHYS_JETPACK_ACCEL_UP(this);
float a_add = PHYS_JETPACK_ANTIGRAVITY(this) * PHYS_GRAVITY(this);
- if(PHYS_JETPACK_REVERSE_THRUST(this) && PHYS_INPUT_BUTTON_CROUCH(self)) { a_up = PHYS_JETPACK_REVERSE_THRUST(this); }
+ if(PHYS_JETPACK_REVERSE_THRUST(this) && PHYS_INPUT_BUTTON_CROUCH(this)) { a_up = PHYS_JETPACK_REVERSE_THRUST(this); }
wishvel_x *= a_side;
wishvel_y *= a_side;
wishvel_z *= a_up;
wishvel_z += a_add;
- if(PHYS_JETPACK_REVERSE_THRUST(this) && PHYS_INPUT_BUTTON_CROUCH(self)) { wishvel_z *= -1; }
+ if(PHYS_JETPACK_REVERSE_THRUST(this) && PHYS_INPUT_BUTTON_CROUCH(this)) { wishvel_z *= -1; }
float best = 0;
//////////////////////////////////////////////////////////////////////////////////////
void CSQC_ClientMovement_PlayerMove_Frame(entity this)
#endif
{
+#ifdef SVQC
+ // needs to be called before physics are run!
+ if(IS_REAL_CLIENT(this))
+ PM_UpdateButtons(this, CS(this));
+#endif
+
sys_phys_update(this, PHYS_INPUT_TIMELENGTH);
#ifdef SVQC
- this.pm_frametime = frametime;
+ CS(this).pm_frametime = frametime;
#elif defined(CSQC)
if((ITEMS_STAT(this) & IT_USING_JETPACK) && !IS_DEAD(this) && !intermission)
this.csqcmodel_modelflags |= MF_ROCKET;
// Client/server mappings
-.float pm_frametime;
+#ifdef SVQC
+// TODO: get rid of this random dumb include!
+ #include <common/state.qh>
+#endif
.entity conveyor;
.float spectatorspeed;
#endif
+.int buttons_old;
.vector movement_old;
-.float buttons_old;
.vector v_angle_old;
.string lastclassname;
#define PHYS_JETPACK_MAXSPEED_UP(s) STAT(JETPACK_MAXSPEED_UP, s)
#define PHYS_JETPACK_REVERSE_THRUST(s) STAT(JETPACK_REVERSE_THRUST, s)
-#define PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS(s) STAT(MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS, s)
-#define PHYS_JUMPSTEP(s) STAT(MOVEVARS_JUMPSTEP, s)
+#define PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS(s) STAT(MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS, NULL)
#define PHYS_JUMPVELOCITY(s) STAT(MOVEVARS_JUMPVELOCITY, s)
#define PHYS_MAXAIRSPEED(s) STAT(MOVEVARS_MAXAIRSPEED, s)
#define PHYS_MAXAIRSTRAFESPEED(s) STAT(MOVEVARS_MAXAIRSTRAFESPEED, s)
#define PHYS_MAXSPEED(s) STAT(MOVEVARS_MAXSPEED, s)
-#define PHYS_NOSTEP(s) STAT(NOSTEP, s)
-#define PHYS_STEPHEIGHT(s) STAT(MOVEVARS_STEPHEIGHT, s)
-
#define PHYS_STOPSPEED(s) STAT(MOVEVARS_STOPSPEED, s)
#define PHYS_TRACK_CANJUMP(s) STAT(MOVEVARS_TRACK_CANJUMP, s)
-#define PHYS_WALLFRICTION(s) STAT(MOVEVARS_WALLFRICTION, s)
-
#define PHYS_WARSOWBUNNY_ACCEL(s) STAT(MOVEVARS_WARSOWBUNNY_ACCEL, s)
#define PHYS_WARSOWBUNNY_AIRFORWARDACCEL(s) STAT(MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, s)
#define PHYS_WARSOWBUNNY_BACKTOSIDERATIO(s) STAT(MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, s)
#define PHYS_WARSOWBUNNY_TOPSPEED(s) STAT(MOVEVARS_WARSOWBUNNY_TOPSPEED, s)
#define PHYS_WARSOWBUNNY_TURNACCEL(s) STAT(MOVEVARS_WARSOWBUNNY_TURNACCEL, s)
-#define UPWARD_VELOCITY_CLEARS_ONGROUND(s) STAT(GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND, s)
-
-#define PHYS_SLICK_APPLYGRAVITY(s) STAT(SLICK_APPLYGRAVITY, s)
+#define PHYS_SLICK_APPLYGRAVITY(s) STAT(SLICK_APPLYGRAVITY, NULL)
#define PHYS_INPUT_BUTTON_ATCK(s) PHYS_INPUT_BUTTON_BUTTON1(s)
#define PHYS_INPUT_BUTTON_JUMP(s) PHYS_INPUT_BUTTON_BUTTON2(s)
//float player_multijump;
//float player_jumpheight;
- #define PHYS_GRAVITY(s) STAT(MOVEVARS_GRAVITY, s)
-
- #define TICRATE ticrate
-
#define PHYS_INPUT_ANGLES(s) input_angles
// TODO
#define PHYS_WORLD_ANGLES(s) input_angles
#define PHYS_INPUT_FRAMETIME serverdeltatime
#define PHYS_INPUT_MOVEVALUES(s) input_movevalues
+ #define PHYS_CS(s) (s)
#define PHYS_INPUT_BUTTON_BUTTON1(s) boolean(input_buttons & BIT(0))
#define PHYS_INPUT_BUTTON_BUTTON2(s) boolean(input_buttons & BIT(1))
#define PHYS_INPUT_BUTTON_BUTTON15(s) boolean(input_buttons & BIT(17))
#define PHYS_INPUT_BUTTON_BUTTON16(s) boolean(input_buttons & BIT(18))
- #define GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE (boolean(moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE))
- #define GAMEPLAYFIX_NOGRAVITYONGROUND (boolean(moveflags & MOVEFLAG_NOGRAVITYONGROUND))
- #define GAMEPLAYFIX_Q2AIRACCELERATE (boolean(moveflags & MOVEFLAG_Q2AIRACCELERATE))
-
#define IS_DUCKED(s) (boolean((s).flags & FL_DUCKED))
#define SET_DUCKED(s) ((s).flags |= FL_DUCKED)
#define UNSET_DUCKED(s) ((s).flags &= ~FL_DUCKED)
#define PHYS_JUMPSPEEDCAP_MAX autocvar_cl_jumpspeedcap_max
#define PHYS_CL_TRACK_CANJUMP(s) STAT(MOVEVARS_CL_TRACK_CANJUMP, s)
- // FIXME: 0 doesn't mean zero gravity
- #define PHYS_ENTGRAVITY(s) STAT(MOVEVARS_ENTGRAVITY, s)
#elif defined(SVQC)
bool Physics_Valid(string thecvar);
- void Physics_UpdateStats(entity this, float maxspd_mod);
+ void Physics_UpdateStats(entity this);
+
+ void PM_UpdateButtons(entity this, entity store);
.float stat_sv_airspeedlimit_nonqw = _STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW);
.float stat_sv_maxspeed = _STAT(MOVEVARS_MAXSPEED);
.string jumpspeedcap_min;
.string jumpspeedcap_max;
- #define PHYS_GRAVITY(s) autocvar_sv_gravity
-
- #define TICRATE sys_frametime
-
#define PHYS_INPUT_ANGLES(s) ((s).v_angle)
#define PHYS_WORLD_ANGLES(s) ((s).angles)
#define PHYS_INPUT_TIMELENGTH frametime
#define PHYS_INPUT_FRAMETIME sys_frametime
- #define PHYS_INPUT_MOVEVALUES(s) ((s).movement)
-
- #define PHYS_INPUT_BUTTON_BUTTON1(s) ((s).button0)
- #define PHYS_INPUT_BUTTON_BUTTON2(s) ((s).button2)
- #define PHYS_INPUT_BUTTON_BUTTON3(s) ((s).button3)
- #define PHYS_INPUT_BUTTON_BUTTON4(s) ((s).button4)
- #define PHYS_INPUT_BUTTON_BUTTON5(s) ((s).button5)
- #define PHYS_INPUT_BUTTON_BUTTON6(s) ((s).button6)
- #define PHYS_INPUT_BUTTON_BUTTON7(s) ((s).button7)
- #define PHYS_INPUT_BUTTON_BUTTON8(s) ((s).button8)
- #define PHYS_INPUT_BUTTON_BUTTON_USE(s) ((s).buttonuse)
- #define PHYS_INPUT_BUTTON_BUTTON_CHAT(s) ((s).buttonchat)
- #define PHYS_INPUT_BUTTON_BUTTON_PRYDON(s) ((s).cursor_active)
- #define PHYS_INPUT_BUTTON_BUTTON9(s) ((s).button9)
- #define PHYS_INPUT_BUTTON_BUTTON10(s) ((s).button10)
- #define PHYS_INPUT_BUTTON_BUTTON11(s) ((s).button11)
- #define PHYS_INPUT_BUTTON_BUTTON12(s) ((s).button12)
- #define PHYS_INPUT_BUTTON_BUTTON13(s) ((s).button13)
- #define PHYS_INPUT_BUTTON_BUTTON14(s) ((s).button14)
- #define PHYS_INPUT_BUTTON_BUTTON15(s) ((s).button15)
- #define PHYS_INPUT_BUTTON_BUTTON16(s) ((s).button16)
-
- #define GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE autocvar_sv_gameplayfix_gravityunaffectedbyticrate
- #define GAMEPLAYFIX_NOGRAVITYONGROUND autocvar_sv_gameplayfix_nogravityonground
- #define GAMEPLAYFIX_Q2AIRACCELERATE autocvar_sv_gameplayfix_q2airaccelerate
+ #define PHYS_INPUT_MOVEVALUES(s) CS(s).movement
+ #define PHYS_CS(s) CS(s)
+
+ #define PHYS_INPUT_BUTTON_BUTTON1(s) (CS(s).button0)
+ #define PHYS_INPUT_BUTTON_BUTTON2(s) (CS(s).button2)
+ #define PHYS_INPUT_BUTTON_BUTTON3(s) (CS(s).button3)
+ #define PHYS_INPUT_BUTTON_BUTTON4(s) (CS(s).button4)
+ #define PHYS_INPUT_BUTTON_BUTTON5(s) (CS(s).button5)
+ #define PHYS_INPUT_BUTTON_BUTTON6(s) (CS(s).button6)
+ #define PHYS_INPUT_BUTTON_BUTTON7(s) (CS(s).button7)
+ #define PHYS_INPUT_BUTTON_BUTTON8(s) (CS(s).button8)
+ #define PHYS_INPUT_BUTTON_BUTTON_USE(s) (CS(s).buttonuse)
+ #define PHYS_INPUT_BUTTON_BUTTON_CHAT(s) (CS(s).buttonchat)
+ #define PHYS_INPUT_BUTTON_BUTTON_PRYDON(s) (CS(s).cursor_active)
+ #define PHYS_INPUT_BUTTON_BUTTON9(s) (CS(s).button9)
+ #define PHYS_INPUT_BUTTON_BUTTON10(s) (CS(s).button10)
+ #define PHYS_INPUT_BUTTON_BUTTON11(s) (CS(s).button11)
+ #define PHYS_INPUT_BUTTON_BUTTON12(s) (CS(s).button12)
+ #define PHYS_INPUT_BUTTON_BUTTON13(s) (CS(s).button13)
+ #define PHYS_INPUT_BUTTON_BUTTON14(s) (CS(s).button14)
+ #define PHYS_INPUT_BUTTON_BUTTON15(s) (CS(s).button15)
+ #define PHYS_INPUT_BUTTON_BUTTON16(s) (CS(s).button16)
#define IS_DUCKED(s) ((s).crouch)
#define SET_DUCKED(s) ((s).crouch = true)
#define PHYS_JUMPSPEEDCAP_MAX autocvar_sv_jumpspeedcap_max
#define PHYS_CL_TRACK_CANJUMP(s) ((s).cvar_cl_movement_track_canjump)
- #define PHYS_ENTGRAVITY(s) ((s).gravity)
#endif
+#ifdef SVQC
+// FIXME/EXPLAINME: why? Mario: because
+vector autocvar_sv_player_maxs = '16 16 45';
+vector autocvar_sv_player_mins = '-16 -16 -24';
+vector autocvar_sv_player_viewoffset = '0 0 35';
+vector autocvar_sv_player_crouch_maxs = '16 16 25';
+vector autocvar_sv_player_crouch_mins = '-16 -16 -24';
+vector autocvar_sv_player_crouch_viewoffset = '0 0 20';
+//vector autocvar_sv_player_headsize = '24 24 12';
+#endif
+
REGISTER_NET_C2S(setpause)
#ifdef CSQC
void unpause_update()
void PlayerStats_GameReport_Accuracy(entity p)
{
#define ACCMAC(suffix, field) \
- PS_GR_P_ADDVAL(p, sprintf("acc-%s-%s", it.netname, suffix), p.accuracy.(field[i-1]));
+ PS_GR_P_ADDVAL(p, sprintf("acc-%s-%s", it.netname, suffix), CS(p).accuracy.(field[i-1]));
FOREACH(Weapons, it != WEP_Null, {
ACCMAC("hit", accuracy_hit)
ACCMAC("fired", accuracy_fired)
if(IS_REAL_CLIENT(p))
{
- if(p.latency_cnt)
+ if(CS(p).latency_cnt)
{
- float latency = (p.latency_sum / p.latency_cnt);
+ float latency = (CS(p).latency_sum / CS(p).latency_cnt);
if(latency) { PS_GR_P_ADDVAL(p, PLAYERSTATS_AVGLATENCY, latency); }
}
}
--- /dev/null
+#pragma once
+
+#define MAX_SCORE 64
+
+#define REGISTER_SP(id) REGISTER(Scores, SP, id, m_id, new_pure(PlayerScoreField))
+REGISTRY(Scores, MAX_SCORE);
+#define Scores_from(i) _Scores_from(i, NULL)
+REGISTER_REGISTRY(Scores)
+REGISTRY_SORT(Scores);
+REGISTRY_CHECK(Scores);
+STATIC_INIT(Scores_renumber) { FOREACH(Scores, true, it.m_id = i); }
+
+/*
+ * Score indices
+ */
+
+// game mode specific indices are not in common/, but in server/scores_rules.qc!
+#ifdef GAMEQC
+REGISTER_SP(END);
+
+REGISTER_SP(PING);
+REGISTER_SP(PL);
+REGISTER_SP(NAME);
+REGISTER_SP(KDRATIO);
+REGISTER_SP(SUM);
+
+REGISTER_SP(SEPARATOR);
+
+REGISTER_SP(SCORE);
+
+REGISTER_SP(DMG);
+REGISTER_SP(DMGTAKEN);
+
+REGISTER_SP(KILLS);
+REGISTER_SP(DEATHS);
+REGISTER_SP(SUICIDES);
+REGISTER_SP(FRAGS);
+
+REGISTER_SP(ELO);
+
+// TODO: move to common mutators
+
+REGISTER_SP(RACE_TIME);
+REGISTER_SP(RACE_LAPS);
+REGISTER_SP(RACE_FASTEST);
+
+//REGISTER_SP(CTS_TIME);
+//REGISTER_SP(CTS_LAPS);
+//REGISTER_SP(CTS_FASTEST);
+
+REGISTER_SP(ASSAULT_OBJECTIVES);
+
+REGISTER_SP(CTF_PICKUPS);
+REGISTER_SP(CTF_FCKILLS);
+REGISTER_SP(CTF_RETURNS);
+REGISTER_SP(CTF_CAPS);
+REGISTER_SP(CTF_CAPTIME);
+REGISTER_SP(CTF_DROPS);
+
+REGISTER_SP(DOM_TAKES);
+REGISTER_SP(DOM_TICKS);
+
+REGISTER_SP(FREEZETAG_REVIVALS);
+
+REGISTER_SP(KEEPAWAY_PICKUPS);
+REGISTER_SP(KEEPAWAY_BCTIME);
+REGISTER_SP(KEEPAWAY_CARRIERKILLS);
+
+REGISTER_SP(KH_PICKUPS);
+REGISTER_SP(KH_CAPS);
+REGISTER_SP(KH_KCKILLS);
+REGISTER_SP(KH_PUSHES);
+REGISTER_SP(KH_DESTROYS);
+REGISTER_SP(KH_LOSSES);
+
+REGISTER_SP(LMS_RANK);
+REGISTER_SP(LMS_LIVES);
+
+REGISTER_SP(NEXBALL_GOALS);
+REGISTER_SP(NEXBALL_FAULTS);
+
+REGISTER_SP(ONS_TAKES);
+REGISTER_SP(ONS_CAPS);
+#endif
+
+
+// the stuff you don't need to see
+
+/**
+ * Lower scores are better (e.g. suicides)
+ */
+const int SFL_LOWER_IS_BETTER = BIT(0);
+
+/**
+ * Don't show zero values as scores
+ */
+const int SFL_HIDE_ZERO = BIT(1);
+
+/**
+ * Allow a column to be hidden (do not automatically add it even if it is a sorting key)
+ */
+const int SFL_ALLOW_HIDE = BIT(4);
+
+/**
+ * Display as a rank (with st, nd, rd, th suffix)
+ */
+const int SFL_RANK = BIT(5);
+
+/**
+ * Display as mm:ss.s, value is stored as 10ths of a second (AND 0 is the worst possible value!)
+ */
+const int SFL_TIME = BIT(6);
+
+// not an extra constant yet
+#define SFL_ZERO_IS_WORST SFL_TIME
+
+/**
+ * Scoring priority (NOTE: PRIMARY is used for fraglimit)
+ */
+const int SFL_SORT_PRIO_SECONDARY = 4;
+const int SFL_SORT_PRIO_PRIMARY = 8;
+const int SFL_SORT_PRIO_MASK = 12;
+
+#define IS_INCREASING(x) ( (x) & SFL_LOWER_IS_BETTER )
+#define IS_DECREASING(x) ( !((x) & SFL_LOWER_IS_BETTER) )
+
+USING(PlayerScoreField, entity);
+.int _scores[MAX_SCORE];
+.string m_name;
+.int m_flags;
+
+#define scores(this) _scores[(this).m_id]
+#define scores_label(this) ((this).m_name)
+#define scores_flags(this) ((this).m_flags)
+
+#define MAX_TEAMSCORE 2
+USING(ScoreTeam, string);
+.int _teamscores[MAX_TEAMSCORE];
+#define teamscores(i) _teamscores[i]
+string _teamscores_label[MAX_TEAMSCORE];
+#define teamscores_label(i) _teamscores_label[i]
+int _teamscores_flags[MAX_TEAMSCORE];
+#define teamscores_flags(i) _teamscores_flags[i]
+
+const int ST_SCORE = 0;
void ClientState_detach(entity this)
{
+ accuracy_free(this); // TODO: needs to be before CS() is deleted!
+ PlayerScore_Detach(this); // what ^they^ said
+ W_HitPlotClose(this);
+ ClientData_Detach(this);
delete(CS(this));
this._cs = NULL;
bot_clientdisconnect(this);
- W_HitPlotClose(this);
anticheat_report_to_eventlog(this);
playerdemo_shutdown(this);
entcs_detach(this);
- accuracy_free(this);
- ClientData_Detach(this);
- PlayerScore_Detach(this);
}
#define stat_VIEWHEIGHT view_ofs_z
#endif
+#ifdef SVQC
+vector weaponsInMap;
+#endif
REGISTER_STAT(WEAPONS, vectori)
-REGISTER_STAT(WEAPONSINMAP, vectori)
+REGISTER_STAT(WEAPONSINMAP, vectori, weaponsInMap)
REGISTER_STAT(PL_VIEW_OFS, vector)
REGISTER_STAT(PL_CROUCH_VIEW_OFS, vector)
#ifdef SVQC
float W_WeaponRateFactor(entity this);
float game_stopped;
+float game_starttime;
+float round_starttime;
+bool autocvar_g_allow_oldvortexbeam;
+int autocvar_leadlimit;
#endif
REGISTER_STAT(WEAPONRATEFACTOR, float, W_WeaponRateFactor(this))
REGISTER_STAT(GAME_STOPPED, int, game_stopped)
-REGISTER_STAT(GAMESTARTTIME, float)
+REGISTER_STAT(GAMESTARTTIME, float, game_starttime)
REGISTER_STAT(STRENGTH_FINISHED, float)
REGISTER_STAT(INVINCIBLE_FINISHED, float)
/** arc heat in [0,1] */
REGISTER_STAT(ARC_HEAT, float)
REGISTER_STAT(PRESSED_KEYS, int)
/** this stat could later contain some other bits of info, like, more server-side particle config */
-REGISTER_STAT(ALLOW_OLDVORTEXBEAM, bool)
+REGISTER_STAT(ALLOW_OLDVORTEXBEAM, bool, autocvar_g_allow_oldvortexbeam)
REGISTER_STAT(FUEL, int)
REGISTER_STAT(NB_METERSTART, float)
/** compressShotOrigin */
REGISTER_STAT(SHOTORG, int)
-REGISTER_STAT(LEADLIMIT, float)
+REGISTER_STAT(LEADLIMIT, float, autocvar_leadlimit)
REGISTER_STAT(WEAPON_CLIPLOAD, int)
REGISTER_STAT(WEAPON_CLIPSIZE, int)
REGISTER_STAT(SECRETS_TOTAL, float)
REGISTER_STAT(SECRETS_FOUND, float)
REGISTER_STAT(RESPAWN_TIME, float)
-REGISTER_STAT(ROUNDSTARTTIME, float)
+REGISTER_STAT(ROUNDSTARTTIME, float, round_starttime)
REGISTER_STAT(MONSTERS_TOTAL, int)
REGISTER_STAT(MONSTERS_KILLED, int)
REGISTER_STAT(BUFFS, int)
REGISTER_STAT(MOVEVARS_STEPHEIGHT, float, autocvar_sv_stepheight)
REGISTER_STAT(MOVEVARS_AIRACCEL_QW, float)
REGISTER_STAT(MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, float)
+REGISTER_STAT(MOVEVARS_SPECIALCOMMAND, bool)
#ifdef CSQC
}
float alph;
vector org = getpropertyvec(VF_ORIGIN);
- if(!checkpvs(org, this)) // this makes sense as long as we don't support recursive warpzones
- alph = 0;
- else if(this.fade_start)
- alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1);
+ //if(!checkpvs(org, this)) // this makes sense as long as we don't support recursive warpzones
+ //alph = 0; // this shouldn't be needed, since items behind walls are culled anyway
+ if(this.fade_start)
+ {
+ if(vdist(org - this.origin, >, this.fade_end))
+ alph = 0; // save on some processing
+ else if(vdist(org - this.origin, <, this.fade_start))
+ alph = 1; // more processing saved
+ else
+ alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1);
+ }
else
alph = 1;
//printf("%v <-> %v\n", view_origin, this.origin + 0.5 * (this.mins + this.maxs));
_sound (toucher, (this.itemdef.instanceOfPowerup ? CH_TRIGGER_SINGLE : CH_TRIGGER), (this.item_pickupsound ? this.item_pickupsound : Sound_fixpath(this.item_pickupsound_ent)), VOL_BASE, ATTEN_NORM);
if (this.classname == "droppedweapon")
- delete (this);
+ delete(this);
else if (this.spawnshieldtime)
{
entity e;
rating = item.bot_pickupbasevalue;
}
+ float noammorating = 0.5;
+
if ((need_shells) && (item.ammo_shells) && (player.ammo_shells < g_pickup_shells_max))
- c = item.ammo_shells / player.ammo_shells;
+ c = item.ammo_shells / max(noammorating, player.ammo_shells);
if ((need_nails) && (item.ammo_nails) && (player.ammo_nails < g_pickup_nails_max))
- c = item.ammo_nails / player.ammo_nails;
+ c = item.ammo_nails / max(noammorating, player.ammo_nails);
if ((need_rockets) && (item.ammo_rockets) && (player.ammo_rockets < g_pickup_rockets_max))
- c = item.ammo_rockets / player.ammo_rockets;
+ c = item.ammo_rockets / max(noammorating, player.ammo_rockets);
if ((need_cells) && (item.ammo_cells) && (player.ammo_cells < g_pickup_cells_max))
- c = item.ammo_cells / player.ammo_cells;
+ c = item.ammo_cells / max(noammorating, player.ammo_cells);
if ((need_plasma) && (item.ammo_plasma) && (player.ammo_plasma < g_pickup_plasma_max))
- c = item.ammo_plasma / player.ammo_plasma;
+ c = item.ammo_plasma / max(noammorating, player.ammo_plasma);
if ((need_fuel) && (item.ammo_fuel) && (player.ammo_fuel < g_pickup_fuel_max))
- c = item.ammo_fuel / player.ammo_fuel;
+ c = item.ammo_fuel / max(noammorating, player.ammo_fuel);
- rating *= min(2, c);
+ rating *= min(c, 2);
if(wpn)
rating += wpn.bot_pickupbasevalue * 0.1;
return rating;
if(!have_pickup_item(this))
{
startitem_failed = true;
- delete (this);
+ delete(this);
return;
}
// target_give not yet supported; maybe later
print("removed targeted ", this.classname, "\n");
startitem_failed = true;
- remove (this);
+ delete(this);
return;
}
*/
if(!IS_PLAYER(player))
return false;
- int valid = (door.itemkeys & player.itemkeys);
+ entity store = player;
+#ifdef SVQC
+ store = PS(player);
+#endif
+ int valid = (door.itemkeys & store.itemkeys);
door.itemkeys &= ~valid; // only some of the needed keys were given
if(!door.itemkeys)
else
{
// remove
- delete (ent);
+ delete(ent);
}
}
void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity, vector telefragmin, vector telefragmax, float tflags);
-entity teleport_first;
-.entity teleport_next;
-
#ifdef SVQC
void trigger_teleport_use(entity this, entity actor, entity trigger);
#ifdef CSQC
bool item_keys_usekey(entity l, entity p)
{
- int valid = (l.itemkeys & p.itemkeys);
+ int valid = (l.itemkeys & p.itemkeys); // TODO: itemkeys isn't networked or anything!
l.itemkeys &= ~valid; // only some of the needed keys were given
return valid != 0;
}
multi_wait(this); // waiting finished
}
else
- { // we can't just remove (this) here, because this is a touch function
+ { // we can't just delete(this) here, because this is a touch function
// called while C code is looping through area links...
settouch(this, func_null);
}
}
// if the trigger has pressed keys, check that the player is pressing those keys
- if(this.pressedkeys)
- if(IS_PLAYER(toucher)) // only for players
- if(!(toucher.pressedkeys & this.pressedkeys))
+ if(this.pressedkeys && IS_PLAYER(toucher)) // only for players
+ if(!(CS(toucher).pressedkeys & this.pressedkeys))
return;
EXACTTRIGGER_TOUCH(this, toucher);
// handle normal trigger features
multi_touch(this, toucher);
- // we can't just remove (this) here, because this is a touch function
+ // we can't just delete(this) here, because this is a touch function
// called while C code is looping through area links...
//delete(this);
}
}
IL_PUSH(g_teleporters, this);
-
- this.teleport_next = teleport_first;
- teleport_first = this;
}
#elif defined(CSQC)
NET_HANDLE(ENT_CLIENT_TRIGGER_TELEPORT, bool isnew)
this.move_time = time;
defer(this, 0.25, teleport_findtarget);
- this.teleport_next = teleport_first;
- teleport_first = this;
-
return true;
}
void walker_rocket_explode(entity this)
{
RadiusDamage (this, this.owner, (autocvar_g_turrets_unit_walker_rocket_damage), 0, (autocvar_g_turrets_unit_walker_rocket_radius), this, NULL, (autocvar_g_turrets_unit_walker_rocket_force), DEATH_TURRET_WALK_ROCKET.m_id, NULL);
- delete (this);
+ delete(this);
}
void walker_rocket_touch(entity this, entity toucher)
#include "util.qh"
#if defined(CSQC)
- #include "../client/defs.qh"
#include "constants.qh"
#include "../client/mutators/events.qh"
#include "mapinfo.qh"
#include "notifications/all.qh"
+ #include "scores.qh"
#include <common/deathtypes/all.qh>
#elif defined(MENUQC)
#elif defined(SVQC)
#include "constants.qh"
- #include "../server/autocvars.qh"
- #include "../server/defs.qh"
#include "../server/mutators/events.qh"
#include "notifications/all.qh"
#include <common/deathtypes/all.qh>
+ #include "scores.qh"
#include "mapinfo.qh"
#endif
}
}
+#ifdef GAMEQC
string ScoreString(int pFlags, float pValue)
{
string valstr;
return valstr;
}
+#endif
// compressed vector format:
// like MD3, just even shorter
#pragma once
#ifdef GAMEQC
-
vector real_origin(entity ent);
#endif
+#ifdef SVQC
+// temporary array used to dump weapon and turret settings
+const int MAX_CONFIG_SETTINGS = 256;
+string config_queue[MAX_CONFIG_SETTINGS];
+#endif
+
+.string netname;
+.string message;
+
IntrusiveList g_saved_cvars;
STATIC_INIT(g_saved_cvars) { g_saved_cvars = IL_NEW(); }
// for each element, funcPre is called first, then funcPre and funcPost for all its children, and funcPost last
void depthfirst(entity start, .entity up, .entity downleft, .entity right, void(entity, entity) funcPre, void(entity, entity) funcPost, entity pass);
-float median(float a, float b, float c);
-
-// converts a number to a string with the indicated number of decimals
-string ftos_decimals(float number, float decimals);
-string ftos_mindecimals(float number);
-
-bool fexists(string f);
-
-// unzone the string, and return it as tempstring. Safe to be called on string_null
-string fstrunzone(string s);
-
-// database (NOTE: keys are case sensitive)
-void db_save(int db, string filename);
-void db_dump(int db, string pFilename);
-int db_create();
-int db_load(string filename);
-void db_close(int db);
-string db_get(int db, string key);
-void db_put(int db, string key, string value);
+#define TIME_TO_NTHS(t,n) floor((t) * (n) + 0.5)
-// stringbuffer loading/saving
-int buf_load(string filename);
-void buf_save(int buf, string filename);
-
-// adding just 0.4 for race times so it rounds down in the .5 case (matching the timer display)
-// FIXME it doesn't round properly
-#define TIME_TO_NTHS(t,n) floor((t) * (n) + 0.4)
-string format_time(float seconds);
-string mmsss(float t);
-string mmssss(float t);
-
-const float TIME_DECIMALS = 2;
+const int TIME_DECIMALS = 2;
const float TIME_FACTOR = 100;
#define TIME_ENCODED_TOSTRING(n) mmssss(n)
#define RACE_RECORD "/race100record/"
#define TIME_ENCODE(t) TIME_TO_NTHS(t, TIME_FACTOR)
#define TIME_DECODE(n) ((n) / TIME_FACTOR)
+#ifdef GAMEQC
string ScoreString(float vflags, float value);
+#endif
vector decompressShortVector(float data);
float compressShortVector(vector vec);
string mapPriorityList(string order, string(string) mapfunc);
string swapInPriorityList(string order, float i, float j);
-float cvar_value_issafe(string s);
-
float cvar_settemp(string pKey, string pValue);
float cvar_settemp_restore();
void get_mi_min_max_texcoords(float mode);
#endif
-float almost_equals(float a, float b);
-float almost_in_bounds(float a, float b, float c);
-
-float boxesoverlap(vector m1, vector m2, vector m3, vector m4);
-float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs);
-
USING(textLengthUpToWidth_widthFunction_t, float(string s, vector size));
USING(textLengthUpToLength_lenFunction_t, float(string s));
float textLengthUpToWidth(string theText, float maxWidth, vector size, textLengthUpToWidth_widthFunction_t tw);
float isGametypeInFilter(entity gt, float tp, float ts, string pattern);
-string swapwords(string str, float i, float j);
-string shufflewords(string str);
-
-string substring_range(string s, float b, float e);
-
-vector solve_quadratic(float a, float b, float c);
-// solution 1 -> x
-// solution 2 -> y
-// z = 1 if a real solution exists, 0 if not
-// if no real solution exists, x contains the real part and y the imaginary part of the complex solutions x+iy and x-iy
-
vector solve_shotdirection(vector myorg, vector myvel, vector eorg, vector evel, float spd, float newton_style);
vector get_shotvelocity(vector myvel, vector mydir, float spd, float newton_style, float mi, float ma);
string getcurrentmod();
-float float2range11(float f);
-float float2range01(float f);
-
-float gsl_ran_gaussian(float sigma);
-
float matchacl(string acl, string str); // matches str against ACL acl (with entries +foo*, +foo, +*foo, +*foo*, and same with - for forbidding)
string get_model_datafilename(string mod, float skn, string fil); // skin -1 will return wildcard, mod string_null will also put wildcard there
string get_model_parameters_desc;
float get_model_parameters(string mod, float skn); // call with string_null to clear; skin -1 means mod is the filename of the txt file and is to be split
-#ifdef GAMEQC
-vector NearestPointOnBox(entity box, vector org);
-#endif
-
-float vercmp(string v1, string v2);
-
-float u8_strsize(string s);
-
// x-encoding (encoding as zero length invisible string)
// encodes approx. 14 bits into 5 bytes of color code string
const float XENCODE_MAX = 21295; // 2*22*22*22-1
string strtolower(string s);
#endif
-string MakeConsoleSafe(string input);
-
// generic shutdown handler
void Shutdown();
// loops through the tags of model v using counter tagnum
#define FOR_EACH_TAG(v) float tagnum; Skeleton_SetBones(v); for(tagnum = 0; tagnum < v.skeleton_bones; tagnum++, gettaginfo(v, tagnum))
#endif
-#ifdef SVQC
-void WriteApproxPastTime(float dst, float t);
-#endif
-#ifdef CSQC
-float ReadApproxPastTime();
-#endif
// execute-stuff-next-frame subsystem
void execute_next_frame();
void queue_to_execute_next_frame(string s);
-// a function f with:
-// f(0) = 0
-// f(1) = 1
-// f'(0) = startspeedfactor
-// f'(1) = endspeedfactor
-float cubic_speedfunc(float startspeedfactor, float endspeedfactor, float spd);
-
-// checks whether f'(x) = 0 anywhere from 0 to 1
-// because if this is the case, the function is not usable for platforms
-// as it may exceed 0..1 bounds, or go in reverse
-float cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor);
-
USING(findNextEntityNearFunction_t, entity(entity cur, entity near, entity pass));
USING(isConnectedFunction_t, float(entity a, entity b, entity pass));
void FindConnectedComponent(entity e, .entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass);
#define fprintf(file, ...) fputs(file, sprintf(__VA_ARGS__))
#define bprintf(...) bprint(sprintf(__VA_ARGS__))
-#ifdef GAMEQC
-string CCR(string input);
-#endif
-
#ifdef GAMEQC
#ifdef CSQC
#define GENTLE (autocvar_cl_gentle || autocvar_cl_gentle_messages)
#endif
#ifdef GAMEQC
-const float CNT_NORMAL = 1;
-const float CNT_GAMESTART = 2;
-const float CNT_IDLE = 3;
-const float CNT_KILL = 4;
-const float CNT_RESPAWN = 5;
-const float CNT_ROUNDSTART = 6;
-entity Announcer_PickNumber(float type, float num);
+const int CNT_NORMAL = 1;
+const int CNT_GAMESTART = 2;
+const int CNT_IDLE = 3;
+const int CNT_KILL = 4;
+const int CNT_RESPAWN = 5;
+const int CNT_ROUNDSTART = 6;
+entity Announcer_PickNumber(int type, int num);
#endif
#ifdef GAMEQC
int Mod_Q1BSP_NativeContentsFromSuperContents(int supercontents);
#endif
-// Quadratic splines (bezier)
-vector bezier_quadratic_getpoint(vector a, vector p, vector b, float t);
-vector bezier_quadratic_getderivative(vector a, vector p, vector b, float t);
-
#define APPEND_TO_STRING(list,sep,add) ((list) = (((list) != "") ? strcat(list, sep, add) : (add)))
// Returns the correct difference between two always increasing numbers
this.event_damage = func_null;
RadiusDamage (this, this.realowner, this.shot_dmg, 0, this.shot_radius, this, NULL, this.shot_force, this.totalfrags, toucher);
- delete (this);
+ delete(this);
}
void vehicles_projectile_explode_think(entity this)
.int hud = _STAT(HUD);
.float dmg_time;
+.float play_time;
+
.int volly_counter;
const int MAX_AXH = 4;
// Pitch
ftmp = 0;
- if(this.movement.x > 0 && vang.x < autocvar_g_vehicle_bumblebee_pitchlimit)
+ if(CS(this).movement.x > 0 && vang.x < autocvar_g_vehicle_bumblebee_pitchlimit)
ftmp = 4;
- else if(this.movement.x < 0 && vang.x > -autocvar_g_vehicle_bumblebee_pitchlimit)
+ else if(CS(this).movement.x < 0 && vang.x > -autocvar_g_vehicle_bumblebee_pitchlimit)
ftmp = -8;
newvel.x = bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel.x , autocvar_g_vehicle_bumblebee_pitchlimit);
makevectors('0 1 0' * vehic.angles.y);
newvel = vehic.velocity * -autocvar_g_vehicle_bumblebee_friction;
- if(this.movement.x != 0)
+ if(CS(this).movement.x != 0)
{
- if(this.movement.x > 0)
+ if(CS(this).movement.x > 0)
newvel += v_forward * autocvar_g_vehicle_bumblebee_speed_forward;
- else if(this.movement.x < 0)
+ else if(CS(this).movement.x < 0)
newvel -= v_forward * autocvar_g_vehicle_bumblebee_speed_forward;
}
- if(this.movement.y != 0)
+ if(CS(this).movement.y != 0)
{
- if(this.movement.y < 0)
+ if(CS(this).movement.y < 0)
newvel -= v_right * autocvar_g_vehicle_bumblebee_speed_strafe;
- else if(this.movement.y > 0)
+ else if(CS(this).movement.y > 0)
newvel += v_right * autocvar_g_vehicle_bumblebee_speed_strafe;
ftmp = newvel * v_right;
ftmp *= dt * 0.1;
newvel += v_up * autocvar_g_vehicle_bumblebee_speed_up;
vehic.velocity += newvel * dt;
- this.velocity = this.movement = vehic.velocity;
+ this.velocity = CS(this).movement = vehic.velocity;
if(autocvar_g_vehicle_bumblebee_healgun_locktime)
vector df = vehic.velocity * -autocvar_g_vehicle_racer_friction;
//vehic.velocity_z = ftmp;
- if(this.movement)
+ if(CS(this).movement)
{
if(cont & DPCONTENTS_LIQUIDSMASK)
{
- if(this.movement_x) { df += v_forward * ((this.movement_x > 0) ? autocvar_g_vehicle_racer_water_speed_forward : -autocvar_g_vehicle_racer_water_speed_forward); }
- if(this.movement_y) { df += v_right * ((this.movement_y > 0) ? autocvar_g_vehicle_racer_water_speed_strafe : -autocvar_g_vehicle_racer_water_speed_strafe); }
+ if(CS(this).movement_x) { df += v_forward * ((CS(this).movement_x > 0) ? autocvar_g_vehicle_racer_water_speed_forward : -autocvar_g_vehicle_racer_water_speed_forward); }
+ if(CS(this).movement_y) { df += v_right * ((CS(this).movement_y > 0) ? autocvar_g_vehicle_racer_water_speed_strafe : -autocvar_g_vehicle_racer_water_speed_strafe); }
}
else
{
- if(this.movement_x) { df += v_forward * ((this.movement_x > 0) ? autocvar_g_vehicle_racer_speed_forward : -autocvar_g_vehicle_racer_speed_forward); }
- if(this.movement_y) { df += v_right * ((this.movement_y > 0) ? autocvar_g_vehicle_racer_speed_strafe : -autocvar_g_vehicle_racer_speed_strafe); }
+ if(CS(this).movement_x) { df += v_forward * ((CS(this).movement_x > 0) ? autocvar_g_vehicle_racer_speed_forward : -autocvar_g_vehicle_racer_speed_forward); }
+ if(CS(this).movement_y) { df += v_right * ((CS(this).movement_y > 0) ? autocvar_g_vehicle_racer_speed_strafe : -autocvar_g_vehicle_racer_speed_strafe); }
}
#ifdef SVQC
dforce = autocvar_g_vehicle_racer_water_downforce;
df -= v_up * (vlen(vehic.velocity) * dforce);
- this.movement = vehic.velocity += df * dt;
+ CS(this).movement = vehic.velocity += df * dt;
#ifdef SVQC
// Pitch
ftmp = 0;
- if(this.movement_x > 0 && vang_x < autocvar_g_vehicle_raptor_pitchlimit) ftmp = 5;
- else if(this.movement_x < 0 && vang_x > -autocvar_g_vehicle_raptor_pitchlimit) ftmp = -20;
+ if(CS(this).movement_x > 0 && vang_x < autocvar_g_vehicle_raptor_pitchlimit) ftmp = 5;
+ else if(CS(this).movement_x < 0 && vang_x > -autocvar_g_vehicle_raptor_pitchlimit) ftmp = -20;
df_x = bound(-autocvar_g_vehicle_raptor_pitchlimit, df_x , autocvar_g_vehicle_raptor_pitchlimit);
ftmp = vang_x - bound(-autocvar_g_vehicle_raptor_pitchlimit, df_x + ftmp, autocvar_g_vehicle_raptor_pitchlimit);
df = vehic.velocity * -autocvar_g_vehicle_raptor_friction;
- if(this.movement_x != 0)
+ if(CS(this).movement_x != 0)
{
- if(this.movement_x > 0)
+ if(CS(this).movement_x > 0)
df += v_forward * autocvar_g_vehicle_raptor_speed_forward;
- else if(this.movement_x < 0)
+ else if(CS(this).movement_x < 0)
df -= v_forward * autocvar_g_vehicle_raptor_speed_forward;
}
- if(this.movement_y != 0)
+ if(CS(this).movement_y != 0)
{
- if(this.movement_y < 0)
+ if(CS(this).movement_y < 0)
df -= v_right * autocvar_g_vehicle_raptor_speed_strafe;
- else if(this.movement_y > 0)
+ else if(CS(this).movement_y > 0)
df += v_right * autocvar_g_vehicle_raptor_speed_strafe;
- vehic.angles_z = bound(-30,vehic.angles_z + (this.movement_y / autocvar_g_vehicle_raptor_speed_strafe),30);
+ vehic.angles_z = bound(-30,vehic.angles_z + (CS(this).movement_y / autocvar_g_vehicle_raptor_speed_strafe),30);
}
else
{
df += v_up * autocvar_g_vehicle_raptor_speed_up;
vehic.velocity += df * dt;
- this.velocity = this.movement = vehic.velocity;
+ this.velocity = CS(this).movement = vehic.velocity;
setorigin(this, vehic.origin + '0 0 32');
this.oldorigin = this.origin; // negate fall damage
}
if (!PHYS_INPUT_BUTTON_JUMP(this))
- PHYS_INPUT_BUTTON_JUMP(vehic) = false;
+ vehic.button2 = false;
- if((IS_ONGROUND(vehic)) && PHYS_INPUT_BUTTON_JUMP(this) && !PHYS_INPUT_BUTTON_JUMP(vehic) && vehic.tur_head.wait < time)
+ if((IS_ONGROUND(vehic)) && PHYS_INPUT_BUTTON_JUMP(this) && !vehic.button2 && vehic.tur_head.wait < time)
{
sound (vehic, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_JUMP, VOL_VEHICLEENGINE, ATTEN_NORM);
//dprint("spiderbot_jump:", ftos(soundlength("vehicles/spiderbot_jump.wav")), "\n");
vehic.tur_head.wait = time + 2;
vehic.jump_delay = time + 2;
- PHYS_INPUT_BUTTON_JUMP(vehic) = true; // set spider's jump
+ vehic.button2 = true; // set spider's jump
//PHYS_INPUT_BUTTON_JUMP(this) = false;
vector movefix = '0 0 0';
- if(this.movement_x > 0) movefix_x = 1;
- if(this.movement_x < 0) movefix_x = -1;
- if(this.movement_y > 0) movefix_y = 1;
- if(this.movement_y < 0) movefix_y = -1;
+ if(CS(this).movement_x > 0) movefix_x = 1;
+ if(CS(this).movement_x < 0) movefix_x = -1;
+ if(CS(this).movement_y > 0) movefix_y = 1;
+ if(CS(this).movement_y < 0) movefix_y = -1;
vector rt = movefix_y * v_right;
vector sd = movefix_x * v_forward;
}
else if(time >= vehic.jump_delay)
{
- if(!this.movement)
+ if(!CS(this).movement)
{
if(IS_ONGROUND(vehic))
{
else
{
// Turn Body
- if(this.movement_x == 0 && this.movement_y != 0)
+ if(CS(this).movement_x == 0 && CS(this).movement_y != 0)
ftmp = autocvar_g_vehicle_spiderbot_turnspeed_strafe * PHYS_INPUT_FRAMETIME;
else
ftmp = autocvar_g_vehicle_spiderbot_turnspeed * PHYS_INPUT_FRAMETIME;
vehic.angles_y = anglemods(vehic.angles_y + ftmp);
vehic.tur_head.angles_y -= ftmp;
- if(this.movement_x != 0)
+ if(CS(this).movement_x != 0)
{
- if(this.movement_x > 0)
+ if(CS(this).movement_x > 0)
{
- this.movement_x = 1;
+ CS(this).movement_x = 1;
if(IS_ONGROUND(vehic))
vehic.frame = 0;
}
- else if(this.movement_x < 0)
+ else if(CS(this).movement_x < 0)
{
- this.movement_x = -1;
+ CS(this).movement_x = -1;
if(IS_ONGROUND(vehic))
vehic.frame = 1;
}
- this.movement_y = 0;
+ CS(this).movement_y = 0;
float oldvelz = vehic.velocity_z;
- movelib_move_simple(vehic, normalize(v_forward * this.movement_x),((PHYS_INPUT_BUTTON_JUMP(this)) ? autocvar_g_vehicle_spiderbot_speed_run : autocvar_g_vehicle_spiderbot_speed_walk),autocvar_g_vehicle_spiderbot_movement_inertia);
+ movelib_move_simple(vehic, normalize(v_forward * CS(this).movement_x),((PHYS_INPUT_BUTTON_JUMP(this)) ? autocvar_g_vehicle_spiderbot_speed_run : autocvar_g_vehicle_spiderbot_speed_walk),autocvar_g_vehicle_spiderbot_movement_inertia);
vehic.velocity_z = oldvelz;
float g = ((autocvar_sv_gameplayfix_gravityunaffectedbyticrate) ? 0.5 : 1);
if(vehic.velocity_z <= 20) // not while jumping
//dprint("spiderbot_walk:", ftos(soundlength("vehicles/spiderbot_walk.wav")), "\n");
}
}
- else if(this.movement_y != 0)
+ else if(CS(this).movement_y != 0)
{
- if(this.movement_y < 0)
+ if(CS(this).movement_y < 0)
{
- this.movement_y = -1;
+ CS(this).movement_y = -1;
if(IS_ONGROUND(vehic))
vehic.frame = 2;
}
- else if(this.movement_y > 0)
+ else if(CS(this).movement_y > 0)
{
- this.movement_y = 1;
+ CS(this).movement_y = 1;
if(IS_ONGROUND(vehic))
vehic.frame = 3;
}
float oldvelz = vehic.velocity_z;
- movelib_move_simple(vehic, normalize(v_right * this.movement_y),autocvar_g_vehicle_spiderbot_speed_strafe,autocvar_g_vehicle_spiderbot_movement_inertia);
+ movelib_move_simple(vehic, normalize(v_right * CS(this).movement_y),autocvar_g_vehicle_spiderbot_speed_strafe,autocvar_g_vehicle_spiderbot_movement_inertia);
vehic.velocity_z = oldvelz;
float g = ((autocvar_sv_gameplayfix_gravityunaffectedbyticrate) ? 0.5 : 1);
if(vehic.velocity_z <= 20) // not while jumping
if(this.viewloc.goalentity == this.viewloc.enemy)
return; // we can't side-scroll in this case
- vector old_movement = this.movement;
- this.movement_x = old_movement_y;
- this.movement_y = 0;
+ vector old_movement = PHYS_CS(this).movement;
+ PHYS_CS(this).movement_x = old_movement_y;
+ PHYS_CS(this).movement_y = 0;
- if(this.movement_x < 0)
- this.movement_x = -this.movement_x;
+ if(PHYS_CS(this).movement_x < 0)
+ PHYS_CS(this).movement_x = -PHYS_CS(this).movement_x;
vector level_start, level_end;
level_start = this.viewloc.enemy.origin;
forward = vectoangles(normalize(level_end - level_start));
backward = vectoangles(normalize(level_start - level_end));
- if(this.movement_x < 0) // left
+ if(PHYS_CS(this).movement_x < 0) // left
this.angles_y = backward_y;
- if(this.movement_x > 0) // right
+ if(PHYS_CS(this).movement_x > 0) // right
this.angles_y = forward_y;
if(old_movement_x > 0)
#include "../constants.qh"
#include "../stats.qh"
#include "../teams.qh"
- #include "../util.qh"
+ #include <common/util.qh>
#include "../monsters/_mod.qh"
#include "config.qh"
#include <server/weapons/csqcprojectile.qh>
return W_FixWeaponOrder(order, 1);
}
-void W_RandomWeapons(entity e, float n)
+void W_RandomWeapons(entity e, int n)
{
- int i;
- WepSet remaining;
- WepSet result;
- remaining = e.weapons;
- result = '0 0 0';
- for (i = 0; i < n; ++i)
+ WepSet remaining = e.weapons;
+ WepSet result = '0 0 0';
+ for (int j = 0; j < n; ++j)
{
RandomSelection_Init();
FOREACH(Weapons, it != WEP_Null, {
#ifdef GAMEQC
#include "calculations.qh"
+#include "projectiles.qh"
#include <common/models/all.qh>
#endif
#if defined(CSQC)
#elif defined(MENUQC)
#elif defined(SVQC)
- #include "../util.qh"
+ #include <common/util.qh>
#include "all.qh"
#endif
--- /dev/null
+#pragma once
+
+const int PROJECTILE_ELECTRO = 1;
+const int PROJECTILE_ROCKET = 2;
+const int PROJECTILE_TAG = 3;
+const int PROJECTILE_CRYLINK = 5;
+const int PROJECTILE_ELECTRO_BEAM = 6;
+const int PROJECTILE_GRENADE = 7;
+const int PROJECTILE_GRENADE_BOUNCING = 8;
+const int PROJECTILE_MINE = 9;
+const int PROJECTILE_BLASTER = 10;
+const int PROJECTILE_HLAC = 11;
+const int PROJECTILE_SEEKER = 12;
+const int PROJECTILE_FLAC = 13;
+const int PROJECTILE_PORTO_RED = 14;
+const int PROJECTILE_PORTO_BLUE = 15;
+const int PROJECTILE_HOOKBOMB = 16;
+const int PROJECTILE_HAGAR = 17;
+const int PROJECTILE_HAGAR_BOUNCING = 18;
+const int PROJECTILE_CRYLINK_BOUNCING = 20;
+const int PROJECTILE_FIREBALL = 21;
+const int PROJECTILE_FIREMINE = 22;
+
+const int PROJECTILE_RAPTORCANNON = 24;
+const int PROJECTILE_RAPTORBOMB = 25;
+const int PROJECTILE_RAPTORBOMBLET = 26;
+const int PROJECTILE_SPIDERROCKET = 27;
+const int PROJECTILE_WAKIROCKET = 28;
+const int PROJECTILE_WAKICANNON = 29;
+
+const int PROJECTILE_BUMBLE_GUN = 30;
+const int PROJECTILE_BUMBLE_BEAM = 31;
+
+const int PROJECTILE_MAGE_SPIKE = 32;
+const int PROJECTILE_SHAMBLER_LIGHTNING = 33;
+
+const int PROJECTILE_ROCKETMINSTA_LASER = 34;
+
+const int PROJECTILE_ARC_BOLT = 35;
+
+// projectile IDs 40-50 reserved
+
+const int PROJECTILE_RPC = 60;
string W_FixWeaponOrder_BuildImpulseList(string o);
string W_FixWeaponOrder_AllowIncomplete(entity this, string order);
string W_FixWeaponOrder_ForceComplete(string order);
-void W_RandomWeapons(entity e, float n);
+void W_RandomWeapons(entity e, int n);
string GetAmmoPicture(.int ammotype);
thiswep.wr_reload(thiswep, actor, weaponentity);
} else
{
- actor.rifle_accumulator = bound(time - WEP_CVAR(rifle, bursttime), actor.rifle_accumulator, time);
+ actor.(weaponentity).rifle_accumulator = bound(time - WEP_CVAR(rifle, bursttime), actor.(weaponentity).rifle_accumulator, time);
if(fire & 1)
if(weapon_prepareattack_check(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire)))
- if(time >= actor.rifle_accumulator + WEP_CVAR_PRI(rifle, burstcost))
+ if(time >= actor.(weaponentity).rifle_accumulator + WEP_CVAR_PRI(rifle, burstcost))
{
weapon_prepareattack_do(actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire));
W_Rifle_BulletHail(actor, weaponentity, WEP_CVAR_PRI(rifle, bullethail), W_Rifle_Attack, WFRAME_FIRE1, WEP_CVAR_PRI(rifle, animtime), WEP_CVAR_PRI(rifle, refire));
- actor.rifle_accumulator += WEP_CVAR_PRI(rifle, burstcost);
+ actor.(weaponentity).rifle_accumulator += WEP_CVAR_PRI(rifle, burstcost);
}
if(fire & 2)
{
} else
{
if(weapon_prepareattack_check(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire)))
- if(time >= actor.rifle_accumulator + WEP_CVAR_SEC(rifle, burstcost))
+ if(time >= actor.(weaponentity).rifle_accumulator + WEP_CVAR_SEC(rifle, burstcost))
{
weapon_prepareattack_do(actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire));
W_Rifle_BulletHail(actor, weaponentity, WEP_CVAR_SEC(rifle, bullethail), W_Rifle_Attack2, WFRAME_FIRE2, WEP_CVAR_SEC(rifle, animtime), WEP_CVAR_PRI(rifle, refire));
- actor.rifle_accumulator += WEP_CVAR_SEC(rifle, burstcost);
+ actor.(weaponentity).rifle_accumulator += WEP_CVAR_SEC(rifle, burstcost);
}
}
}
false
);
- float lag = ANTILAG_LATENCY(actor);
+ float lag = ((IS_REAL_CLIENT(actor)) ? ANTILAG_LATENCY(actor) : 0);
if(lag < 0.001)
lag = 0;
- if (!IS_REAL_CLIENT(actor))
- lag = 0;
if(autocvar_g_antilag == 0 || actor.cvar_cl_noantilag)
lag = 0; // only do hitscan, but no antilag
if(lag)
+ (v_up * swing_factor * WEP_CVAR_SEC(shotgun, melee_swing_up))
+ (v_right * swing_factor * WEP_CVAR_SEC(shotgun, melee_swing_side)));
- WarpZone_traceline_antilag(this, this.realowner.origin + this.realowner.view_ofs, targpos, false, this.realowner, ANTILAG_LATENCY(this.realowner));
+ WarpZone_traceline_antilag(this, this.realowner.origin + this.realowner.view_ofs, targpos, false, this.realowner, ((IS_CLIENT(this.realowner)) ? ANTILAG_LATENCY(this.realowner) : 0));
// draw lightning beams for debugging
//te_lightning2(NULL, targpos, this.realowner.origin + this.realowner.view_ofs + v_forward * 5 - v_up * 5);
int W_Tuba_GetNote(entity pl, int hittype)
{
float movestate = 5;
- if (pl.movement.x < 0) movestate -= 3;
- else if (pl.movement.x > 0) movestate += 3;
- if (pl.movement.y < 0) movestate -= 1;
- else if (pl.movement.y > 0) movestate += 1;
+ if (CS(pl).movement.x < 0) movestate -= 3;
+ else if (CS(pl).movement.x > 0) movestate += 3;
+ if (CS(pl).movement.y < 0) movestate -= 1;
+ else if (CS(pl).movement.y > 0) movestate += 1;
int note = 0;
switch (movestate)
sys_in_update(this, dt);
sys_phys_fix(this, dt);
- if (sys_phys_override(this, dt)) { return; } sys_phys_monitor(this, dt);
+ if (sys_phys_override(this, dt))
+ return;
+
+ sys_phys_monitor(this, dt);
- this.buttons_old = PHYS_INPUT_BUTTON_MASK(this);
- this.movement_old = this.movement;
- this.v_angle_old = this.v_angle;
+ PHYS_CS(this).movement_old = PHYS_CS(this).movement;
+ PHYS_CS(this).v_angle_old = this.v_angle;
+ PHYS_CS(this).buttons_old = PHYS_INPUT_BUTTON_MASK(this);
sys_phys_ai(this);
}
}
makevectors(vmul(this.v_angle, (this.com_phys_vel_2d ? '0 1 0' : '1 1 1')));
- // wishvel = v_forward * this.movement.x + v_right * this.movement.y + v_up * this.movement.z;
- vector wishvel = v_forward * this.movement.x
- + v_right * this.movement.y
- + '0 0 1' * this.movement.z * (this.com_phys_vel_2d ? 0 : 1);
+ // wishvel = v_forward * PHYS_CS(this).movement.x + v_right * PHYS_CS(this).movement.y + v_up * PHYS_CS(this).movement.z;
+ vector wishvel = v_forward * PHYS_CS(this).movement.x
+ + v_right * PHYS_CS(this).movement.y
+ + '0 0 1' * PHYS_CS(this).movement.z * (this.com_phys_vel_2d ? 0 : 1);
if (this.com_phys_water) {
if (PHYS_INPUT_BUTTON_CROUCH(this)) {
wishvel.z = -PHYS_MAXSPEED(this);
}
if (this.com_phys_ladder) {
if (this.viewloc) {
- wishvel.z = this.movement_old.x;
+ wishvel.z = PHYS_CS(this).movement_old.x;
}
if (this.ladder_entity.classname == "func_water") {
float f = vlen(wishvel);
// dv/dt = accel * maxspeed * (1 - accelqw) (when fast)
// log dv/dt = logaccel + logmaxspeed (when slow)
// log dv/dt = logaccel + logmaxspeed + log(1 - accelqw) (when fast)
- float strafity = IsMoveInDirection(this.movement, -90) + IsMoveInDirection(this.movement, +90); // if one is nonzero, other is always zero
+ float strafity = IsMoveInDirection(PHYS_CS(this).movement, -90) + IsMoveInDirection(PHYS_CS(this).movement, +90); // if one is nonzero, other is always zero
if (PHYS_MAXAIRSTRAFESPEED(this)) {
wishspeed =
min(wishspeed,
}
// !CPM
- if (PHYS_WARSOWBUNNY_TURNACCEL(this) && accelerating && this.movement.y == 0 && this.movement.x != 0) {
+ if (PHYS_WARSOWBUNNY_TURNACCEL(this) && accelerating && PHYS_CS(this).movement.y == 0 && PHYS_CS(this).movement.x != 0) {
PM_AirAccelerate(this, dt, wishdir, wishspeed2);
} else {
float sidefric = maxairspd ? (PHYS_AIRACCEL_SIDEWAYS_FRICTION(this) / maxairspd) : 0;
void sys_phys_fix(entity this, float dt)
{
WarpZone_PlayerPhysics_FixVAngle(this);
- STAT(MOVEVARS_HIGHSPEED, this) = autocvar_g_movement_highspeed;
- MUTATOR_CALLHOOK(PlayerPhysics_UpdateStats, this); // do it BEFORE the function so we can modify highspeed!
- Physics_UpdateStats(this, PHYS_HIGHSPEED(this));
+ Physics_UpdateStats(this);
}
bool sys_phys_override(entity this, float dt)
{
int buttons = PHYS_INPUT_BUTTON_MASK(this);
- float idlesince = this.parm_idlesince;
- this.parm_idlesince = time; // in the case that physics are overridden
+ float idlesince = CS(this).parm_idlesince;
+ CS(this).parm_idlesince = time; // in the case that physics are overridden
if (PM_check_specialcommand(this, buttons)) { return true; }
if (this.PlayerPhysplug && this.PlayerPhysplug(this, dt)) { return true; }
- this.parm_idlesince = idlesince;
+ CS(this).parm_idlesince = idlesince;
return false;
}
int buttons = PHYS_INPUT_BUTTON_MASK(this);
anticheat_physics(this);
if (sv_maxidle > 0) {
- if (buttons != this.buttons_old
- || this.movement != this.movement_old
- || this.v_angle != this.v_angle_old) { this.parm_idlesince = time; }
+ if (buttons != CS(this).buttons_old
+ || CS(this).movement != CS(this).movement_old
+ || this.v_angle != CS(this).v_angle_old) { CS(this).parm_idlesince = time; }
}
PM_check_nickspam(this);
PM_check_punch(this, dt);
{
float maxspeed_mod = autocvar_sv_spectator_speed_multiplier;
if (!this.spectatorspeed) { this.spectatorspeed = maxspeed_mod; }
- if ((this.impulse >= 1 && this.impulse <= 19)
- || (this.impulse >= 200 && this.impulse <= 209)
- || (this.impulse >= 220 && this.impulse <= 229)
+ if ((CS(this).impulse >= 1 && CS(this).impulse <= 19)
+ || (CS(this).impulse >= 200 && CS(this).impulse <= 209)
+ || (CS(this).impulse >= 220 && CS(this).impulse <= 229)
) {
if (this.lastclassname != STR_PLAYER) {
- if (this.impulse == 10
- || this.impulse == 15
- || this.impulse == 18
- || (this.impulse >= 200 && this.impulse <= 209)
- ) { this.spectatorspeed = bound(1, this.spectatorspeed + 0.5, 5); } else if (this.impulse == 11) {
+ if (CS(this).impulse == 10
+ || CS(this).impulse == 15
+ || CS(this).impulse == 18
+ || (CS(this).impulse >= 200 && CS(this).impulse <= 209)
+ ) { this.spectatorspeed = bound(1, this.spectatorspeed + 0.5, 5); } else if (CS(this).impulse == 11) {
this.spectatorspeed = maxspeed_mod;
- } else if (this.impulse == 12
- || this.impulse == 16
- || this.impulse == 19
- || (this.impulse >= 220 && this.impulse <= 229)
+ } else if (CS(this).impulse == 12
+ || CS(this).impulse == 16
+ || CS(this).impulse == 19
+ || (CS(this).impulse >= 220 && CS(this).impulse <= 229)
) {
this.spectatorspeed = bound(1, this.spectatorspeed - 0.5, 5);
- } else if (this.impulse >= 1 && this.impulse <= 9) {
- this.spectatorspeed = 1 + 0.5 * (this.impulse - 1);
+ } else if (CS(this).impulse >= 1 && CS(this).impulse <= 9) {
+ this.spectatorspeed = 1 + 0.5 * (CS(this).impulse - 1);
}
} // otherwise just clear
- this.impulse = 0;
+ CS(this).impulse = 0;
}
}
#define bool float
#endif
+#ifndef QCC_SUPPORT_ERASEABLE
+ #define ERASEABLE
+#else
+ #define ERASEABLE [[eraseable]]
+#endif
+
#include <dpdefs/pre.qh>
#if defined(CSQC)
/*
* Return a angle within +/- 360.
*/
-[[eraseable]]
+ERASEABLE
float anglemods(float v)
{
v = v - 360 * floor(v / 360);
/*
* Return the short angle
*/
-[[eraseable]]
+ERASEABLE
float shortangle_f(float ang1, float ang2)
{
if(ang1 > ang2)
return ang1;
}
-[[eraseable]]
+ERASEABLE
vector shortangle_v(vector ang1, vector ang2)
{
vector vtmp;
return vtmp;
}
-[[eraseable]]
+ERASEABLE
vector shortangle_vxy(vector ang1, vector ang2)
{
vector vtmp = '0 0 0';
* Return the angle offset between angle ang and angle of the vector from->to
*/
-[[eraseable]]
+ERASEABLE
vector angleofs3(vector from, vector ang, vector to)
{
vector v_res;
#define BITSET(var, mask, flag) ((var) ^ (-(flag) ^ (var)) & (mask))
#endif
-[[eraseable]]
+ERASEABLE
int lowestbit(int f)
{
f &= ~(f << 1);
return f;
}
-[[eraseable]]
+ERASEABLE
int randombit(int bits)
{
if (!(bits & (bits - 1))) // this ONLY holds for powers of two!
return b;
}
-[[eraseable]]
+ERASEABLE
int randombits(int bits, int k, bool error_return)
{
int r = 0;
OP_MINUS
};
-[[eraseable]]
+ERASEABLE
bool GiveBit(entity e, .int fld, int bit, int op, int val)
{
int v0 = (e.(fld) & bit);
return v0 != v1;
}
-[[eraseable]]
+ERASEABLE
bool GiveValue(entity e, .int fld, int op, int val)
{
int v0 = e.(fld);
#define boolean(value) ((value) != 0)
// get true/false value of a string with multiple different inputs
-[[eraseable]]
+ERASEABLE
float InterpretBoolean(string input)
{
switch (strtolower(input))
#include "string.qh"
#define colormapPaletteColor(c, isPants) colormapPaletteColor_(c, isPants, time)
-[[eraseable]]
+ERASEABLE
vector colormapPaletteColor_(int c, bool isPants, float t)
{
switch (c)
}
}
-[[eraseable]]
+ERASEABLE
float rgb_mi_ma_to_hue(vector rgb, float mi, float ma)
{
if (mi == ma)
}
}
-[[eraseable]]
+ERASEABLE
vector hue_mi_ma_to_rgb(float hue, float mi, float ma)
{
vector rgb;
return rgb;
}
-[[eraseable]]
+ERASEABLE
vector rgb_to_hsv(vector rgb)
{
float mi, ma;
return hsv;
}
-[[eraseable]]
+ERASEABLE
vector hsv_to_rgb(vector hsv)
{
return hue_mi_ma_to_rgb(hsv.x, hsv.z * (1 - hsv.y), hsv.z);
}
-[[eraseable]]
+ERASEABLE
vector rgb_to_hsl(vector rgb)
{
float mi, ma;
return hsl;
}
-[[eraseable]]
+ERASEABLE
vector hsl_to_rgb(vector hsl)
{
float mi, ma, maminusmi;
return hue_mi_ma_to_rgb(hsl.x, mi, ma);
}
-[[eraseable]]
+ERASEABLE
string rgb_to_hexcolor(vector rgb)
{
return strcat(
#endif
#endif
+#ifndef QCC_SUPPORT_ERASEABLE
+ #ifdef GMQCC
+ #define QCC_SUPPORT_ERASEABLE
+ #endif
+#endif
+
#ifdef GMQCC
#define LABEL(id) :id
#else
_("CI_THI^%d seconds"), /* third */ \
_("CI_MUL^%d seconds")) /* multi */
-[[eraseable]]
+ERASEABLE
string count_ordinal(int interval)
{
// This function is designed primarily for the English language, it's impossible
return "";
}
-[[eraseable]]
+ERASEABLE
string count_fill(float interval, string zeroth, string first, string second, string third, string multi)
{
// This function is designed primarily for the English language, it's impossible
return "";
}
-[[eraseable]]
+ERASEABLE
string process_time(float outputtype, float seconds)
{
float tmp_hours = 0, tmp_minutes = 0, tmp_seconds = 0;
#include "progname.qh"
#include "static.qh"
-[[eraseable]]
+ERASEABLE
void RegisterCvars(void(string name, string def, string desc, bool archive, string file) f) {}
-[[eraseable]]
+ERASEABLE
bool cvar_value_issafe(string s)
{
if (strstrofs(s, "\"", 0) >= 0) return false;
}
/** escape the string to make it safe for consoles */
-[[eraseable]]
+ERASEABLE
string MakeConsoleSafe(string input)
{
input = strreplace("\n", "", input);
return input;
}
-[[eraseable]]
+ERASEABLE
void cvar_describe(string name, string desc)
{
localcmd(sprintf("\nset %1$s \"$%1$s\" \"%2$s\"\n", name, MakeConsoleSafe(desc)));
}
-[[eraseable]]
+ERASEABLE
void cvar_archive(string name)
{
localcmd(sprintf("\nseta %1$s \"$%1$s\"\n", name));
}
-[[eraseable]]
+ERASEABLE
void RegisterCvars_Set(string name, string def, string desc, bool archive, string file)
{
cvar_describe(name, desc);
}
int RegisterCvars_Save_fd;
-[[eraseable]]
+ERASEABLE
void RegisterCvars_Save(string name, string def, string desc, bool archive, string file)
{
if (!archive) return;
}
}
- [[eraseable]]
+ ERASEABLE
void drawstringright(vector position, string text, vector theScale, vector rgb, float theAlpha, int flag)
{
position.x -= 2 / 3 * strlen(text) * theScale.x;
drawstring_builtin(position, text, theScale, rgb, theAlpha, flag);
}
- [[eraseable]]
+ ERASEABLE
void drawstringcenter(vector position, string text, vector theScale, vector rgb, float theAlpha, int flag)
{
position.x = 0.5 * (vid_conwidth - 0.6025 * strlen(text) * theScale.x);
#pragma once
-[[eraseable]]
+ERASEABLE
bool fexists(string f)
{
int fh = fopen(f, FILE_READ);
/**
* @deprecated prefer _("translated")
*/
-[[eraseable]]
+ERASEABLE
string language_filename(string s)
{
string fn = prvm_language;
}
#endif
-[[eraseable]]
+ERASEABLE
string CTX(string s)
{
#if CTX_CACHE
const int IL_MAX = 128;
-[[eraseable]]
+ERASEABLE
void IL_INIT(entity this);
-[[eraseable]]
+ERASEABLE
void IL_DTOR(entity this);
-[[eraseable]]
+ERASEABLE
void IL_ENDFRAME();
/**
#define IL_LAST(this) (this.il_tail)
#define IL_PEEK(this) (this.il_tail)
-[[eraseable]]
+ERASEABLE
bool IL_CONTAINS(IntrusiveList this, entity it)
{
assert(this, return false);
/**
* Push to tail
*/
-[[eraseable]]
+ERASEABLE
entity IL_PUSH(IntrusiveList this, entity it)
{
assert(this, return NULL);
/**
* Push to head
*/
-[[eraseable]]
+ERASEABLE
entity IL_UNSHIFT(IntrusiveList this, entity it)
{
assert(this, return NULL);
/**
* Pop from tail
*/
-[[eraseable]]
+ERASEABLE
entity IL_POP(IntrusiveList this)
{
assert(this, return NULL);
/**
* Pop from head
*/
-[[eraseable]]
+ERASEABLE
entity IL_SHIFT(IntrusiveList this)
{
assert(this, return NULL);
/**
* Remove any element, anywhere in the list
*/
-[[eraseable]]
+ERASEABLE
void IL_REMOVE(IntrusiveList this, entity it)
{
assert(this, return);
#define IL_LISTS_PER_BIT IL_CEIL(IL_MAX / (3 * 24))
-[[eraseable]]
+ERASEABLE
void IL_INIT(IntrusiveList this)
{
.entity nextfld, prevfld;
LOG_WARNF("IntrusiveList overflow");
}
-[[eraseable]]
+ERASEABLE
void IL_DTOR(IntrusiveList this)
{
IL_CLEAR(this);
il_links[this.il_id] = NULL;
}
-[[eraseable]]
+ERASEABLE
void IL_ENDFRAME()
{
#if 0
#endif
}
-[[eraseable]]
+ERASEABLE
void ONREMOVE(entity this)
{
if (this.il_lists) {
// Current keys
int _json_keys;
-[[eraseable]]
+ERASEABLE
bool _json_parse_object() {
JSON_BEGIN();
if (STRING_ITERATOR_GET(_json) != '{') JSON_FAIL("expected '{'");
JSON_END();
}
- [[eraseable]]
+ ERASEABLE
bool _json_parse_members() {
JSON_BEGIN();
for (;;) {
JSON_END();
}
- [[eraseable]]
+ ERASEABLE
bool _json_parse_pair() {
JSON_BEGIN();
if (!_json_parse_string(false)) JSON_FAIL("expected string");
JSON_END();
}
-[[eraseable]]
+ERASEABLE
bool _json_parse_array() {
JSON_BEGIN();
if (STRING_ITERATOR_GET(_json) != '[') JSON_FAIL("expected '['");
JSON_END();
}
-[[eraseable]]
+ERASEABLE
bool _json_parse_value() {
JSON_BEGIN();
if (!(_json_parse_string(true)
JSON_END();
}
- [[eraseable]]
+ ERASEABLE
bool _json_parse_true() {
JSON_BEGIN();
if (!(STRING_ITERATOR_GET(_json) == 't'
JSON_END();
}
- [[eraseable]]
+ ERASEABLE
bool _json_parse_false() {
JSON_BEGIN();
if (!(STRING_ITERATOR_GET(_json) == 'f'
JSON_END();
}
- [[eraseable]]
+ ERASEABLE
bool _json_parse_null() {
JSON_BEGIN();
if (!(STRING_ITERATOR_GET(_json) == 'n'
JSON_END();
}
-[[eraseable]]
+ERASEABLE
bool _json_parse_string(bool add) {
JSON_BEGIN();
if (STRING_ITERATOR_GET(_json) != '"') JSON_FAIL("expected opening '\"'");
JSON_END();
}
-[[eraseable]]
+ERASEABLE
bool _json_parse_number() {
JSON_BEGIN();
if (!(_json_parse_float() || _json_parse_int())) JSON_FAIL("expected number");
JSON_END();
}
- [[eraseable]]
+ ERASEABLE
bool _json_parse_float() {
JSON_BEGIN();
string s = "";
JSON_END();
}
- [[eraseable]]
+ ERASEABLE
bool _json_parse_int() {
JSON_BEGIN();
string s = "";
JSON_END();
}
-[[eraseable]]
+ERASEABLE
int json_parse(string in, bool() func) {
string trimmed = "";
LABEL(trim) {
return _json_buffer;
}
-[[eraseable]]
+ERASEABLE
string json_get(int buf, string key)
{
for (int i = 1, n = buf_getsize(buf); i < n; i += 2) {
return string_null;
}
-[[eraseable]]
+ERASEABLE
void json_del(int buf)
{
buf_del(buf);
}
-[[eraseable]]
+ERASEABLE
void json_dump(int buf)
{
for (int i = 0, n = buf_getsize(buf); i < n; ++i) {
// Databases (hash tables)
const int DB_BUCKETS = 8192;
-[[eraseable]]
+ERASEABLE
void db_save(int db, string filename)
{
int fh = fopen(filename, FILE_WRITE);
USING(HashMap, int);
-[[eraseable]]
+ERASEABLE
int db_create()
{
return buf_create();
}
#define HM_NEW(this) (this = db_create())
-[[eraseable]]
+ERASEABLE
void db_put(int db, string key, string value);
-[[eraseable]]
+ERASEABLE
int db_load(string filename)
{
int db = buf_create();
return db;
}
-[[eraseable]]
+ERASEABLE
void db_dump(int db, string filename)
{
int fh = fopen(filename, FILE_WRITE);
fclose(fh);
}
-[[eraseable]]
+ERASEABLE
void db_close(int db)
{
buf_del(db);
}
#define HM_DELETE(this) db_close(this)
-[[eraseable]]
+ERASEABLE
string db_get(int db, string key)
{
int h = crc16(false, key) % DB_BUCKETS;
#define db_remove(db, key) db_put(db, key, "")
-[[eraseable]]
+ERASEABLE
void db_put(int db, string key, string value)
{
int h = crc16(false, key) % DB_BUCKETS;
* - two spaces escape a linebreak (otherwise text wraps)
* - two linebreaks become a paragraph (remain unchanged)
*/
-[[eraseable]]
+ERASEABLE
string markdown(string s)
{
string buf = "";
#include "lib/float.qh"
-[[eraseable]]
+ERASEABLE
void mean_accumulate(entity e, .float a, .float c, float mean, float value, float weight)
{
if (weight == 0) return;
e.(c) += weight;
}
-[[eraseable]]
+ERASEABLE
float mean_evaluate(entity e, .float a, .float c, float mean)
{
if (e.(c) == 0) return 0;
*/
-[[eraseable]]
+ERASEABLE
float angc(float a1, float a2)
{
while (a1 > 180)
return a;
}
-[[eraseable]]
+ERASEABLE
float fsnap(float val, float fsize)
{
return rint(val / fsize) * fsize;
}
-[[eraseable]]
+ERASEABLE
vector vsnap(vector point, float fsize)
{
vector vret;
return vret;
}
-[[eraseable]]
+ERASEABLE
vector lerpv(float t0, vector v0, float t1, vector v1, float t)
{
return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));
}
-[[eraseable]]
+ERASEABLE
vector bezier_quadratic_getpoint(vector a, vector b, vector c, float t)
{
return (c - 2 * b + a) * (t * t)
+ a;
}
-[[eraseable]]
+ERASEABLE
vector bezier_quadratic_getderivative(vector a, vector b, vector c, float t)
{
return (c - 2 * b + a) * (2 * t)
+ (b - a) * 2;
}
-[[eraseable]]
+ERASEABLE
float cubic_speedfunc(float startspeedfactor, float endspeedfactor, float spd)
{
return (((startspeedfactor + endspeedfactor - 2
) * spd;
}
-[[eraseable]]
+ERASEABLE
bool cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor)
{
if (startspeedfactor < 0 || endspeedfactor < 0) return false;
}
/** continuous function mapping all reals into -1..1 */
-[[eraseable]]
+ERASEABLE
float float2range11(float f)
{
return f / (fabs(f) + 1);
}
/** continuous function mapping all reals into 0..1 */
-[[eraseable]]
+ERASEABLE
float float2range01(float f)
{
return 0.5 + 0.5 * float2range11(f);
}
-[[eraseable]]
+ERASEABLE
float median(float a, float b, float c)
{
return (a < c) ? bound(a, b, c) : bound(c, b, a);
}
-[[eraseable]]
+ERASEABLE
float almost_equals(float a, float b)
{
float eps = (max(a, -a) + max(b, -b)) * 0.001;
return a - b < eps && b - a < eps;
}
-[[eraseable]]
+ERASEABLE
float almost_equals_eps(float a, float b, float times_eps)
{
float eps = max(fabs(a), fabs(b)) * FLOAT_EPSILON * times_eps;
return a - b < eps && b - a < eps;
}
-[[eraseable]]
+ERASEABLE
float almost_in_bounds(float a, float b, float c)
{
float eps = (max(a, -a) + max(c, -c)) * 0.001;
return b == median(a - eps, b, c + eps);
}
-[[eraseable]]
+ERASEABLE
float ExponentialFalloff(float mindist, float maxdist, float halflifedist, float d)
{
if (halflifedist > 0) return (0.5 ** ((bound(mindist, d, maxdist) - mindist) / halflifedist));
#define power2of(e) (2 ** e)
-[[eraseable]]
+ERASEABLE
float log2of(float e)
{
// NOTE: generated code
}
/** ax^2 + bx + c = 0 */
-[[eraseable]]
+ERASEABLE
vector solve_quadratic(float a, float b, float c)
{
vector v;
class(Noise).float noise_paccum3;
class(Noise).float noise_bstate;
-[[eraseable]]
+ERASEABLE
float Noise_Brown(entity e, float dt)
{
e.noise_baccum += random() * sqrt(dt); // same stddev for all dt
return e.noise_baccum;
}
-[[eraseable]]
+ERASEABLE
float Noise_Pink(entity e, float dt)
{
float f;
if (random() > (0.9613 ** f)) e.noise_paccum3 = 0.43488 * (2 * random() - 1);
return e.noise_paccum + e.noise_paccum2 + e.noise_paccum3;
}
-[[eraseable]]
+ERASEABLE
float Noise_White(entity e, float dt)
{
return random() * 2 - 1;
}
/** +1 or -1 */
-[[eraseable]]
+ERASEABLE
float Noise_Burst(entity e, float dt, float p)
{
if (random() > (p ** dt)) e.noise_bstate = !e.noise_bstate;
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-[[eraseable]]
+ERASEABLE
vector vec_bias(vector v, float f)
{
vector c;
c.z = v.z + f;
return c;
}
-[[eraseable]]
+ERASEABLE
vector vec_to_min(vector a, vector b)
{
vector c;
return c;
}
-[[eraseable]]
+ERASEABLE
vector vec_to_max(vector a, vector b)
{
vector c;
}
// there may already be a function for bounding a vector in this manner, however my very quick search did not reveal one -- Player_2
-[[eraseable]]
+ERASEABLE
vector vec_bounds_in(vector point, vector a, vector b)
{
vector d = vec_to_min(a, b);
return c;
}
-[[eraseable]]
+ERASEABLE
vector vec_bounds_out(vector point, vector a, vector b)
{
vector d = vec_to_max(a, b);
return c;
}
-[[eraseable]]
+ERASEABLE
float angle_snap_f(float f, float increment)
{
for (int j = 0; j <= 360; )
return 0;
}
-[[eraseable]]
+ERASEABLE
vector angle_snap_vec(vector v, float increment)
{
vector c;
return c;
}
-[[eraseable]]
+ERASEABLE
vector aim_vec(vector org, vector targ)
{
vector v;
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-[[eraseable]]
+ERASEABLE
vector vec_bias(vector v, float f);
-[[eraseable]]
+ERASEABLE
vector vec_to_min(vector a, vector b);
-[[eraseable]]
+ERASEABLE
vector vec_to_max(vector a, vector b);
// there may already be a function for bounding a vector in this manner, however my very quick search did not reveal one -- Player_2
-[[eraseable]]
+ERASEABLE
vector vec_bounds_in(vector point, vector a, vector b);
-[[eraseable]]
+ERASEABLE
vector vec_bounds_out(vector point, vector a, vector b);
-[[eraseable]]
+ERASEABLE
float angle_snap_f(float f, float increment);
-[[eraseable]]
+ERASEABLE
vector angle_snap_vec(vector v, float increment);
-[[eraseable]]
+ERASEABLE
vector aim_vec(vector org, vector targ);
#include "random.qh"
-[[eraseable]]
+ERASEABLE
void RandomSelection_Init()
{
RandomSelection_totalweight = 0;
RandomSelection_best_priority = -1;
}
-[[eraseable]]
+ERASEABLE
void RandomSelection_Add(entity e, float f, string s, vector v, float weight, float priority)
{
if (priority > RandomSelection_best_priority)
float DistributeEvenly_amount;
float DistributeEvenly_totalweight;
-[[eraseable]]
+ERASEABLE
void DistributeEvenly_Init(float amount, float totalweight)
{
if (DistributeEvenly_amount)
DistributeEvenly_totalweight = totalweight;
}
-[[eraseable]]
+ERASEABLE
float DistributeEvenly_Get(float weight)
{
float f;
return f;
}
-[[eraseable]]
+ERASEABLE
float DistributeEvenly_GetRandomized(float weight)
{
float f;
// from the GNU Scientific Library
float gsl_ran_gaussian_lastvalue;
float gsl_ran_gaussian_lastvalue_set;
-[[eraseable]]
+ERASEABLE
float gsl_ran_gaussian(float sigma)
{
if (gsl_ran_gaussian_lastvalue_set)
string RandomSelection_chosen_string;
vector RandomSelection_chosen_vec;
-[[eraseable]]
+ERASEABLE
void RandomSelection_Init();
-[[eraseable]]
+ERASEABLE
void RandomSelection_Add(entity e, float f, string s, vector v, float weight, float priority);
#define RandomSelection_AddEnt(e, weight, priority) RandomSelection_Add(e, 0, string_null, '0 0 0', weight, priority)
#define RandomSelection_AddFloat(f, weight, priority) RandomSelection_Add(NULL, f, string_null, '0 0 0', weight, priority)
#define REGISTRY_HASH(id) Registry_hash_##id
-[[eraseable]]
+ERASEABLE
[[accumulate]] void Registry_check(string r, string server) { }
-[[eraseable]]
+ERASEABLE
[[accumulate]] void Registry_send_all() { }
#ifdef SVQC
/** <0 for <, ==0 for ==, >0 for > (like strcmp) */
USING(comparefunc_t, int (int i1, int i2, entity pass));
-[[eraseable]]
+ERASEABLE
void heapsort(int n, swapfunc_t swap, comparefunc_t cmp, entity pass)
{
#define heapify(_count) \
}
}
-[[eraseable]]
+ERASEABLE
void shuffle(float n, swapfunc_t swap, entity pass)
{
for (int i = 1; i < n; ++i)
#include "sortlist.qh"
-[[eraseable]]
+ERASEABLE
entity Sort_Spawn()
{
entity sort = new_pure(sortlist);
float(int tmr) _gettime = #519;
#endif
-[[eraseable]]
+ERASEABLE
void profile(string s)
{
static float g_starttime;
}
#endif
-[[eraseable]]
+ERASEABLE
string seconds_tostring(float sec)
{
float minutes = floor(sec / 60);
return sprintf("%d:%02d", minutes, sec);
}
-[[eraseable]]
+ERASEABLE
string format_time(float seconds)
{
seconds = floor(seconds + 0.5);
else return sprintf(_("%02d:%02d:%02d"), hours, minutes, seconds);
}
-[[eraseable]]
+ERASEABLE
string mmsss(float tenths)
{
tenths = floor(tenths + 0.5);
return strcat(ftos(minutes), ":", substring(s, 1, 2), ".", substring(s, 3, 1));
}
-[[eraseable]]
+ERASEABLE
string mmssss(float hundredths)
{
hundredths = floor(hundredths + 0.5);
int ColorTranslateMode;
-[[eraseable]]
+ERASEABLE
string ColorTranslateRGB(string s)
{
return (ColorTranslateMode & 1) ? strdecolorize(s) : s;
#define startsWith(haystack, needle) (strstrofs(haystack, needle, 0) == 0)
-[[eraseable]]
+ERASEABLE
bool startsWithNocase(string haystack, string needle)
{
return strcasecmp(substring(haystack, 0, strlen(needle)), needle) == 0;
#define endsWith(this, suffix) (_endsWith_suffix = suffix, substring(this, -strlen(_endsWith_suffix), -1) == _endsWith_suffix)
/** unzone the string, and return it as tempstring. Safe to be called on string_null */
-[[eraseable]]
+ERASEABLE
string fstrunzone(string s)
{
if (!s) return s;
}
/** returns first word */
-[[eraseable]]
+ERASEABLE
string car(string s)
{
int o = strstrofs(s, " ", 0);
}
/** returns all but first word */
-[[eraseable]]
+ERASEABLE
string cdr(string s)
{
int o = strstrofs(s, " ", 0);
return substring(s, o + 1, strlen(s) - (o + 1));
}
-[[eraseable]]
+ERASEABLE
string cons(string a, string b)
{
if (a == "") return b;
return strcat(a, " ", b);
}
-[[eraseable]]
+ERASEABLE
string substring_range(string s, float b, float e)
{
return substring(s, b, e - b);
}
-[[eraseable]]
+ERASEABLE
string swapwords(string str, float i, float j)
{
float n;
}
string _shufflewords_str;
-[[eraseable]]
+ERASEABLE
void _shufflewords_swapfunc(float i, float j, entity pass)
{
_shufflewords_str = swapwords(_shufflewords_str, i, j);
}
-[[eraseable]]
+ERASEABLE
string shufflewords(string str)
{
_shufflewords_str = str;
return str;
}
-[[eraseable]]
+ERASEABLE
string unescape(string in)
{
in = strzone(in); // but it doesn't seem to be necessary in my tests at least
return str;
}
-[[eraseable]]
+ERASEABLE
string strwords(string s, int w)
{
int endpos = 0;
#define strhasword(s, w) (strstrofs(strcat(" ", s, " "), strcat(" ", w, " "), 0) >= 0)
-[[eraseable]]
+ERASEABLE
int u8_strsize(string s)
{
int l = 0;
return l;
}
-[[eraseable]]
+ERASEABLE
bool isInvisibleString(string s)
{
s = strdecolorize(s);
// Multiline text file buffers
-[[eraseable]]
+ERASEABLE
int buf_load(string pFilename)
{
int buf = buf_create();
return buf;
}
-[[eraseable]]
+ERASEABLE
void buf_save(float buf, string pFilename)
{
int fh = fopen(pFilename, FILE_WRITE);
/**
* converts a number to a string with the indicated number of decimals
*/
-[[eraseable]]
+ERASEABLE
string ftos_decimals(float number, int decimals)
{
// inhibit stupid negative zero
/**
* converts a number to a string with the minimum number of decimals
*/
-[[eraseable]]
+ERASEABLE
string ftos_mindecimals(float number)
{
// inhibit stupid negative zero
return sprintf("%.7g", number);
}
-[[eraseable]]
+ERASEABLE
int vercmp_recursive(string v1, string v2)
{
int dot1 = strstrofs(v1, ".", 0);
else return (dot2 == -1) ? 1 : vercmp_recursive(substring(v1, dot1 + 1, 999), substring(v2, dot2 + 1, 999));
}
-[[eraseable]]
+ERASEABLE
int vercmp(string v1, string v2)
{
if (strcasecmp(v1, v2) == 0) return 0; // early out check
entity url_fromid[NUM_URL_ID];
int autocvar__urllib_nextslot;
-[[eraseable]]
+ERASEABLE
float url_URI_Get_Callback(int id, float status, string data)
{
if (id < MIN_URL_ID) return 0;
}
}
-[[eraseable]]
+ERASEABLE
void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
{
entity e;
}
// close a file
-[[eraseable]]
+ERASEABLE
void url_fclose(entity e)
{
int i;
}
// with \n (blame FRIK_FILE)
-[[eraseable]]
+ERASEABLE
string url_fgets(entity e)
{
if (e.url_fh == URL_FH_CURL)
}
// without \n (blame FRIK_FILE)
-[[eraseable]]
+ERASEABLE
void url_fputs(entity e, string s)
{
if (e.url_fh == URL_FH_CURL)
}
// multi URL object, tries URLs separated by space in sequence
-[[eraseable]]
+ERASEABLE
void url_multi_ready(entity fh, entity me, float status)
{
float n;
me.url_ready(fh, me.url_ready_pass, status);
}
-[[eraseable]]
+ERASEABLE
void url_multi_fopen(string url, int mode, url_ready_func rdy, entity pass)
{
float n;
// errors: -1, or negative HTTP status code
USING(url_ready_func, void (entity handle, entity pass, float status));
-[[eraseable]]
+ERASEABLE
void url_single_fopen(string url, float mode, url_ready_func rdy, entity pass);
-[[eraseable]]
+ERASEABLE
void url_fclose(entity e);
-[[eraseable]]
+ERASEABLE
string url_fgets(entity e);
-[[eraseable]]
+ERASEABLE
void url_fputs(entity e, string s);
// returns true if handled
-[[eraseable]]
+ERASEABLE
float url_URI_Get_Callback(int id, float status, string data);
#define MIN_URL_ID URI_GET_URLLIB
#define NUM_URL_ID (URI_GET_URLLIB_END - URI_GET_URLLIB + 1)
-[[eraseable]]
+ERASEABLE
void url_multi_fopen(string url, float mode, url_ready_func rdy, entity pass);
#if 1
#define cross(a, b) ((a) >< (b))
#else
-[[eraseable]]
+ERASEABLE
vector cross(vector a, vector b)
{
return
const vector eY = '0 1 0';
const vector eZ = '0 0 1';
-[[eraseable]]
+ERASEABLE
vector randompos(vector m1, vector m2)
{
vector v;
return v;
}
-[[eraseable]]
+ERASEABLE
float vlen_maxnorm2d(vector v)
{
return max(v.x, v.y, -v.x, -v.y);
}
-[[eraseable]]
+ERASEABLE
float vlen_minnorm2d(vector v)
{
return min(max(v.x, -v.x), max(v.y, -v.y));
}
-[[eraseable]]
+ERASEABLE
float dist_point_line(vector p, vector l0, vector ldir)
{
ldir = normalize(ldir);
}
/** requires that m2>m1 in all coordinates, and that m4>m3 */
-[[eraseable]]
+ERASEABLE
float boxesoverlap(vector m1, vector m2, vector m3, vector m4) { return m2_x >= m3_x && m1_x <= m4_x && m2_y >= m3_y && m1_y <= m4_y && m2_z >= m3_z && m1_z <= m4_z; }
/** requires the same as boxesoverlap, but is a stronger condition */
-[[eraseable]]
+ERASEABLE
float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) { return smins.x >= bmins.x && smaxs.x <= bmaxs.x && smins.y >= bmins.y && smaxs.y <= bmaxs.y && smins.z >= bmins.z && smaxs.z <= bmaxs.z; }
#define PITCH(v) ((v).x)
noref vector _vec3;
#define vec3(_x, _y, _z) (_vec3.x = (_x), _vec3.y = (_y), _vec3.z = (_z), _vec3)
-[[eraseable]]
+ERASEABLE
vector Rotate(vector v, float a)
{
float a_sin = sin(a), a_cos = cos(a);
* @param norm the normalized normal
* @returns dir reflected by norm
*/
-[[eraseable]]
+ERASEABLE
vector reflect(vector dir, vector norm)
{
return dir - 2 * (dir * norm) * norm;
/**
* clip vel along the plane defined by norm (assuming 0 distance away), bounciness determined by bounce 0..1
*/
-[[eraseable]]
+ERASEABLE
vector vec_reflect(vector vel, vector norm, float bounce)
{
return vel - (1 + bounce) * (vel * norm) * norm;
}
-[[eraseable]]
+ERASEABLE
vector vec_epsilon(vector this, float eps)
{
if (this.x > -eps && this.x < eps) this.x = 0;
(out = vec_epsilon(vec_reflect(in, normal, (overbounce) - 1), 0.1))
#ifdef GAMEQC
- [[eraseable]]
+ ERASEABLE
vector get_corner_position(entity box, int corner)
{
switch (corner)
}
}
- [[eraseable]]
+ ERASEABLE
vector NearestPointOnBox(entity box, vector org)
{
vector m1 = box.mins + box.origin;
return e;
}
-float WarpZoneLib_ExactTrigger_Touch(entity this, entity toucher)
+bool WarpZoneLib_ExactTrigger_Touch(entity this, entity toucher)
{
return !WarpZoneLib_BoxTouchesBrush(toucher.absmin, toucher.absmax, this, toucher);
}
}
}
-float WarpZoneLib_MoveOutOfSolid(entity e)
+bool WarpZoneLib_MoveOutOfSolid(entity e)
{
- vector o, m0, m1;
-
- o = e.origin;
+ vector o = e.origin;
traceline(o, o, MOVE_WORLDONLY, e);
if (trace_startsolid)
return false;
if (!trace_startsolid)
return true;
- m0 = e.mins;
- m1 = e.maxs;
+ vector m0 = e.mins;
+ vector m1 = e.maxs;
e.mins = '0 0 0';
e.maxs = '0 0 0';
- WarpZoneLib_MoveOutOfSolid_Expand(e, '1 0 0' * m0_x);
- e.mins_x = m0_x;
- WarpZoneLib_MoveOutOfSolid_Expand(e, '1 0 0' * m1_x);
- e.maxs_x = m1_x;
- WarpZoneLib_MoveOutOfSolid_Expand(e, '0 1 0' * m0_y);
- e.mins_y = m0_y;
- WarpZoneLib_MoveOutOfSolid_Expand(e, '0 1 0' * m1_y);
- e.maxs_y = m1_y;
- WarpZoneLib_MoveOutOfSolid_Expand(e, '0 0 1' * m0_z);
- e.mins_z = m0_z;
- WarpZoneLib_MoveOutOfSolid_Expand(e, '0 0 1' * m1_z);
- e.maxs_z = m1_z;
+ WarpZoneLib_MoveOutOfSolid_Expand(e, eX * m0.x); e.mins.x = m0.x;
+ WarpZoneLib_MoveOutOfSolid_Expand(e, eX * m1.x); e.maxs.x = m1.x;
+ WarpZoneLib_MoveOutOfSolid_Expand(e, eY * m0.y); e.mins.y = m0.y;
+ WarpZoneLib_MoveOutOfSolid_Expand(e, eY * m1.y); e.maxs.y = m1.y;
+ WarpZoneLib_MoveOutOfSolid_Expand(e, eZ * m0.z); e.mins.z = m0.z;
+ WarpZoneLib_MoveOutOfSolid_Expand(e, eZ * m1.z); e.maxs.z = m1.z;
setorigin(e, e.origin);
tracebox(e.origin, e.mins, e.maxs, e.origin, MOVE_WORLDONLY, e);
#ifndef BITXOR_ASSIGN
# define BITXOR_ASSIGN(a,b) ((a) = ((a) | (b)) - ((a) & (b)))
#endif
-float WarpZoneLib_MoveOutOfSolid(entity e);
+bool WarpZoneLib_MoveOutOfSolid(entity e);
#define move_out_of_solid(e) WarpZoneLib_MoveOutOfSolid(e)
-float WarpZoneLib_ExactTrigger_Touch(entity this, entity toucher);
+bool WarpZoneLib_ExactTrigger_Touch(entity this, entity toucher);
void WarpZoneLib_ExactTrigger_Init(entity this);
// WARNING: this kills the trace globals
#ifndef WARPZONE_DONT_FIX_VANGLE
if(IS_REAL_CLIENT(this))
if(this.v_angle.z <= 360) // if not already adjusted
- if(time - this.ping * 0.001 < this.warpzone_teleport_time)
+ if(time - CS(this).ping * 0.001 < this.warpzone_teleport_time)
{
this.v_angle = WarpZone_TransformVAngles(this.warpzone_teleport_zone, this.v_angle);
this.v_angle_z += 720; // mark as adjusted
#pragma once
-float WarpZoneLib_MoveOutOfSolid(entity e);
-float WarpZoneLib_ExactTrigger_Touch(entity this, entity toucher);
+bool WarpZoneLib_MoveOutOfSolid(entity e);
+bool WarpZoneLib_ExactTrigger_Touch(entity this, entity toucher);
#ifdef SVQC
void WarpZoneLib_ExactTrigger_Init(entity this);
#endif
MEAN_ACCUMULATE(CS(this), anticheat_div0_evade, 0.5 - 0.5 * (CS(this).anticheat_div0_evade_forward_initial * v_forward), 1);
}
- MEAN_ACCUMULATE(CS(this), anticheat_div0_strafebot_old, movement_oddity(this.movement, CS(this).anticheat_div0_strafebot_movement_prev), 1);
- CS(this).anticheat_div0_strafebot_movement_prev = this.movement;
+ MEAN_ACCUMULATE(CS(this), anticheat_div0_strafebot_old, movement_oddity(CS(this).movement, CS(this).anticheat_div0_strafebot_movement_prev), 1);
+ CS(this).anticheat_div0_strafebot_movement_prev = CS(this).movement;
// Note: this actually tries to detect snap-aim.
if(CS(this).anticheat_div0_strafebot_forward_prev && time > CS(this).anticheat_fixangle_endtime) {
.float antilag_debug;
-#define ANTILAG_LATENCY(e) min(0.4, e.ping * 0.001)
+#define ANTILAG_LATENCY(e) min(0.4, CS(e).ping * 0.001)
// add one ticrate?
float autocvar_ekg;
#define autocvar_fraglimit cvar("fraglimit")
#define autocvar_fraglimit_override cvar("fraglimit_override")
-bool autocvar_g_allow_oldvortexbeam;
+//bool autocvar_g_allow_oldvortexbeam;
int autocvar_g_antilag;
float autocvar_g_antilag_nudge;
float autocvar_g_balance_armor_blockpercent;
float autocvar_gameversion_max;
string autocvar_hostname;
bool autocvar_lastlevel;
-int autocvar_leadlimit;
+//int autocvar_leadlimit;
int autocvar_leadlimit_and_fraglimit;
int autocvar_leadlimit_override;
int autocvar_loddebug;
return;
}
this.bot_aimtarg = e1;
- this.bot_aimlatency = this.ping; // FIXME? Shouldn't this be in the lag item?
+ this.bot_aimlatency = CS(this).ping; // FIXME? Shouldn't this be in the lag item?
//this.bot_aimorigin = v1;
//this.bot_aimvelocity = v2;
this.bot_aimtargorigin = v3;
if (!IS_PLAYER(this) || (autocvar_g_campaign && !campaign_bots_may_start))
{
- this.movement = '0 0 0';
+ CS(this).movement = '0 0 0';
this.bot_nextthink = time + 0.5;
return;
}
// (simulated network latency + naturally delayed reflexes)
//this.ping = 0.7 - bound(0, 0.05 * skill, 0.5); // moved the reflexes to bot_aimdir (under the name 'think')
// minimum ping 20+10 random
- this.ping = bound(0,0.07 - bound(0, (skill + this.bot_pingskill) * 0.005,0.05)+random()*0.01,0.65); // Now holds real lag to server, and higer skill players take a less laggy server
+ CS(this).ping = bound(0,0.07 - bound(0, (skill + this.bot_pingskill) * 0.005,0.05)+random()*0.01,0.65); // Now holds real lag to server, and higer skill players take a less laggy server
// skill 10 = ping 0.2 (adrenaline)
// skill 0 = ping 0.7 (slightly drunk)
if (time < game_starttime)
{
// block the bot during the countdown to game start
- this.movement = '0 0 0';
+ CS(this).movement = '0 0 0';
this.bot_nextthink = game_starttime;
return;
}
// if dead, just wait until we can respawn
if (IS_DEAD(this))
{
- this.movement = '0 0 0';
+ CS(this).movement = '0 0 0';
if (this.deadflag == DEAD_DEAD)
{
PHYS_INPUT_BUTTON_JUMP(this) = true; // press jump to respawn
// we are currently holding a weapon that's not fully loaded, reload it
if(skill >= 2) // bots can only reload the held weapon on purpose past this skill
if(this.(weaponentity).clip_load < this.(weaponentity).clip_size)
- this.impulse = IMP_weapon_reload.impulse; // not sure if this is done right
+ CS(this).impulse = IMP_weapon_reload.impulse; // not sure if this is done right
// if we're not reloading a weapon, switch to any weapon in our invnetory that's not fully loaded to reload it next
// the code above executes next frame, starting the reloading then
+ 0.05 / max(1, sk + this.havocbot_keyboardskill)
+ random() * 0.025 / max(0.00025, skill + this.havocbot_keyboardskill)
, time);
- keyboard = this.movement / autocvar_sv_maxspeed;
+ keyboard = CS(this).movement / autocvar_sv_maxspeed;
float trigger = autocvar_bot_ai_keyboard_threshold;
float trigger1 = -trigger;
keyboard = this.havocbot_keyboard;
float blend = bound(0, vlen(destorg - this.origin) / autocvar_bot_ai_keyboard_distance, 1); // When getting close move with 360 degree
- //dprint("movement ", vtos(this.movement), " keyboard ", vtos(keyboard), " blend ", ftos(blend), "\n");
- this.movement = this.movement + (keyboard - this.movement) * blend;
+ //dprint("movement ", vtos(CS(this).movement), " keyboard ", vtos(keyboard), " blend ", ftos(blend), "\n");
+ CS(this).movement = CS(this).movement + (keyboard - CS(this).movement) * blend;
}
void havocbot_bunnyhop(entity this, vector dir)
while (deviation.y > 180) deviation.y = deviation.y - 360;
if(fabs(deviation.y)>10)
- this.movement_x = 0;
+ CS(this).movement_x = 0;
if(deviation.y>10)
- this.movement_y = maxspeed * -1;
+ CS(this).movement_y = maxspeed * -1;
else if(deviation.y<10)
- this.movement_y = maxspeed;
+ CS(this).movement_y = maxspeed;
}
}
vector dodge;
//if (this.goalentity)
// te_lightning2(this, this.origin, (this.goalentity.absmin + this.goalentity.absmax) * 0.5);
- this.movement = '0 0 0';
+ CS(this).movement = '0 0 0';
maxspeed = autocvar_sv_maxspeed;
// Jetpack navigation
// Brake
if(fabs(this.velocity.x)>maxspeed*0.3)
{
- this.movement_x = dir * v_forward * -maxspeed;
+ CS(this).movement_x = dir * v_forward * -maxspeed;
return;
}
// Switch to normal mode
PHYS_INPUT_BUTTON_HOOK(this) = true;
if(this.navigation_jetpack_point.z - STAT(PL_MAX, this).z + STAT(PL_MIN, this).z < this.origin.z)
{
- this.movement_x = dir * v_forward * maxspeed;
- this.movement_y = dir * v_right * maxspeed;
+ CS(this).movement_x = dir * v_forward * maxspeed;
+ CS(this).movement_y = dir * v_right * maxspeed;
}
return;
}
tracebox(this.origin, this.mins, this.maxs, this.origin + (dir * maxspeed * 3), MOVE_NOMONSTERS, this);
if(trace_fraction==1)
{
- this.movement_x = dir * v_forward * maxspeed;
- this.movement_y = dir * v_right * maxspeed;
+ CS(this).movement_x = dir * v_forward * maxspeed;
+ CS(this).movement_y = dir * v_right * maxspeed;
if (skill < 10)
havocbot_keyboard_movement(this, this.origin + dir * 100);
}
if(client_hasweapon(this, WEP_DEVASTATOR, weaponentity, true, false))
{
- this.movement_x = maxspeed;
+ CS(this).movement_x = maxspeed;
if(this.rocketjumptime)
{
{
// If there is no goal try to move forward
if(this.goalcurrent==NULL)
- this.movement_x = maxspeed;
+ CS(this).movement_x = maxspeed;
}
}
else
PHYS_INPUT_BUTTON_JUMP(this) = false;
makevectors(this.v_angle.y * '0 1 0');
- this.movement_x = dir * v_forward * maxspeed;
- this.movement_y = dir * v_right * maxspeed;
- this.movement_z = dir * v_up * maxspeed;
+ CS(this).movement_x = dir * v_forward * maxspeed;
+ CS(this).movement_y = dir * v_right * maxspeed;
+ CS(this).movement_z = dir * v_up * maxspeed;
}
// if there is nowhere to go, exit
//dir = this.bot_dodgevector;
//if (this.bot_dodgevector_jumpbutton)
// PHYS_INPUT_BUTTON_JUMP(this) = true;
- this.movement_x = dir * v_forward * maxspeed;
- this.movement_y = dir * v_right * maxspeed;
- this.movement_z = dir * v_up * maxspeed;
+ CS(this).movement_x = dir * v_forward * maxspeed;
+ CS(this).movement_y = dir * v_right * maxspeed;
+ CS(this).movement_z = dir * v_up * maxspeed;
// Emulate keyboard interface
if (skill < 10)
vector enemyvel = this.enemy.velocity;
if (!this.enemy.waterlevel)
enemyvel.z = 0;
- lag_additem(this, time + this.ping, 0, 0, this.enemy, this.origin, myvel, (this.enemy.absmin + this.enemy.absmax) * 0.5, enemyvel);
+ lag_additem(this, time + CS(this).ping, 0, 0, this.enemy, this.origin, myvel, (this.enemy.absmin + this.enemy.absmax) * 0.5, enemyvel);
}
else
- lag_additem(this, time + this.ping, 0, 0, NULL, this.origin, myvel, ( this.goalcurrent.absmin + this.goalcurrent.absmax ) * 0.5, '0 0 0');
+ lag_additem(this, time + CS(this).ping, 0, 0, NULL, this.origin, myvel, ( this.goalcurrent.absmin + this.goalcurrent.absmax ) * 0.5, '0 0 0');
}
bool havocbot_moveto_refresh_route(entity this)
float bot_cmd_impulse(entity this)
{
- this.impulse = bot_cmd.bot_cmd_parm_float;
+ CS(this).impulse = bot_cmd.bot_cmd_parm_float;
return CMD_STATUS_FINISHED;
}
bool bot_presskeys(entity this)
{
- this.movement = '0 0 0';
+ CS(this).movement = '0 0 0';
PHYS_INPUT_BUTTON_JUMP(this) = false;
PHYS_INPUT_BUTTON_CROUCH(this) = false;
PHYS_INPUT_BUTTON_ATCK(this) = false;
return false;
if(this.bot_cmd_keys & BOT_CMD_KEY_FORWARD)
- this.movement_x = autocvar_sv_maxspeed;
+ CS(this).movement_x = autocvar_sv_maxspeed;
else if(this.bot_cmd_keys & BOT_CMD_KEY_BACKWARD)
- this.movement_x = -autocvar_sv_maxspeed;
+ CS(this).movement_x = -autocvar_sv_maxspeed;
if(this.bot_cmd_keys & BOT_CMD_KEY_RIGHT)
- this.movement_y = autocvar_sv_maxspeed;
+ CS(this).movement_y = autocvar_sv_maxspeed;
else if(this.bot_cmd_keys & BOT_CMD_KEY_LEFT)
- this.movement_y = -autocvar_sv_maxspeed;
+ CS(this).movement_y = -autocvar_sv_maxspeed;
if(this.bot_cmd_keys & BOT_CMD_KEY_JUMP)
PHYS_INPUT_BUTTON_JUMP(this) = true;
PHYS_INPUT_BUTTON_ATCK2(this) = false;
PHYS_INPUT_BUTTON_CROUCH(this) = false;
- this.movement = '0 0 0';
+ CS(this).movement = '0 0 0';
this.bot_cmd_keys = BOT_CMD_KEY_NONE;
bot_clear(this);
bot_setcurrentcommand(this);
// Ignore all commands except continue when the bot is paused
- if(!(self.bot_exec_status & BOT_EXEC_STATUS_PAUSED))
+ if(!(this.bot_exec_status & BOT_EXEC_STATUS_PAUSED))
{
// if we have no bot command, better return
// old logic kept pressing previously pressed keys, but that has problems
{
if(PHYS_INPUT_BUTTON_DRAG(this))
{
- if(this.impulse == 10 || this.impulse == 15 || this.impulse == 18)
+ if(CS(this).impulse == 10 || CS(this).impulse == 15 || CS(this).impulse == 18)
{
Drag_MoveForward(this);
- this.impulse = 0;
+ CS(this).impulse = 0;
}
- else if(this.impulse == 12 || this.impulse == 16 || this.impulse == 19)
+ else if(CS(this).impulse == 12 || CS(this).impulse == 16 || CS(this).impulse == 19)
{
Drag_MoveBackward(this);
- this.impulse = 0;
+ CS(this).impulse = 0;
}
- else if(this.impulse >= 1 && this.impulse <= 9)
+ else if(CS(this).impulse >= 1 && CS(this).impulse <= 9)
{
- Drag_SetSpeed(this, this.impulse - 1);
+ Drag_SetSpeed(this, CS(this).impulse - 1);
}
- else if(this.impulse == 14)
+ else if(CS(this).impulse == 14)
{
Drag_SetSpeed(this, 9);
}
if (IS_SPEC(e)) e = e.enemy;
sf = 0;
- if (e.race_completed) sf |= 1; // forced scoreboard
- if (to.spectatee_status) sf |= 2; // spectator ent number follows
- if (e.zoomstate) sf |= 4; // zoomed
+ if (CS(e).race_completed) sf |= 1; // forced scoreboard
+ if (CS(to).spectatee_status) sf |= 2; // spectator ent number follows
+ if (CS(e).zoomstate) sf |= 4; // zoomed
if (autocvar_sv_showspectators) sf |= 16; // show spectators
WriteHeader(MSG_ENTITY, ENT_CLIENT_CLIENTDATA);
if (sf & 2)
{
- WriteByte(MSG_ENTITY, to.spectatee_status);
+ WriteByte(MSG_ENTITY, CS(to).spectatee_status);
}
if(sf & 16)
void ClientData_Attach(entity this)
{
- Net_LinkEntity(this.clientdata = new_pure(clientdata), false, 0, ClientData_Send);
- this.clientdata.drawonlytoclient = this;
- this.clientdata.owner = this;
+ Net_LinkEntity(CS(this).clientdata = new_pure(clientdata), false, 0, ClientData_Send);
+ CS(this).clientdata.drawonlytoclient = this;
+ CS(this).clientdata.owner = this;
}
void ClientData_Detach(entity this)
{
- delete(this.clientdata);
- this.clientdata = NULL;
+ delete(CS(this).clientdata);
+ CS(this).clientdata = NULL;
}
void ClientData_Touch(entity e)
{
- e.clientdata.SendFlags = 1;
+ CS(e).clientdata.SendFlags = 1;
// make it spectatable
- FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != e && IS_SPEC(it) && it.enemy == e, LAMBDA(it.clientdata.SendFlags = 1));
+ FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != e && IS_SPEC(it) && it.enemy == e, LAMBDA(CS(it).clientdata.SendFlags = 1));
}
-.string netname_previous;
-
void SetSpectatee(entity this, entity spectatee);
void SetSpectatee_status(entity this, int spectatee_num);
{
entity spot = SelectSpawnPoint(this, true);
if (!spot) LOG_FATAL("No spawnpoints for observers?!?");
- this.angles = spot.angles;
- this.angles_z = 0;
+ this.angles = vec2(spot.angles);
this.fixangle = true;
// offset it so that the spectator spawns higher off the ground, looks better this way
setorigin(this, spot.origin + STAT(PL_VIEW_OFS, this));
- this.prevorigin = this.origin;
if (IS_REAL_CLIENT(this))
{
msg_entity = this;
PlayerScore_Clear(this); // clear scores when needed
}
- if (this.killcount != FRAGS_SPECTATOR)
+ if (CS(this).killcount != FRAGS_SPECTATOR)
{
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_SPECTATE, this.netname);
if(!game_stopped)
if(autocvar_g_chat_nospectators == 1 || (!warmup_stage && autocvar_g_chat_nospectators == 2))
Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_CHAT_NOSPECTATORS);
- if(this.just_joined == false) {
+ if(!CS(this).just_joined)
LogTeamchange(this.playerid, -1, 4);
- } else
- this.just_joined = false;
+ else
+ CS(this).just_joined = false;
}
accuracy_resend(this);
- this.spectatortime = time;
+ CS(this).spectatortime = time;
if(this.bot_attack)
IL_REMOVE(g_bot_targets, this);
this.bot_attack = false;
this.items = 0;
this.weapons = '0 0 0';
- this.dual_weapons = '0 0 0';
this.drawonlytoclient = this;
this.weaponmodel = "";
this.weaponentities[slot] = NULL;
}
this.exteriorweaponentity = NULL;
- this.killcount = FRAGS_SPECTATOR;
+ CS(this).killcount = FRAGS_SPECTATOR;
this.velocity = '0 0 0';
this.avelocity = '0 0 0';
this.punchangle = '0 0 0';
int n = tokenize_console(defaultmodel);
if(n > 0)
{
- defaultmodel = argv(floor(n * player.model_randomizer));
+ defaultmodel = argv(floor(n * CS(player).model_randomizer));
// However, do NOT randomize if the player-selected model is in the list.
for (int i = 0; i < n; ++i)
if ((argv(i) == player.playermodel && defaultskin == stof(player.playerskin)) || argv(i) == strcat(player.playermodel, ":", player.playerskin))
setcolor(player, stof(autocvar_sv_defaultplayercolors));
}
-
-/** Called when a client spawns in the server */
-void PutClientInServer(entity this)
+void PutPlayerInServer(entity this)
{
- if (IS_BOT_CLIENT(this)) {
- TRANSMUTE(Player, this);
- } else if (IS_REAL_CLIENT(this)) {
- msg_entity = this;
- WriteByte(MSG_ONE, SVC_SETVIEW);
- WriteEntity(MSG_ONE, this);
+ if (this.vehicle) vehicles_exit(this.vehicle, VHEF_RELEASE);
+
+ PlayerState_attach(this);
+ accuracy_resend(this);
+
+ if (this.team < 0)
+ JoinBestTeam(this, false, true);
+
+ entity spot = SelectSpawnPoint(this, false);
+ if (!spot) {
+ Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_JOIN_NOSPAWNS);
+ return; // spawn failed
}
- if (game_stopped)
- TRANSMUTE(Observer, this);
- SetSpectatee(this, NULL);
+ TRANSMUTE(Player, this);
- // reset player keys
- this.itemkeys = 0;
+ CS(this).wasplayer = true;
+ this.iscreature = true;
+ this.teleportable = TELEPORT_NORMAL;
+ if(!this.damagedbycontents)
+ IL_PUSH(g_damagedbycontents, this);
+ this.damagedbycontents = true;
+ set_movetype(this, MOVETYPE_WALK);
+ this.solid = SOLID_SLIDEBOX;
+ this.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID;
+ if (autocvar_g_playerclip_collisions)
+ this.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP;
+ if (IS_BOT_CLIENT(this) && autocvar_g_botclip_collisions)
+ this.dphitcontentsmask |= DPCONTENTS_BOTCLIP;
+ this.frags = FRAGS_PLAYER;
+ if (INDEPENDENT_PLAYERS) MAKE_INDEPENDENT_PLAYER(this);
+ this.flags = FL_CLIENT | FL_PICKUPITEMS;
+ if (autocvar__notarget)
+ this.flags |= FL_NOTARGET;
+ this.takedamage = DAMAGE_AIM;
+ this.effects = EF_TELEPORT_BIT | EF_RESTARTANIM_BIT;
+ this.dmg = 2; // WTF
+
+ if (warmup_stage) {
+ this.ammo_shells = warmup_start_ammo_shells;
+ this.ammo_nails = warmup_start_ammo_nails;
+ this.ammo_rockets = warmup_start_ammo_rockets;
+ this.ammo_cells = warmup_start_ammo_cells;
+ this.ammo_plasma = warmup_start_ammo_plasma;
+ this.ammo_fuel = warmup_start_ammo_fuel;
+ this.health = warmup_start_health;
+ this.armorvalue = warmup_start_armorvalue;
+ this.weapons = WARMUP_START_WEAPONS;
+ } else {
+ this.ammo_shells = start_ammo_shells;
+ this.ammo_nails = start_ammo_nails;
+ this.ammo_rockets = start_ammo_rockets;
+ this.ammo_cells = start_ammo_cells;
+ this.ammo_plasma = start_ammo_plasma;
+ this.ammo_fuel = start_ammo_fuel;
+ this.health = start_health;
+ this.armorvalue = start_armorvalue;
+ this.weapons = start_weapons;
+ }
+ SetSpectatee_status(this, 0);
+
+ PS(this).dual_weapons = '0 0 0';
+
+ this.superweapons_finished = (this.weapons & WEPSET_SUPERWEAPONS) ? time + autocvar_g_balance_superweapons_time : 0;
+
+ this.items = start_items;
+
+ this.spawnshieldtime = time + autocvar_g_spawnshieldtime;
+ this.pauserotarmor_finished = time + autocvar_g_balance_pause_armor_rot_spawn;
+ this.pauserothealth_finished = time + autocvar_g_balance_pause_health_rot_spawn;
+ this.pauserotfuel_finished = time + autocvar_g_balance_pause_fuel_rot_spawn;
+ this.pauseregen_finished = time + autocvar_g_balance_pause_health_regen_spawn;
+ // extend the pause of rotting if client was reset at the beginning of the countdown
+ if (!autocvar_sv_ready_restart_after_countdown && time < game_starttime) { // TODO why is this cvar NOTted?
+ float f = game_starttime - time;
+ this.spawnshieldtime += f;
+ this.pauserotarmor_finished += f;
+ this.pauserothealth_finished += f;
+ this.pauseregen_finished += f;
+ }
+ this.damageforcescale = 2;
+ this.death_time = 0;
+ this.respawn_flags = 0;
+ this.respawn_time = 0;
+ this.stat_respawn_time = 0;
+ this.scale = autocvar_sv_player_scale;
+ this.fade_time = 0;
+ this.pain_frame = 0;
+ this.pain_finished = 0;
+ this.pushltime = 0;
+ setthink(this, func_null); // players have no think function
+ this.nextthink = 0;
+ this.dmg_team = 0;
+ PS(this).ballistics_density = autocvar_g_ballistics_density_player;
- MUTATOR_CALLHOOK(PutClientInServer, this);
+ this.deadflag = DEAD_NO;
- if (IS_OBSERVER(this)) {
- PutObserverInServer(this);
- } else if (IS_PLAYER(this)) {
- if (this.vehicle) vehicles_exit(this.vehicle, VHEF_RELEASE);
+ this.angles = spot.angles;
+ this.angles_z = 0; // never spawn tilted even if the spot says to
+ if (IS_BOT_CLIENT(this))
+ this.v_angle = this.angles;
+ this.fixangle = true; // turn this way immediately
+ this.oldvelocity = this.velocity = '0 0 0';
+ this.avelocity = '0 0 0';
+ this.punchangle = '0 0 0';
+ this.punchvector = '0 0 0';
- PlayerState_attach(this);
- accuracy_resend(this);
+ this.strength_finished = 0;
+ this.invincible_finished = 0;
+ this.fire_endtime = -1;
+ this.revive_progress = 0;
+ this.revival_time = 0;
+ this.air_finished = time + 12;
- if (this.team < 0)
- JoinBestTeam(this, false, true);
+ entity spawnevent = new_pure(spawnevent);
+ spawnevent.owner = this;
+ Net_LinkEntity(spawnevent, false, 0.5, SpawnEvent_Send);
- entity spot = SelectSpawnPoint(this, false);
- if (!spot) {
- Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_JOIN_NOSPAWNS);
- return; // spawn failed
- }
+ // Cut off any still running player sounds.
+ stopsound(this, CH_PLAYER_SINGLE);
- TRANSMUTE(Player, this);
+ this.model = "";
+ FixPlayermodel(this);
+ this.drawonlytoclient = NULL;
- this.wasplayer = true;
- this.iscreature = true;
- this.teleportable = TELEPORT_NORMAL;
- if(!this.damagedbycontents)
- IL_PUSH(g_damagedbycontents, this);
- this.damagedbycontents = true;
- set_movetype(this, MOVETYPE_WALK);
- this.solid = SOLID_SLIDEBOX;
- this.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID;
- if (autocvar_g_playerclip_collisions)
- this.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP;
- if (IS_BOT_CLIENT(this) && autocvar_g_botclip_collisions)
- this.dphitcontentsmask |= DPCONTENTS_BOTCLIP;
- this.frags = FRAGS_PLAYER;
- if (INDEPENDENT_PLAYERS) MAKE_INDEPENDENT_PLAYER(this);
- this.flags = FL_CLIENT | FL_PICKUPITEMS;
- if (autocvar__notarget)
- this.flags |= FL_NOTARGET;
- this.takedamage = DAMAGE_AIM;
- this.effects = EF_TELEPORT_BIT | EF_RESTARTANIM_BIT;
- this.dmg = 2; // WTF
-
- if (warmup_stage) {
- this.ammo_shells = warmup_start_ammo_shells;
- this.ammo_nails = warmup_start_ammo_nails;
- this.ammo_rockets = warmup_start_ammo_rockets;
- this.ammo_cells = warmup_start_ammo_cells;
- this.ammo_plasma = warmup_start_ammo_plasma;
- this.ammo_fuel = warmup_start_ammo_fuel;
- this.health = warmup_start_health;
- this.armorvalue = warmup_start_armorvalue;
- this.weapons = WARMUP_START_WEAPONS;
- } else {
- this.ammo_shells = start_ammo_shells;
- this.ammo_nails = start_ammo_nails;
- this.ammo_rockets = start_ammo_rockets;
- this.ammo_cells = start_ammo_cells;
- this.ammo_plasma = start_ammo_plasma;
- this.ammo_fuel = start_ammo_fuel;
- this.health = start_health;
- this.armorvalue = start_armorvalue;
- this.weapons = start_weapons;
- }
- SetSpectatee_status(this, 0);
-
- this.dual_weapons = '0 0 0';
-
- this.superweapons_finished = (this.weapons & WEPSET_SUPERWEAPONS) ? time + autocvar_g_balance_superweapons_time : 0;
-
- this.items = start_items;
-
- this.spawnshieldtime = time + autocvar_g_spawnshieldtime;
- this.pauserotarmor_finished = time + autocvar_g_balance_pause_armor_rot_spawn;
- this.pauserothealth_finished = time + autocvar_g_balance_pause_health_rot_spawn;
- this.pauserotfuel_finished = time + autocvar_g_balance_pause_fuel_rot_spawn;
- this.pauseregen_finished = time + autocvar_g_balance_pause_health_regen_spawn;
- // extend the pause of rotting if client was reset at the beginning of the countdown
- if (!autocvar_sv_ready_restart_after_countdown && time < game_starttime) { // TODO why is this cvar NOTted?
- float f = game_starttime - time;
- this.spawnshieldtime += f;
- this.pauserotarmor_finished += f;
- this.pauserothealth_finished += f;
- this.pauseregen_finished += f;
- }
- this.damageforcescale = 2;
- this.death_time = 0;
- this.respawn_flags = 0;
- this.respawn_time = 0;
- this.stat_respawn_time = 0;
- this.scale = autocvar_sv_player_scale;
- this.fade_time = 0;
- this.pain_frame = 0;
- this.pain_finished = 0;
- this.pushltime = 0;
- setthink(this, func_null); // players have no think function
- this.nextthink = 0;
- this.dmg_team = 0;
- this.ballistics_density = autocvar_g_ballistics_density_player;
-
- this.deadflag = DEAD_NO;
-
- this.angles = spot.angles;
- this.angles_z = 0; // never spawn tilted even if the spot says to
- if (IS_BOT_CLIENT(this))
- this.v_angle = this.angles;
- this.fixangle = true; // turn this way immediately
- this.oldvelocity = this.velocity = '0 0 0';
- this.avelocity = '0 0 0';
- this.punchangle = '0 0 0';
- this.punchvector = '0 0 0';
-
- this.strength_finished = 0;
- this.invincible_finished = 0;
- this.fire_endtime = -1;
- this.revive_progress = 0;
- this.revival_time = 0;
- this.air_finished = time + 12;
-
- entity spawnevent = new_pure(spawnevent);
- spawnevent.owner = this;
- Net_LinkEntity(spawnevent, false, 0.5, SpawnEvent_Send);
-
- // Cut off any still running player sounds.
- stopsound(this, CH_PLAYER_SINGLE);
-
- this.model = "";
- FixPlayermodel(this);
- this.drawonlytoclient = NULL;
-
- this.viewloc = NULL;
-
- this.crouch = false;
- this.view_ofs = STAT(PL_VIEW_OFS, this);
- setsize(this, STAT(PL_MIN, this), STAT(PL_MAX, this));
- this.spawnorigin = spot.origin;
- setorigin(this, spot.origin + '0 0 1' * (1 - this.mins.z - 24));
- // don't reset back to last position, even if new position is stuck in solid
- this.oldorigin = this.origin;
- this.prevorigin = this.origin;
- this.lastteleporttime = time; // prevent insane speeds due to changing origin
- if(this.conveyor)
- IL_REMOVE(g_conveyed, this);
- this.conveyor = NULL; // prevent conveyors at the previous location from moving a freshly spawned player
- this.hud = HUD_NORMAL;
-
- this.event_damage = PlayerDamage;
-
- if(!this.bot_attack)
- IL_PUSH(g_bot_targets, this);
- this.bot_attack = true;
- if(!this.monster_attack)
- IL_PUSH(g_monster_targets, this);
- this.monster_attack = true;
- navigation_dynamicgoal_init(this, false);
-
- PHYS_INPUT_BUTTON_ATCK(this) = PHYS_INPUT_BUTTON_JUMP(this) = PHYS_INPUT_BUTTON_ATCK2(this) = false;
-
- if (this.killcount == FRAGS_SPECTATOR) {
- PlayerScore_Clear(this);
- this.killcount = 0;
- }
+ this.viewloc = NULL;
- for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- {
- .entity weaponentity = weaponentities[slot];
- entity oldwep = this.(weaponentity);
- CL_SpawnWeaponentity(this, weaponentity);
- if(oldwep && oldwep.owner == this)
- this.(weaponentity).m_gunalign = oldwep.m_gunalign;
- }
- this.alpha = default_player_alpha;
- this.colormod = '1 1 1' * autocvar_g_player_brightness;
- this.exteriorweaponentity.alpha = default_weapon_alpha;
+ this.crouch = false;
+ this.view_ofs = STAT(PL_VIEW_OFS, this);
+ setsize(this, STAT(PL_MIN, this), STAT(PL_MAX, this));
+ this.spawnorigin = spot.origin;
+ setorigin(this, spot.origin + '0 0 1' * (1 - this.mins.z - 24));
+ // don't reset back to last position, even if new position is stuck in solid
+ this.oldorigin = this.origin;
+ this.lastteleporttime = time; // prevent insane speeds due to changing origin
+ if(this.conveyor)
+ IL_REMOVE(g_conveyed, this);
+ this.conveyor = NULL; // prevent conveyors at the previous location from moving a freshly spawned player
+ this.hud = HUD_NORMAL;
+
+ this.event_damage = PlayerDamage;
+
+ if(!this.bot_attack)
+ IL_PUSH(g_bot_targets, this);
+ this.bot_attack = true;
+ if(!this.monster_attack)
+ IL_PUSH(g_monster_targets, this);
+ this.monster_attack = true;
+ navigation_dynamicgoal_init(this, false);
+
+ PHYS_INPUT_BUTTON_ATCK(this) = PHYS_INPUT_BUTTON_JUMP(this) = PHYS_INPUT_BUTTON_ATCK2(this) = false;
+
+ if (CS(this).killcount == FRAGS_SPECTATOR) {
+ PlayerScore_Clear(this);
+ CS(this).killcount = 0;
+ }
+
+ for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ entity oldwep = this.(weaponentity);
+ CL_SpawnWeaponentity(this, weaponentity);
+ if(oldwep && oldwep.owner == this)
+ this.(weaponentity).m_gunalign = oldwep.m_gunalign;
+ }
+ this.alpha = default_player_alpha;
+ this.colormod = '1 1 1' * autocvar_g_player_brightness;
+ this.exteriorweaponentity.alpha = default_weapon_alpha;
- this.speedrunning = false;
+ this.speedrunning = false;
- target_voicescript_clear(this);
+ target_voicescript_clear(this);
- // reset fields the weapons may use
- FOREACH(Weapons, true, LAMBDA(
- it.wr_resetplayer(it, this);
+ // reset fields the weapons may use
+ FOREACH(Weapons, true, LAMBDA(
+ it.wr_resetplayer(it, this);
// reload all reloadable weapons
- if (it.spawnflags & WEP_FLAG_RELOADABLE) {
- for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- {
- .entity weaponentity = weaponentities[slot];
- this.(weaponentity).weapon_load[it.m_id] = it.reloading_ammo;
- }
+ if (it.spawnflags & WEP_FLAG_RELOADABLE) {
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ this.(weaponentity).weapon_load[it.m_id] = it.reloading_ammo;
}
- ));
-
- {
- string s = spot.target;
- spot.target = string_null;
- SUB_UseTargets(spot, this, NULL);
- spot.target = s;
}
+ ));
- Unfreeze(this);
+ {
+ string s = spot.target;
+ spot.target = string_null;
+ SUB_UseTargets(spot, this, NULL);
+ spot.target = s;
+ }
- MUTATOR_CALLHOOK(PlayerSpawn, this, spot);
+ Unfreeze(this);
- if (autocvar_spawn_debug)
- {
- sprint(this, strcat("spawnpoint origin: ", vtos(spot.origin), "\n"));
- delete(spot); // usefull for checking if there are spawnpoints, that let drop through the floor
- }
+ MUTATOR_CALLHOOK(PlayerSpawn, this, spot);
- for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- {
- .entity weaponentity = weaponentities[slot];
- if(slot == 0 || autocvar_g_weaponswitch_debug == 1)
- this.(weaponentity).m_switchweapon = w_getbestweapon(this, weaponentity);
- else
- this.(weaponentity).m_switchweapon = WEP_Null;
- this.(weaponentity).m_weapon = WEP_Null;
- this.(weaponentity).weaponname = "";
- this.(weaponentity).m_switchingweapon = WEP_Null;
- this.(weaponentity).cnt = -1;
- }
+ if (autocvar_spawn_debug)
+ {
+ sprint(this, strcat("spawnpoint origin: ", vtos(spot.origin), "\n"));
+ delete(spot); // usefull for checking if there are spawnpoints, that let drop through the floor
+ }
+
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(slot == 0 || autocvar_g_weaponswitch_debug == 1)
+ this.(weaponentity).m_switchweapon = w_getbestweapon(this, weaponentity);
+ else
+ this.(weaponentity).m_switchweapon = WEP_Null;
+ this.(weaponentity).m_weapon = WEP_Null;
+ this.(weaponentity).weaponname = "";
+ this.(weaponentity).m_switchingweapon = WEP_Null;
+ this.(weaponentity).cnt = -1;
+ }
+
+ MUTATOR_CALLHOOK(PlayerWeaponSelect, this);
+
+ if (!warmup_stage && !this.alivetime)
+ this.alivetime = time;
+
+ antilag_clear(this, CS(this));
+}
+
+/** Called when a client spawns in the server */
+void PutClientInServer(entity this)
+{
+ if (IS_BOT_CLIENT(this)) {
+ TRANSMUTE(Player, this);
+ } else if (IS_REAL_CLIENT(this)) {
+ msg_entity = this;
+ WriteByte(MSG_ONE, SVC_SETVIEW);
+ WriteEntity(MSG_ONE, this);
+ }
+ if (game_stopped)
+ TRANSMUTE(Observer, this);
- MUTATOR_CALLHOOK(PlayerWeaponSelect, this);
+ SetSpectatee(this, NULL);
- if (!warmup_stage && !this.alivetime)
- this.alivetime = time;
+ // reset player keys
+ if(PS(this))
+ PS(this).itemkeys = 0;
+
+ MUTATOR_CALLHOOK(PutClientInServer, this);
- antilag_clear(this, CS(this));
+ if (IS_OBSERVER(this)) {
+ PutObserverInServer(this);
+ } else if (IS_PLAYER(this)) {
+ PutPlayerInServer(this);
}
}
else
WriteString(channel, "");
WriteByte(channel, this.count * 255.0); // g_balance_armor_blockpercent
+ WriteByte(channel, this.cnt * 255.0); // g_balance_damagepush_speedfactor
WriteByte(channel, serverflags);
WriteCoord(channel, autocvar_g_trueaim_minrange);
}
this.count = autocvar_g_balance_armor_blockpercent;
this.SendFlags |= 1;
}
+ if(this.cnt != autocvar_g_balance_damagepush_speedfactor)
+ {
+ this.cnt = autocvar_g_balance_damagepush_speedfactor;
+ this.SendFlags |= 1;
+ }
}
void ClientInit_Spawn()
void SetChangeParms (entity this)
{
// save parms for level change
- parm1 = this.parm_idlesince - time;
+ parm1 = CS(this).parm_idlesince - time;
MUTATOR_CALLHOOK(SetChangeParms);
}
void DecodeLevelParms(entity this)
{
// load parms
- this.parm_idlesince = parm1;
- if (this.parm_idlesince == -(86400 * 366))
- this.parm_idlesince = time;
+ CS(this).parm_idlesince = parm1;
+ if (CS(this).parm_idlesince == -(86400 * 366))
+ CS(this).parm_idlesince = time;
// whatever happens, allow 60 seconds of idling directly after connect for map loading
- this.parm_idlesince = max(this.parm_idlesince, time - sv_maxidle + 60);
+ CS(this).parm_idlesince = max(CS(this).parm_idlesince, time - sv_maxidle + 60);
MUTATOR_CALLHOOK(DecodeLevelParms);
}
.float clientkill_nexttime;
void ClientKill_Now_TeamChange(entity this)
{
- if(this.killindicator_teamchange == -1)
+ if(CS(this).killindicator_teamchange == -1)
{
JoinBestTeam( this, false, true );
}
- else if(this.killindicator_teamchange == -2)
+ else if(CS(this).killindicator_teamchange == -2)
{
if(blockSpectators)
Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
PutObserverInServer(this);
}
else
- SV_ChangeTeam(this, this.killindicator_teamchange - 1);
- this.killindicator_teamchange = 0;
+ SV_ChangeTeam(this, CS(this).killindicator_teamchange - 1);
+ CS(this).killindicator_teamchange = 0;
}
void ClientKill_Now(entity this)
if(this.vehicle)
{
vehicles_exit(this.vehicle, VHEF_RELEASE);
- if(!this.killindicator_teamchange)
+ if(!CS(this).killindicator_teamchange)
{
this.vehicle_health = -1;
Damage(this, this, this, 1 , DEATH_KILL.m_id, this.origin, '0 0 0');
this.killindicator = NULL;
- if(this.killindicator_teamchange)
+ if(CS(this).killindicator_teamchange)
ClientKill_Now_TeamChange(this);
if(!IS_SPEC(this) && !IS_OBSERVER(this))
return;
killtime = M_ARGV(1, float);
- this.killindicator_teamchange = targetteam;
+ CS(this).killindicator_teamchange = targetteam;
if(!this.killindicator)
{
MUTATOR_CALLHOOK(FixClientCvars, e);
}
-float PlayerInIDList(entity p, string idlist)
+bool findinlist_abbrev(string tofind, string list)
{
- float n, i;
- string s;
+ if(list == "" || tofind == "")
+ return false; // empty list or search, just return
+ // this function allows abbreviated strings!
+ FOREACH_WORD(list, it == substring(tofind, 0, strlen(it)),
+ {
+ return true;
+ });
+
+ return false;
+}
+
+bool PlayerInIPList(entity p, string iplist)
+{
+ // some safety checks (never allow local?)
+ if(p.netaddress == "local" || p.netaddress == "" || !IS_REAL_CLIENT(p))
+ return false;
+
+ return findinlist_abbrev(p.netaddress, iplist);
+}
+
+bool PlayerInIDList(entity p, string idlist)
+{
// NOTE: we do NOT check crypto_idfp_signed here, an unsigned ID is fine too for this
- if (!p.crypto_idfp)
- return 0;
+ if(!p.crypto_idfp)
+ return false;
- // this function allows abbreviated player IDs too!
- n = tokenize_console(idlist);
- for(i = 0; i < n; ++i)
- {
- s = argv(i);
- if(s == substring(p.crypto_idfp, 0, strlen(s)))
- return 1;
- }
+ return findinlist_abbrev(p.crypto_idfp, idlist);
+}
- return 0;
+bool PlayerInList(entity player, string list)
+{
+ return boolean(PlayerInIDList(player, list) || PlayerInIPList(player, list));
}
#ifdef DP_EXT_PRECONNECT
#ifdef WATERMARK
Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_WATERMARK, WATERMARK);
#endif
- this.version_nagtime = time + 10 + random() * 10;
TRANSMUTE(Client, this);
+ CS(this).version_nagtime = time + 10 + random() * 10;
// identify the right forced team
if (autocvar_g_campaign)
}
}
}
- else if (PlayerInIDList(this, autocvar_g_forced_team_red)) this.team_forced = NUM_TEAM_1;
- else if (PlayerInIDList(this, autocvar_g_forced_team_blue)) this.team_forced = NUM_TEAM_2;
- else if (PlayerInIDList(this, autocvar_g_forced_team_yellow)) this.team_forced = NUM_TEAM_3;
- else if (PlayerInIDList(this, autocvar_g_forced_team_pink)) this.team_forced = NUM_TEAM_4;
+ else if (PlayerInList(this, autocvar_g_forced_team_red)) this.team_forced = NUM_TEAM_1;
+ else if (PlayerInList(this, autocvar_g_forced_team_blue)) this.team_forced = NUM_TEAM_2;
+ else if (PlayerInList(this, autocvar_g_forced_team_yellow)) this.team_forced = NUM_TEAM_3;
+ else if (PlayerInList(this, autocvar_g_forced_team_pink)) this.team_forced = NUM_TEAM_4;
else switch (autocvar_g_forced_team_otherwise)
{
default: this.team_forced = 0; break;
LogTeamchange(this.playerid, this.team, 1);
- this.just_joined = true; // stop spamming the eventlog with additional lines when the client connects
+ CS(this).just_joined = true; // stop spamming the eventlog with additional lines when the client connects
- this.netname_previous = strzone(this.netname);
+ CS(this).netname_previous = strzone(this.netname);
if(teamplay && IS_PLAYER(this))
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(this.team, INFO_JOIN_CONNECT_TEAM), this.netname);
bot_relinkplayerlist();
- this.spectatortime = time;
+ CS(this).spectatortime = time;
if (blockSpectators)
{
Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
}
- this.jointime = time;
- this.allowed_timeouts = autocvar_sv_timeout_number;
+ CS(this).jointime = time;
+ CS(this).allowed_timeouts = autocvar_sv_timeout_number;
if (IS_REAL_CLIENT(this))
{
CSQCMODEL_AUTOINIT(this);
- this.model_randomizer = random();
+ CS(this).model_randomizer = random();
if (IS_REAL_CLIENT(this))
sv_notice_join(this);
// update physics stats (players can spawn before physics runs)
- STAT(MOVEVARS_HIGHSPEED, this) = autocvar_g_movement_highspeed;
- MUTATOR_CALLHOOK(PlayerPhysics_UpdateStats, this); // do it BEFORE the function so we can modify highspeed!
- Physics_UpdateStats(this, PHYS_HIGHSPEED(this));
+ Physics_UpdateStats(this);
IL_EACH(g_initforplayer, it.init_for_player, {
it.init_for_player(it, this);
{
if (!autocvar_g_campaign && !IS_PLAYER(this))
{
- this.motd_actived_time = -1;
+ CS(this).motd_actived_time = -1;
Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MOTD, getwelcomemessage(this));
}
}
PlayerStats_GameReport_FinalizePlayer(this);
if (this.vehicle) vehicles_exit(this.vehicle, VHEF_RELEASE);
- if (this.active_minigame) part_minigame(this);
+ if (CS(this).active_minigame) part_minigame(this);
if (IS_PLAYER(this)) Send_Effect(EFFECT_SPAWN_NEUTRAL, this.origin, '0 0 0', 1);
if (autocvar_sv_eventlog)
MUTATOR_CALLHOOK(ClientDisconnect, this);
+ if (CS(this).netname_previous) strunzone(CS(this).netname_previous); // needs to be before the CS entity is removed!
ClientState_detach(this);
Portal_ClearAll(this);
bot_relinkplayerlist();
- if (this.netname_previous) strunzone(this.netname_previous);
if (this.clientstatus) strunzone(this.clientstatus);
if (this.weaponorder_byimpulse) strunzone(this.weaponorder_byimpulse);
if (this.personal) delete(this.personal);
if ( !IS_DEAD(this.owner) && IS_PLAYER(this.owner) )
{
- if ( this.owner.active_minigame )
+ if ( CS(this.owner).active_minigame )
this.mdl = "models/sprites/minigame_busy.iqm";
else if (PHYS_INPUT_BUTTON_CHAT(this.owner))
this.mdl = "models/misc/chatbubble.spr";
bool zoomstate_set;
void SetZoomState(entity this, float newzoom)
{
- if(newzoom != this.zoomstate)
+ if(newzoom != CS(this).zoomstate)
{
- this.zoomstate = newzoom;
+ CS(this).zoomstate = newzoom;
ClientData_Touch(this);
}
zoomstate_set = true;
{
MUTATOR_CALLHOOK(GetPressedKeys, this);
int keys = STAT(PRESSED_KEYS, this);
- keys = BITSET(keys, KEY_FORWARD, this.movement.x > 0);
- keys = BITSET(keys, KEY_BACKWARD, this.movement.x < 0);
- keys = BITSET(keys, KEY_RIGHT, this.movement.y > 0);
- keys = BITSET(keys, KEY_LEFT, this.movement.y < 0);
+ keys = BITSET(keys, KEY_FORWARD, CS(this).movement.x > 0);
+ keys = BITSET(keys, KEY_BACKWARD, CS(this).movement.x < 0);
+ keys = BITSET(keys, KEY_RIGHT, CS(this).movement.y > 0);
+ keys = BITSET(keys, KEY_LEFT, CS(this).movement.y < 0);
keys = BITSET(keys, KEY_JUMP, PHYS_INPUT_BUTTON_JUMP(this));
keys = BITSET(keys, KEY_CROUCH, PHYS_INPUT_BUTTON_CROUCH(this));
keys = BITSET(keys, KEY_ATCK, PHYS_INPUT_BUTTON_ATCK(this));
keys = BITSET(keys, KEY_ATCK2, PHYS_INPUT_BUTTON_ATCK2(this));
- this.pressedkeys = keys; // store for other users
+ CS(this).pressedkeys = keys; // store for other users
STAT(PRESSED_KEYS, this) = keys;
}
this.clip_size = spectatee.clip_size;
this.effects = spectatee.effects & EFMASK_CHEAP; // eat performance
this.health = spectatee.health;
- this.impulse = 0;
+ CS(this).impulse = 0;
this.items = spectatee.items;
this.last_pickup = spectatee.last_pickup;
this.hit_time = spectatee.hit_time;
this.superweapons_finished = spectatee.superweapons_finished;
STAT(PRESSED_KEYS, this) = STAT(PRESSED_KEYS, spectatee);
this.weapons = spectatee.weapons;
- this.dual_weapons = spectatee.dual_weapons;
this.vortex_charge = spectatee.vortex_charge;
this.vortex_chargepool_ammo = spectatee.vortex_chargepool_ammo;
this.okvortex_charge = spectatee.okvortex_charge;
this.fixangle = true;
setorigin(this, spectatee.origin);
setsize(this, spectatee.mins, spectatee.maxs);
- SetZoomState(this, spectatee.zoomstate);
+ SetZoomState(this, CS(spectatee).zoomstate);
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
void SetSpectatee_status(entity this, int spectatee_num)
{
- int oldspectatee_status = this.spectatee_status;
- this.spectatee_status = spectatee_num;
+ int oldspectatee_status = CS(this).spectatee_status;
+ CS(this).spectatee_status = spectatee_num;
- if (this.spectatee_status != oldspectatee_status)
+ if (CS(this).spectatee_status != oldspectatee_status)
{
ClientData_Touch(this);
if (g_race || g_cts) race_InitSpectator();
.bool team_selected;
bool ShowTeamSelection(entity this)
{
- if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || this.team_selected || (this.wasplayer && autocvar_g_changeteam_banned) || this.team_forced > 0)
+ if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || this.team_selected || (CS(this).wasplayer && autocvar_g_changeteam_banned) || this.team_forced > 0)
return false;
stuffcmd(this, "menu_showteamselect\n");
return true;
if(!this.caplayer)
if(IS_REAL_CLIENT(this))
{
- if( time > (this.spectatortime + autocvar_g_maxplayers_spectator_blocktime) ) {
+ if( time > (CS(this).spectatortime + autocvar_g_maxplayers_spectator_blocktime) ) {
Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_QUIT_KICK_SPECTATING);
dropclient(this);
}
void PrintWelcomeMessage(entity this)
{
- if(this.motd_actived_time == 0)
+ if(CS(this).motd_actived_time == 0)
{
if (autocvar_g_campaign) {
if ((IS_PLAYER(this) && PHYS_INPUT_BUTTON_INFO(this)) || (!IS_PLAYER(this))) {
- this.motd_actived_time = time;
+ CS(this).motd_actived_time = time;
Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MOTD, campaign_message);
}
} else {
if (PHYS_INPUT_BUTTON_INFO(this)) {
- this.motd_actived_time = time;
+ CS(this).motd_actived_time = time;
Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MOTD, getwelcomemessage(this));
}
}
}
- else if(this.motd_actived_time > 0) // showing MOTD or campaign message
+ else if(CS(this).motd_actived_time > 0) // showing MOTD or campaign message
{
if (autocvar_g_campaign) {
if (PHYS_INPUT_BUTTON_INFO(this))
- this.motd_actived_time = time;
- else if ((time - this.motd_actived_time > 2) && IS_PLAYER(this)) { // hide it some seconds after BUTTON_INFO has been released
- this.motd_actived_time = 0;
+ CS(this).motd_actived_time = time;
+ else if ((time - CS(this).motd_actived_time > 2) && IS_PLAYER(this)) { // hide it some seconds after BUTTON_INFO has been released
+ CS(this).motd_actived_time = 0;
Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
}
} else {
if (PHYS_INPUT_BUTTON_INFO(this))
- this.motd_actived_time = time;
- else if (time - this.motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
- this.motd_actived_time = 0;
+ CS(this).motd_actived_time = time;
+ else if (time - CS(this).motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
+ CS(this).motd_actived_time = 0;
Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
}
}
}
- else //if(this.motd_actived_time < 0) // just connected, motd is active
+ else //if(CS(this).motd_actived_time < 0) // just connected, motd is active
{
if(PHYS_INPUT_BUTTON_INFO(this)) // BUTTON_INFO hides initial MOTD
- this.motd_actived_time = -2; // wait until BUTTON_INFO gets released
- else if(this.motd_actived_time == -2 || IS_PLAYER(this) || IS_SPEC(this))
+ CS(this).motd_actived_time = -2; // wait until BUTTON_INFO gets released
+ else if(CS(this).motd_actived_time == -2 || IS_PLAYER(this) || IS_SPEC(this))
{
// instanctly hide MOTD
- this.motd_actived_time = 0;
+ CS(this).motd_actived_time = 0;
Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
}
}
bool joinAllowed(entity this)
{
- if (this.version_mismatch) return false;
+ if (CS(this).version_mismatch) return false;
if (!nJoinAllowed(this, this)) return false;
if (teamplay && lockteams) return false;
if (ShowTeamSelection(this)) return false;
return true;
}
+.int items_added;
+bool PlayerThink(entity this)
+{
+ if (game_stopped || intermission_running) {
+ this.modelflags &= ~MF_ROCKET;
+ if(intermission_running)
+ IntermissionThink(this);
+ return false;
+ }
+
+ if (timeout_status == TIMEOUT_ACTIVE) {
+ // don't allow the player to turn around while game is paused
+ // FIXME turn this into CSQC stuff
+ this.v_angle = this.lastV_angle;
+ this.angles = this.lastV_angle;
+ this.fixangle = true;
+ }
+
+ if (frametime) player_powerups(this);
+
+ if (IS_DEAD(this)) {
+ if (this.personal && g_race_qualifying) {
+ if (time > this.respawn_time) {
+ STAT(RESPAWN_TIME, this) = this.respawn_time = time + 1; // only retry once a second
+ respawn(this);
+ CS(this).impulse = CHIMPULSE_SPEEDRUN.impulse;
+ }
+ } else {
+ if (frametime) player_anim(this);
+
+ if (this.respawn_flags & RESPAWN_DENY)
+ {
+ STAT(RESPAWN_TIME, this) = 0;
+ return false;
+ }
+
+ bool button_pressed = (PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_JUMP(this) || PHYS_INPUT_BUTTON_ATCK2(this) || PHYS_INPUT_BUTTON_HOOK(this) || PHYS_INPUT_BUTTON_USE(this));
+
+ switch(this.deadflag)
+ {
+ case DEAD_DYING:
+ {
+ if ((this.respawn_flags & RESPAWN_FORCE) && !(this.respawn_time < this.respawn_time_max))
+ this.deadflag = DEAD_RESPAWNING;
+ else if (!button_pressed || (time >= this.respawn_time_max && (this.respawn_flags & RESPAWN_FORCE)))
+ this.deadflag = DEAD_DEAD;
+ break;
+ }
+ case DEAD_DEAD:
+ {
+ if (button_pressed)
+ this.deadflag = DEAD_RESPAWNABLE;
+ else if (time >= this.respawn_time_max && (this.respawn_flags & RESPAWN_FORCE))
+ this.deadflag = DEAD_RESPAWNING;
+ break;
+ }
+ case DEAD_RESPAWNABLE:
+ {
+ if (!button_pressed || (this.respawn_flags & RESPAWN_FORCE))
+ this.deadflag = DEAD_RESPAWNING;
+ break;
+ }
+ case DEAD_RESPAWNING:
+ {
+ if (time > this.respawn_time)
+ {
+ this.respawn_time = time + 1; // only retry once a second
+ this.respawn_time_max = this.respawn_time;
+ respawn(this);
+ }
+ break;
+ }
+ }
+
+ ShowRespawnCountdown(this);
+
+ if (this.respawn_flags & RESPAWN_SILENT)
+ STAT(RESPAWN_TIME, this) = 0;
+ else if ((this.respawn_flags & RESPAWN_FORCE) && this.respawn_time < this.respawn_time_max)
+ {
+ if (time < this.respawn_time)
+ STAT(RESPAWN_TIME, this) = this.respawn_time;
+ else if (this.deadflag != DEAD_RESPAWNING)
+ STAT(RESPAWN_TIME, this) = -this.respawn_time_max;
+ }
+ else
+ STAT(RESPAWN_TIME, this) = this.respawn_time;
+ }
+
+ // if respawning, invert stat_respawn_time to indicate this, the client translates it
+ if (this.deadflag == DEAD_RESPAWNING && STAT(RESPAWN_TIME, this) > 0)
+ STAT(RESPAWN_TIME, this) *= -1;
+
+ return false;
+ }
+
+ bool have_hook = false;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(this.(weaponentity).hook.state)
+ {
+ have_hook = true;
+ break;
+ }
+ }
+ bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
+ if (have_hook) {
+ do_crouch = false;
+ } else if (this.waterlevel >= WATERLEVEL_SWIMMING) {
+ do_crouch = false;
+ } else if (this.vehicle) {
+ do_crouch = false;
+ } else if (STAT(FROZEN, this)) {
+ do_crouch = false;
+ }
+
+ if (do_crouch) {
+ if (!this.crouch) {
+ this.crouch = true;
+ this.view_ofs = STAT(PL_CROUCH_VIEW_OFS, this);
+ setsize(this, STAT(PL_CROUCH_MIN, this), STAT(PL_CROUCH_MAX, this));
+ // setanim(this, this.anim_duck, false, true, true); // this anim is BROKEN anyway
+ }
+ } else if (this.crouch) {
+ tracebox(this.origin, STAT(PL_MIN, this), STAT(PL_MAX, this), this.origin, false, this);
+ if (!trace_startsolid) {
+ this.crouch = false;
+ this.view_ofs = STAT(PL_VIEW_OFS, this);
+ setsize(this, STAT(PL_MIN, this), STAT(PL_MAX, this));
+ }
+ }
+
+ FixPlayermodel(this);
+
+ // LordHavoc: allow firing on move frames (sub-ticrate), this gives better timing on slow servers
+ //if(frametime)
+ {
+ this.items &= ~this.items_added;
+
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_WeaponFrame(this, weaponentity);
+
+ if(slot == 0)
+ {
+ this.clip_load = this.(weaponentity).clip_load;
+ this.clip_size = this.(weaponentity).clip_size;
+ }
+ }
+
+ this.items_added = 0;
+ if ((this.items & ITEM_Jetpack.m_itemid) && ((this.items & ITEM_JetpackRegen.m_itemid) || this.ammo_fuel >= 0.01))
+ this.items_added |= IT_FUEL;
+
+ this.items |= this.items_added;
+ }
+
+ player_regen(this);
+
+ // WEAPONTODO: Add a weapon request for this
+ // rot vortex charge to the charge limit
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if (WEP_CVAR(vortex, charge_rot_rate) && this.(weaponentity).vortex_charge > WEP_CVAR(vortex, charge_limit) && this.(weaponentity).vortex_charge_rottime < time)
+ this.(weaponentity).vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.(weaponentity).vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
+ }
+
+ if (frametime) player_anim(this);
+
+ // secret status
+ secrets_setstatus(this);
+
+ // monsters status
+ monsters_setstatus(this);
+
+ this.dmg_team = max(0, this.dmg_team - autocvar_g_teamdamage_resetspeed * frametime);
+
+ return true;
+}
+
void ObserverThink(entity this)
{
- if ( this.impulse )
+ if ( CS(this).impulse )
{
- MinigameImpulse(this, this.impulse);
- this.impulse = 0;
+ MinigameImpulse(this, CS(this).impulse);
+ CS(this).impulse = 0;
}
if (this.flags & FL_JUMPRELEASED) {
if (PHYS_INPUT_BUTTON_JUMP(this) && joinAllowed(this)) {
this.flags &= ~FL_JUMPRELEASED;
this.flags |= FL_SPAWNING;
- } else if(PHYS_INPUT_BUTTON_ATCK(this) && !this.version_mismatch) {
+ } else if(PHYS_INPUT_BUTTON_ATCK(this) && !CS(this).version_mismatch) {
this.flags &= ~FL_JUMPRELEASED;
if(SpectateNext(this)) {
TRANSMUTE(Spectator, this);
void SpectatorThink(entity this)
{
- if ( this.impulse )
+ if ( CS(this).impulse )
{
- if(MinigameImpulse(this, this.impulse))
- this.impulse = 0;
+ if(MinigameImpulse(this, CS(this).impulse))
+ CS(this).impulse = 0;
- if (this.impulse == IMP_weapon_drop.impulse)
+ if (CS(this).impulse == IMP_weapon_drop.impulse)
{
STAT(CAMERA_SPECTATOR, this) = (STAT(CAMERA_SPECTATOR, this) + 1) % 3;
- this.impulse = 0;
+ CS(this).impulse = 0;
return;
}
}
if (PHYS_INPUT_BUTTON_JUMP(this) && joinAllowed(this)) {
this.flags &= ~FL_JUMPRELEASED;
this.flags |= FL_SPAWNING;
- } else if(PHYS_INPUT_BUTTON_ATCK(this) || this.impulse == 10 || this.impulse == 15 || this.impulse == 18 || (this.impulse >= 200 && this.impulse <= 209)) {
+ } else if(PHYS_INPUT_BUTTON_ATCK(this) || CS(this).impulse == 10 || CS(this).impulse == 15 || CS(this).impulse == 18 || (CS(this).impulse >= 200 && CS(this).impulse <= 209)) {
this.flags &= ~FL_JUMPRELEASED;
if(SpectateNext(this)) {
TRANSMUTE(Spectator, this);
TRANSMUTE(Observer, this);
PutClientInServer(this);
}
- this.impulse = 0;
- } else if(this.impulse == 12 || this.impulse == 16 || this.impulse == 19 || (this.impulse >= 220 && this.impulse <= 229)) {
+ CS(this).impulse = 0;
+ } else if(CS(this).impulse == 12 || CS(this).impulse == 16 || CS(this).impulse == 19 || (CS(this).impulse >= 220 && CS(this).impulse <= 229)) {
this.flags &= ~FL_JUMPRELEASED;
if(SpectatePrev(this)) {
TRANSMUTE(Spectator, this);
TRANSMUTE(Observer, this);
PutClientInServer(this);
}
- this.impulse = 0;
+ CS(this).impulse = 0;
} else if (PHYS_INPUT_BUTTON_ATCK2(this)) {
this.flags &= ~FL_JUMPRELEASED;
TRANSMUTE(Observer, this);
Called every frame for each client before the physics are run
=============
*/
-.float usekeypressed;
.float last_vehiclecheck;
-.int items_added;
void PlayerPreThink (entity this)
{
WarpZone_PlayerPhysics_FixVAngle(this);
- STAT(GAMESTARTTIME, this) = game_starttime;
- STAT(ROUNDSTARTTIME, this) = round_starttime;
- STAT(ALLOW_OLDVORTEXBEAM, this) = autocvar_g_allow_oldvortexbeam;
- STAT(LEADLIMIT, this) = autocvar_leadlimit;
-
- STAT(WEAPONSINMAP, this) = weaponsInMap;
-
if (frametime) {
// physics frames: update anticheat stuff
anticheat_prethink(this);
this.netname = strzone(sprintf("Player#%d", this.playerid));
// stuffcmd(this, strcat("name ", this.netname, "\n")); // maybe?
}
- if (this.netname != this.netname_previous) {
+ if (this.netname != CS(this).netname_previous) {
if (autocvar_sv_eventlog) {
GameLogEcho(strcat(":name:", ftos(this.playerid), ":", playername(this, false)));
}
- if (this.netname_previous) strunzone(this.netname_previous);
- this.netname_previous = strzone(this.netname);
+ if (CS(this).netname_previous) strunzone(CS(this).netname_previous);
+ CS(this).netname_previous = strzone(this.netname);
}
// version nagging
- if (this.version_nagtime && this.cvar_g_xonoticversion && time > this.version_nagtime) {
- this.version_nagtime = 0;
+ if (CS(this).version_nagtime && this.cvar_g_xonoticversion && time > CS(this).version_nagtime) {
+ CS(this).version_nagtime = 0;
if (strstrofs(this.cvar_g_xonoticversion, "git", 0) >= 0 || strstrofs(this.cvar_g_xonoticversion, "autobuild", 0) >= 0) {
// git client
} else if (strstrofs(autocvar_g_xonoticversion, "git", 0) >= 0 || strstrofs(autocvar_g_xonoticversion, "autobuild", 0) >= 0) {
this.max_armorvalue = 0;
}
- if (STAT(FROZEN, this) == 2)
- {
- this.revive_progress = bound(0, this.revive_progress + frametime * this.revive_speed, 1);
- this.health = max(1, this.revive_progress * start_health);
- this.iceblock.alpha = bound(0.2, 1 - this.revive_progress, 1);
-
- if (this.revive_progress >= 1)
- Unfreeze(this);
- }
- else if (STAT(FROZEN, this) == 3)
+ if(IS_PLAYER(this))
{
- this.revive_progress = bound(0, this.revive_progress - frametime * this.revive_speed, 1);
- this.health = max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * this.revive_progress );
+ if (STAT(FROZEN, this) == 2)
+ {
+ this.revive_progress = bound(0, this.revive_progress + frametime * this.revive_speed, 1);
+ this.health = max(1, this.revive_progress * start_health);
+ this.iceblock.alpha = bound(0.2, 1 - this.revive_progress, 1);
- if (this.health < 1)
+ if (this.revive_progress >= 1)
+ Unfreeze(this);
+ }
+ else if (STAT(FROZEN, this) == 3)
{
- if (this.vehicle)
- vehicles_exit(this.vehicle, VHEF_RELEASE);
- if(this.event_damage)
- this.event_damage(this, this, this.frozen_by, 1, DEATH_NADE_ICE_FREEZE.m_id, this.origin, '0 0 0');
+ this.revive_progress = bound(0, this.revive_progress - frametime * this.revive_speed, 1);
+ this.health = max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * this.revive_progress );
+
+ if (this.health < 1)
+ {
+ if (this.vehicle)
+ vehicles_exit(this.vehicle, VHEF_RELEASE);
+ if(this.event_damage)
+ this.event_damage(this, this, this.frozen_by, 1, DEATH_NADE_ICE_FREEZE.m_id, this.origin, '0 0 0');
+ }
+ else if (this.revive_progress <= 0)
+ Unfreeze(this);
}
- else if (this.revive_progress <= 0)
- Unfreeze(this);
}
MUTATOR_CALLHOOK(PlayerPreThink, this);
if(!this.cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button
{
- if(PHYS_INPUT_BUTTON_USE(this) && !this.usekeypressed)
+ if(PHYS_INPUT_BUTTON_USE(this) && !CS(this).usekeypressed)
PlayerUseKey(this);
- this.usekeypressed = PHYS_INPUT_BUTTON_USE(this);
+ CS(this).usekeypressed = PHYS_INPUT_BUTTON_USE(this);
}
if (IS_REAL_CLIENT(this))
PrintWelcomeMessage(this);
if (IS_PLAYER(this)) {
- CheckRules_Player(this);
-
- if (game_stopped || intermission_running) {
- this.modelflags &= ~MF_ROCKET;
- if(intermission_running)
- IntermissionThink(this);
- return;
- }
-
- if (timeout_status == TIMEOUT_ACTIVE) {
- // don't allow the player to turn around while game is paused
- // FIXME turn this into CSQC stuff
- this.v_angle = this.lastV_angle;
- this.angles = this.lastV_angle;
- this.fixangle = true;
- }
-
- if (frametime) player_powerups(this);
-
- if (IS_DEAD(this)) {
- if (this.personal && g_race_qualifying) {
- if (time > this.respawn_time) {
- STAT(RESPAWN_TIME, this) = this.respawn_time = time + 1; // only retry once a second
- respawn(this);
- this.impulse = CHIMPULSE_SPEEDRUN.impulse;
- }
- } else {
- if (frametime) player_anim(this);
-
- if (this.respawn_flags & RESPAWN_DENY)
- {
- STAT(RESPAWN_TIME, this) = 0;
- return;
- }
-
- bool button_pressed = (PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_JUMP(this) || PHYS_INPUT_BUTTON_ATCK2(this) || PHYS_INPUT_BUTTON_HOOK(this) || PHYS_INPUT_BUTTON_USE(this));
-
- switch(this.deadflag)
- {
- case DEAD_DYING:
- {
- if ((this.respawn_flags & RESPAWN_FORCE) && !(this.respawn_time < this.respawn_time_max))
- this.deadflag = DEAD_RESPAWNING;
- else if (!button_pressed || (time >= this.respawn_time_max && (this.respawn_flags & RESPAWN_FORCE)))
- this.deadflag = DEAD_DEAD;
- break;
- }
- case DEAD_DEAD:
- {
- if (button_pressed)
- this.deadflag = DEAD_RESPAWNABLE;
- else if (time >= this.respawn_time_max && (this.respawn_flags & RESPAWN_FORCE))
- this.deadflag = DEAD_RESPAWNING;
- break;
- }
- case DEAD_RESPAWNABLE:
- {
- if (!button_pressed || (this.respawn_flags & RESPAWN_FORCE))
- this.deadflag = DEAD_RESPAWNING;
- break;
- }
- case DEAD_RESPAWNING:
- {
- if (time > this.respawn_time)
- {
- this.respawn_time = time + 1; // only retry once a second
- this.respawn_time_max = this.respawn_time;
- respawn(this);
- }
- break;
- }
- }
-
- ShowRespawnCountdown(this);
-
- if (this.respawn_flags & RESPAWN_SILENT)
- STAT(RESPAWN_TIME, this) = 0;
- else if ((this.respawn_flags & RESPAWN_FORCE) && this.respawn_time < this.respawn_time_max)
- {
- if (time < this.respawn_time)
- STAT(RESPAWN_TIME, this) = this.respawn_time;
- else if (this.deadflag != DEAD_RESPAWNING)
- STAT(RESPAWN_TIME, this) = -this.respawn_time_max;
- }
- else
- STAT(RESPAWN_TIME, this) = this.respawn_time;
- }
-
- // if respawning, invert stat_respawn_time to indicate this, the client translates it
- if (this.deadflag == DEAD_RESPAWNING && STAT(RESPAWN_TIME, this) > 0)
- STAT(RESPAWN_TIME, this) *= -1;
-
+ if(!PlayerThink(this))
return;
- }
-
- this.prevorigin = this.origin;
-
- bool have_hook = false;
- for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- {
- .entity weaponentity = weaponentities[slot];
- if(this.(weaponentity).hook.state)
- {
- have_hook = true;
- break;
- }
- }
- bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
- if (have_hook) {
- do_crouch = false;
- } else if (this.waterlevel >= WATERLEVEL_SWIMMING) {
- do_crouch = false;
- } else if (this.vehicle) {
- do_crouch = false;
- } else if (STAT(FROZEN, this)) {
- do_crouch = false;
- }
-
- if (do_crouch) {
- if (!this.crouch) {
- this.crouch = true;
- this.view_ofs = STAT(PL_CROUCH_VIEW_OFS, this);
- setsize(this, STAT(PL_CROUCH_MIN, this), STAT(PL_CROUCH_MAX, this));
- // setanim(this, this.anim_duck, false, true, true); // this anim is BROKEN anyway
- }
- } else if (this.crouch) {
- tracebox(this.origin, STAT(PL_MIN, this), STAT(PL_MAX, this), this.origin, false, this);
- if (!trace_startsolid) {
- this.crouch = false;
- this.view_ofs = STAT(PL_VIEW_OFS, this);
- setsize(this, STAT(PL_MIN, this), STAT(PL_MAX, this));
- }
- }
-
- FixPlayermodel(this);
-
- // LordHavoc: allow firing on move frames (sub-ticrate), this gives better timing on slow servers
- //if(frametime)
- {
- this.items &= ~this.items_added;
-
- for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- {
- .entity weaponentity = weaponentities[slot];
- W_WeaponFrame(this, weaponentity);
-
- if(slot == 0)
- {
- this.clip_load = this.(weaponentity).clip_load;
- this.clip_size = this.(weaponentity).clip_size;
- }
- }
-
- this.items_added = 0;
- if (this.items & ITEM_Jetpack.m_itemid && (this.items & ITEM_JetpackRegen.m_itemid || this.ammo_fuel >= 0.01))
- this.items_added |= IT_FUEL;
-
- this.items |= this.items_added;
- }
-
- player_regen(this);
-
- // WEAPONTODO: Add a weapon request for this
- // rot vortex charge to the charge limit
- for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- {
- .entity weaponentity = weaponentities[slot];
- if (WEP_CVAR(vortex, charge_rot_rate) && this.(weaponentity).vortex_charge > WEP_CVAR(vortex, charge_limit) && this.(weaponentity).vortex_charge_rottime < time)
- {
- this.(weaponentity).vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.(weaponentity).vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
- }
- if (WEP_CVAR(okvortex, charge_rot_rate) && this.(weaponentity).okvortex_charge > WEP_CVAR(okvortex, charge_limit) && this.(weaponentity).okvortex_charge_rottime < time)
- {
- this.(weaponentity).okvortex_charge = bound(WEP_CVAR(okvortex, charge_limit), this.(weaponentity).okvortex_charge - WEP_CVAR(okvortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
- }
- }
-
- if (frametime) player_anim(this);
-
- // secret status
- secrets_setstatus(this);
-
- // monsters status
- monsters_setstatus(this);
-
- this.dmg_team = max(0, this.dmg_team - autocvar_g_teamdamage_resetspeed * frametime);
}
else if (game_stopped || intermission_running) {
if(intermission_running)
SetZoomState(this, PHYS_INPUT_BUTTON_ZOOM(this) || PHYS_INPUT_BUTTON_ZOOMSCRIPT(this) || wep_zoomed);
}
- if (this.teamkill_soundtime && time > this.teamkill_soundtime)
+ if (CS(this).teamkill_soundtime && time > CS(this).teamkill_soundtime)
{
- this.teamkill_soundtime = 0;
+ CS(this).teamkill_soundtime = 0;
- entity e = this.teamkill_soundsource;
+ entity e = CS(this).teamkill_soundsource;
entity oldpusher = e.pusher;
e.pusher = this;
PlayerSound(e, playersound_teamshoot, CH_VOICE, VOL_BASEVOICE, VOICETYPE_LASTATTACKER_ONLY);
e.pusher = oldpusher;
}
- if (this.taunt_soundtime && time > this.taunt_soundtime) {
- this.taunt_soundtime = 0;
+ if (CS(this).taunt_soundtime && time > CS(this).taunt_soundtime) {
+ CS(this).taunt_soundtime = 0;
PlayerSound(this, playersound_taunt, CH_VOICE, VOL_BASEVOICE, VOICETYPE_AUTOTAUNT);
}
if(!this.move_qcphysics)
return;
- if(!frametime && !this.pm_frametime)
+ if(!frametime && !CS(this).pm_frametime)
return;
- Movetype_Physics_NoMatchTicrate(this, this.pm_frametime, true);
+ Movetype_Physics_NoMatchTicrate(this, CS(this).pm_frametime, true);
- this.pm_frametime = 0;
+ CS(this).pm_frametime = 0;
}
/*
Called every frame for each client after the physics are run
=============
*/
-.float idlekick_lasttimeleft;
void PlayerPostThink (entity this)
{
Player_Physics(this);
if (sv_maxidle_slots > 0 && (maxclients - totalClients) > sv_maxidle_slots)
{ /* do nothing */ }
- else if (time - this.parm_idlesince < 1) // instead of (time == this.parm_idlesince) to support sv_maxidle <= 10
+ else if (time - CS(this).parm_idlesince < 1) // instead of (time == this.parm_idlesince) to support sv_maxidle <= 10
{
- if (this.idlekick_lasttimeleft)
+ if (CS(this).idlekick_lasttimeleft)
{
- this.idlekick_lasttimeleft = 0;
+ CS(this).idlekick_lasttimeleft = 0;
Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_IDLING);
}
}
else
{
- float timeleft = ceil(sv_maxidle - (time - this.parm_idlesince));
+ float timeleft = ceil(sv_maxidle - (time - CS(this).parm_idlesince));
if (timeleft == min(10, sv_maxidle - 1)) { // - 1 to support sv_maxidle <= 10
- if (!this.idlekick_lasttimeleft)
+ if (!CS(this).idlekick_lasttimeleft)
Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_DISCONNECT_IDLING, timeleft);
}
if (timeleft <= 0) {
return;
}
else if (timeleft <= 10) {
- if (timeleft != this.idlekick_lasttimeleft) {
+ if (timeleft != CS(this).idlekick_lasttimeleft) {
Send_Notification(NOTIF_ONE, this, MSG_ANNCE, Announcer_PickNumber(CNT_IDLE, timeleft));
}
- this.idlekick_lasttimeleft = timeleft;
+ CS(this).idlekick_lasttimeleft = timeleft;
}
}
}
CheatFrame(this);
- //CheckPlayerJump();
if (game_stopped)
{
this.solid = SOLID_NOT;
if (IS_PLAYER(this)) {
DrownPlayer(this);
- CheckRules_Player(this);
UpdateChatBubble(this);
- if (this.impulse) ImpulseCommands(this);
+ if (CS(this).impulse) ImpulseCommands(this);
if (game_stopped)
{
CSQCMODEL_AUTOUPDATE(this);
CSQCMODEL_AUTOUPDATE(this);
}
+
+// hack to copy the button fields from the client entity to the Client State
+void PM_UpdateButtons(entity this, entity store)
+{
+ if(this.impulse)
+ store.impulse = this.impulse;
+ this.impulse = 0;
+
+ store.button0 = this.button0;
+ store.button2 = this.button2;
+ store.button3 = this.button3;
+ store.button4 = this.button4;
+ store.button5 = this.button5;
+ store.button6 = this.button6;
+ store.button7 = this.button7;
+ store.button8 = this.button8;
+ store.button9 = this.button9;
+ store.button10 = this.button10;
+ store.button11 = this.button11;
+ store.button12 = this.button12;
+ store.button13 = this.button13;
+ store.button14 = this.button14;
+ store.button15 = this.button15;
+ store.button16 = this.button16;
+ store.buttonuse = this.buttonuse;
+ store.buttonchat = this.buttonchat;
+
+ store.cursor_active = this.cursor_active;
+ store.cursor_screen = this.cursor_screen;
+ store.cursor_trace_start = this.cursor_trace_start;
+ store.cursor_trace_endpos = this.cursor_trace_endpos;
+ store.cursor_trace_ent = this.cursor_trace_ent;
+
+ store.ping = this.ping;
+ store.ping_packetloss = this.ping_packetloss;
+ store.ping_movementloss = this.ping_movementloss;
+
+ store.v_angle = this.v_angle;
+ store.movement = this.movement;
+}
/** the string "HMAC-SHA256" if signing, and string_null if plaintext */
ATTRIB(Client, crypto_signmethod, string, this.crypto_signmethod);
+ // engine client fields
+ ATTRIB(Client, impulse, int, this.impulse);
+
+ ATTRIB(Client, button0, int, this.button0);
+ ATTRIB(Client, button2, int, this.button2);
+ ATTRIB(Client, button3, int, this.button3);
+ ATTRIB(Client, button4, int, this.button4);
+ ATTRIB(Client, button5, int, this.button5);
+ ATTRIB(Client, button6, int, this.button6);
+ ATTRIB(Client, button7, int, this.button7);
+ ATTRIB(Client, button8, int, this.button8);
+ ATTRIB(Client, button9, int, this.button9);
+ ATTRIB(Client, button10, int, this.button10);
+ ATTRIB(Client, button11, int, this.button11);
+ ATTRIB(Client, button12, int, this.button12);
+ ATTRIB(Client, button13, int, this.button13);
+ ATTRIB(Client, button14, int, this.button14);
+ ATTRIB(Client, button15, int, this.button15);
+ ATTRIB(Client, button16, int, this.button16);
+ ATTRIB(Client, buttonuse, int, this.buttonuse);
+ ATTRIB(Client, buttonchat, int, this.buttonchat);
+
+ ATTRIB(Client, cursor_active, int, this.cursor_active);
+ ATTRIB(Client, cursor_screen, vector, this.cursor_screen);
+ ATTRIB(Client, cursor_trace_start, vector, this.cursor_trace_start);
+ ATTRIB(Client, cursor_trace_endpos, vector, this.cursor_trace_endpos);
+ ATTRIB(Client, cursor_trace_ent, entity, this.cursor_trace_ent);
+
+ ATTRIB(Client, ping, float, this.ping);
+ ATTRIB(Client, ping_packetloss, float, this.ping_packetloss);
+ ATTRIB(Client, ping_movementloss, float, this.ping_movementloss);
+
+ ATTRIB(Client, v_angle, vector, this.v_angle);
+ ATTRIB(Client, movement, vector, this.movement);
+
// custom
ATTRIB(Client, playerid, int, this.playerid);
+ ATTRIB(Client, parm_idlesince, int, this.parm_idlesince);
+ ATTRIB(Client, muted, bool, this.muted);
+ ATTRIB(Client, killindicator_teamchange, int, this.killindicator_teamchange);
+ ATTRIB(Client, idlekick_lasttimeleft, float, this.idlekick_lasttimeleft);
+ ATTRIB(Client, pm_frametime, float, this.pm_frametime);
+ ATTRIB(Client, pressedkeys, int, this.pressedkeys);
+ ATTRIB(Client, movement_old, vector, this.movement_old);
+ ATTRIB(Client, buttons_old, int, this.buttons_old);
+ ATTRIB(Client, teamkill_complain, float, this.teamkill_complain);
+ ATTRIB(Client, teamkill_soundtime, float, this.teamkill_soundtime);
+ ATTRIB(Client, teamkill_soundsource, entity, this.teamkill_soundsource);
+ ATTRIB(Client, usekeypressed, bool, this.usekeypressed);
+ ATTRIB(Client, motd_actived_time, float, this.motd_actived_time);
+ ATTRIB(Client, jointime, float, this.jointime);
+ ATTRIB(Client, spectatortime, float, this.spectatortime);
+ ATTRIB(Client, version_nagtime, float, this.version_nagtime);
+ ATTRIB(Client, netname_previous, string, this.netname_previous);
+ ATTRIB(Client, allowed_timeouts, int, this.allowed_timeouts);
+ ATTRIB(Client, active_minigame, entity, this.active_minigame);
+ ATTRIB(Client, taunt_soundtime, float, this.taunt_soundtime);
+ ATTRIB(Client, killcount, int, this.killcount);
+ ATTRIB(Client, version_mismatch, bool, this.version_mismatch);
+ ATTRIB(Client, version, int, this.version);
+ ATTRIB(Client, spectatee_status, int, this.spectatee_status);
+ ATTRIB(Client, zoomstate, bool, this.zoomstate);
+ ATTRIB(Client, just_joined, bool, this.just_joined);
+ ATTRIB(Client, race_completed, bool, this.race_completed);
+ ATTRIBARRAY(Client, msg_choice_choices, int, 50); // TODO: actually NOTIF_CHOICE_MAX
+ ATTRIB(Client, latency_sum, float, this.latency_sum);
+ ATTRIB(Client, latency_cnt, int, this.latency_cnt);
+ ATTRIB(Client, latency_time, float, this.latency_time);
+ ATTRIB(Client, v_angle_old, vector, this.v_angle_old);
+ ATTRIB(Client, model_randomizer, float, this.model_randomizer);
+ ATTRIB(Client, accuracy, entity, this.accuracy);
+ ATTRIB(Client, hasweapon_complain_spam, float, this.hasweapon_complain_spam);
+ ATTRIB(Client, scorekeeper, entity, this.scorekeeper);
+ ATTRIB(Client, specialcommand_pos, int, this.specialcommand_pos);
+ ATTRIB(Client, hitplotfh, int, this.hitplotfh);
+ ATTRIB(Client, clientdata, entity, this.clientdata);
+ ATTRIB(Client, wasplayer, bool, this.wasplayer);
+
METHOD(Client, m_unwind, bool(Client this));
STATIC_METHOD(Client, Add, void(Client this, int _team));
ENDCLASS(Spectator)
CLASS(Player, Client)
+
+ // custom
+
+ ATTRIB(Player, dual_weapons, vector, this.dual_weapons); // TODO: actually WepSet!
+ ATTRIB(Player, itemkeys, int, this.itemkeys);
+ ATTRIB(Player, ballistics_density, float, this.ballistics_density);
+ ATTRIB(Player, prevstrengthsound, float, this.prevstrengthsound);
+ ATTRIB(Player, prevstrengthsoundattempt, float, this.prevstrengthsoundattempt);
+ ATTRIB(Player, buff_shield, float, this.buff_shield);
+
INIT(Player) {
this.classname = STR_PLAYER;
IL_PUSH(g_players, this);
#include "banning.qh"
+#include <common/state.qh>
#include <common/command/_mod.qh>
#include "banning.qh"
if (accepted > 0)
{
- client.muted = true;
+ CS(client).muted = true;
return;
}
else
if (accepted > 0)
{
- client.muted = false;
+ CS(client).muted = false;
return;
}
else
{
if (IS_CLIENT(caller))
{
- caller.version = ((argv(1) == "$gameversion") ? 1 : stof(argv(1)));
+ CS(caller).version = ((argv(1) == "$gameversion") ? 1 : stof(argv(1)));
- if (caller.version < autocvar_gameversion_min || caller.version > autocvar_gameversion_max)
+ if (CS(caller).version < autocvar_gameversion_min || CS(caller).version > autocvar_gameversion_max)
{
- caller.version_mismatch = 1;
+ CS(caller).version_mismatch = true;
ClientKill_TeamChange(caller, -2); // observe
}
else if (autocvar_g_campaign || autocvar_g_balance_teams)
{
sprint(caller, "^7You already are on that team.\n");
}
- else if (caller.wasplayer && autocvar_g_changeteam_banned)
+ else if (CS(caller).wasplayer && autocvar_g_changeteam_banned)
{
sprint(caller, "^1You cannot change team, forbidden by the server.\n");
}
{
print_to(caller, "^7Error: You can not call a timeout while the map is being restarted.");
}
- else if (caller && (caller.allowed_timeouts < 1))
+ else if (caller && (CS(caller).allowed_timeouts < 1))
{
print_to(caller, "^7Error: You already used all your timeout calls for this map.");
}
else // everything should be okay, proceed with starting the timeout
{
- if (caller) caller.allowed_timeouts -= 1;
+ if (caller) CS(caller).allowed_timeouts -= 1;
// write a bprint who started the timeout (and how many they have left)
- bprint(GetCallerName(caller), " ^7called a timeout", (caller ? strcat(" (", ftos(caller.allowed_timeouts), " timeout(s) left)") : ""), "!\n");
+ bprint(GetCallerName(caller), " ^7called a timeout", (caller ? strcat(" (", ftos(CS(caller).allowed_timeouts), " timeout(s) left)") : ""), "!\n");
timeout_status = TIMEOUT_LEADTIME;
timeout_caller = caller;
print_to(caller, sprintf(strreplace(" ", separator, " #%-3d %-20.20s %-5d %-3d %-9s %-16s %s "),
etof(it),
it.netname,
- it.ping,
- it.ping_packetloss,
- process_time(1, time - it.jointime),
+ CS(it).ping,
+ CS(it).ping_packetloss,
+ process_time(1, time - CS(it).jointime),
tmp_netaddress,
tmp_crypto_idfp));
FOREACH_CLIENT(IS_REAL_CLIENT(it) && (IS_SPEC(it) || IS_OBSERVER(it)) && !it.caplayer, LAMBDA(
if(!it.caplayer)
{
- it.spectatortime = time;
+ CS(it).spectatortime = time;
Send_Notification(NOTIF_ONE_ONLY, it, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
}
));
*/
// NEW: changed behaviour so that it prevents that previous spectators/observers suddenly spawn as players
// PlayerScore_Clear(it);
- it.killcount = 0;
+ CS(it).killcount = 0;
// stop the player from moving so that he stands still once he gets respawned
it.velocity = '0 0 0';
it.avelocity = '0 0 0';
- it.movement = '0 0 0';
+ CS(it).movement = '0 0 0';
PutClientInServer(it);
});
}
// clear player attributes
FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(
it.alivetime = 0;
- it.killcount = 0;
+ CS(it).killcount = 0;
PS_GR_P_ADDVAL(it, PLAYERSTATS_ALIVETIME, -PS_GR_P_ADDVAL(it, PLAYERSTATS_ALIVETIME, 0));
));
// after a restart every players number of allowed timeouts gets reset, too
if (autocvar_sv_timeout)
{
- FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), LAMBDA(it.allowed_timeouts = autocvar_sv_timeout_number));
+ FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), LAMBDA(CS(it).allowed_timeouts = autocvar_sv_timeout_number));
}
// reset map immediately if this cvar is not set
if (!autocvar_sv_ready_restart_after_countdown) reset_map(true);
.float count;
//.float cnt2;
-.float play_time;
.int respawn_flags;
.float respawn_time;
.float respawn_time_max;
float intermission_exittime;
float alreadychangedlevel;
-.float version;
-
// footstep interval
.float nextstep;
.float cvar_cl_allow_uidtracking;
.string stored_netname;
-.float version_nagtime;
-
string gamemode_name;
float startitem_failed;
void FixClientCvars(entity e);
// WEAPONTODO: remove this
-WepSet weaponsInMap;
+//WepSet weaponsInMap;
#define weapons _STAT(WEAPONS)
// set when showing a kill countdown
.entity killindicator;
-.float killindicator_teamchange;
void Damage (entity targ, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
float lockteams;
-.float parm_idlesince;
float sv_maxidle;
float sv_maxidle_spectatorsareidle;
int sv_maxidle_slots;
.float cvar_cl_voice_directional;
.float cvar_cl_voice_directional_taunt_attenuation;
-.float version_mismatch;
-
int autocvar__independent_players;
bool independent_players;
#define INDEPENDENT_PLAYERS (autocvar__independent_players ? (autocvar__independent_players > 0) : independent_players)
string cvar_purechanges;
float cvar_purechanges_count;
-float game_starttime; //point in time when the countdown to game start is over
-float round_starttime; //point in time when the countdown to round start is over
+//float game_starttime; //point in time when the countdown to game start is over
+//float round_starttime; //point in time when the countdown to round start is over
void W_Porto_Remove (entity p);
//vector debug_shotorg; // if non-zero, overrides the shot origin of all weapons
-.float wasplayer;
+.bool wasplayer;
float servertime, serverprevtime, serverframetime;
.float ammo_fuel;
-.vector prevorigin;
-
//flood fields
.float nickspamtime; // time of last nick change
.float nickspamcount;
{
if(deathtype == DEATH_FIRE.m_id)
{
- Send_Notification(NOTIF_ONE, attacker, MSG_CHOICE, CHOICE_FRAG_FIRE, targ.netname, kill_count_to_attacker, (IS_BOT_CLIENT(targ) ? -1 : targ.ping));
- Send_Notification(NOTIF_ONE, targ, MSG_CHOICE, CHOICE_FRAGGED_FIRE, attacker.netname, kill_count_to_target, attacker.health, attacker.armorvalue, (IS_BOT_CLIENT(attacker) ? -1 : attacker.ping));
+ Send_Notification(NOTIF_ONE, attacker, MSG_CHOICE, CHOICE_FRAG_FIRE, targ.netname, kill_count_to_attacker, (IS_BOT_CLIENT(targ) ? -1 : CS(targ).ping));
+ Send_Notification(NOTIF_ONE, targ, MSG_CHOICE, CHOICE_FRAGGED_FIRE, attacker.netname, kill_count_to_target, attacker.health, attacker.armorvalue, (IS_BOT_CLIENT(attacker) ? -1 : CS(attacker).ping));
return true;
}
{
case DEATH_MIRRORDAMAGE:
{
- Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
+ Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
break;
}
default:
{
- Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
+ Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
break;
}
}
}
}
- else if (!Obituary_WeaponDeath(targ, false, deathtype, targ.netname, deathlocation, "", targ.killcount, 0))
+ else if (!Obituary_WeaponDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0))
{
backtrace("SUICIDE: what the hell happened here?\n");
return;
LogDeath("tk", deathtype, attacker, targ);
GiveFrags(attacker, targ, -1, deathtype);
- attacker.killcount = 0;
+ CS(attacker).killcount = 0;
Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAG, targ.netname);
Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAGGED, attacker.netname);
- Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(targ.team, INFO_DEATH_TEAMKILL), targ.netname, attacker.netname, deathlocation, targ.killcount);
+ Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(targ.team, INFO_DEATH_TEAMKILL), targ.netname, attacker.netname, deathlocation, CS(targ).killcount);
// In this case, the death message will ALWAYS be "foo was betrayed by bar"
// No need for specific death/weapon messages...
LogDeath("frag", deathtype, attacker, targ);
GiveFrags(attacker, targ, 1, deathtype);
- attacker.taunt_soundtime = time + 1;
- attacker.killcount = attacker.killcount + 1;
+ CS(attacker).taunt_soundtime = time + 1;
+ CS(attacker).killcount = CS(attacker).killcount + 1;
attacker.killsound += 1;
PS_GR_P_ADDVAL(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
break; \
}
- switch(attacker.killcount)
+ switch(CS(attacker).killcount)
{
KILL_SPREE_LIST
default: break;
}
else
{
- kill_count_to_attacker = attacker.killcount;
+ kill_count_to_attacker = CS(attacker).killcount;
kill_count_to_target = 0;
}
CHOICE_TYPEFRAG,
targ.netname,
kill_count_to_attacker,
- (IS_BOT_CLIENT(targ) ? -1 : targ.ping)
+ (IS_BOT_CLIENT(targ) ? -1 : CS(targ).ping)
);
Send_Notification(
NOTIF_ONE,
kill_count_to_target,
attacker.health,
attacker.armorvalue,
- (IS_BOT_CLIENT(attacker) ? -1 : attacker.ping)
+ (IS_BOT_CLIENT(attacker) ? -1 : CS(attacker).ping)
);
}
else if(!frag_centermessage_override(attacker, targ, deathtype, kill_count_to_attacker, kill_count_to_target))
CHOICE_FRAG,
targ.netname,
kill_count_to_attacker,
- (IS_BOT_CLIENT(targ) ? -1 : targ.ping)
+ (IS_BOT_CLIENT(targ) ? -1 : CS(targ).ping)
);
Send_Notification(
NOTIF_ONE,
kill_count_to_target,
attacker.health,
attacker.armorvalue,
- (IS_BOT_CLIENT(attacker) ? -1 : attacker.ping)
+ (IS_BOT_CLIENT(attacker) ? -1 : CS(attacker).ping)
);
}
if(deathtype == DEATH_BUFF.m_id)
f3 = buff_FirstFromFlags(attacker.buffs).m_id;
- if (!Obituary_WeaponDeath(targ, true, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker))
- Obituary_SpecialDeath(targ, true, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker, f3);
+ if (!Obituary_WeaponDeath(targ, true, deathtype, targ.netname, attacker.netname, deathlocation, CS(targ).killcount, kill_count_to_attacker))
+ Obituary_SpecialDeath(targ, true, deathtype, targ.netname, attacker.netname, deathlocation, CS(targ).killcount, kill_count_to_attacker, f3);
}
}
targ.netname,
inflictor.message,
deathlocation,
- targ.killcount,
+ CS(targ).killcount,
0,
0);
break;
targ.netname,
((strstrofs(deathmessage, "%", 0) < 0) ? strcat("%s ", deathmessage) : deathmessage),
deathlocation,
- targ.killcount,
+ CS(targ).killcount,
0,
0);
break;
default:
{
- Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
+ Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
break;
}
}
}
// reset target kill count
- if(targ.killcount) { targ.killcount = 0; }
+ CS(targ).killcount = 0;
}
void Ice_Think(entity this)
float mirrordamage = 0;
float mirrorforce = 0;
- if (game_stopped || targ.killcount == FRAGS_SPECTATOR)
+ if (game_stopped || (IS_CLIENT(targ) && CS(targ).killcount == FRAGS_SPECTATOR))
return;
entity attacker_save = attacker;
setorigin(targ, spot.origin + '0 0 1' * (1 - targ.mins.z - 24));
// don't reset back to last position, even if new position is stuck in solid
targ.oldorigin = targ.origin;
- targ.prevorigin = targ.origin;
Send_Effect(EFFECT_TELEPORT, targ.origin, '0 0 0', 1);
}
}
}
}
- else
+ else if(IS_PLAYER(attacker))
{
if(deathtype != DEATH_FIRE.m_id)
{
attacker.typehitsound += 1;
}
if(complainteamdamage > 0)
- if(time > attacker.teamkill_complain)
+ if(time > CS(attacker).teamkill_complain)
{
- attacker.teamkill_complain = time + 5;
- attacker.teamkill_soundtime = time + 0.4;
- attacker.teamkill_soundsource = targ;
+ CS(attacker).teamkill_complain = time + 5;
+ CS(attacker).teamkill_soundtime = time + 0.4;
+ CS(attacker).teamkill_soundsource = targ;
}
}
}
{
WriteHeader(MSG_BROADCAST, TE_CSQC_PINGPLREPORT);
WriteByte(MSG_BROADCAST, this.cnt);
- WriteShort(MSG_BROADCAST, bound(1, e.ping, 65535));
- WriteByte(MSG_BROADCAST, min(ceil(e.ping_packetloss * 255), 255));
- WriteByte(MSG_BROADCAST, min(ceil(e.ping_movementloss * 255), 255));
+ WriteShort(MSG_BROADCAST, bound(1, CS(e).ping, 65535));
+ WriteByte(MSG_BROADCAST, min(ceil(CS(e).ping_packetloss * 255), 255));
+ WriteByte(MSG_BROADCAST, min(ceil(CS(e).ping_movementloss * 255), 255));
// record latency times for clients throughout the match so we can report it to playerstats
- if(time > (e.latency_time + LATENCY_THINKRATE))
+ if(time > (CS(e).latency_time + LATENCY_THINKRATE))
{
- e.latency_sum += e.ping;
- e.latency_cnt += 1;
- e.latency_time = time;
- //print("sum: ", ftos(e.latency_sum), ", cnt: ", ftos(e.latency_cnt), ", avg: ", ftos(e.latency_sum / e.latency_cnt), ".\n");
+ CS(e).latency_sum += CS(e).ping;
+ CS(e).latency_cnt += 1;
+ CS(e).latency_time = time;
+ //print("sum: ", ftos(CS(e).latency_sum), ", cnt: ", ftos(CS(e).latency_cnt), ", avg: ", ftos(CS(e).latency_sum / CS(e).latency_cnt), ".\n");
}
}
else
// these can contain player IDs, so better hide
BADPREFIX("g_forced_team_");
BADCVAR("sv_muteban_list");
+ BADCVAR("sv_allow_customplayermodels_idlist");
+ BADCVAR("sv_allow_customplayermodels_speciallist");
// mapinfo
BADCVAR("fraglimit");
BADCVAR("teamplay_mode");
BADCVAR("timelimit_override");
BADPREFIX("g_warmup_");
+ BADPREFIX("sv_info_");
BADPREFIX("sv_ready_restart_");
// mutators that announce themselves properly to the server browser
FOREACH_CLIENT(IS_REAL_CLIENT(it) || (IS_BOT_CLIENT(it) && autocvar_sv_logscores_bots), LAMBDA(
s = strcat(":player:see-labels:", GetPlayerScoreString(it, 0), ":");
- s = strcat(s, ftos(rint(time - it.jointime)), ":");
+ s = strcat(s, ftos(rint(time - CS(it).jointime)), ":");
if(IS_PLAYER(it) || MUTATOR_CALLHOOK(GetPlayerStatus, it))
s = strcat(s, ftos(it.team), ":");
else
localcmd("\nsv_hook_gameend\n");
}
-/*
-============
-CheckRules_Player
-
-Exit deathmatch games upon conditions
-============
-*/
-void CheckRules_Player(entity this)
-{
- if (game_stopped) // someone else quit the game already
- return;
-
- if(!IS_DEAD(this))
- this.play_time += frametime;
-
- // fixme: don't check players; instead check spawnfunc_dom_team and spawnfunc_ctf_team entities
- // (div0: and that in CheckRules_World please)
-}
-
float InitiateSuddenDeath()
{
float WinningCondition_Scores(float limit, float leadlimit);
void SetWinners(.float field, float value);
-void CheckRules_Player(entity this);
void IntermissionThink(entity this);
void GotoNextMap(float reinit);
void ReadyRestart();
{
if (game_stopped) return;
- int imp = this.impulse;
+ int imp = CS(this).impulse;
if (!imp) return;
- this.impulse = 0;
+ CS(this).impulse = 0;
if (MinigameImpulse(this, imp)) return;
bool item_keys_usekey(entity l, entity p)
{
- float valid = l.itemkeys & p.itemkeys;
+ int valid = l.itemkeys & PS(p).itemkeys;
if (!valid) {
- // other has none of the needed keys
+ // player has none of the needed keys
return false;
} else if (l.itemkeys == valid) {
// ALL needed keys were given
return;
// player already picked up this key
- if (toucher.itemkeys & this.itemkeys)
+ if (PS(toucher).itemkeys & this.itemkeys)
return;
- toucher.itemkeys |= this.itemkeys;
+ PS(toucher).itemkeys |= this.itemkeys;
play2(toucher, this.noise);
centerprint(toucher, this.message);
#include <common/net_linked.qh>
#include "../common/mapinfo.qh"
#include "../common/playerstats.qh"
+#include <common/state.qh>
#include "../common/util.qh"
if(it.health != 2342)
{
it.health = 2342;
- it.impulse = 0;
+ CS(it).impulse = 0;
msg_entity = it;
WriteByte(MSG_ONE, SVC_FINALE);
if ( !(mapvote_maps_flags[it.mapvote-1] & GTV_AVAILABLE) )
it.mapvote = 0;
// use impulses as new vote
- if(it.impulse >= 1 && it.impulse <= mapvote_count)
- if( mapvote_maps_flags[it.impulse - 1] & GTV_AVAILABLE )
+ if(CS(it).impulse >= 1 && CS(it).impulse <= mapvote_count)
+ if( mapvote_maps_flags[CS(it).impulse - 1] & GTV_AVAILABLE )
{
- it.mapvote = it.impulse;
+ it.mapvote = CS(it).impulse;
MapVote_TouchVotes(it);
}
- it.impulse = 0;
+ CS(it).impulse = 0;
if(it.mapvote)
++totalvotes;
void crosshair_trace(entity pl)
{
- traceline_antilag(pl, pl.cursor_trace_start, pl.cursor_trace_start + normalize(pl.cursor_trace_endpos - pl.cursor_trace_start) * max_shot_distance, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
+ traceline_antilag(pl, CS(pl).cursor_trace_start, CS(pl).cursor_trace_start + normalize(CS(pl).cursor_trace_endpos - CS(pl).cursor_trace_start) * max_shot_distance, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
}
.bool ctrace_solidchanged;
void crosshair_trace_plusvisibletriggers(entity pl)
}
void WarpZone_crosshair_trace(entity pl)
{
- WarpZone_traceline_antilag(pl, pl.cursor_trace_start, pl.cursor_trace_start + normalize(pl.cursor_trace_endpos - pl.cursor_trace_start) * max_shot_distance, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
+ WarpZone_traceline_antilag(pl, CS(pl).cursor_trace_start, CS(pl).cursor_trace_start + normalize(CS(pl).cursor_trace_endpos - CS(pl).cursor_trace_start) * max_shot_distance, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
}
}
}
}
-void GetCvars_handleFloat(entity this, string thisname, float f, .float field, string name)
+void GetCvars_handleFloat(entity this, entity store, string thisname, float f, .float field, string name)
{
if (f < 0)
{
else if (f > 0)
{
if (thisname == name)
- this.(field) = stof(argv(f + 1));
+ store.(field) = stof(argv(f + 1));
}
else
stuffcmd(this, strcat("cl_cmd sendcvar ", name, "\n"));
GetCvars_handleString_Fixup(this, s, f, cvar_cl_weaponpriorities[8], "cl_weaponpriority8", W_FixWeaponOrder_AllowIncomplete);
GetCvars_handleString_Fixup(this, s, f, cvar_cl_weaponpriorities[9], "cl_weaponpriority9", W_FixWeaponOrder_AllowIncomplete);
- GetCvars_handleFloat(this, s, f, cvar_cl_allow_uidtracking, "cl_allow_uidtracking");
+ GetCvars_handleFloat(this, this, s, f, cvar_cl_allow_uidtracking, "cl_allow_uidtracking");
// fixup of switchweapon (needed for LMS or when spectating is disabled, as PutClientInServer comes too early)
if (f > 0)
return strcat(t, strdecolorize(p.netname));
}
else
- return ColorTranslateRGB(p.netname);
+ return p.netname;
}
float want_weapon(entity weaponinfo, float allguns) // WEAPONTODO: what still needs done?
void play2team(float t, string filename);
-void GetCvars_handleFloat(entity this, string thisname, float f, .float field, string name);
+void GetCvars_handleFloat(entity this, entity store, string thisname, float f, .float field, string name);
float spamsound(entity e, float chan, Sound samp, float vol, float _atten);
/** attacker */ i(entity, MUTATOR_ARGV_1_entity) \
/** target */ i(entity, MUTATOR_ARGV_2_entity) \
/** deathtype */ i(float, MUTATOR_ARGV_3_float) \
- /** damage */ i(float, MUTATOR_ARGV_4_float) \
+ /** damage */ i(float, MUTATOR_ARGV_4_float) \
/** damage */ o(float, MUTATOR_ARGV_4_float) \
/**/
MUTATOR_HOOKABLE(PlayerDies, EV_PlayerDies);
MUTATOR_HOOKABLE(WantWeapon, EV_WantWeapon);
#define EV_AddPlayerScore(i, o) \
- /** score field */ i(PlayerScoreField, MUTATOR_ARGV_0_entity) \
+ /** score field */ i(entity, MUTATOR_ARGV_0_entity) \
/** score */ i(float, MUTATOR_ARGV_1_float) \
/**/ o(float, MUTATOR_ARGV_1_float) \
/** player */ i(entity, MUTATOR_ARGV_2_entity) \
#include <lib/warpzone/util_server.qh>
#include <lib/warpzone/server.qh>
#include <common/constants.qh>
+#include <common/scores.qh>
#include <common/stats.qh>
#include <common/teams.qh>
#include <common/util.qh>
#include <server/pathlib/pathlib.qh>
#include <common/vehicles/all.qh>
+#include <common/mutators/mutator/waypoints/waypointsprites.qh>
+
#include <server/client.qh>
#include <server/player.qh>
#include <server/impulse.qh>
if (!allowed_to_spawn && IS_PLAYER(player)) // this is true even when player is trying to join
{
TRANSMUTE(Observer, player);
- if (player.jointime != time && !player.caplayer) // not when connecting
+ if (CS(player).jointime != time && !player.caplayer) // not when connecting
{
player.caplayer = 0.5;
Send_Notification(NOTIF_ONE_ONLY, player, MSG_INFO, INFO_CA_JOIN_LATE);
MUTATOR_HOOKFUNCTION(ca, reset_map_players)
{
FOREACH_CLIENT(true, {
- it.killcount = 0;
+ CS(it).killcount = 0;
if (!it.caplayer && IS_BOT_CLIENT(it))
{
it.team = -1;
if (!IS_DEAD(player))
ca_LastPlayerForTeam_Notify(player);
- if (player.killindicator_teamchange == -2) // player wants to spectate
+ if (CS(player).killindicator_teamchange == -2) // player wants to spectate
player.caplayer = 0;
if (player.caplayer)
player.frags = FRAGS_LMS_LOSER;
if(ctf_oneflag)
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_CTF_CAPTURE_NEUTRAL, player.netname);
else if(!ctf_captimerecord)
- Send_Notification(NOTIF_ALL, NULL, MSG_CHOICE, APP_TEAM_NUM(flag.team, CHOICE_CTF_CAPTURE_TIME), player.netname, (cap_time * 100));
+ Send_Notification(NOTIF_ALL, NULL, MSG_CHOICE, APP_TEAM_NUM(flag.team, CHOICE_CTF_CAPTURE_TIME), player.netname, TIME_ENCODE(cap_time));
else if(cap_time < cap_record)
- Send_Notification(NOTIF_ALL, NULL, MSG_CHOICE, APP_TEAM_NUM(flag.team, CHOICE_CTF_CAPTURE_BROKEN), player.netname, refername, (cap_time * 100), (cap_record * 100));
+ Send_Notification(NOTIF_ALL, NULL, MSG_CHOICE, APP_TEAM_NUM(flag.team, CHOICE_CTF_CAPTURE_BROKEN), player.netname, refername, TIME_ENCODE(cap_time), TIME_ENCODE(cap_record));
else
- Send_Notification(NOTIF_ALL, NULL, MSG_CHOICE, APP_TEAM_NUM(flag.team, CHOICE_CTF_CAPTURE_UNBROKEN), player.netname, refername, (cap_time * 100), (cap_record * 100));
+ Send_Notification(NOTIF_ALL, NULL, MSG_CHOICE, APP_TEAM_NUM(flag.team, CHOICE_CTF_CAPTURE_UNBROKEN), player.netname, refername, TIME_ENCODE(cap_time), TIME_ENCODE(cap_record));
// write that shit in the database
if(!ctf_oneflag) // but not in 1-flag mode
ctf_captimerecord = cap_time;
db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time"), ftos(cap_time));
db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"), player.netname);
- write_recordmarker(player, (time - cap_time), cap_time);
+ write_recordmarker(player, flag.ctf_pickuptime, cap_time);
}
if(autocvar_g_ctf_leaderboard && !ctf_oneflag)
case RETURN_DAMAGE:
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_NUM(flag.team, INFO_CTF_FLAGRETURN_DAMAGED)); break;
case RETURN_SPEEDRUN:
- Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_NUM(flag.team, INFO_CTF_FLAGRETURN_SPEEDRUN), ctf_captimerecord); break;
+ Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_NUM(flag.team, INFO_CTF_FLAGRETURN_SPEEDRUN), TIME_ENCODE(ctf_captimerecord)); break;
case RETURN_NEEDKILL:
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_NUM(flag.team, INFO_CTF_FLAGRETURN_NEEDKILL)); break;
default:
this.health = 0;
ctf_CheckFlagReturn(this, RETURN_SPEEDRUN);
- this.owner.impulse = CHIMPULSE_SPEEDRUN.impulse; // move the player back to the waypoint they set
+ CS(this.owner).impulse = CHIMPULSE_SPEEDRUN.impulse; // move the player back to the waypoint they set
ImpulseCommands(this.owner);
}
if(autocvar_g_ctf_stalemate)
// ensure nothing EVIL is being done (i.e. div0_evade)
// this hinders joystick users though
// but it still gives SOME analog control
- wishvel.x = fabs(player.movement.x);
- wishvel.y = fabs(player.movement.y);
+ wishvel.x = fabs(CS(player).movement.x);
+ wishvel.y = fabs(CS(player).movement.y);
if(wishvel.x != 0 && wishvel.y != 0 && wishvel.x != wishvel.y)
{
wishvel.z = 0;
if(wishvel.x >= 2 * wishvel.y)
{
// pure X motion
- if(player.movement.x > 0)
- player.movement_x = wishspeed;
+ if(CS(player).movement.x > 0)
+ CS(player).movement_x = wishspeed;
else
- player.movement_x = -wishspeed;
- player.movement_y = 0;
+ CS(player).movement_x = -wishspeed;
+ CS(player).movement_y = 0;
}
else if(wishvel.y >= 2 * wishvel.x)
{
// pure Y motion
- player.movement_x = 0;
- if(player.movement.y > 0)
- player.movement_y = wishspeed;
+ CS(player).movement_x = 0;
+ if(CS(player).movement.y > 0)
+ CS(player).movement_y = wishspeed;
else
- player.movement_y = -wishspeed;
+ CS(player).movement_y = -wishspeed;
}
else
{
// diagonal
- if(player.movement.x > 0)
- player.movement_x = M_SQRT1_2 * wishspeed;
+ if(CS(player).movement.x > 0)
+ CS(player).movement_x = M_SQRT1_2 * wishspeed;
else
- player.movement_x = -M_SQRT1_2 * wishspeed;
- if(player.movement.y > 0)
- player.movement_y = M_SQRT1_2 * wishspeed;
+ CS(player).movement_x = -M_SQRT1_2 * wishspeed;
+ if(CS(player).movement.y > 0)
+ CS(player).movement_y = M_SQRT1_2 * wishspeed;
else
- player.movement_y = -M_SQRT1_2 * wishspeed;
+ CS(player).movement_y = -M_SQRT1_2 * wishspeed;
}
}
}
if(IS_PLAYER(player))
if(!game_stopped)
{
- if(player.killcount == FRAGS_SPECTATOR /* initial spawn */ || g_race_qualifying) // spawn
+ if(CS(player).killcount == FRAGS_SPECTATOR /* initial spawn */ || g_race_qualifying) // spawn
race_PreparePlayer(player);
else // respawn
race_RetractPlayer(player);
MUTATOR_HOOKFUNCTION(ft, reset_map_players)
{
FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(
- it.killcount = 0;
+ CS(it).killcount = 0;
it.freezetag_frozen_timeout = -1;
PutClientInServer(it);
it.freezetag_frozen_timeout = 0;
if(STAT(FROZEN, frag_target))
return; // target was already frozen, so this is just pushing them off the cliff
- Send_Notification(NOTIF_ONE, frag_attacker, MSG_CHOICE, CHOICE_FRAG_FREEZE, frag_target.netname, kill_count_to_attacker, (IS_BOT_CLIENT(frag_target) ? -1 : frag_target.ping));
- Send_Notification(NOTIF_ONE, frag_target, MSG_CHOICE, CHOICE_FRAGGED_FREEZE, frag_attacker.netname, kill_count_to_target, frag_attacker.health, frag_attacker.armorvalue, (IS_BOT_CLIENT(frag_attacker) ? -1 : frag_attacker.ping));
+ Send_Notification(NOTIF_ONE, frag_attacker, MSG_CHOICE, CHOICE_FRAG_FREEZE, frag_target.netname, kill_count_to_attacker, (IS_BOT_CLIENT(frag_target) ? -1 : CS(frag_target).ping));
+ Send_Notification(NOTIF_ONE, frag_target, MSG_CHOICE, CHOICE_FRAGGED_FREEZE, frag_attacker.netname, kill_count_to_target, frag_attacker.health, frag_attacker.armorvalue, (IS_BOT_CLIENT(frag_attacker) ? -1 : CS(frag_attacker).ping));
return true;
}
lms_lowest_lives = 0; // end the game now!
}
- if(player.killcount != FRAGS_SPECTATOR)
+ if(CS(player).killcount != FRAGS_SPECTATOR)
if(PlayerScore_Add(player, SP_LMS_RANK, 0) > 0 && player.lms_spectate_warning != 2)
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_LMS_NOLIVES, player.netname);
else
c = 0;
FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(
++n;
- if(it.race_completed)
+ if(CS(it).race_completed)
++c;
));
if(n && (n == c))
// ensure nothing EVIL is being done (i.e. div0_evade)
// this hinders joystick users though
// but it still gives SOME analog control
- wishvel.x = fabs(player.movement.x);
- wishvel.y = fabs(player.movement.y);
+ wishvel.x = fabs(CS(player).movement.x);
+ wishvel.y = fabs(CS(player).movement.y);
if(wishvel.x != 0 && wishvel.y != 0 && wishvel.x != wishvel.y)
{
wishvel.z = 0;
if(wishvel.x >= 2 * wishvel.y)
{
// pure X motion
- if(player.movement.x > 0)
- player.movement_x = wishspeed;
+ if(CS(player).movement.x > 0)
+ CS(player).movement_x = wishspeed;
else
- player.movement_x = -wishspeed;
- player.movement_y = 0;
+ CS(player).movement_x = -wishspeed;
+ CS(player).movement_y = 0;
}
else if(wishvel.y >= 2 * wishvel.x)
{
// pure Y motion
- player.movement_x = 0;
- if(player.movement.y > 0)
- player.movement_y = wishspeed;
+ CS(player).movement_x = 0;
+ if(CS(player).movement.y > 0)
+ CS(player).movement_y = wishspeed;
else
- player.movement_y = -wishspeed;
+ CS(player).movement_y = -wishspeed;
}
else
{
// diagonal
- if(player.movement.x > 0)
- player.movement_x = M_SQRT1_2 * wishspeed;
+ if(CS(player).movement.x > 0)
+ CS(player).movement_x = M_SQRT1_2 * wishspeed;
else
- player.movement_x = -M_SQRT1_2 * wishspeed;
- if(player.movement.y > 0)
- player.movement_y = M_SQRT1_2 * wishspeed;
+ CS(player).movement_x = -M_SQRT1_2 * wishspeed;
+ if(CS(player).movement.y > 0)
+ CS(player).movement_y = M_SQRT1_2 * wishspeed;
else
- player.movement_y = -M_SQRT1_2 * wishspeed;
+ CS(player).movement_y = -M_SQRT1_2 * wishspeed;
}
}
}
if(IS_PLAYER(player))
if(!game_stopped)
{
- if(player.killcount == FRAGS_SPECTATOR /* initial spawn */ || g_race_qualifying) // spawn
+ if(CS(player).killcount == FRAGS_SPECTATOR /* initial spawn */ || g_race_qualifying) // spawn
race_PreparePlayer(player);
else // respawn
race_RetractPlayer(player);
clone.move_qcphysics = false; // don't run gamecode logic on clones, too many
set_movetype(clone, this.move_movetype);
clone.solid = this.solid;
- clone.ballistics_density = this.ballistics_density;
clone.takedamage = this.takedamage;
setcefc(clone, getcefc(this));
clone.uncustomizeentityforclient = this.uncustomizeentityforclient;
//clone.weapon = this.weapon;
setorigin(clone, this.origin);
setsize(clone, this.mins, this.maxs);
- clone.prevorigin = this.origin;
clone.reset = SUB_Remove;
clone._ps = this._ps;
{
delete(this.killindicator);
this.killindicator = NULL;
- if(this.killindicator_teamchange)
+ if(CS(this).killindicator_teamchange)
defer_ClientKill_Now_TeamChange = true;
if(this.classname == "body")
// increment frag counter for used weapon type
Weapon w = DEATH_WEAPONOF(deathtype);
if(w != WEP_Null && accuracy_isgooddamage(attacker, this))
- attacker.accuracy.(accuracy_frags[w.m_id-1]) += 1;
+ CS(attacker).accuracy.(accuracy_frags[w.m_id-1]) += 1;
MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, this, deathtype, damage);
- excess = M_ARGV(4, float);
+ damage = M_ARGV(4, float);
+ excess = max(0, damage - take - save);
//Weapon wep = this.(weaponentity).m_weapon;
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
set_movetype(this, MOVETYPE_TOSS);
// shootable corpse
this.solid = SOLID_CORPSE;
- this.ballistics_density = autocvar_g_ballistics_density_corpse;
+ PS(this).ballistics_density = autocvar_g_ballistics_density_corpse;
// don't stick to the floor
UNSET_ONGROUND(this);
// dying animation
this.deadflag = DEAD_DYING;
+ STAT(MOVEVARS_SPECIALCOMMAND, this) = false; // sweet release
+
// when to allow respawn
calculate_player_respawn_time(this);
if (!teamsay && !privatesay && substring(msgin, 0, 1) == " ")
msgin = substring(msgin, 1, -1); // work around DP say bug (say_team does not have this!)
- msgin = formatmessage(source, msgin);
+ if(source)
+ msgin = formatmessage(source, msgin);
string colorstr;
if (!IS_PLAYER(source))
// FLOOD CONTROL
int flood = 0;
var .float flood_field = floodcontrol_chat;
- if(floodcontrol)
+ if(floodcontrol && source)
{
float flood_spl;
float flood_burst;
sourcemsgstr = strcat(privatemsgprefix, substring(sourcemsgstr, privatemsgprefixlen, -1));
int ret;
- if(source.muted)
+ if(source && CS(source).muted)
{
// always fake the message
ret = -1;
centerprint(privatesay, cmsgstr);
}
}
- else if ( teamsay && source.active_minigame )
+ else if ( teamsay && CS(source).active_minigame )
{
sprint(source, sourcemsgstr);
dedicated_print(msgstr); // send to server console too
- FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != source && it.active_minigame == source.active_minigame && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), sprint(it, msgstr));
+ FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != source && CS(it).active_minigame == CS(source).active_minigame && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), sprint(it, msgstr));
}
else if(teamsay > 0) // team message, only sent to team mates
{
void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
-/** to be used by `prvm_edictset server playernumber muted 1` */
-.float muted;
int Say(entity source, float teamsay, entity privatesay, string msgin, float floodcontrol);
#elif defined(SVQC)
#include "defs.qh"
#include "playerdemo.qh"
+ #include <common/state.qh>
#endif
.float playerdemo_fh;
PLAYERDEMO_FIELD(ent,func,float,frame) \
PLAYERDEMO_FIELD(ent,func,float,effects) \
/* PLAYERDEMO_FIELD(ent,func,float,switchweapon) */ \
- PLAYERDEMO_FIELD(ent,func,float,button0) /* TODO: PHYS_INPUT_BUTTON_ATCK */ \
- PLAYERDEMO_FIELD(ent,func,float,button3) /* TODO: PHYS_INPUT_BUTTON_ATCK2 */ \
- PLAYERDEMO_FIELD(ent,func,float,button5) /* TODO: PHYS_INPUT_BUTTON_CROUCH */ \
- PLAYERDEMO_FIELD(ent,func,float,button6) /* TODO: PHYS_INPUT_BUTTON_HOOK */ \
- PLAYERDEMO_FIELD(ent,func,float,buttonuse) /* TODO: PHYS_INPUT_BUTTON_USE */ \
+ PLAYERDEMO_FIELD(CS(ent),func,float,button0) /* TODO: PHYS_INPUT_BUTTON_ATCK */ \
+ PLAYERDEMO_FIELD(CS(ent),func,float,button3) /* TODO: PHYS_INPUT_BUTTON_ATCK2 */ \
+ PLAYERDEMO_FIELD(CS(ent),func,float,button5) /* TODO: PHYS_INPUT_BUTTON_CROUCH */ \
+ PLAYERDEMO_FIELD(CS(ent),func,float,button6) /* TODO: PHYS_INPUT_BUTTON_HOOK */ \
+ PLAYERDEMO_FIELD(CS(ent),func,float,buttonuse) /* TODO: PHYS_INPUT_BUTTON_USE */ \
PLAYERDEMO_FIELD(ent,func,float,flags) \
// end of list
this.playerdemo_time += this.playerdemo_starttime;
}
this.velocity = '0 0 0';
+ CS(this).movement = '0 0 0';
+ this.dmg_take = 0; // so screen doesn't stay blurry
+ this.dmg_save = 0;
+ this.dmg_inflictor = NULL;
time = t;
return 1;
}
#include "../common/notifications/all.qh"
#include "../common/mapinfo.qh"
#include <common/net_linked.qh>
+#include <common/state.qh>
#include "../common/triggers/subs.qh"
#include "../lib/warpzone/util_server.qh"
#include "../lib/warpzone/common.qh"
float race_checkpoint_lastlaps[MAX_CHECKPOINTS];
entity race_checkpoint_lastplayers[MAX_CHECKPOINTS];
+.float race_checkpoint_record[MAX_CHECKPOINTS];
+
float race_highest_checkpoint;
float race_timed_checkpoint;
void race_SendNextCheckpoint(entity e, float spec) // qualifying only
{
- float recordtime;
- string recordholder;
- float cp;
-
if(!e.race_laptime)
return;
- cp = e.race_checkpoint;
- recordtime = race_checkpoint_records[cp];
- recordholder = race_checkpoint_recordholders[cp];
+ int cp = e.race_checkpoint;
+ float recordtime = race_checkpoint_records[cp];
+ float myrecordtime = e.race_checkpoint_record[cp];
+ string recordholder = race_checkpoint_recordholders[cp];
if(recordholder == e.netname)
recordholder = "";
WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_NEXT_QUALIFYING);
WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player will be at next
WriteInt24_t(MSG_ONE, recordtime);
+ if(!spec)
+ WriteInt24_t(MSG_ONE, myrecordtime);
WriteString(MSG_ONE, recordholder);
});
}
if(tvalid)
if(cp == race_timed_checkpoint) // finish line
- if (!e.race_completed)
+ if (!CS(e).race_completed)
{
float s;
if(g_race_qualifying)
if(race_completing)
{
- e.race_completed = 1;
+ CS(e).race_completed = 1;
MAKE_INDEPENDENT_PLAYER(e);
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_FINISHED, e.netname);
ClientData_Touch(e);
}
}
- float recordtime;
- string recordholder;
if(g_race_qualifying)
{
+ float recordtime;
+ string recordholder;
+
if(tvalid)
{
recordtime = race_checkpoint_records[cp];
+ float myrecordtime = e.race_checkpoint_record[cp];
recordholder = strcat1(race_checkpoint_recordholders[cp]); // make a tempstring copy, as we'll possibly strunzone it!
if(recordholder == e.netname)
recordholder = "";
race_setTime(GetMapname(), t, e.crypto_idfp, e.netname, e, true);
MUTATOR_CALLHOOK(Race_FinalCheckpoint, e);
}
+ if(t < myrecordtime || myrecordtime == 0)
+ e.race_checkpoint_record[cp] = t; // resending done below
+
if(t < recordtime || recordtime == 0)
{
race_checkpoint_records[cp] = t;
strunzone(race_checkpoint_recordholders[cp]);
race_checkpoint_recordholders[cp] = strzone(e.netname);
if(g_race_qualifying)
- {
FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it.race_checkpoint == cp, LAMBDA(race_SendNextCheckpoint(it, 0)));
- }
}
+
}
}
else
if(IS_REAL_CLIENT(e))
{
- msg_entity = e;
if(g_race_qualifying)
{
- WRITESPECTATABLE_MSG_ONE(msg_entity, {
- WriteHeader(MSG_ONE, TE_CSQC_RACE);
- WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_QUALIFYING);
- WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
- WriteInt24_t(MSG_ONE, t); // time to that intermediate
- WriteInt24_t(MSG_ONE, recordtime); // previously best time
- WriteString(MSG_ONE, recordholder); // record holder
+ FOREACH_CLIENT(IS_REAL_CLIENT(it),
+ {
+ if(it == e || (IS_SPEC(it) && it.enemy == e))
+ {
+ msg_entity = it;
+ WriteHeader(MSG_ONE, TE_CSQC_RACE);
+ WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_QUALIFYING);
+ WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
+ WriteInt24_t(MSG_ONE, t); // time to that intermediate
+ WriteInt24_t(MSG_ONE, recordtime); // previously best time
+ WriteInt24_t(MSG_ONE, ((tvalid) ? it.race_checkpoint_record[cp] : 0)); // previously best time
+ WriteString(MSG_ONE, recordholder); // record holder
+ }
});
}
}
else // RACE! Not Qualifying
{
float mylaps, lother, othtime;
- entity oth;
- oth = race_checkpoint_lastplayers[cp];
+ entity oth = race_checkpoint_lastplayers[cp];
if(oth)
{
mylaps = PlayerScore_Add(e, SP_RACE_LAPS, 0);
{
WriteInt24_t(MSG_ONE, 0);
WriteByte(MSG_ONE, 0);
- WriteString(MSG_ONE, "");
+ WriteByte(MSG_ONE, 0);
}
else
{
WriteInt24_t(MSG_ONE, TIME_ENCODE(time - race_checkpoint_lasttimes[cp]));
WriteByte(MSG_ONE, mylaps - lother);
- WriteString(MSG_ONE, oth.netname); // record holder
+ WriteByte(MSG_ONE, etof(oth)); // record holder
}
});
}
{
WriteInt24_t(MSG_ONE, 0);
WriteByte(MSG_ONE, 0);
- WriteString(MSG_ONE, "");
+ WriteByte(MSG_ONE, 0);
}
else
{
WriteInt24_t(MSG_ONE, TIME_ENCODE(time - othtime));
WriteByte(MSG_ONE, lother - mylaps);
- WriteString(MSG_ONE, e.netname); // record holder
+ WriteByte(MSG_ONE, etof(e) - 1); // record holder
}
});
}
g_race_qualifying = qual;
- IL_EACH(g_race_targets, true,
+ IL_EACH(g_race_targets, it.classname == "target_checkpoint" || it.classname == "target_startTimer" || it.classname == "target_stopTimer",
{
+ if(it.targetname == "" || !it.targetname) // somehow this is a case...
+ continue;
entity cpt = it;
FOREACH_ENTITY_STRING(target, cpt.targetname,
{
if (race_timed_checkpoint) {
if (defrag_ents) {
- IL_EACH(g_race_targets, true,
+ IL_EACH(g_race_targets, it.classname == "target_checkpoint" || it.classname == "target_startTimer" || it.classname == "target_stopTimer",
{
entity cpt = it;
if(it.classname == "target_startTimer" || it.classname == "target_stopTimer") {
+ if(it.targetname == "" || !it.targetname) // somehow this is a case...
+ continue;
FOREACH_ENTITY_STRING(target, cpt.targetname, {
- WaypointSprite_UpdateSprites(it.sprite, ((cpt.classname == "target_startTimer") ? WP_RaceStart : WP_RaceFinish), WP_Null, WP_Null);
+ if(it.sprite)
+ WaypointSprite_UpdateSprites(it.sprite, ((cpt.classname == "target_startTimer") ? WP_RaceStart : WP_RaceFinish), WP_Null, WP_Null);
});
}
if(it.classname == "target_checkpoint") {
void race_AbandonRaceCheck(entity p)
{
- if(race_completing && !p.race_completed)
+ if(race_completing && !CS(p).race_completed)
{
- p.race_completed = 1;
+ CS(p).race_completed = 1;
MAKE_INDEPENDENT_PLAYER(p);
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_ABANDONED, p.netname);
ClientData_Touch(p);
void race_ClearRecords()
{
- float i;
-
- for(i = 0; i < MAX_CHECKPOINTS; ++i)
+ for(int j = 0; j < MAX_CHECKPOINTS; ++j)
{
- race_checkpoint_records[i] = 0;
- if(race_checkpoint_recordholders[i])
- strunzone(race_checkpoint_recordholders[i]);
- race_checkpoint_recordholders[i] = string_null;
+ race_checkpoint_records[j] = 0;
+ if(race_checkpoint_recordholders[j])
+ strunzone(race_checkpoint_recordholders[j]);
+ race_checkpoint_recordholders[j] = string_null;
}
FOREACH_CLIENT(true, LAMBDA(
float l;
l = PlayerScore_Add(e, SP_RACE_LAPS, 0);
- if(e.race_completed)
+ if(CS(e).race_completed)
return l; // not fractional
vector o0, o1;
#include <common/net_linked.qh>
#include "../common/playerstats.qh"
#include "../common/teams.qh"
+#include <common/scores.qh>
.entity scorekeeper;
entity teamscorekeepers[16];
if(MUTATOR_CALLHOOK(ForbidPlayerScore_Clear)) return 0;
- sk = player.scorekeeper;
+ sk = CS(player).scorekeeper;
FOREACH(Scores, true, {
if(sk.(scores(it)) != 0)
if(scores_label(it) != "")
entity sk;
float t;
FOREACH_CLIENTSLOT(true, {
- sk = it.scorekeeper;
+ sk = CS(it).scorekeeper;
if (!sk) continue;
FOREACH(Scores, true, {
if(sk.(scores(it)) != 0)
void PlayerScore_Attach(entity player)
{
- if(player.scorekeeper)
+ if(CS(player).scorekeeper)
error("player already has a scorekeeper");
entity sk = new_pure(scorekeeper);
sk.owner = player;
Net_LinkEntity(sk, false, 0, PlayerScore_SendEntity);
- player.scorekeeper = sk;
+ CS(player).scorekeeper = sk;
}
void PlayerScore_Detach(entity player)
{
- if(!player.scorekeeper)
+ if(!CS(player).scorekeeper)
error("player has no scorekeeper");
- delete(player.scorekeeper);
- player.scorekeeper = NULL;
+ delete(CS(player).scorekeeper);
+ CS(player).scorekeeper = NULL;
}
float PlayerScore_Add(entity player, PlayerScoreField scorefield, float score)
score = 0;
if(!scores_initialized) return 0; // FIXME remove this when everything uses this system
- entity s = player.scorekeeper;
+ entity s = CS(player).scorekeeper;
if(!s)
{
if(game_stopped)
winnerscorekeeper = NULL;
secondscorekeeper = NULL;
FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(
- sk = it.scorekeeper;
+ sk = CS(it).scorekeeper;
c = PlayerScore_Compare(winnerscorekeeper, sk, 1);
if(c < 0)
{
});
out = substring(out, 0, strlen(out) - 1);
}
- else if((sk = pl.scorekeeper))
+ else if((sk = CS(pl).scorekeeper))
{
FOREACH(Scores, true, {
if ((scores_flags(it) & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_PRIMARY)
return 0;
}
- return PlayerScore_Compare(p1.scorekeeper, p2.scorekeeper, strict);
+ return PlayerScore_Compare(CS(p1).scorekeeper, CS(p2).scorekeeper, strict);
}
entity PlayerScore_Sort(.float field, float teams, float strict, float nospectators)
FOREACH_CLIENT(true, LAMBDA(it.(field) = 0));
- FOREACH_CLIENT(it.scorekeeper,
+ FOREACH_CLIENT(CS(it).scorekeeper,
{
if(nospectators)
if(it.frags == FRAGS_SPECTATOR)
float fl, sc;
s = " ";
- sk = p.scorekeeper;
+ sk = CS(p).scorekeeper;
s = strcat(s, playername(p, false));
for (;;)
void PlayerScore_PlayerStats(entity p)
{
- entity s = p.scorekeeper;
+ entity s = CS(p).scorekeeper;
FOREACH(Scores, true, {
if(s.(scores(it)) != 0)
if(scores_label(it) != "")
#pragma once
-#include <common/constants.qh>
+#include <common/scores.qh>
entity scores_initialized; // non-NULL when scores labels/rules have been set
.float scoreboard_pos;
#pragma once
+// spawnpoint prios
+const int SPAWN_PRIO_NEAR_TEAMMATE_FOUND = 200;
+const int SPAWN_PRIO_NEAR_TEAMMATE_SAMETEAM = 100;
+const int SPAWN_PRIO_RACE_PREVIOUS_SPAWN = 50;
+const int SPAWN_PRIO_GOOD_DISTANCE = 10;
+
.vector spawnpoint_score;
float spawnpoint_nag;
bool SpawnEvent_Send(entity this, entity to, int sf);
string GetClientVersionMessage(entity this)
{
- if (this.version_mismatch) {
- if(this.version < autocvar_gameversion) {
+ 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 {
cb1 = cb1 + bvalue;
}
}
- if(t == NUM_TEAM_2)
+ else if(t == NUM_TEAM_2)
{
if(c2 >= 0)
{
cb2 = cb2 + bvalue;
}
}
- if(t == NUM_TEAM_3)
+ else if(t == NUM_TEAM_3)
{
if(c3 >= 0)
{
cb3 = cb3 + bvalue;
}
}
- if(t == NUM_TEAM_4)
+ else if(t == NUM_TEAM_4)
{
if(c4 >= 0)
{
return;
}
- if((autocvar_g_campaign) || (autocvar_g_changeteam_banned && this.wasplayer)) {
+ if((autocvar_g_campaign) || (autocvar_g_changeteam_banned && CS(this).wasplayer)) {
Send_Notification(NOTIF_ONE, this, MSG_INFO, INFO_TEAMCHANGE_NOTALLOWED);
return; // changing teams is not allowed
}
entity a = this.owner;
if (IS_SPEC(a)) a = a.enemy;
- a = a.accuracy;
+ a = CS(a).accuracy;
if (to != a.owner)
if (!autocvar_sv_accuracy_data_share && !a.owner.cvar_cl_accuracy_data_share)
// init/free
void accuracy_init(entity e)
{
- entity a = e.accuracy = new_pure(accuracy);
+ entity a = CS(e).accuracy = new_pure(accuracy);
a.owner = e;
a.drawonlytoclient = e;
Net_LinkEntity(a, false, 0, accuracy_send);
void accuracy_free(entity e)
{
- delete(e.accuracy);
+ delete(CS(e).accuracy);
}
// force a resend of a player's accuracy stats
void accuracy_resend(entity e)
{
- e.accuracy.SendFlags = 0xFFFFFF;
+ CS(e).accuracy.SendFlags = 0xFFFFFF;
}
// update accuracy stats
void accuracy_add(entity this, int w, int fired, int hit)
{
if (IS_INDEPENDENT_PLAYER(this)) return;
- entity a = this.accuracy;
+ entity a = CS(this).accuracy;
if (!a) return;
if (!hit && !fired) return;
w -= WEP_FIRST;
if (b == accuracy_byte(a.accuracy_hit[w], a.accuracy_fired[w])) return; // no change
int sf = 1 << (w % 24);
a.SendFlags |= sf;
- FOREACH_CLIENT(IS_SPEC(it) && it.enemy == this, LAMBDA(it.accuracy.SendFlags |= sf));
+ FOREACH_CLIENT(IS_SPEC(it) && it.enemy == this, LAMBDA(CS(it).accuracy.SendFlags |= sf));
}
bool accuracy_isgooddamage(entity attacker, entity targ)
#include <common/net_linked.qh>
#include <common/deathtypes/all.qh>
#include <common/notifications/all.qh>
+#include <common/state.qh>
#include <common/util.qh>
#include <common/weapons/_all.qh>
#include <common/items/_mod.qh>
}
}
-void W_PlayStrengthSound(entity player) // void W_PlayStrengthSound
+void W_PlayStrengthSound(entity player)
{
+ entity store = IS_PLAYER(player) ? PS(player) : player; // because non-player entities can fire, but can they have items? TODO
+
if((player.items & ITEM_Strength.m_itemid)
- && ((time > player.prevstrengthsound + autocvar_sv_strengthsound_antispam_time) // prevent insane sound spam
- || (time > player.prevstrengthsoundattempt + autocvar_sv_strengthsound_antispam_refire_threshold)))
+ && ((time > store.prevstrengthsound + autocvar_sv_strengthsound_antispam_time) // prevent insane sound spam
+ || (time > store.prevstrengthsoundattempt + autocvar_sv_strengthsound_antispam_refire_threshold)))
{
sound(player, CH_TRIGGER, SND_STRENGTH_FIRE, VOL_BASE, ATTEN_NORM);
- player.prevstrengthsound = time;
+ store.prevstrengthsound = time;
}
- player.prevstrengthsoundattempt = time;
+ store.prevstrengthsoundattempt = time;
}
float W_CheckProjectileDamage(entity inflictor, entity projowner, int deathtype, float exception)
void W_HitPlotAnalysis(entity player, .entity weaponentity, vector screenforward, vector screenright, vector screenup)
{
- vector hitplot;
- vector org;
- float lag;
-
- if(player.hitplotfh >= 0)
+ if(CS(player).hitplotfh >= 0)
{
- lag = ANTILAG_LATENCY(player);
+ float lag = ANTILAG_LATENCY(player);
if(lag < 0.001)
lag = 0;
if(!IS_REAL_CLIENT(player))
lag = 0; // only antilag for clients
- org = player.origin + player.view_ofs;
+ vector org = player.origin + player.view_ofs;
traceline_antilag_force(player, org, org + screenforward * max_shot_distance, MOVE_NORMAL, player, lag);
if(IS_CLIENT(trace_ent) || IS_MONSTER(trace_ent))
{
entity store = IS_CLIENT(trace_ent) ? CS(trace_ent) : trace_ent;
antilag_takeback(trace_ent, store, time - lag);
- hitplot = W_HitPlotNormalizedUntransform(org, trace_ent, screenforward, screenright, screenup, trace_endpos);
+ vector hitplot = W_HitPlotNormalizedUntransform(org, trace_ent, screenforward, screenright, screenup, trace_endpos);
antilag_restore(trace_ent, store);
- fputs(player.hitplotfh, strcat(ftos(hitplot.x), " ", ftos(hitplot.y), " ", ftos(hitplot.z), " ", ftos(player.(weaponentity).m_switchweapon.m_id), "\n"));
+ fputs(CS(player).hitplotfh, strcat(ftos(hitplot.x), " ", ftos(hitplot.y), " ", ftos(hitplot.z), " ", ftos(player.(weaponentity).m_switchweapon.m_id), "\n"));
//print(strcat(ftos(hitplot_x), " ", ftos(hitplot_y), " ", ftos(hitplot_z), "\n"));
}
}
{
if(autocvar_g_hitplots || strhasword(autocvar_g_hitplots_individuals, player.netaddress))
{
- player.hitplotfh = fopen(strcat("hits-", matchid, "-", player.netaddress, "-", ftos(player.playerid), ".plot"), FILE_WRITE);
- fputs(player.hitplotfh, strcat("#name ", playername(player, false), "\n"));
+ CS(player).hitplotfh = fopen(strcat("hits-", matchid, "-", player.netaddress, "-", ftos(player.playerid), ".plot"), FILE_WRITE);
+ fputs(CS(player).hitplotfh, strcat("#name ", playername(player, false), "\n"));
}
- else { player.hitplotfh = -1; }
+ else { CS(player).hitplotfh = -1; }
}
void W_HitPlotClose(entity player)
{
- if(player.hitplotfh >= 0)
+ if(CS(player).hitplotfh >= 0)
{
- fclose(player.hitplotfh);
- player.hitplotfh = -1;
+ fclose(CS(player).hitplotfh);
+ CS(player).hitplotfh = -1;
}
}
{
float f = 0;
- if (time < this.hasweapon_complain_spam)
+ if (time < CS(this).hasweapon_complain_spam)
complain = 0;
// ignore hook button when using other offhand equipment
complain = 0;
if (complain)
- this.hasweapon_complain_spam = time + 0.2;
+ CS(this).hasweapon_complain_spam = time + 0.2;
if (wpn == WEP_Null)
{
sprint(this, "Invalid weapon\n");
return false;
}
- if (autocvar_g_weaponswitch_debug == 2 && weaponslot(weaponentity) > 0 && !(wpn.spawnflags & WEP_FLAG_DUALWIELD) && !(this.dual_weapons & wpn.m_wepset))
+ if (autocvar_g_weaponswitch_debug == 2 && weaponslot(weaponentity) > 0 && !(wpn.spawnflags & WEP_FLAG_DUALWIELD) && !(PS(this).dual_weapons & wpn.m_wepset))
return false; // no complaints needed
if (this.weapons & WepSet_FromWeapon(wpn))
{
{
TC(Sound, snd);
float nudge = 1; // added to traceline target and subtracted from result TOOD(divVerent): do we still need this? Doesn't the engine do this now for us?
- float oldsolid;
- vector vecs, dv;
- oldsolid = ent.dphitcontentsmask;
+ float oldsolid = ent.dphitcontentsmask;
+ if(!IS_CLIENT(ent))
+ antilag = false; // no antilag for non-clients!
if (IS_PLAYER(ent) && ent.(weaponentity).m_weapon == WEP_RIFLE)
ent.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_CORPSE;
else
W_HitPlotAnalysis(ent, weaponentity, v_forward, v_right, v_up);
vector md = ent.(weaponentity).movedir;
- if(md.x > 0)
- vecs = md;
- else
- vecs = '0 0 0';
+ vector vecs = ((md.x > 0) ? md : '0 0 0');
- dv = v_right * -vecs.y + v_up * vecs.z;
+ vector dv = v_right * -vecs.y + v_up * vecs.z;
w_shotorg = ent.origin + ent.view_ofs + dv;
// now move the shotorg forward as much as requested if possible
else if(autocvar_g_antilag == 3) // client side hitscan
{
// this part MUST use prydon cursor
- if (ent.cursor_trace_ent) // client was aiming at someone
- if (ent.cursor_trace_ent != ent) // just to make sure
- if (ent.cursor_trace_ent.takedamage) // and that person is killable
- if (IS_PLAYER(ent.cursor_trace_ent)) // and actually a player
+ if (CS(ent).cursor_trace_ent) // client was aiming at someone
+ if (CS(ent).cursor_trace_ent != ent) // just to make sure
+ if (CS(ent).cursor_trace_ent.takedamage) // and that person is killable
+ if (IS_PLAYER(CS(ent).cursor_trace_ent)) // and actually a player
{
// verify that the shot would miss without antilag
// (avoids an issue where guns would always shoot at their origin)
if (!trace_ent.takedamage)
{
// verify that the shot would hit if altered
- traceline(w_shotorg, ent.cursor_trace_ent.origin, MOVE_NORMAL, ent);
- if (trace_ent == ent.cursor_trace_ent)
- w_shotdir = normalize(ent.cursor_trace_ent.origin - w_shotorg);
+ traceline(w_shotorg, CS(ent).cursor_trace_ent.origin, MOVE_NORMAL, ent);
+ if (trace_ent == CS(ent).cursor_trace_ent)
+ w_shotdir = normalize(CS(ent).cursor_trace_ent.origin - w_shotorg);
else
LOG_INFO("antilag fail\n");
}
else
fireBullet_trace_callback_eff = EFFECT_BULLET;
- float lag = ANTILAG_LATENCY(this);
+ float lag = ((IS_REAL_CLIENT(this)) ? ANTILAG_LATENCY(this) : 0);
if(lag < 0.001)
lag = 0;
- if (!IS_REAL_CLIENT(this))
- lag = 0;
if(autocvar_g_antilag == 0 || this.cvar_cl_noantilag)
lag = 0; // only do hitscan, but no antilag
if(lag)
break;
float maxdist;
+ entity hitstore = IS_PLAYER(hit) ? PS(hit) : hit;
if(max_solid_penetration < 0)
break;
- else if(hit.ballistics_density < -1)
+ else if(hitstore.ballistics_density < -1)
break; // -2: no solid penetration, ever
- else if(hit.ballistics_density < 0)
+ else if(hitstore.ballistics_density < 0)
maxdist = vlen(hit.maxs - hit.mins) + 1; // -1: infinite travel distance
- else if(hit.ballistics_density == 0)
+ else if(hitstore.ballistics_density == 0)
maxdist = max_solid_penetration * solid_penetration_left;
else
- maxdist = max_solid_penetration * solid_penetration_left * hit.ballistics_density;
+ maxdist = max_solid_penetration * solid_penetration_left * hitstore.ballistics_density;
if(maxdist <= autocvar_g_ballistics_mindistance)
break;
.entity wepe1 = weaponentities[0];
entity wep1 = actor.(wepe1);
this.m_switchweapon = wep1.m_switchweapon;
- if(!(this.m_switchweapon.spawnflags & WEP_FLAG_DUALWIELD) && !(actor.dual_weapons & wep1.m_switchweapon.m_wepset))
+ entity store = IS_PLAYER(actor) ? PS(actor) : actor;
+ if(!(this.m_switchweapon.spawnflags & WEP_FLAG_DUALWIELD) && !(store.dual_weapons & wep1.m_switchweapon.m_wepset))
{
this.m_weapon = WEP_Null;
this.m_switchingweapon = WEP_Null;
set -eu
cd ${0%/*}
+# This script attempts to build the codebase in every possible header configuration,
+# to check that all files #include what they need, so that we can eventually move away
+# from a unity build and into incremental compilation.
+
+# If these files exist from previous compilation, `./all compile` will stop
+# detecting changes after running this script so delete them to trigger
+# a recompile next time.
+if [ -f ../../csprogs.dat ]; then
+ rm ../../csprogs.dat
+fi
+
+if [ -f ../../menu.dat ]; then
+ rm ../../menu.dat
+fi
+
+if [ -f ../../progs.dat ]; then
+ rm ../../progs.dat
+fi
+
WORKDIR=../.tmp
CPP="cc -xc -E"
-DNDEBUG=1
-DXONOTIC=1
-DWATERMARK="\"$(git describe --tags --dirty='~')\""
+ -DENABLE_EFFECTINFO=0
+ -DENABLE_DEBUGDRAW=0
+ -DENABLE_DEBUGTRACE=0
)
QCCDEFS="${QCCDEFS[@]}"