]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into terencehill/bot_waypoints
authorterencehill <piuntn@gmail.com>
Mon, 17 Jul 2017 22:23:08 +0000 (00:23 +0200)
committerterencehill <piuntn@gmail.com>
Mon, 17 Jul 2017 22:23:08 +0000 (00:23 +0200)
119 files changed:
.gitlab-ci.yml
CMakeLists.txt
balance-mario.cfg
balance-nexuiz25.cfg
balance-overkill.cfg
balance-samual.cfg
balance-xdf.cfg
balance-xonotic.cfg
balance-xpm.cfg
defaultXonotic.cfg
qcsrc/Makefile
qcsrc/client/autocvars.qh
qcsrc/client/csqcmodel_hooks.qc
qcsrc/client/defs.qh
qcsrc/client/hud/hud.qh
qcsrc/client/hud/panel/racetimer.qc
qcsrc/client/main.qc
qcsrc/client/main.qh
qcsrc/client/view.qc
qcsrc/common/debug.qh
qcsrc/common/effects/all.qc
qcsrc/common/effects/qc/damageeffects.qc
qcsrc/common/gamemodes/gamemode/nexball/nexball.qc
qcsrc/common/minigames/sv_minigames.qc
qcsrc/common/models/all.inc
qcsrc/common/mutators/mutator/bugrigs/bugrigs.qc
qcsrc/common/mutators/mutator/campcheck/sv_campcheck.qc
qcsrc/common/mutators/mutator/dodging/sv_dodging.qc
qcsrc/common/mutators/mutator/multijump/multijump.qc
qcsrc/common/mutators/mutator/nades/nades.qc
qcsrc/common/physics/player.qc
qcsrc/common/physics/player.qh
qcsrc/common/stats.qh
qcsrc/common/t_items.qc
qcsrc/common/triggers/func/door.qc
qcsrc/common/triggers/trigger/keylock.qh
qcsrc/common/triggers/trigger/multi.qc
qcsrc/common/vehicles/sv_vehicles.qh
qcsrc/common/vehicles/vehicle/bumblebee.qc
qcsrc/common/vehicles/vehicle/racer.qc
qcsrc/common/vehicles/vehicle/raptor.qc
qcsrc/common/vehicles/vehicle/spiderbot.qc
qcsrc/common/viewloc.qc
qcsrc/common/weapons/all.qc
qcsrc/common/weapons/weapon.qh
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/common/weapons/weapon/shotgun.qc
qcsrc/common/weapons/weapon/tuba.qc
qcsrc/ecs/systems/physics.qc
qcsrc/ecs/systems/sv_physics.qc
qcsrc/lib/_all.inc
qcsrc/lib/angle.qc
qcsrc/lib/bits.qh
qcsrc/lib/bool.qh
qcsrc/lib/color.qh
qcsrc/lib/compiler.qh
qcsrc/lib/counting.qh
qcsrc/lib/cvar.qh
qcsrc/lib/draw.qh
qcsrc/lib/file.qh
qcsrc/lib/i18n.qh
qcsrc/lib/intrusivelist.qh
qcsrc/lib/json.qc
qcsrc/lib/map.qh
qcsrc/lib/markdown.qh
qcsrc/lib/math.qh
qcsrc/lib/noise.qh
qcsrc/lib/p2mathlib.qc
qcsrc/lib/p2mathlib.qh
qcsrc/lib/random.qc
qcsrc/lib/random.qh
qcsrc/lib/registry.qh
qcsrc/lib/sort.qh
qcsrc/lib/sortlist.qc
qcsrc/lib/static.qh
qcsrc/lib/string.qh
qcsrc/lib/urllib.qc
qcsrc/lib/urllib.qh
qcsrc/lib/vector.qh
qcsrc/lib/warpzone/server.qc
qcsrc/server/anticheat.qc
qcsrc/server/antilag.qh
qcsrc/server/autocvars.qh
qcsrc/server/bot/default/aim.qc
qcsrc/server/bot/default/bot.qc
qcsrc/server/bot/default/havocbot/havocbot.qc
qcsrc/server/bot/default/scripting.qc
qcsrc/server/cheats.qc
qcsrc/server/client.qc
qcsrc/server/client.qh
qcsrc/server/command/banning.qc
qcsrc/server/command/cmd.qc
qcsrc/server/command/common.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_world.qc
qcsrc/server/g_world.qh
qcsrc/server/impulse.qc
qcsrc/server/item_key.qc
qcsrc/server/mapvoting.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/mutator/gamemode_ca.qc
qcsrc/server/mutators/mutator/gamemode_ctf.qc
qcsrc/server/mutators/mutator/gamemode_cts.qc
qcsrc/server/mutators/mutator/gamemode_freezetag.qc
qcsrc/server/mutators/mutator/gamemode_lms.qc
qcsrc/server/mutators/mutator/gamemode_race.qc
qcsrc/server/player.qc
qcsrc/server/player.qh
qcsrc/server/playerdemo.qc
qcsrc/server/race.qc
qcsrc/server/race.qh
qcsrc/server/teamplay.qc
qcsrc/server/weapons/selection.qc
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/weaponsystem.qc
qcsrc/tools/compilationunits.sh

index 5427860963c0ccbf2c1760a8f49e6d75497d7acc..e25bf40836322adb4649fe0ff37d099fce9690df 100644 (file)
@@ -29,7 +29,7 @@ test_sv_game:
     - 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=585cfa6d62ce59f4854bedfce7c51c20
+    - EXPECT=61265f867b0817396a503ecc0411dc25
     - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
       | tee /dev/stderr
       | grep '^:'
index 2f38e43ba2be7ad75167b6683b238baae72dbc1a..d550d7b6c6849d35738b93c394a9d52fed0ac79a 100644 (file)
@@ -6,14 +6,21 @@ include_directories(qcsrc)
 
 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(
@@ -27,15 +34,21 @@ 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)
index d290be01265d0280de9b1f06955478a641911aa5..42cf31196553096d8e7a3e6df76db560f99cdc29 100644 (file)
@@ -207,7 +207,6 @@ set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (n
 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
index 39405f399881c31eecdc243527b81eec5e3628f5..4967fa7e47936208ca64c9e719e5e41fa373b968 100644 (file)
@@ -207,7 +207,6 @@ set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (n
 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
index 381eb51d7ba3d19948ad83cd5d3acfbb838fd828..fc99616f94eaff821e575442fcdfca74d0de6052 100644 (file)
@@ -207,7 +207,6 @@ set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (n
 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
index ad7192227eb4abcf842a2b02f57b1025de46ff27..4357eff7646aad75e967bfbd9de0f32b697b104b 100644 (file)
@@ -207,7 +207,6 @@ set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (n
 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
index 5eda67ba945a7f66f4d178a8f80622828c792280..a7d6b43740de047372c391bb438c70919ffd87b4 100644 (file)
@@ -207,7 +207,6 @@ set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (n
 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
index f317d2e6b422d1225078fe3fa4d58de4ee128ce4..5bd1536feab823df7b40dbd50df1133d194222ef 100644 (file)
@@ -207,7 +207,6 @@ set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (n
 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
index f5ec29240e97d8b8646c7ba8aabb535037049acd..5c14aa36206256e19c240ecf105815a8c7fc8e41 100644 (file)
@@ -207,7 +207,6 @@ set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (n
 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
index ba8bdb228d0f7116abaf7a7cea39eb25561d122a..c63fc31e3dbc8d1cd0175f4375c1d31d4eccbd8b 100644 (file)
@@ -589,7 +589,9 @@ r_glsl_offsetmapping 0
 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
@@ -1102,6 +1104,7 @@ seta cl_autoscreenshot 1 "Take a screenshot upon the end of a match... 0 = Disab
 
 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:
@@ -1167,6 +1170,7 @@ seta cl_gentle_messages 0 "client side gentle mode (only replaces frag messages/
 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."
 
index c660a7e94e5269d40aeea9f433fc2de70ee00bca..bd17dad6aaf5e93c0c729891009cfedfa85ca258 100644 (file)
@@ -8,6 +8,9 @@ QCCFLAGS_WATERMARK ?= $(shell git describe --tags --dirty='~')
 VER = $(subst *,\*,$(QCCFLAGS_WATERMARK))
 NDEBUG ?= 1
 XONOTIC ?= 1
+ENABLE_EFFECTINFO ?= 0
+ENABLE_DEBUGDRAW ?= 0
+ENABLE_DEBUGTRACE ?= 0
 BUILD_MOD ?=
 
 ifndef ZIP
@@ -34,6 +37,9 @@ QCCDEFS ?= \
        -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)
 
index d95958392bb9626e2cadba13cd6edf88394bdb98..6d3fb626771723a0d86af77ab2e775f7a24364f7 100644 (file)
@@ -152,7 +152,6 @@ float autocvar_crosshair_ring_reload_size;
 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;
@@ -441,7 +440,9 @@ int autocvar__cl_playerskin;
 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;
index 104465360770beaddc14298f06d2872f0d2d6d1f..d2b28e9b08f2a9b4cacd3a49bc0f45076a52de8e 100644 (file)
@@ -561,7 +561,7 @@ void CSQCModel_Effects_Apply(entity this)
        {
                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;
                }
        }
@@ -569,7 +569,7 @@ void CSQCModel_Effects_Apply(entity this)
        {
                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;
                }
        }
index c520a2f1eb8fe6180cfb7ddb18ab5d890f91b259..d36994ec3d2e69bbc6849d82eaf3272686c01949 100644 (file)
@@ -36,9 +36,11 @@ float race_time;
 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
index 1418dff830e28379454380c5a848c056eac51766..d070dce380d3b4877f5ac6457a9993a388717957 100644 (file)
@@ -61,7 +61,7 @@ void HUD_Reset ();
 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;
index 2f54e2a37981bfa42c166fbe8ea18f1d7a5b7c42..b107a40c0378b95c62ea046030e6dc03d99209d9 100644 (file)
@@ -5,14 +5,12 @@
 // 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
        {
@@ -32,6 +30,22 @@ string MakeRaceString(int cp, float mytime, float theirtime, float lapdelta, str
                        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);
@@ -50,11 +64,11 @@ string MakeRaceString(int cp, float mytime, float theirtime, float lapdelta, str
                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)
@@ -70,6 +84,8 @@ string MakeRaceString(int cp, float mytime, float theirtime, float lapdelta, str
                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)));
 }
@@ -146,20 +162,24 @@ void HUD_RaceTimer ()
                        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);
+                               }
                        }
                }
 
@@ -205,14 +225,14 @@ void HUD_RaceTimer ()
                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);
                }
index bf82ccb3425840d2b82409c12bf23bf001dbd66f..539461187e6fadf95f05a31adb55337016e56325 100644 (file)
@@ -132,8 +132,6 @@ void CSQC_Init()
 
        registercvar("cl_spawn_near_teammate", "1");
 
-       registercvar("cl_race_cptimes_onlyself", "0");
-
        if(autocvar_cl_lockview)
                cvar_set("cl_lockview", "0");
 
@@ -856,7 +854,7 @@ void Ent_Remove(entity this)
 
        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;
        }
 
@@ -978,6 +976,7 @@ NET_HANDLE(ENT_CLIENT_INIT, bool isnew)
        forcefog = strzone(ReadString());
 
        armorblockpercent = ReadByte() / 255.0;
+       damagepush_speedfactor = ReadByte() / 255.0;
 
        serverflags = ReadByte();
 
@@ -1036,25 +1035,18 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        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());
-
-                       race_checkpointtime = time;
-
-                       if(race_checkpoint == 0 || race_checkpoint == 254)
+                       string pbestname = ReadString();
+                       if(autocvar_cl_race_cptimes_onlyself)
                        {
-                               race_penaltyaccumulator = 0;
-                               race_laptime = time; // valid
+                               race_previousbesttime = race_mypreviousbesttime;
+                               race_mypreviousbesttime = 0;
+                               race_previousbestname = strzone("");
                        }
-                       break;
-               case RACE_NET_CHECKPOINT_HIT_SELF_QUALIFYING:
-                       race_checkpoint = ReadByte();
-                       race_time = ReadInt24_t();
-                       race_previousbesttime = ReadInt24_t();
-                       if(race_previousbestname)
-                               strunzone(race_previousbestname);
-                       race_previousbestname = strzone(""); // handled by MakeRaceString
+                       else
+                               race_previousbestname = strzone(pbestname);
 
                        race_checkpointtime = time;
 
@@ -1078,18 +1070,18 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        race_nextcheckpoint = ReadByte();
 
                        race_nextbesttime = ReadInt24_t();
+                       race_mybesttime = ReadInt24_t();
                        if(race_nextbestname)
                                strunzone(race_nextbestname);
-                       race_nextbestname = strzone(ReadString());
-                       break;
-
-               case RACE_NET_CHECKPOINT_NEXT_SELF_QUALIFYING:
-                       race_nextcheckpoint = ReadByte();
-
-                       race_nextbesttime = ReadInt24_t();
-                       if(race_nextbestname)
-                               strunzone(race_nextbestname);
-                       race_nextbestname = strzone(""); // handled by MakeRaceString
+                       string newname = ReadString();
+                       if(autocvar_cl_race_cptimes_onlyself)
+                       {
+                               race_nextbesttime = race_mybesttime;
+                               race_mybesttime = 0;
+                               race_nextbestname = strzone("");
+                       }
+                       else
+                               race_nextbestname = strzone(newname);
                        break;
 
                case RACE_NET_CHECKPOINT_HIT_RACE:
index bbf69d28d1bcd39586a78041babc247bc2166cea..a2f4d18bba97e2ef4070fe83ac362d83dd462404 100644 (file)
@@ -86,6 +86,7 @@ void centerprint_generic(float new_id, string strMessage, float duration, float
 const float ALPHA_MIN_VISIBLE = 0.003;
 
 float armorblockpercent;
+float damagepush_speedfactor;
 
 //hooks
 int calledhooks;
index 75afcfccb1691869a863bab13166837ee142f32c..9b78e4907402b309345698a5082ea38cf761bc5a 100644 (file)
@@ -2256,7 +2256,7 @@ void CSQC_UpdateView(entity this, float w, float h)
        // draw 2D entities
        IL_EACH(g_drawables_2d, it.draw2d, it.draw2d(it));
        Draw_ShowNames_All();
-#ifdef DEBUGDRAW
+#if ENABLE_DEBUGDRAW
        Debug_Draw();
 #endif
 
index 7aabe69a90e51f29d6cdcb6156a8730a25cb29a3..28153a7d404a0eb764de7ca093c79ab43c04cd2f 100644 (file)
@@ -47,7 +47,7 @@ REGISTER_NET_TEMP(net_debug)
        }
 #endif
 
-#ifdef DEBUGDRAW
+#if ENABLE_DEBUGDRAW
 #ifdef GAMEQC
 /**
  * 0: off
@@ -259,7 +259,7 @@ GENERIC_COMMAND(cvar_localchanges, "Print locally changed cvars")
        }
 }
 
-#ifdef DEBUGTRACE
+#if ENABLE_DEBUGTRACE
 REGISTER_STAT(TRACE_ENT, int)
 #ifdef SVQC
 bool autocvar_debugtrace;
index f43b25dcfbcac143bb7e29580befba124cc782c3..af41054e31c1c40c462ce041a2cc540fa1c570be 100644 (file)
@@ -91,6 +91,6 @@ void Send_Effect_(string eff_name, vector eff_loc, vector eff_vel, int eff_cnt)
 }
 #endif
 
-#ifdef EFFECTINFO_ENABLED
+#if ENABLE_EFFECTINFO
        #include "effectinfo.qc"
 #endif
index 71e1e2a7bcdd96dcf3f72629d7e147d4db03aab3..c62bbd6b68cd5b08c5108a9b0c0dd9ac77598693 100644 (file)
@@ -244,7 +244,7 @@ NET_HANDLE(ENT_CLIENT_DAMAGEINFO, bool isNew)
                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);
                        }
 
index b917deba6a05f5d6be554cf68f04dc55d5d85ed2..ba42962692441141079d57526061e381fa17322a 100644 (file)
@@ -753,11 +753,11 @@ void W_Nexball_Touch(entity this, entity toucher)
                                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);
index 033a524fb3cf896b7c26e928a3634cb75637b625..4f1cd5dc2d9975bff6419159559e7ece0f3cf2e4 100644 (file)
@@ -3,7 +3,7 @@
 
 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);
@@ -124,11 +124,11 @@ bool minigame_CheckSend(entity this, entity client)
 
 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);
@@ -140,7 +140,7 @@ int minigame_addplayer(entity minigame_session, entity player)
                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);
@@ -215,7 +215,7 @@ entity join_minigame(entity player, string game_id )
 
 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);
@@ -262,19 +262,19 @@ void end_minigames()
 
 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 "";
@@ -282,10 +282,10 @@ string invite_minigame(entity inviter, entity player)
 
 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;
@@ -293,11 +293,11 @@ entity minigame_find_player(entity client)
 
 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;
 }
@@ -350,7 +350,7 @@ void ClientCommand_minigame(entity caller, int request, int argc, string command
                }
                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");
@@ -361,14 +361,14 @@ void ClientCommand_minigame(entity caller, int request, int argc, string command
                }
                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");
@@ -377,12 +377,12 @@ void ClientCommand_minigame(entity caller, int request, int argc, string command
                                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;
 
                }
index f47d8e7c5afdd76ea2ce79630d28a11e4ee608e6..eb95d7c28260d2a81ad306a1a37b00c97b4802ca 100644 (file)
@@ -335,6 +335,7 @@ MODEL(VEH_SPIDERBOT_TOP,                "models/vehicles/spiderbot_top.dpm");
 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");
index 318cc10f4a95657a2d237a5e904ebd44283aa002..40f19d6b1770bc88fa1fded89aa345397f2f3812 100644 (file)
@@ -63,6 +63,24 @@ void bugrigs_SetVars()
 
 #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"
@@ -71,8 +89,8 @@ void RaceCarPhysics(entity this, float dt)
        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))
        {
@@ -202,11 +220,11 @@ void RaceCarPhysics(entity this, float dt)
                {
                        // 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);
                }
@@ -231,11 +249,11 @@ void RaceCarPhysics(entity this, float dt)
        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
                                );
        }
@@ -243,12 +261,12 @@ void RaceCarPhysics(entity this, float dt)
        {
                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
@@ -263,8 +281,8 @@ void RaceCarPhysics(entity this, float dt)
        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
index 41f538b7a52f02e018c364ef1aec9b123e9a7383..52fc52466d5f93ec8203f3b104ac2b72e295dba1 100644 (file)
@@ -9,6 +9,8 @@ REGISTER_MUTATOR(campcheck, cvar("g_campcheck"));
 .float campcheck_nextcheck;
 .float campcheck_traveled_distance;
 
+.vector campcheck_prevorigin;
+
 MUTATOR_HOOKFUNCTION(campcheck, PlayerDies)
 {
        entity frag_target = M_ARGV(2, entity);
@@ -33,23 +35,19 @@ MUTATOR_HOOKFUNCTION(campcheck, Damage_Calculate)
 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()))
@@ -72,10 +70,21 @@ MUTATOR_HOOKFUNCTION(campcheck, PlayerPreThink)
                        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)
index 88547f7bf4c2268e3dabd7507152aa100fa9d87d..93feb5d94626d2d4a5451cc97fba881e02ad7e5b 100644 (file)
@@ -12,7 +12,6 @@
 #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
@@ -156,9 +157,10 @@ bool PM_dodging_checkpressedkeys(entity this)
        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;                                                                                                 \
@@ -236,7 +238,7 @@ void PM_dodging(entity this)
        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);
@@ -279,10 +281,10 @@ void PM_dodging_GetPressedKeys(entity this)
        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));
index ecedc475961585184fd61bad6785d2986f00f23e..b00ad7475dbb882a3d754d1c607cf880627bceba 100644 (file)
@@ -82,7 +82,7 @@ MUTATOR_HOOKFUNCTION(multijump, PlayerJump)
                        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;
@@ -97,7 +97,7 @@ MUTATOR_HOOKFUNCTION(multijump, PlayerJump)
 //#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
index 052a132b93b1aea01e8bf0924947c9c31b253700..9447ba3955e9d14355a539e45dc702b81612243a 100644 (file)
@@ -1373,19 +1373,19 @@ MUTATOR_HOOKFUNCTION(nades, PlayerDies, CBC_ORDER_LAST)
        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;
index 3b86ebcecacc7433bfc8f86ad594e04d4f17be6c..ec255c8d3c66defdcee629cbfcd8f903529ffe44 100644 (file)
@@ -30,8 +30,14 @@ float Physics_ClientOption(entity this, string option, float defaultval)
        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)
@@ -135,13 +141,13 @@ void PM_ClientMovement_UpdateStatus(entity this)
 
 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);
@@ -477,24 +483,6 @@ void CheckPlayerJump(entity this)
                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;
@@ -550,7 +538,7 @@ void PM_check_nickspam(entity this)
        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!
@@ -598,12 +586,12 @@ void PM_check_frozen(entity this)
 #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)
@@ -684,7 +672,7 @@ void PM_check_blocked(entity this)
 #ifdef SVQC
        if (!this.player_blocked)
                return;
-       this.movement = '0 0 0';
+       PHYS_CS(this).movement = '0 0 0';
        this.disableclientprediction = 1;
 #endif
 }
@@ -693,8 +681,8 @@ void PM_jetpack(entity this, float maxspd_mod, float dt)
 {
        //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
@@ -818,10 +806,15 @@ void SV_PlayerPhysics(entity this)
 void CSQC_ClientMovement_PlayerMove_Frame(entity this)
 #endif
 {
+#ifdef SVQC
+       // needs to be called before physics are run!
+       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;
index 88c735c630fac40950ba1e9eb965f1decc5f83ea..a77a03b5860042b2100bca0b82fc49ab281350b3 100644 (file)
@@ -2,7 +2,10 @@
 
 // Client/server mappings
 
-.float pm_frametime;
+#ifdef SVQC
+// TODO: get rid of this random dumb include!
+       #include <common/state.qh>
+#endif
 
 .entity conveyor;
 
@@ -20,7 +23,6 @@
 #endif
 
 .vector movement_old;
-.float buttons_old;
 .vector v_angle_old;
 .string lastclassname;
 
@@ -208,6 +210,7 @@ STATIC_INIT(PHYS_INPUT_BUTTON_DODGE)
        #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))
@@ -244,7 +247,9 @@ STATIC_INIT(PHYS_INPUT_BUTTON_DODGE)
 
        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);
@@ -259,27 +264,28 @@ STATIC_INIT(PHYS_INPUT_BUTTON_DODGE)
        #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 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)
index 2cb353361eb0867750cbbfc2a9ee47e26086dca7..bfed4390de6395dc857719e0e7a9108864c36e37 100644 (file)
@@ -41,8 +41,11 @@ const int MAX_CL_STATS = 256;
     #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)
@@ -58,22 +61,26 @@ REGISTER_STAT(KH_KEYS, int)
 #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)
 
@@ -99,7 +106,7 @@ REGISTER_STAT(NADE_TIMER, float)
 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)
index 811115b68071f36e358f2faa6d664b6a801f585d..d85cf7861478c33e8b4451e8e624cb5f30c7d9c5 100644 (file)
@@ -1024,25 +1024,27 @@ float ammo_pickupevalfunc(entity player, entity item)
                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;
index 01250e0aae6ab3baba60262094db79c95d43fff2..dc0be6ae24a9822b67865e2c4a2cb0c6b0b32c6b 100644 (file)
@@ -169,7 +169,11 @@ bool door_check_keys(entity door, entity player)
        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)
index 756d3b25a5c861867fc8f0b525836d40c21f5671..904c3fa3d4a7404d5d4c0535fbc59858b2d6cc42 100644 (file)
@@ -3,7 +3,7 @@
 #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;
 }
index 7e6311df1bc7cde481ee40b3efcf54ec58e51522..808d08101b120ca18ced191749a3de141f4b29d2 100644 (file)
@@ -86,9 +86,8 @@ void multi_touch(entity this, entity toucher)
        }
 
        // 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);
index 653532b43dd9ce1f8a143e51770c06120359a9f0..22e2e4859dd170c94f3bf03c571822bb9c496052 100644 (file)
@@ -67,6 +67,8 @@ const float VHSF_FACTORY = 2;
 .int hud = _STAT(HUD);
 .float dmg_time;
 
+.float play_time;
+
 .int volly_counter;
 
 const int MAX_AXH = 4;
index 1c9e6e1a41d549166b53d6c9f3ec004438a1dc07..d3f802791eb578c3d6a6c26a26096f95bbde3cda 100644 (file)
@@ -439,9 +439,9 @@ bool bumblebee_pilot_frame(entity this, float dt)
 
        // 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);
@@ -455,19 +455,19 @@ bool bumblebee_pilot_frame(entity this, float dt)
        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;
@@ -486,7 +486,7 @@ bool bumblebee_pilot_frame(entity this, float dt)
                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)
index 01488e624e2c0781580f8fd782dc1cc7e14b2f17..a648a005e4892994fa6a9177fd744c3fdeb59730 100644 (file)
@@ -198,17 +198,17 @@ bool racer_frame(entity this, float dt)
        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
@@ -284,7 +284,7 @@ bool racer_frame(entity this, float dt)
                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
 
index da556c4fc5a53a2fe991fcbf5ced0ee9562c5f24..e48600c47a0ae38c653a8513cadee7e28fdb0c00 100644 (file)
@@ -204,8 +204,8 @@ bool raptor_frame(entity this, float dt)
 
        // 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);
@@ -222,22 +222,22 @@ bool raptor_frame(entity this, float dt)
 
        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
        {
@@ -252,7 +252,7 @@ bool raptor_frame(entity this, float dt)
                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
 
index 164371e131b5274eef7f81c41e7d74f4ffcf9911..79d938d2ef8c0fcba5b3676667ef506184242b23 100644 (file)
@@ -137,10 +137,10 @@ bool spiderbot_frame(entity this, float dt)
                        //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;
@@ -154,7 +154,7 @@ bool spiderbot_frame(entity this, float dt)
                }
                else if(time >= vehic.jump_delay)
                {
-                       if(!this.movement)
+                       if(!CS(this).movement)
                        {
                                if(IS_ONGROUND(vehic))
                                {
@@ -172,7 +172,7 @@ bool spiderbot_frame(entity this, float dt)
                        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;
@@ -181,23 +181,23 @@ bool spiderbot_frame(entity this, float dt)
                                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
@@ -211,23 +211,23 @@ bool spiderbot_frame(entity this, float dt)
                                                //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
index 90da2662facda4b54627b3a6f64cfee608c53bb2..d6d7d9facfb2edc3f7f32c39138119723a47f5b0 100644 (file)
@@ -17,12 +17,12 @@ void viewloc_PlayerPhysics(entity this)
                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;
@@ -31,9 +31,9 @@ void viewloc_PlayerPhysics(entity this)
                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)
index 94deed55197c21056d7f8a56b03bbed4af1aa14f..9efbb29a2615aab18f98eaddd1a0359620455086 100644 (file)
@@ -192,14 +192,11 @@ string W_FixWeaponOrder_ForceComplete(string order)
        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, {
index 634fbf812cc8133ef060ec68c697eeeefd034ae5..16332634352f966d7f49f2923c1ff5a09c20901e 100644 (file)
@@ -208,7 +208,7 @@ string W_NumberWeaponOrder(string order);
 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);
 
index b69b9663229a75f8de6381c458774845eabc5128..8d627adda68712b24421f83130949cdfa243c70c 100644 (file)
@@ -398,11 +398,9 @@ void W_Shockwave_Attack(entity actor, .entity weaponentity)
                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)
index e597665c5ebee23918afad49a5a47cf2abb48145..87a24d13a3a96a2d3985073f911f70212d13c956 100644 (file)
@@ -125,7 +125,7 @@ void W_Shotgun_Melee_Think(entity this)
                        + (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);
index ef3c4dc83ccfeb798396159ea4c2d3beba3226c8..0b43a24c15640c23b3b6e655b5c76b5c301db2bb 100644 (file)
@@ -186,10 +186,10 @@ void W_Tuba_NoteOff(entity this)
 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)
index db59359b31abd8a22c08a5bb28f143be94356e1d..8a324281abb101f1eda605ff6f047204ce766d8a 100644 (file)
@@ -17,8 +17,7 @@ void sys_phys_update(entity this, float dt)
        sys_phys_fix(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;
+       PHYS_CS(this).movement_old = PHYS_CS(this).movement;
        this.v_angle_old = this.v_angle;
 
        sys_phys_ai(this);
@@ -200,10 +199,10 @@ void sys_phys_simulate(entity this, float dt)
                }
        }
        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);
@@ -216,7 +215,7 @@ void sys_phys_simulate(entity this, float dt)
        }
        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);
@@ -271,7 +270,7 @@ void sys_phys_simulate(entity this, float dt)
                        // 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,
@@ -288,7 +287,7 @@ void sys_phys_simulate(entity this, float dt)
                        }
                        // !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;
index 9e46dcfc57513b42bb6d6e634666a7c30fe6ed80..87982b5d55f8ac0a8073c2b48cce992ff4fddf30 100644 (file)
@@ -3,19 +3,17 @@
 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;
 }
 
@@ -24,12 +22,14 @@ void sys_phys_monitor(entity this, float dt)
        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 != this.v_angle_old) { CS(this).parm_idlesince = time; }
        }
        PM_check_nickspam(this);
        PM_check_punch(this, dt);
+
+       CS(this).buttons_old = PHYS_INPUT_BUTTON_MASK(this);
 }
 
 void sys_phys_ai(entity this)
@@ -57,28 +57,28 @@ void sys_phys_spectator_control(entity this)
 {
        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;
        }
 }
 
index b8d78cd0419e209ff8eca3a62e96240ac4d99bfe..4da78f1444eb27b397d926442c7a153012adf01e 100644 (file)
        #define bool float
 #endif
 
+#ifndef QCC_SUPPORT_ERASEABLE
+       #define ERASEABLE
+#else
+       #define ERASEABLE [[eraseable]]
+#endif
+
 #include <dpdefs/pre.qh>
 
 #if defined(CSQC)
index cebf84493e09bb60ffbee5d73ac9f71b7e406608..e2e7ae628b8099682c5434216707aa55bfc81567 100644 (file)
@@ -4,7 +4,7 @@
 /*
 * Return a angle within +/- 360.
 */
-[[eraseable]]
+ERASEABLE
 float anglemods(float v)
 {
        v = v - 360 * floor(v / 360);
@@ -20,7 +20,7 @@ float anglemods(float v)
 /*
 * Return the short angle
 */
-[[eraseable]]
+ERASEABLE
 float shortangle_f(float ang1, float ang2)
 {
        if(ang1 > ang2)
@@ -37,7 +37,7 @@ float shortangle_f(float ang1, float ang2)
        return ang1;
 }
 
-[[eraseable]]
+ERASEABLE
 vector shortangle_v(vector ang1, vector ang2)
 {
        vector vtmp;
@@ -49,7 +49,7 @@ vector shortangle_v(vector ang1, vector ang2)
        return vtmp;
 }
 
-[[eraseable]]
+ERASEABLE
 vector shortangle_vxy(vector ang1, vector ang2)
 {
        vector vtmp = '0 0 0';
@@ -64,7 +64,7 @@ vector shortangle_vxy(vector ang1, vector ang2)
 * 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;
index ec9246c99b4ddd09da26475d93471a5f28d862de..c158ea032d497cb29a8709c2e02ad4fa8e2bd610 100644 (file)
@@ -10,7 +10,7 @@
        #define BITSET(var, mask, flag) ((var) ^ (-(flag) ^ (var)) & (mask))
 #endif
 
-[[eraseable]]
+ERASEABLE
 int lowestbit(int f)
 {
        f &= ~(f << 1);
@@ -21,7 +21,7 @@ int lowestbit(int f)
        return f;
 }
 
-[[eraseable]]
+ERASEABLE
 int randombit(int bits)
 {
        if (!(bits & (bits - 1)))  // this ONLY holds for powers of two!
@@ -44,7 +44,7 @@ int randombit(int bits)
        return b;
 }
 
-[[eraseable]]
+ERASEABLE
 int randombits(int bits, int k, bool error_return)
 {
        int r = 0;
@@ -78,7 +78,7 @@ enum {
        OP_MINUS
 };
 
-[[eraseable]]
+ERASEABLE
 bool GiveBit(entity e, .int fld, int bit, int op, int val)
 {
        int v0 = (e.(fld) & bit);
@@ -103,7 +103,7 @@ bool GiveBit(entity e, .int fld, int bit, int op, int val)
        return v0 != v1;
 }
 
-[[eraseable]]
+ERASEABLE
 bool GiveValue(entity e, .int fld, int op, int val)
 {
        int v0 = e.(fld);
index 8ea9058074e3780e60ae45862f533717369a2560..c78f717d9e983be74923a5dd8fb5252b73f9b627 100644 (file)
@@ -9,7 +9,7 @@
 #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))
index 7de70e8314e9dbe47cc6a9472257a415c1230f1d..5f9297f2dab1f5be24887ff2fead30390ee59fd6 100644 (file)
@@ -3,7 +3,7 @@
 #include "string.qh"
 
 #define colormapPaletteColor(c, isPants) colormapPaletteColor_(c, isPants, time)
-[[eraseable]]
+ERASEABLE
 vector colormapPaletteColor_(int c, bool isPants, float t)
 {
        switch (c)
@@ -36,7 +36,7 @@ vector colormapPaletteColor_(int c, bool isPants, float t)
        }
 }
 
-[[eraseable]]
+ERASEABLE
 float rgb_mi_ma_to_hue(vector rgb, float mi, float ma)
 {
        if (mi == ma)
@@ -58,7 +58,7 @@ float rgb_mi_ma_to_hue(vector rgb, float mi, float ma)
        }
 }
 
-[[eraseable]]
+ERASEABLE
 vector hue_mi_ma_to_rgb(float hue, float mi, float ma)
 {
        vector rgb;
@@ -113,7 +113,7 @@ vector hue_mi_ma_to_rgb(float hue, float mi, float ma)
        return rgb;
 }
 
-[[eraseable]]
+ERASEABLE
 vector rgb_to_hsv(vector rgb)
 {
        float mi, ma;
@@ -131,13 +131,13 @@ vector rgb_to_hsv(vector rgb)
        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;
@@ -157,7 +157,7 @@ vector rgb_to_hsl(vector rgb)
        return hsl;
 }
 
-[[eraseable]]
+ERASEABLE
 vector hsl_to_rgb(vector hsl)
 {
        float mi, ma, maminusmi;
@@ -173,7 +173,7 @@ vector hsl_to_rgb(vector hsl)
        return hue_mi_ma_to_rgb(hsl.x, mi, ma);
 }
 
-[[eraseable]]
+ERASEABLE
 string rgb_to_hexcolor(vector rgb)
 {
        return strcat(
index 7cd34bc8487bfae058f168ca4471a07e07156077..d1bdc4fe5b55e609bc4d02b32dc0f55b0761f21a 100644 (file)
        #endif
 #endif
 
+#ifndef QCC_SUPPORT_ERASEABLE
+       #ifdef GMQCC
+               #define QCC_SUPPORT_ERASEABLE
+       #endif
+#endif
+
 #ifdef GMQCC
     #define LABEL(id) :id
 #else
index 12ec4a9b61dc7f09a4fff6c80a735022c558ae70..b38ba9d05a9313f670f8fa8bdeede09c565ebf2c 100644 (file)
@@ -61,7 +61,7 @@
        _("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
@@ -87,7 +87,7 @@ string count_ordinal(int interval)
        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
@@ -118,7 +118,7 @@ string count_fill(float interval, string zeroth, string first, string second, st
        return "";
 }
 
-[[eraseable]]
+ERASEABLE
 string process_time(float outputtype, float seconds)
 {
        float tmp_hours = 0, tmp_minutes = 0, tmp_seconds = 0;
index f322753c0af92d9d5eda78b9e57497633777b052..a17f2bad72397d55a470fc32bb64851cfcbe5152 100644 (file)
@@ -4,10 +4,10 @@
 #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;
@@ -20,7 +20,7 @@ bool cvar_value_issafe(string s)
 }
 
 /** escape the string to make it safe for consoles */
-[[eraseable]]
+ERASEABLE
 string MakeConsoleSafe(string input)
 {
        input = strreplace("\n", "", input);
@@ -30,19 +30,19 @@ string MakeConsoleSafe(string 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);
@@ -50,7 +50,7 @@ void RegisterCvars_Set(string name, string def, string desc, bool archive, strin
 }
 
 int RegisterCvars_Save_fd;
-[[eraseable]]
+ERASEABLE
 void RegisterCvars_Save(string name, string def, string desc, bool archive, string file)
 {
        if (!archive) return;
index 5dbdb67b546a2f7774ac7fd938e8f0a6963955b6..2bf480a8782aed99c16167731c5f38efd1300fcd 100644 (file)
                }
        }
 
-       [[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);
index 9e1ba4c9928fcb2df244f304eab190c6acda8d76..5bc24f627185f5fd5c4bf87aaaf32a40f0908ff8 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 
-[[eraseable]]
+ERASEABLE
 bool fexists(string f)
 {
        int fh = fopen(f, FILE_READ);
index 6a17fbaca4ab94c5a0938b55f9b0b7360d465a44..3dfac622464a1144ed74096703108d0e9afa8251 100644 (file)
@@ -10,7 +10,7 @@ string prvm_language;
 /**
  * @deprecated prefer _("translated")
  */
-[[eraseable]]
+ERASEABLE
 string language_filename(string s)
 {
        string fn = prvm_language;
@@ -41,7 +41,7 @@ string language_filename(string s)
        }
 #endif
 
-[[eraseable]]
+ERASEABLE
 string CTX(string s)
 {
 #if CTX_CACHE
index 524c6bec7d4334793b088633f9e43718c9e36247..fc0e080eae32fa103333559653d439a403895cb2 100644 (file)
@@ -4,11 +4,11 @@
 
 const int IL_MAX = 128;
 
-[[eraseable]]
+ERASEABLE
 void IL_INIT(entity this);
-[[eraseable]]
+ERASEABLE
 void IL_DTOR(entity this);
-[[eraseable]]
+ERASEABLE
 void IL_ENDFRAME();
 
 /**
@@ -40,7 +40,7 @@ ENDCLASS(IntrusiveList)
 #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);
@@ -50,7 +50,7 @@ bool IL_CONTAINS(IntrusiveList this, entity it)
 /**
  * Push to tail
  */
-[[eraseable]]
+ERASEABLE
 entity IL_PUSH(IntrusiveList this, entity it)
 {
        assert(this, return NULL);
@@ -69,7 +69,7 @@ entity IL_PUSH(IntrusiveList this, entity it)
 /**
  * Push to head
  */
-[[eraseable]]
+ERASEABLE
 entity IL_UNSHIFT(IntrusiveList this, entity it)
 {
        assert(this, return NULL);
@@ -88,7 +88,7 @@ entity IL_UNSHIFT(IntrusiveList this, entity it)
 /**
  * Pop from tail
  */
-[[eraseable]]
+ERASEABLE
 entity IL_POP(IntrusiveList this)
 {
        assert(this, return NULL);
@@ -106,7 +106,7 @@ entity IL_POP(IntrusiveList this)
 /**
  * Pop from head
  */
-[[eraseable]]
+ERASEABLE
 entity IL_SHIFT(IntrusiveList this)
 {
        assert(this, return NULL);
@@ -124,7 +124,7 @@ entity IL_SHIFT(IntrusiveList this)
 /**
  * Remove any element, anywhere in the list
  */
-[[eraseable]]
+ERASEABLE
 void IL_REMOVE(IntrusiveList this, entity it)
 {
        assert(this, return);
@@ -189,7 +189,7 @@ int il_links_ptr;
 
 #define IL_LISTS_PER_BIT IL_CEIL(IL_MAX / (3 * 24))
 
-[[eraseable]]
+ERASEABLE
 void IL_INIT(IntrusiveList this)
 {
        .entity nextfld, prevfld;
@@ -218,14 +218,14 @@ void IL_INIT(IntrusiveList this)
        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
@@ -245,7 +245,7 @@ void IL_ENDFRAME()
 #endif
 }
 
-[[eraseable]]
+ERASEABLE
 void ONREMOVE(entity this)
 {
        if (this.il_lists) {
index f15aa8cd62ab96d584dc18198ccf87d04a4a5858..b477fe15e59124924662e4c463030ff7016ca94e 100644 (file)
@@ -32,7 +32,7 @@ string _json_ns;
 // Current keys
 int _json_keys;
 
-[[eraseable]]
+ERASEABLE
 bool _json_parse_object() {
     JSON_BEGIN();
     if (STRING_ITERATOR_GET(_json) != '{') JSON_FAIL("expected '{'");
@@ -41,7 +41,7 @@ bool _json_parse_object() {
     JSON_END();
 }
 
-    [[eraseable]]
+    ERASEABLE
     bool _json_parse_members() {
         JSON_BEGIN();
         for (;;) {
@@ -55,7 +55,7 @@ bool _json_parse_object() {
         JSON_END();
     }
 
-        [[eraseable]]
+        ERASEABLE
         bool _json_parse_pair() {
             JSON_BEGIN();
             if (!_json_parse_string(false)) JSON_FAIL("expected string");
@@ -69,7 +69,7 @@ bool _json_parse_object() {
             JSON_END();
         }
 
-[[eraseable]]
+ERASEABLE
 bool _json_parse_array() {
     JSON_BEGIN();
     if (STRING_ITERATOR_GET(_json) != '[') JSON_FAIL("expected '['");
@@ -97,7 +97,7 @@ bool _json_parse_array() {
     JSON_END();
 }
 
-[[eraseable]]
+ERASEABLE
 bool _json_parse_value() {
     JSON_BEGIN();
     if (!(_json_parse_string(true)
@@ -110,7 +110,7 @@ bool _json_parse_value() {
     JSON_END();
 }
 
-    [[eraseable]]
+    ERASEABLE
     bool _json_parse_true() {
         JSON_BEGIN();
         if (!(STRING_ITERATOR_GET(_json) == 't'
@@ -122,7 +122,7 @@ bool _json_parse_value() {
         JSON_END();
     }
 
-    [[eraseable]]
+    ERASEABLE
     bool _json_parse_false() {
         JSON_BEGIN();
         if (!(STRING_ITERATOR_GET(_json) == 'f'
@@ -135,7 +135,7 @@ bool _json_parse_value() {
         JSON_END();
     }
 
-    [[eraseable]]
+    ERASEABLE
     bool _json_parse_null() {
         JSON_BEGIN();
         if (!(STRING_ITERATOR_GET(_json) == 'n'
@@ -147,7 +147,7 @@ bool _json_parse_value() {
         JSON_END();
     }
 
-[[eraseable]]
+ERASEABLE
 bool _json_parse_string(bool add) {
     JSON_BEGIN();
     if (STRING_ITERATOR_GET(_json) != '"') JSON_FAIL("expected opening '\"'");
@@ -179,14 +179,14 @@ bool _json_parse_string(bool add) {
     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 = "";
@@ -208,7 +208,7 @@ bool _json_parse_number() {
         JSON_END();
     }
 
-    [[eraseable]]
+    ERASEABLE
     bool _json_parse_int() {
         JSON_BEGIN();
         string s = "";
@@ -226,7 +226,7 @@ bool _json_parse_number() {
         JSON_END();
     }
 
-[[eraseable]]
+ERASEABLE
 int json_parse(string in, bool() func) {
     string trimmed = "";
     LABEL(trim) {
@@ -272,7 +272,7 @@ int json_parse(string in, bool() func) {
     return _json_buffer;
 }
 
-[[eraseable]]
+ERASEABLE
 string json_get(int buf, string key)
 {
     for (int i = 1, n = buf_getsize(buf); i < n; i += 2) {
@@ -281,13 +281,13 @@ string json_get(int buf, string key)
     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) {
index bec7842ecd76b593037f7c25d1d7db98bc756873..ea7f0e1fe26f62143774a14a217047780abb9e6c 100644 (file)
@@ -4,7 +4,7 @@
 
 // Databases (hash tables)
 const int DB_BUCKETS = 8192;
-[[eraseable]]
+ERASEABLE
 void db_save(int db, string filename)
 {
        int fh = fopen(filename, FILE_WRITE);
@@ -21,17 +21,17 @@ void db_save(int db, string filename)
 
 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();
@@ -65,7 +65,7 @@ int db_load(string filename)
        return db;
 }
 
-[[eraseable]]
+ERASEABLE
 void db_dump(int db, string filename)
 {
        int fh = fopen(filename, FILE_WRITE);
@@ -80,14 +80,14 @@ void db_dump(int db, string filename)
        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;
@@ -97,7 +97,7 @@ string db_get(int db, string key)
 
 #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;
index 3244877195355bc90b7363881ebb9532443d5b2c..a3bffeaaef3b223e96273b4e81959c7306083c85 100644 (file)
@@ -5,7 +5,7 @@
  *   - two spaces escape a linebreak (otherwise text wraps)
  *   - two linebreaks become a paragraph (remain unchanged)
  */
-[[eraseable]]
+ERASEABLE
 string markdown(string s)
 {
        string buf = "";
index fbfe1d1d4fae4fa06bf5a66b2620a987597baf54..8ba31516dda7fecffca459d112cbb4affaa92a76 100644 (file)
@@ -2,7 +2,7 @@
 
 #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;
@@ -11,7 +11,7 @@ void mean_accumulate(entity e, .float a, .float c, float mean, float value, floa
        e.(c) += weight;
 }
 
-[[eraseable]]
+ERASEABLE
 float mean_evaluate(entity e, .float a, .float c, float mean)
 {
        if (e.(c) == 0) return 0;
@@ -34,7 +34,7 @@ Angc used for animations
 */
 
 
-[[eraseable]]
+ERASEABLE
 float angc(float a1, float a2)
 {
        while (a1 > 180)
@@ -53,13 +53,13 @@ float angc(float a1, float a2)
        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;
@@ -71,13 +71,13 @@ vector vsnap(vector point, float fsize)
        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)
@@ -85,14 +85,14 @@ vector bezier_quadratic_getpoint(vector a, vector b, vector c, float 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
@@ -101,7 +101,7 @@ float cubic_speedfunc(float startspeedfactor, float endspeedfactor, float spd)
               ) * spd;
 }
 
-[[eraseable]]
+ERASEABLE
 bool cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor)
 {
        if (startspeedfactor < 0 || endspeedfactor < 0) return false;
@@ -166,40 +166,40 @@ bool cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor)
 }
 
 /** 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;
@@ -207,7 +207,7 @@ float almost_in_bounds(float a, float b, float c)
        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));
@@ -217,7 +217,7 @@ float ExponentialFalloff(float mindist, float maxdist, float halflifedist, float
 
 #define power2of(e) (2 ** e)
 
-[[eraseable]]
+ERASEABLE
 float log2of(float e)
 {
        // NOTE: generated code
@@ -270,7 +270,7 @@ float log2of(float e)
 }
 
 /** ax^2 + bx + c = 0 */
-[[eraseable]]
+ERASEABLE
 vector solve_quadratic(float a, float b, float c)
 {
        vector v;
index 9dc4d4f32ee041a8a1358b8c77b988d05d172572..782798c9fe5c492799d0892f4f1f5cc3f155731d 100644 (file)
@@ -8,13 +8,13 @@ class(Noise).float noise_paccum2;
 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;
@@ -25,13 +25,13 @@ float Noise_Pink(entity e, float dt)
        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;
index 39b18bb62a349c9d90384bed26abf7d5552572f2..ce6f7ea899c8513995827f5c6bf373fae8baa539 100644 (file)
@@ -17,7 +17,7 @@
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 
-[[eraseable]]
+ERASEABLE
 vector vec_bias(vector v, float f)
 {
        vector c;
@@ -26,7 +26,7 @@ vector vec_bias(vector v, float f)
        c.z = v.z + f;
        return c;
 }
-[[eraseable]]
+ERASEABLE
 vector vec_to_min(vector a, vector b)
 {
        vector c;
@@ -36,7 +36,7 @@ vector vec_to_min(vector a, vector b)
        return c;
 }
 
-[[eraseable]]
+ERASEABLE
 vector vec_to_max(vector a, vector b)
 {
        vector c;
@@ -47,7 +47,7 @@ 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)
 {
        vector d = vec_to_min(a, b);
@@ -58,7 +58,7 @@ vector vec_bounds_in(vector point, vector a, vector b)
        return c;
 }
 
-[[eraseable]]
+ERASEABLE
 vector vec_bounds_out(vector point, vector a, vector b)
 {
        vector d = vec_to_max(a, b);
@@ -69,7 +69,7 @@ vector vec_bounds_out(vector point, vector a, vector b)
        return c;
 }
 
-[[eraseable]]
+ERASEABLE
 float angle_snap_f(float f, float increment)
 {
        for (int j = 0; j <= 360; )
@@ -81,7 +81,7 @@ float angle_snap_f(float f, float increment)
        return 0;
 }
 
-[[eraseable]]
+ERASEABLE
 vector angle_snap_vec(vector v, float increment)
 {
        vector c;
@@ -91,7 +91,7 @@ vector angle_snap_vec(vector v, float increment)
        return c;
 }
 
-[[eraseable]]
+ERASEABLE
 vector aim_vec(vector org, vector targ)
 {
        vector v;
index 1f4deb1d877461d2b5d58234c3c82ed7720a3641..898d6ca1ceae2c3a2338a92d88e1397ce5a6e59a 100644 (file)
  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);
index d39cfdcadcfef74b2b74e9513de62690f89ab659..a5ff69356a21f516ba290bac01761eac2a7cce88 100644 (file)
@@ -1,6 +1,6 @@
 #include "random.qh"
 
-[[eraseable]]
+ERASEABLE
 void RandomSelection_Init()
 {
        RandomSelection_totalweight = 0;
@@ -10,7 +10,7 @@ void RandomSelection_Init()
        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)
@@ -38,7 +38,7 @@ void RandomSelection_Add(entity e, float f, string s, vector v, float weight, fl
 float DistributeEvenly_amount;
 float DistributeEvenly_totalweight;
 
-[[eraseable]]
+ERASEABLE
 void DistributeEvenly_Init(float amount, float totalweight)
 {
        if (DistributeEvenly_amount)
@@ -50,7 +50,7 @@ void DistributeEvenly_Init(float amount, float totalweight)
        DistributeEvenly_totalweight = totalweight;
 }
 
-[[eraseable]]
+ERASEABLE
 float DistributeEvenly_Get(float weight)
 {
        float f;
@@ -61,7 +61,7 @@ float DistributeEvenly_Get(float weight)
        return f;
 }
 
-[[eraseable]]
+ERASEABLE
 float DistributeEvenly_GetRandomized(float weight)
 {
        float f;
@@ -75,7 +75,7 @@ float DistributeEvenly_GetRandomized(float weight)
 // 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)
index 668e49784b439c2ba79275300b5395a69f7f091d..e3900697b7d1a54b29f30a75e592abe9fc426b01 100644 (file)
@@ -7,9 +7,9 @@ float RandomSelection_chosen_float;
 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)
index e9712970eb8747fa7a8925d0f4b7e8cdc6d5606a..a3282a0ab1c9e1e3181a80353531defe91491a43 100644 (file)
@@ -140,9 +140,9 @@ REGISTRY(Registries, BITS(8))
 
 #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
index 068707d0b649d9e709f6bd00711ba816da8eeea6..565ebb29c81513276a8f49334cfebd2589cb0986 100644 (file)
@@ -5,7 +5,7 @@ USING(swapfunc_t, void (int i1, int i2, entity pass));
 /** <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) \
@@ -40,7 +40,7 @@ void heapsort(int n, swapfunc_t swap, comparefunc_t cmp, entity pass)
        }
 }
 
-[[eraseable]]
+ERASEABLE
 void shuffle(float n, swapfunc_t swap, entity pass)
 {
        for (int i = 1; i < n; ++i)
index 2cc90268cd16e704a15124a87359ba8ab4a448e7..e800bc4576ae8d81ca1c4a37838e5ae6db2c0bf7 100644 (file)
@@ -1,6 +1,6 @@
 #include "sortlist.qh"
 
-[[eraseable]]
+ERASEABLE
 entity Sort_Spawn()
 {
        entity sort = new_pure(sortlist);
index 46b3a7fa9fb3daa5b77ddcab966ec4c38ce01982..e2c5fd4f0048d90ccbbd719fdbcf12b310bb5fe8 100644 (file)
@@ -16,7 +16,7 @@ float(int tmr) _gettime = #67;
 float(int tmr) _gettime = #519;
 #endif
 
-[[eraseable]]
+ERASEABLE
 void profile(string s)
 {
        static float g_starttime;
index 33aacebabdbd8d8eee975006f6c9c1bf4dab1c5d..b05a316c94a2a4d6b438420d000ce7242f506f19 100644 (file)
@@ -27,7 +27,7 @@
        }
 #endif
 
-[[eraseable]]
+ERASEABLE
 string seconds_tostring(float sec)
 {
        float minutes = floor(sec / 60);
@@ -35,7 +35,7 @@ string seconds_tostring(float sec)
        return sprintf("%d:%02d", minutes, sec);
 }
 
-[[eraseable]]
+ERASEABLE
 string format_time(float seconds)
 {
        seconds = floor(seconds + 0.5);
@@ -49,7 +49,7 @@ string format_time(float seconds)
        else return sprintf(_("%02d:%02d:%02d"), hours, minutes, seconds);
 }
 
-[[eraseable]]
+ERASEABLE
 string mmsss(float tenths)
 {
        tenths = floor(tenths + 0.5);
@@ -59,7 +59,7 @@ string mmsss(float tenths)
        return strcat(ftos(minutes), ":", substring(s, 1, 2), ".", substring(s, 3, 1));
 }
 
-[[eraseable]]
+ERASEABLE
 string mmssss(float hundredths)
 {
        hundredths = floor(hundredths + 0.5);
@@ -71,7 +71,7 @@ string mmssss(float hundredths)
 
 int ColorTranslateMode;
 
-[[eraseable]]
+ERASEABLE
 string ColorTranslateRGB(string s)
 {
        return (ColorTranslateMode & 1) ? strdecolorize(s) : s;
@@ -116,7 +116,7 @@ string CCR(string input)
 
 #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;
@@ -126,7 +126,7 @@ noref string _endsWith_suffix;
 #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;
@@ -136,7 +136,7 @@ string fstrunzone(string s)
 }
 
 /** returns first word */
-[[eraseable]]
+ERASEABLE
 string car(string s)
 {
        int o = strstrofs(s, " ", 0);
@@ -145,7 +145,7 @@ string car(string s)
 }
 
 /** returns all but first word */
-[[eraseable]]
+ERASEABLE
 string cdr(string s)
 {
        int o = strstrofs(s, " ", 0);
@@ -153,7 +153,7 @@ string cdr(string s)
        return substring(s, o + 1, strlen(s) - (o + 1));
 }
 
-[[eraseable]]
+ERASEABLE
 string cons(string a, string b)
 {
        if (a == "") return b;
@@ -161,13 +161,13 @@ string cons(string a, string 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;
@@ -189,13 +189,13 @@ string swapwords(string str, float i, float j)
 }
 
 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;
@@ -206,7 +206,7 @@ string shufflewords(string 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
@@ -231,7 +231,7 @@ string unescape(string in)
        return str;
 }
 
-[[eraseable]]
+ERASEABLE
 string strwords(string s, int w)
 {
        int endpos = 0;
@@ -243,7 +243,7 @@ string strwords(string s, int w)
 
 #define strhasword(s, w) (strstrofs(strcat(" ", s, " "), strcat(" ", w, " "), 0) >= 0)
 
-[[eraseable]]
+ERASEABLE
 int u8_strsize(string s)
 {
        int l = 0;
@@ -256,7 +256,7 @@ int u8_strsize(string s)
        return l;
 }
 
-[[eraseable]]
+ERASEABLE
 bool isInvisibleString(string s)
 {
        s = strdecolorize(s);
@@ -284,7 +284,7 @@ bool isInvisibleString(string s)
 
 // Multiline text file buffers
 
-[[eraseable]]
+ERASEABLE
 int buf_load(string pFilename)
 {
        int buf = buf_create();
@@ -302,7 +302,7 @@ int buf_load(string pFilename)
        return buf;
 }
 
-[[eraseable]]
+ERASEABLE
 void buf_save(float buf, string pFilename)
 {
        int fh = fopen(pFilename, FILE_WRITE);
@@ -316,7 +316,7 @@ void buf_save(float buf, string pFilename)
 /**
  * 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
@@ -327,7 +327,7 @@ string ftos_decimals(float number, int decimals)
 /**
  * converts a number to a string with the minimum number of decimals
  */
-[[eraseable]]
+ERASEABLE
 string ftos_mindecimals(float number)
 {
        // inhibit stupid negative zero
@@ -335,7 +335,7 @@ string ftos_mindecimals(float number)
        return sprintf("%.7g", number);
 }
 
-[[eraseable]]
+ERASEABLE
 int vercmp_recursive(string v1, string v2)
 {
        int dot1 = strstrofs(v1, ".", 0);
@@ -354,7 +354,7 @@ int vercmp_recursive(string v1, string v2)
        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
index 9f5d3e26fe5ae88a3638b12edf23784835b20d5b..fd8b16d881d7177db5a8f623cb2051f9260ca8ea 100644 (file)
@@ -24,7 +24,7 @@ const float URL_FH_STDOUT = -2;
 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;
@@ -83,7 +83,7 @@ float url_URI_Get_Callback(int id, float status, string data)
        }
 }
 
-[[eraseable]]
+ERASEABLE
 void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
 {
        entity e;
@@ -203,7 +203,7 @@ void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
 }
 
 // close a file
-[[eraseable]]
+ERASEABLE
 void url_fclose(entity e)
 {
        int i;
@@ -283,7 +283,7 @@ void url_fclose(entity e)
 }
 
 // with \n (blame FRIK_FILE)
-[[eraseable]]
+ERASEABLE
 string url_fgets(entity e)
 {
        if (e.url_fh == URL_FH_CURL)
@@ -308,7 +308,7 @@ string url_fgets(entity e)
 }
 
 // without \n (blame FRIK_FILE)
-[[eraseable]]
+ERASEABLE
 void url_fputs(entity e, string s)
 {
        if (e.url_fh == URL_FH_CURL)
@@ -331,7 +331,7 @@ void url_fputs(entity e, string s)
 }
 
 // multi URL object, tries URLs separated by space in sequence
-[[eraseable]]
+ERASEABLE
 void url_multi_ready(entity fh, entity me, float status)
 {
        float n;
@@ -360,7 +360,7 @@ void url_multi_ready(entity fh, entity me, float status)
        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;
index acb4077d6a49422c9f275d0ea37910d4e05d3c9c..8918ca0a2a695df6ade44e96df9837b271adc3a4 100644 (file)
@@ -17,20 +17,20 @@ const float URL_READY_CANREAD  =  2;
 // 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);
index 746a43d089015eec6eed881b76ea86df8eb10d87..8340381bab3aff467e543a1fdf1d1c19eacf1463 100644 (file)
@@ -25,7 +25,7 @@ noref vector _dotproduct_a, _dotproduct_b;
 #if 1
 #define cross(a, b) ((a) >< (b))
 #else
-[[eraseable]]
+ERASEABLE
 vector cross(vector a, vector b)
 {
        return
@@ -46,7 +46,7 @@ const vector eX = '1 0 0';
 const vector eY = '0 1 0';
 const vector eZ = '0 0 1';
 
-[[eraseable]]
+ERASEABLE
 vector randompos(vector m1, vector m2)
 {
        vector v;
@@ -57,19 +57,19 @@ vector randompos(vector m1, vector m2)
        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);
@@ -82,11 +82,11 @@ float dist_point_line(vector p, vector l0, vector 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)
@@ -112,7 +112,7 @@ noref vector _vec2;
 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);
@@ -127,7 +127,7 @@ noref vector _yinvert;
  * @param norm the normalized normal
  * @returns dir reflected by norm
  */
-[[eraseable]]
+ERASEABLE
 vector reflect(vector dir, vector norm)
 {
        return dir - 2 * (dir * norm) * norm;
@@ -136,13 +136,13 @@ vector reflect(vector dir, vector 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;
@@ -155,7 +155,7 @@ vector vec_epsilon(vector this, float eps)
        (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)
@@ -172,7 +172,7 @@ vector vec_epsilon(vector this, float eps)
                }
        }
 
-       [[eraseable]]
+       ERASEABLE
        vector NearestPointOnBox(entity box, vector org)
        {
                vector m1 = box.mins + box.origin;
index 116ad00023ae98b1a4321c609698298a2dd46f0b..40c317a6910ec9f994614af7e88ef2db16230946 100644 (file)
@@ -888,7 +888,7 @@ void WarpZone_PlayerPhysics_FixVAngle(entity this)
 #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
index 4e794cb3fc361e7796c98fb66d80b2daae4f4525..7173ae5970721388811a5f639476540732851b54 100644 (file)
@@ -81,8 +81,8 @@ void anticheat_physics(entity this)
                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) {
index ee7b5d4e37c0095628517a93ca765173f32bbd14..6cf392eed5ae1e8bd2bc125b3a19aa5b9e70d6dd 100644 (file)
@@ -8,5 +8,5 @@ void antilag_clear(entity e, entity store);
 
 .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?
index 0c2c1ed4feb90f96b025792af4737a1b715f967e..f585a9a2c33db3eafb7b72168b2b3d8a50de8afd 100644 (file)
@@ -13,7 +13,7 @@ int autocvar_captureleadlimit_override;
 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;
@@ -258,7 +258,7 @@ float autocvar_gameversion_min;
 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;
index 0b813dae1fd5b3be51a7828a22f5c86efefef404..d0ba63365abfc5fc3b7877e5e45549e4f8fced47 100644 (file)
@@ -157,7 +157,7 @@ void bot_lagfunc(entity this, float t, float f1, float f2, entity e1, vector v1,
                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;
index 3b9dd7c60ccd8a5b878bb9a01a5e3e2b4a91442c..b3395c671ff383bb980ba3a832860c864ce37696 100644 (file)
@@ -74,7 +74,7 @@ void bot_think(entity this)
 
        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;
        }
@@ -94,7 +94,7 @@ void bot_think(entity this)
        // (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)
 
@@ -113,7 +113,7 @@ void bot_think(entity this)
        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;
        }
@@ -121,7 +121,7 @@ void bot_think(entity this)
        // 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
index 06cf57992f5b707dc24711f2ecd166891ac183dc..f0b229bae48e151018ca143584bfef4019522a28 100644 (file)
@@ -181,7 +181,7 @@ void havocbot_ai(entity this)
                        // 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
@@ -213,7 +213,7 @@ void havocbot_keyboard_movement(entity this, vector destorg)
                                        + 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;
@@ -265,8 +265,8 @@ void havocbot_keyboard_movement(entity this, vector destorg)
 
        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)
@@ -402,12 +402,12 @@ 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;
 
                }
        }
@@ -448,7 +448,7 @@ void havocbot_movetogoal(entity this)
        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
@@ -492,7 +492,7 @@ void havocbot_movetogoal(entity this)
                                // 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
@@ -514,8 +514,8 @@ void havocbot_movetogoal(entity this)
                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;
        }
@@ -632,8 +632,8 @@ void havocbot_movetogoal(entity this)
                                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);
                                }
@@ -656,7 +656,7 @@ void havocbot_movetogoal(entity this)
 
                                        if(client_hasweapon(this, WEP_DEVASTATOR, weaponentity, true, false))
                                        {
-                                               this.movement_x = maxspeed;
+                                               CS(this).movement_x = maxspeed;
 
                                                if(this.rocketjumptime)
                                                {
@@ -681,7 +681,7 @@ void havocbot_movetogoal(entity this)
                {
                        // If there is no goal try to move forward
                        if(this.goalcurrent==NULL)
-                               this.movement_x = maxspeed;
+                               CS(this).movement_x = maxspeed;
                }
        }
 
@@ -697,9 +697,9 @@ void havocbot_movetogoal(entity this)
                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
@@ -927,9 +927,9 @@ void havocbot_movetogoal(entity this)
        //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)
@@ -1217,10 +1217,10 @@ void havocbot_aim(entity this)
                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)
index 7ba7defbac08c66d6b91869f590263e4fa584da8..9dca0af07637ce9f44d1fbd194115a0a88581cf3 100644 (file)
@@ -485,7 +485,7 @@ float bot_cmd_cc(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;
 }
 
@@ -836,7 +836,7 @@ const int BOT_CMD_KEY_CHAT          = BIT(10);
 
 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;
@@ -849,14 +849,14 @@ bool bot_presskeys(entity this)
                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;
@@ -1008,7 +1008,7 @@ float bot_cmd_pause(entity this)
        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);
index ded5e8409885efa1500d13237e5b2b2921bdab45..6d78e160cf1624b9a43cd5339f710e69b3c00f2d 100644 (file)
@@ -780,21 +780,21 @@ float Drag(entity this, float force_allow_pick, float ischeat)
                        {
                                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);
                                        }
index 381373ad2bcb713d93ccc4046efa6ac2341c14ed..abb5693a340481980f363730e2af91eb7f4b59ed 100644 (file)
@@ -110,9 +110,9 @@ bool ClientData_Send(entity this, entity to, int sf)
        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);
@@ -120,7 +120,7 @@ bool ClientData_Send(entity this, entity to, int sf)
 
        if (sf & 2)
        {
-               WriteByte(MSG_ENTITY, to.spectatee_status);
+               WriteByte(MSG_ENTITY, CS(to).spectatee_status);
        }
 
        if(sf & 16)
@@ -154,8 +154,6 @@ void ClientData_Touch(entity e)
        FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != e && IS_SPEC(it) && it.enemy == e, LAMBDA(it.clientdata.SendFlags = 1));
 }
 
-.string netname_previous;
-
 void SetSpectatee(entity this, entity spectatee);
 void SetSpectatee_status(entity this, int spectatee_num);
 
@@ -227,12 +225,10 @@ void PutObserverInServer(entity this)
     {
         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;
@@ -276,22 +272,22 @@ void PutObserverInServer(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;
@@ -338,7 +334,6 @@ void PutObserverInServer(entity this)
 
        this.items = 0;
        this.weapons = '0 0 0';
-       this.dual_weapons = '0 0 0';
        this.drawonlytoclient = this;
 
        this.weaponmodel = "";
@@ -347,7 +342,7 @@ void PutObserverInServer(entity this)
                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';
@@ -488,253 +483,257 @@ void FixPlayermodel(entity player)
                                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;
+       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;
+       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;
 
-               antilag_clear(this, CS(this));
+       MUTATOR_CALLHOOK(PutClientInServer, this);
+
+       if (IS_OBSERVER(this)) {
+               PutObserverInServer(this);
+       } else if (IS_PLAYER(this)) {
+               PutPlayerInServer(this);
        }
 }
 
@@ -773,6 +772,7 @@ void ClientInit_misc(entity 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);
 }
@@ -785,6 +785,11 @@ void ClientInit_CheckUpdate(entity this)
                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()
@@ -817,7 +822,7 @@ SetChangeParms
 void SetChangeParms (entity this)
 {
        // save parms for level change
-       parm1 = this.parm_idlesince - time;
+       parm1 = CS(this).parm_idlesince - time;
 
        MUTATOR_CALLHOOK(SetChangeParms);
 }
@@ -830,12 +835,12 @@ DecodeLevelParms
 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);
 }
@@ -851,19 +856,19 @@ Called when a client types 'kill' in the console
 .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)
@@ -871,7 +876,7 @@ 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');
@@ -883,7 +888,7 @@ void ClientKill_Now(entity this)
 
        this.killindicator = NULL;
 
-       if(this.killindicator_teamchange)
+       if(CS(this).killindicator_teamchange)
                ClientKill_Now_TeamChange(this);
 
        if(!IS_SPEC(this) && !IS_OBSERVER(this))
@@ -946,7 +951,7 @@ void ClientKill_TeamChange (entity this, float targetteam) // 0 = don't change,
        return;
     killtime = M_ARGV(1, float);
 
-       this.killindicator_teamchange = targetteam;
+       CS(this).killindicator_teamchange = targetteam;
 
     if(!this.killindicator)
        {
@@ -1049,25 +1054,41 @@ void FixClientCvars(entity e)
        MUTATOR_CALLHOOK(FixClientCvars, e);
 }
 
-float PlayerInIDList(entity p, string idlist)
+bool findinlist_abbrev(string tofind, string list)
+{
+       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)
 {
-       float n, i;
-       string s;
+       // 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
@@ -1108,8 +1129,8 @@ void ClientConnect(entity this)
 #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)
@@ -1126,10 +1147,10 @@ void ClientConnect(entity this)
                        }
                }
        }
-       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;
@@ -1172,9 +1193,9 @@ void ClientConnect(entity this)
 
        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);
@@ -1207,14 +1228,14 @@ void ClientConnect(entity this)
 
        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))
        {
@@ -1237,9 +1258,7 @@ void ClientConnect(entity 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);
@@ -1251,7 +1270,7 @@ void ClientConnect(entity 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));
                }
        }
@@ -1271,7 +1290,7 @@ void ClientDisconnect(entity 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)
@@ -1284,6 +1303,7 @@ void ClientDisconnect(entity this)
 
     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);
@@ -1303,7 +1323,6 @@ void ClientDisconnect(entity 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);
@@ -1330,7 +1349,7 @@ void ChatBubbleThink(entity this)
 
        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";
@@ -1644,9 +1663,9 @@ void player_regen(entity this)
 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;
@@ -1656,16 +1675,16 @@ void GetPressedKeys(entity this)
 {
        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;
 }
@@ -1694,7 +1713,7 @@ void SpectateCopy(entity this, entity spectatee)
        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;
@@ -1703,7 +1722,6 @@ void SpectateCopy(entity this, entity spectatee)
        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.hagar_load = spectatee.hagar_load;
@@ -1724,7 +1742,7 @@ void SpectateCopy(entity this, entity spectatee)
                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)
        {
@@ -1804,10 +1822,10 @@ bool SpectateSet(entity this)
 
 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();
@@ -2025,7 +2043,7 @@ void checkSpectatorBlock(entity this)
        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);
                }
@@ -2034,46 +2052,46 @@ void checkSpectatorBlock(entity 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);
                }
        }
@@ -2081,7 +2099,7 @@ void PrintWelcomeMessage(entity this)
 
 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;
@@ -2089,19 +2107,202 @@ bool joinAllowed(entity this)
        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);
@@ -2125,15 +2326,15 @@ void ObserverThink(entity 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;
                }
        }
@@ -2142,7 +2343,7 @@ void SpectatorThink(entity this)
                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);
@@ -2150,8 +2351,8 @@ void SpectatorThink(entity 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);
@@ -2159,7 +2360,7 @@ void SpectatorThink(entity 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);
@@ -2242,20 +2443,11 @@ PlayerPreThink
 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);
@@ -2274,17 +2466,17 @@ void PlayerPreThink (entity 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) {
@@ -2307,29 +2499,32 @@ void PlayerPreThink (entity this)
                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);
@@ -2358,195 +2553,17 @@ void PlayerPreThink (entity 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 (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)
@@ -2573,19 +2590,19 @@ void PlayerPreThink (entity this)
                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);
        }
 
@@ -2632,12 +2649,12 @@ void Player_Physics(entity this)
        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;
 }
 
 /*
@@ -2647,7 +2664,6 @@ PlayerPostThink
 Called every frame for each client after the physics are run
 =============
 */
-.float idlekick_lasttimeleft;
 void PlayerPostThink (entity this)
 {
        Player_Physics(this);
@@ -2668,19 +2684,19 @@ void PlayerPostThink (entity 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) {
@@ -2689,17 +2705,16 @@ void PlayerPostThink (entity this)
                                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;
@@ -2709,9 +2724,8 @@ void PlayerPostThink (entity this)
 
        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);
@@ -2729,3 +2743,43 @@ void PlayerPostThink (entity 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;
+}
index 37e5eeb94d59bf8f8b7d05b184cb9de84298af15..32fa2f0f30c06275fd25205be487e7cee4ae17b8 100644 (file)
@@ -29,10 +29,73 @@ CLASS(Client, Object)
     /** 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);
+
     METHOD(Client, m_unwind, bool(Client this));
 
     STATIC_METHOD(Client, Add, void(Client this, int _team));
@@ -72,6 +135,12 @@ CLASS(Spectator, Client)
 ENDCLASS(Spectator)
 
 CLASS(Player, Client)
+    
+    // custom
+
+    ATTRIB(Player, dual_weapons, vector, this.dual_weapons); // TODO: actually WepSet!
+    ATTRIB(Player, itemkeys, int, this.itemkeys);
+
     INIT(Player) {
         this.classname = STR_PLAYER;
         IL_PUSH(g_players, this);
index 8a35bec2925c2f89658dfe7145308e56dabb0c2a..fa1be75112914be996dde63c5499328c79bab773 100644 (file)
@@ -1,4 +1,5 @@
 #include "banning.qh"
+#include <common/state.qh>
 #include <common/command/_mod.qh>
 #include "banning.qh"
 
@@ -131,7 +132,7 @@ void BanCommand_mute(float request, float argc, string command)  // TODO: Add a
 
                                if (accepted > 0)
                                {
-                                       client.muted = true;
+                                       CS(client).muted = true;
                                        return;
                                }
                                else
@@ -212,7 +213,7 @@ void BanCommand_unmute(float request, float argc)
 
                                if (accepted > 0)
                                {
-                                       client.muted = false;
+                                       CS(client).muted = false;
                                        return;
                                }
                                else
index da9fd8621f171b34aed6ab9ca144b3e0a563fa37..6d7ee81af4ddc7807696a6085ebe11073ebba5c3 100644 (file)
@@ -101,11 +101,11 @@ void ClientCommand_clientversion(entity caller, float request, float argc)  // i
                        {
                                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)
index 9f3a200dac51a17e0e8af00956644b5d5fdd42fd..84366ea6b27b72b9f65e6fc5c6bab97090465e48 100644 (file)
@@ -721,7 +721,7 @@ void CommonCommand_timeout(float request, entity caller)  // DEAR GOD THIS COMMA
                                {
                                        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.");
                                }
@@ -736,9 +736,9 @@ void CommonCommand_timeout(float request, entity caller)  // DEAR GOD THIS COMMA
 
                                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;
@@ -806,9 +806,9 @@ void CommonCommand_who(float request, entity caller, float argc)
                                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));
 
index 92bb25bec635fca06ea55f18fe9f4b8cb65e22e1..9a82a162a14387fd8be0c3cf562576f143bfca3b 100644 (file)
@@ -1144,7 +1144,7 @@ void GameCommand_nospectators(float request)
                        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);
                                }
                        ));
index bc75fd1453e821751dea4feedb6009c3026cdbbd..5f96334ddfd3141ff0208fbd6bb343f5f2e6724d 100644 (file)
@@ -382,11 +382,11 @@ void reset_map(bool dorespawn)
                                        */
                                        // 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);
                                });
                        }
@@ -424,7 +424,7 @@ void ReadyRestart_force()
        // 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));
        ));
 
@@ -456,7 +456,7 @@ void ReadyRestart_force()
        // 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);
index a6ca911bdc64fe4d5cbe29ae4d8bb149348b349e..a18e54d2abf6574933d362d361eb0c68d8855ad6 100644 (file)
@@ -53,7 +53,6 @@ float server_is_dedicated;
 .float count;
 //.float cnt2;
 
-.float play_time;
 .int respawn_flags;
 .float respawn_time;
 .float respawn_time_max;
@@ -131,8 +130,6 @@ float intermission_running;
 float intermission_exittime;
 float alreadychangedlevel;
 
-.float version;
-
 // footstep interval
 .float nextstep;
 
@@ -179,8 +176,6 @@ float default_weapon_alpha;
 .float cvar_cl_allow_uidtracking;
 .string stored_netname;
 
-.float version_nagtime;
-
 string gamemode_name;
 
 float startitem_failed;
@@ -191,7 +186,7 @@ void FixIntermissionClient(entity e);
 void FixClientCvars(entity e);
 
 // WEAPONTODO: remove this
-WepSet weaponsInMap;
+//WepSet weaponsInMap;
 
 #define weapons _STAT(WEAPONS)
 
@@ -226,13 +221,11 @@ int have_team_spawns_forteams; // if Xth bit is 1 then team X has spawns else it
 
 // 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;
@@ -247,8 +240,6 @@ float next_pingtime;
 .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)
@@ -265,8 +256,8 @@ string cvar_changes;
 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);
 
@@ -298,8 +289,6 @@ float servertime, serverprevtime, serverframetime;
 
 .float ammo_fuel;
 
-.vector prevorigin;
-
 //flood fields
 .float nickspamtime; // time of last nick change
 .float nickspamcount;
index 4f428ab1b84defe579d00ae8f5afe84f36f91fa7..83911eeafec9aa0b5d16120444a74b465acefbb8 100644 (file)
@@ -273,8 +273,8 @@ bool frag_centermessage_override(entity attacker, entity targ, int deathtype, in
 {
        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;
        }
 
@@ -326,19 +326,19 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                                {
                                        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;
@@ -358,11 +358,11 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                        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...
@@ -372,8 +372,8 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                        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;
 
@@ -384,7 +384,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                                        PS_GR_P_ADDVAL(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
                                        break; \
                                }
-                       switch(attacker.killcount)
+                       switch(CS(attacker).killcount)
                        {
                                KILL_SPREE_LIST
                                default: break;
@@ -404,7 +404,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                        }
                        else
                        {
-                               kill_count_to_attacker = attacker.killcount;
+                               kill_count_to_attacker = CS(attacker).killcount;
                                kill_count_to_target = 0;
                        }
 
@@ -417,7 +417,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                                        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,
@@ -428,7 +428,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                                        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))
@@ -440,7 +440,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                                        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,
@@ -451,7 +451,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                                        kill_count_to_target,
                                        attacker.health,
                                        attacker.armorvalue,
-                                       (IS_BOT_CLIENT(attacker) ? -1 : attacker.ping)
+                                       (IS_BOT_CLIENT(attacker) ? -1 : CS(attacker).ping)
                                );
                        }
 
@@ -459,8 +459,8 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                        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);
                }
        }
 
@@ -480,7 +480,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                                        targ.netname,
                                        inflictor.message,
                                        deathlocation,
-                                       targ.killcount,
+                                       CS(targ).killcount,
                                        0,
                                        0);
                                break;
@@ -492,7 +492,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                                        targ.netname,
                                        ((strstrofs(deathmessage, "%", 0) < 0) ? strcat("%s ", deathmessage) : deathmessage),
                                        deathlocation,
-                                       targ.killcount,
+                                       CS(targ).killcount,
                                        0,
                                        0);
                                break;
@@ -500,7 +500,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
 
                        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;
                        }
                }
@@ -516,7 +516,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
        }
 
        // reset target kill count
-       if(targ.killcount) { targ.killcount = 0; }
+       CS(targ).killcount = 0;
 }
 
 void Ice_Think(entity this)
@@ -622,7 +622,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
        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;
@@ -785,7 +785,6 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
                                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);
                        }
@@ -854,18 +853,18 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
                                                }
                                        }
                                }
-                               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;
                                                }
                                }
                        }
index 5ad783bbf0f2e157307dfdd1933cf520937374a4..e2532a9d5b62e536368711fac015ac7f50589f95 100644 (file)
@@ -57,14 +57,14 @@ void PingPLReport_Think(entity this)
        {
                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))
                {
-                       e.latency_sum += e.ping;
+                       e.latency_sum += CS(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");
@@ -1459,7 +1459,7 @@ void DumpStats(float final)
 
        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
@@ -1596,25 +1596,6 @@ void NextLevel()
        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()
 {
index e408974bbe04d3b295b2329c912815b89cb4c1f2..4d5401abdf888e5afaf05ec22a286410ee47ce3d 100644 (file)
@@ -15,7 +15,6 @@ void SetLimits(int fraglimit_override, int leadlimit_override, float timelimit_o
 
 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();
index efa0f8425b86cb89413b834e6fcfeadbbbbfbf2c..f528f07b4eb32c9537c798ce6afc727cc6c955c4 100644 (file)
@@ -352,9 +352,9 @@ void ImpulseCommands(entity this)
 {
        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;
 
index d33fe87c2e1a477189000119b501b52c6f69c88e..c645c7facdce7515e3021c441bb586fdbfd1375a 100644 (file)
@@ -17,10 +17,10 @@ TODO:
 
 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
@@ -74,10 +74,10 @@ void item_key_touch(entity this, entity toucher)
                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);
index 638b40f65e52f18580b46c5ab890e2e3a4fc118b..d22073ef6c5d02e25e50263a0ac643c085372aee 100644 (file)
@@ -7,6 +7,7 @@
 #include <common/net_linked.qh>
 #include "../common/mapinfo.qh"
 #include "../common/playerstats.qh"
+#include <common/state.qh>
 #include "../common/util.qh"
 
 
@@ -599,7 +600,7 @@ void MapVote_Tick()
                if(it.health != 2342)
                {
                        it.health = 2342;
-                       it.impulse = 0;
+                       CS(it).impulse = 0;
 
                        msg_entity = it;
                        WriteByte(MSG_ONE, SVC_FINALE);
@@ -610,13 +611,13 @@ void MapVote_Tick()
                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;
index 24f16c487678c3c032ab1ab9ff5dfea0178716b0..578445e815a238c40ecbd0f591b62323eeb8334a 100644 (file)
@@ -33,7 +33,7 @@
 
 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)
@@ -60,7 +60,7 @@ 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));
 }
 
 
index fc06e50e29d73501a0e29d1c35d082325064fec3..e46b22de22c8f2c8536bfcf423d9b75a9c625794 100644 (file)
@@ -188,7 +188,7 @@ MUTATOR_HOOKFUNCTION(ca, PutClientInServer)
        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);
@@ -199,7 +199,7 @@ MUTATOR_HOOKFUNCTION(ca, PutClientInServer)
 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;
@@ -289,7 +289,7 @@ MUTATOR_HOOKFUNCTION(ca, MakePlayerObserver)
 
        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;
index 595671882b496d0980f500e1e9008847de4cf923..253a07e722275646c5bdcb603a277b3018646921 100644 (file)
@@ -994,7 +994,7 @@ void ctf_FlagThink(entity this)
                                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)
index ee8c221e5b9184fdbfab1ad2c38f5acd80a36cb3..8e7512eb6965d42a7e7e4b88bea02bfcd690189d 100644 (file)
@@ -98,8 +98,8 @@ MUTATOR_HOOKFUNCTION(cts, PlayerPhysics)
        // 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;
@@ -107,32 +107,32 @@ MUTATOR_HOOKFUNCTION(cts, PlayerPhysics)
                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;
                }
        }
 }
@@ -238,7 +238,7 @@ MUTATOR_HOOKFUNCTION(cts, PutClientInServer)
        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);
index 1d6e1c1ff63129fdad35064ea91021e2b4534af0..811614c21b9d5771f89b91db197f0742a8de7c27 100644 (file)
@@ -417,7 +417,7 @@ MUTATOR_HOOKFUNCTION(ft, PlayerSpawn)
 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;
@@ -568,8 +568,8 @@ MUTATOR_HOOKFUNCTION(ft, FragCenterMessage)
        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;
 }
index c3c24559e34bc76e112a3c001383df57f7e54407..fbe6b0c1da9c5d60e3703522c3c73157aa84d834 100644 (file)
@@ -212,7 +212,7 @@ void lms_RemovePlayer(entity player)
                        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
index c4c8f087e495d388dfc360ca3cc895724894b771..b1759fb6a62c2b2daafa47aed9532838ddd5d4bd 100644 (file)
@@ -73,7 +73,7 @@ float WinningCondition_Race(float fraglimit)
        c = 0;
        FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(
                ++n;
-               if(it.race_completed)
+               if(CS(it).race_completed)
                        ++c;
        ));
        if(n && (n == c))
@@ -150,8 +150,8 @@ MUTATOR_HOOKFUNCTION(rc, PlayerPhysics)
        // 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;
@@ -159,32 +159,32 @@ MUTATOR_HOOKFUNCTION(rc, PlayerPhysics)
                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;
                }
        }
 }
@@ -283,7 +283,7 @@ MUTATOR_HOOKFUNCTION(rc, PutClientInServer)
        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);
index 0ca9cb8491d3084d309b3a5d92be39303c8448f8..e34826cabcad0966b03af6d1b58a2a4774a343c2 100644 (file)
@@ -111,7 +111,6 @@ void CopyBody(entity this, float keepvelocity)
        //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;
 
@@ -536,7 +535,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                {
                        delete(this.killindicator);
                        this.killindicator = NULL;
-                       if(this.killindicator_teamchange)
+                       if(CS(this).killindicator_teamchange)
                                defer_ClientKill_Now_TeamChange = true;
 
                        if(this.classname == "body")
@@ -744,7 +743,8 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc
        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))
@@ -837,7 +837,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc
        // FLOOD CONTROL
        int flood = 0;
        var .float flood_field = floodcontrol_chat;
-       if(floodcontrol)
+       if(floodcontrol && source)
        {
                float flood_spl;
                float flood_burst;
@@ -944,7 +944,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc
                sourcemsgstr = strcat(privatemsgprefix, substring(sourcemsgstr, privatemsgprefixlen, -1));
 
     int ret;
-       if(source.muted)
+       if(source && CS(source).muted)
        {
                // always fake the message
                ret = -1;
@@ -993,11 +993,11 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc
                                        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
                {
index b9a5fa928835208119144e2d7749149c7685af4e..1834bb865ffbb668801e525eb40b7e90f5afa341 100644 (file)
@@ -73,6 +73,4 @@ void MoveToTeam(entity client, float team_colour, float type);
 
 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);
index 34c886fa10ebc67029ab433831117ccecb1e2fcb..e337e9be478c8112ced3a6bbc55aae446a9dbd0c 100644 (file)
@@ -4,6 +4,7 @@
 #elif defined(SVQC)
     #include "defs.qh"
     #include "playerdemo.qh"
+       #include <common/state.qh>
 #endif
 
 .float playerdemo_fh;
@@ -60,11 +61,11 @@ void playerdemo_open_write(entity this, string f)
        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
 
@@ -160,6 +161,10 @@ float playerdemo_read(entity this)
                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;
 }
index 80023e76ada42a67139ba3aeeaa1644aeda14db5..03c4fa828c9e2732b61c0d301516878fd2f446ab 100644 (file)
@@ -10,6 +10,7 @@
 #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"
@@ -165,6 +166,7 @@ void race_SendNextCheckpoint(entity e, float spec) // qualifying only
 
        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 = "";
@@ -172,7 +174,7 @@ void race_SendNextCheckpoint(entity e, float spec) // qualifying only
        if(!IS_REAL_CLIENT(e))
                return;
 
-       if(!spec && !e.cvar_cl_race_cptimes_onlyself) // don't show spectators the player's personal time
+       if(!spec)
                msg_entity = e;
        WRITESPECTATABLE_MSG_ONE(msg_entity, {
                WriteHeader(MSG_ONE, TE_CSQC_RACE);
@@ -186,20 +188,10 @@ void race_SendNextCheckpoint(entity e, float spec) // qualifying only
                        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(!spec && e.cvar_cl_race_cptimes_onlyself) // don't send to spectators!
-       {
-               recordtime = e.race_checkpoint_record[cp];
-
-               // not spectatable
-               msg_entity = e;
-               WriteHeader(MSG_ONE, TE_CSQC_RACE);
-               WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_NEXT_SELF_QUALIFYING);
-               WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player will be at next
-               WriteInt24_t(MSG_ONE, recordtime);
-       }
 }
 
 void race_send_recordtime(float msg)
@@ -387,7 +379,7 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
 
        if(tvalid)
        if(cp == race_timed_checkpoint) // finish line
-       if (!e.race_completed)
+       if (!CS(e).race_completed)
        {
                float s;
                if(g_race_qualifying)
@@ -413,7 +405,7 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
 
                        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);
@@ -424,13 +416,12 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
        if(g_race_qualifying)
        {
                float recordtime;
-               float myrecordtime;
                string recordholder;
 
                if(tvalid)
                {
                        recordtime = race_checkpoint_records[cp];
-                       myrecordtime = e.race_checkpoint_record[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 = "";
@@ -442,6 +433,9 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                                        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;
@@ -452,8 +446,6 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                                                FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it.race_checkpoint == cp, LAMBDA(race_SendNextCheckpoint(it, 0)));
                                }
 
-                               if(t < myrecordtime || myrecordtime == 0)
-                                       e.race_checkpoint_record[cp] = t; // resending done below
                        }
                }
                else
@@ -461,35 +453,27 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                        // dummies
                        t = 0;
                        recordtime = 0;
-                       myrecordtime = 0;
                        recordholder = "";
                }
 
                if(IS_REAL_CLIENT(e))
                {
-                       msg_entity = e;
                        if(g_race_qualifying)
                        {
-                               WRITESPECTATABLE_MSG_ONE(e, {
-                                       if(it == e && e.cvar_cl_race_cptimes_onlyself)
-                                               continue;
-                                       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
-                               });
-
-                               if(e.cvar_cl_race_cptimes_onlyself)
+                               FOREACH_CLIENT(IS_REAL_CLIENT(it),
                                {
-                                       msg_entity = e;
-                                       WriteHeader(MSG_ONE, TE_CSQC_RACE);
-                                       WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_SELF_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, myrecordtime); // previously best time
-                               }
+                                       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
+                                       }
+                               });
                        }
                }
        }
@@ -1047,9 +1031,9 @@ spawnfunc(target_stopTimer) { spawnfunc_target_checkpoint(this); }
 
 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);
@@ -1094,14 +1078,12 @@ spawnfunc(info_player_race)
 
 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(
@@ -1189,7 +1171,7 @@ float race_GetFractionalLapCount(entity e)
 
        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;
index 7f6a194f291748213ba4e91e46124d15ce488168..472827efa4a81d13a014ae84d998f1b88d62628f 100644 (file)
@@ -66,7 +66,3 @@ void race_SendRankings(float pos, float prevpos, float del, float msg);
 void race_RetractPlayer(entity this);
 
 void race_InitSpectator();
-
-.bool cvar_cl_race_cptimes_onlyself;
-
-REPLICATE(cvar_cl_race_cptimes_onlyself, bool, "cl_race_cptimes_onlyself");
index d8bf72cd6b2a87bc27cc3700053716840c3bd8b3..d991794b75b69e9107c48577fe89602821a291bd 100644 (file)
@@ -87,8 +87,8 @@ void InitGameplayMode()
 
 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 {
@@ -351,7 +351,7 @@ void GetTeamCounts(entity ignore)
                                        cb1 = cb1 + bvalue;
                                }
                        }
-                       if(t == NUM_TEAM_2)
+                       else if(t == NUM_TEAM_2)
                        {
                                if(c2 >= 0)
                                {
@@ -359,7 +359,7 @@ void GetTeamCounts(entity ignore)
                                        cb2 = cb2 + bvalue;
                                }
                        }
-                       if(t == NUM_TEAM_3)
+                       else if(t == NUM_TEAM_3)
                        {
                                if(c3 >= 0)
                                {
@@ -367,7 +367,7 @@ void GetTeamCounts(entity ignore)
                                        cb3 = cb3 + bvalue;
                                }
                        }
-                       if(t == NUM_TEAM_4)
+                       else if(t == NUM_TEAM_4)
                        {
                                if(c4 >= 0)
                                {
index 895c65ae29b0ab7def236c753c9fce930c3288b4..17ba0dc9dfafb4f1063e0f20f14b292f11856b56 100644 (file)
@@ -61,7 +61,7 @@ bool client_hasweapon(entity this, Weapon wpn, .entity weaponentity, float andam
                        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))
        {
index 8e4f88b8cd3d8c4fcf957b1a154e815a4d5158a8..4c6304a1b1b50439070afa5c43a78a71d26d5846 100644 (file)
@@ -25,9 +25,9 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect
 {
        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
@@ -60,12 +60,9 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect
                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
@@ -108,10 +105,10 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect
                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)
@@ -119,9 +116,9 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect
                                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");
                                }
@@ -351,11 +348,9 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo
        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)
index 2e4e160b3e16f1727a810cf3418a8d41b1a81b1e..cbde7d360c61544c8ea3b4d48596c11ac2330435 100644 (file)
@@ -457,7 +457,8 @@ void W_WeaponFrame(Player actor, .entity weaponentity)
                .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;
index ebb232105f51a66d03770486c0afe3950c44f7fb..8543f8c861244934b6b4af4277a80d9ad1ebeace 100755 (executable)
@@ -11,6 +11,9 @@ declare -a QCCDEFS=(
     -DNDEBUG=1
     -DXONOTIC=1
     -DWATERMARK="\"$(git describe --tags --dirty='~')\""
+    -DENABLE_EFFECTINFO=0
+    -DENABLE_DEBUGDRAW=0
+    -DENABLE_DEBUGTRACE=0
 )
 QCCDEFS="${QCCDEFS[@]}"