Merge branch 'Mario/teams_bitflag' into 'master'
authorMario <zacjardine@y7mail.com>
Thu, 28 Jul 2016 15:02:30 +0000 (15:02 +0000)
committerMario <zacjardine@y7mail.com>
Thu, 28 Jul 2016 15:02:30 +0000 (15:02 +0000)
Merge branch Mario/teams_bitflag (M merge request)

Adds support for odd team matches, such as pink vs blue and yellow vs red.

See merge request !335

231 files changed:
.gitlab-ci.yml
bal-wep-mario.cfg
bal-wep-nexuiz25.cfg
bal-wep-overkill.cfg
bal-wep-samual.cfg
bal-wep-xdf.cfg
bal-wep-xonotic.cfg
bal-wep-xpm.cfg
balance-mario.cfg
balance-nexuiz25.cfg
balance-overkill.cfg
balance-samual.cfg
balance-xdf.cfg
balance-xonotic.cfg
balance-xpm.cfg
defaultXonotic.cfg
gfx/hud/default/flag_stalemate.tga [new file with mode: 0644]
gfx/hud/luma/flag_blue_lost.tga
gfx/hud/luma/flag_neutral_lost.tga
gfx/hud/luma/flag_pink_lost.tga
gfx/hud/luma/flag_red_lost.tga
gfx/hud/luma/flag_stalemate.tga [new file with mode: 0644]
gfx/hud/luma/flag_yellow_lost.tga
gfx/hud/luma/notify_blue_lost.tga
gfx/hud/luma/notify_neutral_lost.tga
gfx/hud/luma/notify_pink_lost.tga
gfx/hud/luma/notify_red_lost.tga
gfx/hud/luma/notify_yellow_lost.tga
models/weapons/g_ok_hmg_luma.iqm [new file with mode: 0644]
models/weapons/g_ok_hmg_luma.iqm_0.skin [new file with mode: 0644]
models/weapons/g_ok_hmg_luma.tga [new file with mode: 0644]
models/weapons/g_ok_hmg_simple.iqm [new file with mode: 0644]
models/weapons/g_ok_hmg_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_ok_hmg_simple.tga [new file with mode: 0644]
models/weapons/g_ok_rl_luma.iqm [new file with mode: 0644]
models/weapons/g_ok_rl_luma.iqm_0.skin [new file with mode: 0644]
models/weapons/g_ok_rl_luma.tga [new file with mode: 0644]
models/weapons/g_ok_rl_simple.iqm [new file with mode: 0644]
models/weapons/g_ok_rl_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_ok_rl_simple.tga [new file with mode: 0644]
notifications.cfg
qcsrc/client/commands/cl_cmd.qc
qcsrc/client/csqc_constants.qh
qcsrc/client/hud/panel/infomessages.qc
qcsrc/client/hud/panel/modicons.qc
qcsrc/client/hud/panel/radar.qc
qcsrc/client/main.qc
qcsrc/client/main.qh
qcsrc/client/teamradar.qc
qcsrc/client/view.qc
qcsrc/client/wall.qc
qcsrc/client/weapons/projectile.qc
qcsrc/common/csqcmodel_settings.qh
qcsrc/common/debug.qh
qcsrc/common/effects/qc/casings.qc
qcsrc/common/effects/qc/damageeffects.qc
qcsrc/common/effects/qc/gibs.qc
qcsrc/common/effects/qc/globalsound.qc
qcsrc/common/effects/qc/globalsound.qh
qcsrc/common/effects/qc/modeleffects.qc
qcsrc/common/effects/qc/rubble.qh
qcsrc/common/gamemodes/gamemode/nexball/nexball.qc
qcsrc/common/gamemodes/gamemode/onslaught/cl_controlpoint.qc
qcsrc/common/gamemodes/gamemode/onslaught/cl_generator.qc
qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc
qcsrc/common/items/item/pickup.qh
qcsrc/common/minigames/cl_minigames.qc
qcsrc/common/minigames/sv_minigames.qc
qcsrc/common/models/model.qh
qcsrc/common/monsters/monster/mage.qc
qcsrc/common/monsters/monster/shambler.qc
qcsrc/common/monsters/monster/spider.qc
qcsrc/common/monsters/monster/wyvern.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/mutators/mutator/buffs/buffs.qc
qcsrc/common/mutators/mutator/bugrigs/bugrigs.qc
qcsrc/common/mutators/mutator/damagetext/damagetext.qc
qcsrc/common/mutators/mutator/dodging/dodging.qc
qcsrc/common/mutators/mutator/itemstime.qc
qcsrc/common/mutators/mutator/nades/nades.qc
qcsrc/common/mutators/mutator/nades/net.qc
qcsrc/common/mutators/mutator/new_toys/new_toys.qc
qcsrc/common/mutators/mutator/overkill/hmg.qc
qcsrc/common/mutators/mutator/overkill/overkill.qc
qcsrc/common/mutators/mutator/overkill/rpc.qc
qcsrc/common/mutators/mutator/physical_items/physical_items.qc
qcsrc/common/mutators/mutator/sandbox/sandbox.qc
qcsrc/common/mutators/mutator/waypoints/all.inc
qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc
qcsrc/common/mutators/mutator/waypoints/waypointsprites.qh
qcsrc/common/notifications/all.inc
qcsrc/common/physics/movetypes/_mod.inc
qcsrc/common/physics/movetypes/_mod.qh
qcsrc/common/physics/movetypes/all.inc
qcsrc/common/physics/movetypes/follow.qc
qcsrc/common/physics/movetypes/movetypes.qc
qcsrc/common/physics/movetypes/movetypes.qh
qcsrc/common/physics/movetypes/push.qc [deleted file]
qcsrc/common/physics/movetypes/step.qc
qcsrc/common/physics/movetypes/toss.qc
qcsrc/common/physics/movetypes/walk.qc
qcsrc/common/physics/player.qc
qcsrc/common/physics/player.qh
qcsrc/common/sounds/sound.qh
qcsrc/common/state.qc
qcsrc/common/stats.qh
qcsrc/common/t_items.qc
qcsrc/common/triggers/func/breakable.qc
qcsrc/common/triggers/func/conveyor.qc
qcsrc/common/triggers/func/door.qc
qcsrc/common/triggers/func/plat.qc
qcsrc/common/triggers/func/pointparticles.qc
qcsrc/common/triggers/func/rainsnow.qc
qcsrc/common/triggers/func/train.qc
qcsrc/common/triggers/misc/follow.qc
qcsrc/common/triggers/misc/laser.qc
qcsrc/common/triggers/platforms.qc
qcsrc/common/triggers/subs.qc
qcsrc/common/triggers/subs.qh
qcsrc/common/triggers/teleporters.qc
qcsrc/common/triggers/trigger/impulse.qc
qcsrc/common/triggers/trigger/jumppads.qc
qcsrc/common/triggers/trigger/teleport.qc
qcsrc/common/turrets/cl_turrets.qc
qcsrc/common/turrets/sv_turrets.qc
qcsrc/common/turrets/turret/ewheel.qc
qcsrc/common/turrets/turret/hk_weapon.qc
qcsrc/common/turrets/turret/phaser_weapon.qc
qcsrc/common/turrets/turret/tesla_weapon.qc
qcsrc/common/turrets/turret/walker.qc
qcsrc/common/turrets/util.qc
qcsrc/common/vehicles/cl_vehicles.qc
qcsrc/common/vehicles/sv_vehicles.qc
qcsrc/common/vehicles/vehicle/bumblebee.qc
qcsrc/common/vehicles/vehicle/bumblebee_weapons.qc
qcsrc/common/vehicles/vehicle/racer.qc
qcsrc/common/vehicles/vehicle/raptor.qc
qcsrc/common/vehicles/vehicle/raptor_weapons.qc
qcsrc/common/vehicles/vehicle/spiderbot.qc
qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc
qcsrc/common/weapons/all.qh
qcsrc/common/weapons/weapon.qh
qcsrc/common/weapons/weapon/arc.qc
qcsrc/common/weapons/weapon/blaster.qc
qcsrc/common/weapons/weapon/crylink.qc
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/electro.qc
qcsrc/common/weapons/weapon/fireball.qc
qcsrc/common/weapons/weapon/hagar.qc
qcsrc/common/weapons/weapon/hlac.qc
qcsrc/common/weapons/weapon/hook.qc
qcsrc/common/weapons/weapon/machinegun.qc
qcsrc/common/weapons/weapon/minelayer.qc
qcsrc/common/weapons/weapon/mortar.qc
qcsrc/common/weapons/weapon/porto.qc
qcsrc/common/weapons/weapon/rifle.qc
qcsrc/common/weapons/weapon/seeker.qc
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/common/weapons/weapon/shotgun.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/dpdefs/menudefs.qh
qcsrc/dpdefs/post.qh
qcsrc/dpdefs/pre.qh
qcsrc/lib/_all.inc
qcsrc/lib/counting.qh
qcsrc/lib/csqcmodel/cl_player.qc
qcsrc/lib/csqcmodel/cl_player.qh
qcsrc/lib/intrusivelist.qh [new file with mode: 0644]
qcsrc/lib/iter.qh
qcsrc/lib/log.qh
qcsrc/lib/oo.qh
qcsrc/lib/registry.qh
qcsrc/lib/self.qh
qcsrc/lib/static.qh
qcsrc/lib/stats.qh
qcsrc/lib/warpzone/client.qc
qcsrc/lib/warpzone/server.qc
qcsrc/lib/warpzone/util_server.qc
qcsrc/menu/menu.qc
qcsrc/menu/xonotic/gametypelist.qc
qcsrc/menu/xonotic/gametypelist.qh
qcsrc/menu/xonotic/serverlist.qc
qcsrc/menu/xonotic/slider_resolution.qc
qcsrc/menu/xonotic/util.qc
qcsrc/server/_all.qh
qcsrc/server/autocvars.qh
qcsrc/server/bot/aim.qc
qcsrc/server/bot/bot.qc
qcsrc/server/bot/bot.qh
qcsrc/server/bot/havocbot/havocbot.qc
qcsrc/server/bot/havocbot/roles.qc
qcsrc/server/bot/navigation.qc
qcsrc/server/bot/navigation.qh
qcsrc/server/bot/scripting.qc
qcsrc/server/bot/waypoints.qc
qcsrc/server/campaign.qc
qcsrc/server/cheats.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_impulse.qc
qcsrc/server/cl_player.qc
qcsrc/server/command/common.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_hook.qc
qcsrc/server/g_lights.qc
qcsrc/server/g_models.qc
qcsrc/server/g_subs.qc
qcsrc/server/g_world.qc
qcsrc/server/item_key.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/mutator/gamemode_assault.qc
qcsrc/server/mutators/mutator/gamemode_ctf.qc
qcsrc/server/mutators/mutator/gamemode_ctf.qh
qcsrc/server/mutators/mutator/gamemode_cts.qc
qcsrc/server/mutators/mutator/gamemode_invasion.qc
qcsrc/server/mutators/mutator/gamemode_keepaway.qc
qcsrc/server/mutators/mutator/gamemode_keyhunt.qc
qcsrc/server/mutators/mutator/gamemode_race.qc
qcsrc/server/pathlib/main.qc
qcsrc/server/pathlib/path_waypoint.qc
qcsrc/server/pathlib/pathlib.qh
qcsrc/server/playerdemo.qc
qcsrc/server/steerlib.qc
qcsrc/server/sv_main.qc
qcsrc/server/sys-post.qh
qcsrc/server/sys-pre.qh
qcsrc/server/weapons/csqcprojectile.qc
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/weaponsystem.qc
scripts/luma.shader
scripts/simpleitems.shader

index 7909c32..ce9e150 100644 (file)
@@ -24,7 +24,7 @@ test_sv_game:
     - wget -O data/maps/g-23.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.cache
     - wget -O data/maps/g-23.waypoints.hardwired https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.hardwired
     - make
-    - EXPECT=9b2513f29762de886296f998ac8725c9
+    - EXPECT=d17f62e08ff11b8b25116fa4a64f7e86
     - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
       | tee /dev/stderr
       | grep '^:'
index 9bfca55..ccaa679 100644 (file)
@@ -219,6 +219,7 @@ set g_balance_electro_secondary_speed 1000
 set g_balance_electro_secondary_speed_up 200
 set g_balance_electro_secondary_speed_z 0
 set g_balance_electro_secondary_spread 0.04
+set g_balance_electro_secondary_stick 0
 set g_balance_electro_secondary_touchexplode 0
 set g_balance_electro_switchdelay_drop 0.2
 set g_balance_electro_switchdelay_raise 0.2
index 8a47e40..d4b4759 100644 (file)
@@ -219,6 +219,7 @@ set g_balance_electro_secondary_speed 900
 set g_balance_electro_secondary_speed_up 200
 set g_balance_electro_secondary_speed_z 0
 set g_balance_electro_secondary_spread 0.04
+set g_balance_electro_secondary_stick 0
 set g_balance_electro_secondary_touchexplode 0
 set g_balance_electro_switchdelay_drop 0.15
 set g_balance_electro_switchdelay_raise 0.15
index d0cfa36..d746333 100644 (file)
@@ -219,6 +219,7 @@ set g_balance_electro_secondary_speed 1000
 set g_balance_electro_secondary_speed_up 200
 set g_balance_electro_secondary_speed_z 0
 set g_balance_electro_secondary_spread 0.04
+set g_balance_electro_secondary_stick 0
 set g_balance_electro_secondary_touchexplode 0
 set g_balance_electro_switchdelay_drop 0.2
 set g_balance_electro_switchdelay_raise 0.2
index af2234f..fe3b9ed 100644 (file)
@@ -234,6 +234,7 @@ set g_balance_electro_secondary_speed 1000
 set g_balance_electro_secondary_speed_up 200
 set g_balance_electro_secondary_speed_z 0
 set g_balance_electro_secondary_spread 0.04
+set g_balance_electro_secondary_stick 0
 set g_balance_electro_secondary_touchexplode 0
 set g_balance_electro_switchdelay_drop 0.2
 set g_balance_electro_switchdelay_raise 0.2
index 931a63c..c9bdb2a 100644 (file)
@@ -219,6 +219,7 @@ set g_balance_electro_secondary_speed 900
 set g_balance_electro_secondary_speed_up 200
 set g_balance_electro_secondary_speed_z 0
 set g_balance_electro_secondary_spread 0.05
+set g_balance_electro_secondary_stick 0
 set g_balance_electro_secondary_touchexplode 0
 set g_balance_electro_switchdelay_drop 0
 set g_balance_electro_switchdelay_raise 0
index 779c712..64d79e1 100644 (file)
@@ -219,6 +219,7 @@ set g_balance_electro_secondary_speed 1000
 set g_balance_electro_secondary_speed_up 200
 set g_balance_electro_secondary_speed_z 0
 set g_balance_electro_secondary_spread 0.04
+set g_balance_electro_secondary_stick 0
 set g_balance_electro_secondary_touchexplode 1
 set g_balance_electro_switchdelay_drop 0.2
 set g_balance_electro_switchdelay_raise 0.2
index 779c712..64d79e1 100644 (file)
@@ -219,6 +219,7 @@ set g_balance_electro_secondary_speed 1000
 set g_balance_electro_secondary_speed_up 200
 set g_balance_electro_secondary_speed_z 0
 set g_balance_electro_secondary_spread 0.04
+set g_balance_electro_secondary_stick 0
 set g_balance_electro_secondary_touchexplode 1
 set g_balance_electro_switchdelay_drop 0.2
 set g_balance_electro_switchdelay_raise 0.2
index 544ad03..9995e5e 100644 (file)
@@ -208,6 +208,7 @@ set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
 set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
 set g_jetpack_fuel 8 "fuel per second for jetpack"
 set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
 
 set g_grappling_hook_tarzan 2 // 2: can also pull players
 set g_balance_grapplehook_speed_fly 1800
index f49e50c..ebce2fa 100644 (file)
@@ -208,6 +208,7 @@ set g_jetpack_maxspeed_side 1500 "max speed of the jetpack in xy direction"
 set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
 set g_jetpack_fuel 8 "fuel per second for jetpack"
 set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
 
 set g_grappling_hook_tarzan 2 // 2: can also pull players
 set g_balance_grapplehook_speed_fly 1800
index 1a4b9bb..7571001 100644 (file)
@@ -208,6 +208,7 @@ set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
 set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
 set g_jetpack_fuel 8 "fuel per second for jetpack"
 set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
 
 set g_grappling_hook_tarzan 2 // 2: can also pull players
 set g_balance_grapplehook_speed_fly 1800
index 08e38f1..58a0f37 100644 (file)
@@ -208,6 +208,7 @@ set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
 set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
 set g_jetpack_fuel 8 "fuel per second for jetpack"
 set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
 
 set g_grappling_hook_tarzan 2 // 2: can also pull players
 set g_balance_grapplehook_speed_fly 1800
index e816f89..ff2ec18 100644 (file)
@@ -208,6 +208,7 @@ set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
 set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
 set g_jetpack_fuel 8 "fuel per second for jetpack"
 set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
 
 set g_grappling_hook_tarzan 2 // 2: can also pull players
 set g_balance_grapplehook_speed_fly 1800
index aafb810..e9fb999 100644 (file)
@@ -208,6 +208,7 @@ set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
 set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
 set g_jetpack_fuel 8 "fuel per second for jetpack"
 set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
 
 set g_grappling_hook_tarzan 2 // 2: can also pull players
 set g_balance_grapplehook_speed_fly 1800
index 342d3e0..0c24cf2 100644 (file)
@@ -208,6 +208,7 @@ set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
 set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
 set g_jetpack_fuel 8 "fuel per second for jetpack"
 set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
 
 set g_grappling_hook_tarzan 2 // 2: can also pull players
 set g_balance_grapplehook_speed_fly 1800
index 15aa706..11ba8e4 100644 (file)
@@ -360,9 +360,9 @@ set bot_ai_keyboard_threshold 0.57
 set bot_ai_aimskill_offset 0.3 "Amount of error induced to the bots aim"
 set bot_ai_aimskill_think 1 "Aiming velocity. Use values below 1 for slower aiming"
 set bot_ai_custom_weapon_priority_distances "300 850"  "Define close and far distances in any order. Based on the distance to the enemy bots will choose different weapons"
-set bot_ai_custom_weapon_priority_far   "vaporizer vortex rifle electro devastator mortar hagar hlac crylink blaster machinegun fireball seeker shotgun tuba minelayer"        "Desired weapons for far distances ordered by priority"
-set bot_ai_custom_weapon_priority_mid   "vaporizer devastator vortex fireball seeker mortar electro machinegun crylink hlac hagar shotgun blaster rifle tuba minelayer arc shockwave"  "Desired weapons for middle distances ordered by priority"
-set bot_ai_custom_weapon_priority_close "vaporizer shotgun vortex machinegun hlac tuba seeker hagar crylink mortar electro devastator blaster fireball rifle minelayer arc shockwave"  "Desired weapons for close distances ordered by priority"
+set bot_ai_custom_weapon_priority_far   "vaporizer vortex rifle electro devastator mortar hagar hlac crylink blaster machinegun fireball seeker shotgun shockwave tuba minelayer"      "Desired weapons for far distances ordered by priority"
+set bot_ai_custom_weapon_priority_mid   "vaporizer devastator vortex fireball seeker mortar electro machinegun arc crylink hlac hagar shotgun shockwave blaster rifle tuba minelayer"  "Desired weapons for middle distances ordered by priority"
+set bot_ai_custom_weapon_priority_close "vaporizer shotgun shockwave vortex machinegun arc hlac tuba seeker hagar crylink mortar electro devastator blaster fireball rifle minelayer"  "Desired weapons for close distances ordered by priority"
 set bot_ai_weapon_combo 1      "Enable bots to do weapon combos"
 set bot_ai_weapon_combo_threshold 0.4  "Try to make a combo N seconds after the last attack"
 set bot_ai_friends_aware_pickup_radius "500"   "Bots will not pickup items if a team mate is this distance near the item"
@@ -487,15 +487,15 @@ seta timelimit_suddendeath 5 "number of minutes suddendeath mode lasts after all
 set g_tdm 0 "Team Deathmatch: the team who kills their opponents most often wins"
 set g_tdm_on_dm_maps 0 "when this is set, all DM maps automatically support TDM"
 
-seta teamplay_mode 4 "default teamplay setting in team games. 1 = no friendly fire, self damage. 2 = friendly fire and self damage enabled. 3 = no friendly fire, but self damage enabled. 4 = obey the cvars g_mirrordamage*, g_friendlyfire* and g_teamdamage_threshold*"
-seta g_mirrordamage 0.700000   "for teamplay 4: mirror damage factor"
-seta g_mirrordamage_virtual 1  "for teamplay 4: do not actually apply mirror damage, just show graphics effect for it"
-seta g_mirrordamage_onlyweapons 0 "for teamplay 4: only apply mirror damage if the attack was from a weapon"
-seta g_friendlyfire 0.500000   "for teamplay 4: fiendly fire factor"
-seta g_friendlyfire_virtual 1  "for teamplay 4: do not actually apply friendly fire, just show graphics effect for it"
-seta g_friendlyfire_virtual_force 1    "for teamplay 4: apply force even though damage was made virtual only"
-seta g_teamdamage_threshold 40 "for teamplay 4: threshold over which to apply mirror damage"
-seta g_teamdamage_resetspeed 20        "for teamplay 4: how fast player's teamdamage count decreases"
+seta teamplay_mode 4 "default teamplay setting in team games. 1 = no friendly fire, self damage. 2 = friendly fire and self damage enabled. 3 = no friendly fire, but self damage enabled. 4 = obey the cvars g_mirrordamage*, g_friendlyfire* and g_teamdamage*"
+seta g_mirrordamage 0.7              "for teamplay_mode 4: mirror damage factor"
+seta g_mirrordamage_virtual 1        "for teamplay_mode 4: do not actually apply mirror damage, just show graphics effect for it"
+seta g_mirrordamage_onlyweapons 0    "for teamplay_mode 4: only apply mirror damage if the attack was from a weapon"
+seta g_friendlyfire 0.5              "for teamplay_mode 4: friendly fire factor"
+seta g_friendlyfire_virtual 1        "for teamplay_mode 4: do not actually apply friendly fire, just show graphics effect for it"
+seta g_friendlyfire_virtual_force 1  "for teamplay_mode 4: apply force even though damage was made virtual only"
+seta g_teamdamage_threshold 40       "for teamplay_mode 4: threshold over which to apply mirror damage"
+seta g_teamdamage_resetspeed 20      "for teamplay_mode 4: how fast player's teamdamage count decreases"
 
 seta g_balance_teams 1 "automatically balance out players entering instead of asking them for their preferred team"
 seta g_balance_teams_prevent_imbalance 1       "prevent players from changing to larger teams"
@@ -938,7 +938,7 @@ set con_completion_playermodel      "models/player/*.iqm"
 
 // helper
 // these non-saved engine cvars shall be saved
-alias makesaved "seta $1 \"${$1 ?}\"
+alias makesaved "seta $1 \"${$1 ?}\""
 makesaved cl_maxfps_alwayssleep
 makesaved cl_port
 makesaved gl_finish
@@ -963,8 +963,6 @@ sv_gameplayfix_delayprojectiles 0
 sv_gameplayfix_q2airaccelerate 1
 sv_gameplayfix_stepmultipletimes 1
 
-cl_gameplayfix_fixedcheckwatertransition 1
-
 // delay for "kill" to prevent abuse
 set g_balance_kill_delay 2
 set g_balance_kill_antispam 5
@@ -980,7 +978,7 @@ gl_texturecompression_lightcubemaps 1
 gl_texturecompression_q3bsplightmaps 0
 gl_texturecompression_sky 1
 
-cl_maxfps 125
+cl_maxfps 200
 
 seta menu_mouse_absolute 1 "use the OS mouse pointer motion for menu"
 seta menu_mouse_speed 1 "speed multiplier for the mouse in the menu (does not affect in-game aiming)"
@@ -1022,13 +1020,13 @@ sv_allowdownloads 0 // download protocol is evil
 
 set g_jump_grunt 0     "Do you make a grunting noise every time you jump? Is it the same grunting noise every time?"
 
-seta cl_weaponpriority "vaporizer vortex fireball mortar machinegun hagar rifle arc electro devastator crylink minelayer shotgun hlac tuba blaster porto seeker hook" "weapon priority list"
+seta cl_weaponpriority "vaporizer vortex fireball mortar machinegun hagar rifle arc electro devastator crylink minelayer shotgun shockwave hlac tuba blaster porto seeker hook" "weapon priority list"
 seta cl_weaponpriority_useforcycling 0 "when set, weapon cycling by the mouse wheel makes use of the weapon priority list (the special value 2 uses the weapon ID list for cycling)"
 seta cl_weaponpriority0 "devastator mortar hagar seeker fireball"                       "use weapon_priority_0_prev for prev gun from this list, weapon_priority_0_best for best gun, weapon_priority_0_next for next gun.  Default value: explosives"
 seta cl_weaponpriority1 "vaporizer vortex crylink hlac arc electro blaster shockwave"   "use weapon_priority_1_prev for prev gun from this list, weapon_priority_1_best for best gun, weapon_priority_1_next for next gun.  Default value: energy"
 seta cl_weaponpriority2 "vaporizer vortex rifle"                                        "use weapon_priority_2_prev for prev gun from this list, weapon_priority_2_best for best gun, weapon_priority_2_next for next gun.  Default value: hitscan exact"
-seta cl_weaponpriority3 "vaporizer vortex rifle machinegun shotgun"                     "use weapon_priority_3_prev for prev gun from this list, weapon_priority_3_best for best gun, weapon_priority_3_next for next gun.  Default value: hitscan all"
-seta cl_weaponpriority4 "mortar minelayer hlac hagar crylink seeker shotgun"            "use weapon_priority_4_prev for prev gun from this list, weapon_priority_4_best for best gun, weapon_priority_4_next for next gun.  Default value: spam weapons"
+seta cl_weaponpriority3 "vaporizer vortex rifle machinegun shotgun shockwave"                     "use weapon_priority_3_prev for prev gun from this list, weapon_priority_3_best for best gun, weapon_priority_3_next for next gun.  Default value: hitscan all"
+seta cl_weaponpriority4 "mortar minelayer hlac hagar crylink seeker shotgun shockwave"            "use weapon_priority_4_prev for prev gun from this list, weapon_priority_4_best for best gun, weapon_priority_4_next for next gun.  Default value: spam weapons"
 seta cl_weaponpriority5 "blaster shockwave hook porto"                                  "use weapon_priority_5_prev for prev gun from this list, weapon_priority_5_best for best gun, weapon_priority_5_next for next gun.  Default value: weapons for moving"
 seta cl_weaponpriority6 ""                                                              "use weapon_priority_6_prev for prev gun from this list, weapon_priority_6_best for best gun, weapon_priority_6_next for next gun"
 seta cl_weaponpriority7 ""                                                              "use weapon_priority_7_prev for prev gun from this list, weapon_priority_7_best for best gun, weapon_priority_7_next for next gun"
@@ -1297,6 +1295,8 @@ r_fakelight 1
 r_water_hideplayer 1 // hide your own feet/player model in refraction views, this way you don't see half of your body under water
 r_water_refractdistort 0.019
 
+set cl_rainsnow_maxdrawdist 2048
+
 // strength sound settings
 set sv_strengthsound_antispam_time 0.1 "minimum distance of strength sounds"
 set sv_strengthsound_antispam_refire_threshold 0.04 "apply minimum distance only if refire of the gun is smaller than this"
diff --git a/gfx/hud/default/flag_stalemate.tga b/gfx/hud/default/flag_stalemate.tga
new file mode 100644 (file)
index 0000000..c52ebb8
Binary files /dev/null and b/gfx/hud/default/flag_stalemate.tga differ
index 2c5229a..1609b78 100644 (file)
Binary files a/gfx/hud/luma/flag_blue_lost.tga and b/gfx/hud/luma/flag_blue_lost.tga differ
index e6fd5c5..85ef904 100644 (file)
Binary files a/gfx/hud/luma/flag_neutral_lost.tga and b/gfx/hud/luma/flag_neutral_lost.tga differ
index 0cd5467..f636620 100644 (file)
Binary files a/gfx/hud/luma/flag_pink_lost.tga and b/gfx/hud/luma/flag_pink_lost.tga differ
index 014a416..7260275 100644 (file)
Binary files a/gfx/hud/luma/flag_red_lost.tga and b/gfx/hud/luma/flag_red_lost.tga differ
diff --git a/gfx/hud/luma/flag_stalemate.tga b/gfx/hud/luma/flag_stalemate.tga
new file mode 100644 (file)
index 0000000..c52ebb8
Binary files /dev/null and b/gfx/hud/luma/flag_stalemate.tga differ
index bd5f3de..ec45f11 100644 (file)
Binary files a/gfx/hud/luma/flag_yellow_lost.tga and b/gfx/hud/luma/flag_yellow_lost.tga differ
index 2c5229a..1609b78 100644 (file)
Binary files a/gfx/hud/luma/notify_blue_lost.tga and b/gfx/hud/luma/notify_blue_lost.tga differ
index e6fd5c5..85ef904 100644 (file)
Binary files a/gfx/hud/luma/notify_neutral_lost.tga and b/gfx/hud/luma/notify_neutral_lost.tga differ
index 0cd5467..f636620 100644 (file)
Binary files a/gfx/hud/luma/notify_pink_lost.tga and b/gfx/hud/luma/notify_pink_lost.tga differ
index 014a416..7260275 100644 (file)
Binary files a/gfx/hud/luma/notify_red_lost.tga and b/gfx/hud/luma/notify_red_lost.tga differ
index bd5f3de..ec45f11 100644 (file)
Binary files a/gfx/hud/luma/notify_yellow_lost.tga and b/gfx/hud/luma/notify_yellow_lost.tga differ
diff --git a/models/weapons/g_ok_hmg_luma.iqm b/models/weapons/g_ok_hmg_luma.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_ok_hmg_luma.iqm differ
diff --git a/models/weapons/g_ok_hmg_luma.iqm_0.skin b/models/weapons/g_ok_hmg_luma.iqm_0.skin
new file mode 100644 (file)
index 0000000..2c77f8e
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_ok_hmg_luma
diff --git a/models/weapons/g_ok_hmg_luma.tga b/models/weapons/g_ok_hmg_luma.tga
new file mode 100644 (file)
index 0000000..5f8e135
Binary files /dev/null and b/models/weapons/g_ok_hmg_luma.tga differ
diff --git a/models/weapons/g_ok_hmg_simple.iqm b/models/weapons/g_ok_hmg_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_ok_hmg_simple.iqm differ
diff --git a/models/weapons/g_ok_hmg_simple.iqm_0.skin b/models/weapons/g_ok_hmg_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..f4316a5
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_ok_hmg_simple
\ No newline at end of file
diff --git a/models/weapons/g_ok_hmg_simple.tga b/models/weapons/g_ok_hmg_simple.tga
new file mode 100644 (file)
index 0000000..c811a59
Binary files /dev/null and b/models/weapons/g_ok_hmg_simple.tga differ
diff --git a/models/weapons/g_ok_rl_luma.iqm b/models/weapons/g_ok_rl_luma.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_ok_rl_luma.iqm differ
diff --git a/models/weapons/g_ok_rl_luma.iqm_0.skin b/models/weapons/g_ok_rl_luma.iqm_0.skin
new file mode 100644 (file)
index 0000000..502ff5b
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_ok_rl_luma
diff --git a/models/weapons/g_ok_rl_luma.tga b/models/weapons/g_ok_rl_luma.tga
new file mode 100644 (file)
index 0000000..b2471c8
Binary files /dev/null and b/models/weapons/g_ok_rl_luma.tga differ
diff --git a/models/weapons/g_ok_rl_simple.iqm b/models/weapons/g_ok_rl_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_ok_rl_simple.iqm differ
diff --git a/models/weapons/g_ok_rl_simple.iqm_0.skin b/models/weapons/g_ok_rl_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..804fe52
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_ok_rl_simple
\ No newline at end of file
diff --git a/models/weapons/g_ok_rl_simple.tga b/models/weapons/g_ok_rl_simple.tga
new file mode 100644 (file)
index 0000000..53f1be5
Binary files /dev/null and b/models/weapons/g_ok_rl_simple.tga differ
index 2ee0a40..2409b83 100644 (file)
@@ -420,7 +420,7 @@ seta notification_INFO_WEAPON_TUBA_SUICIDE "1" "0 = off, 1 = print to console, 2
 seta notification_INFO_WEAPON_VAPORIZER_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
 seta notification_INFO_WEAPON_VORTEX_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
 
-// MSG_CENTER notifications (count = 224):
+// MSG_CENTER notifications (count = 225):
 seta notification_CENTER_ALONE "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_ASSAULT_ATTACKING "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_ASSAULT_DEFENDING "1" "0 = off, 1 = centerprint"
@@ -478,6 +478,7 @@ seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE_PINK "1" "0 = off, 1 = centerpr
 seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE_RED "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE_YELLOW "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_CTF_PICKUP_TEAM_YELLOW "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_VISIBLE "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_CTF_PICKUP_YELLOW "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_CTF_RETURN_BLUE "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_CTF_RETURN_PINK "1" "0 = off, 1 = centerprint"
@@ -868,4 +869,4 @@ seta notification_show_sprees_info "3" "Show spree information in MSG_INFO messa
 seta notification_show_sprees_info_newline "1" "Show attacker spree information for MSG_INFO messages on a separate line than the death notification itself"
 seta notification_show_sprees_info_specialonly "1" "Don't show attacker spree information in MSG_INFO messages if it isn't an achievement"
 
-// Notification counts (total = 806): MSG_ANNCE = 89, MSG_INFO = 316, MSG_CENTER = 224, MSG_MULTI = 153, MSG_CHOICE = 24
+// Notification counts (total = 807): MSG_ANNCE = 89, MSG_INFO = 316, MSG_CENTER = 225, MSG_MULTI = 153, MSG_CHOICE = 24
index dce058c..100bebf 100644 (file)
@@ -183,6 +183,7 @@ void LocalCommand_debugmodel(int request, int argc)
                        setorigin(debugmodel_entity, view_origin);
                        debugmodel_entity.angles = view_angles;
                        debugmodel_entity.draw = DrawDebugModel;
+                       IL_PUSH(g_drawables, debugmodel_entity);
 
                        return;
                }
index 2ea1e74..d8906b1 100644 (file)
@@ -132,7 +132,7 @@ const int SOLID_CORPSE      = 5; // same as SOLID_BBOX, except it behaves as SOLID_N
 
 const int MOVE_NORMAL = 0; // same as false
 const int MOVE_NOMONSTERS = 1; // same as true
-const int MOVE_MISSILE = 2; // save as movement with .movetype == MOVETYPE_FLYMISSILE
+const int MOVE_MISSILE = 2; // save as movement with .move_movetype == MOVETYPE_FLYMISSILE
 const int MOVE_HITMODEL = 4;
 const int MOVE_WORLDONLY = 3;
 
index a197963..30b7fa8 100644 (file)
@@ -83,7 +83,7 @@ void HUD_InfoMessages()
                        if(spectatee_status == -1)
                                s = sprintf(_("^1Use ^3%s^1 or ^3%s^1 to change the speed"), getcommandkey("next weapon", "weapnext"), getcommandkey("previous weapon", "weapprev"));
                        else
-                               s = sprintf(_("^1Press ^3%s^1 to observe"), getcommandkey("secondary fire", "+fire2"));
+                               s = sprintf(_("^1Press ^3%s^1 to observe, ^3%s^1 to change camera mode"), getcommandkey("secondary fire", "+fire2"), getcommandkey("drop weapon", "dropweapon"));
                        drawInfoMessage(s);
 
                        s = sprintf(_("^1Press ^3%s^1 for gamemode info"), getcommandkey("server info", "+show_info"));
index 04b97c2..5901a16 100644 (file)
@@ -118,6 +118,7 @@ void HUD_Mod_CTF(vector pos, vector mySize)
        int redflag, blueflag, yellowflag, pinkflag, neutralflag; // current status
        float redflag_statuschange_elapsedtime = 0, blueflag_statuschange_elapsedtime = 0, yellowflag_statuschange_elapsedtime = 0, pinkflag_statuschange_elapsedtime = 0, neutralflag_statuschange_elapsedtime = 0; // time since the status changed
        bool ctf_oneflag; // one-flag CTF mode enabled/disabled
+       bool ctf_stalemate; // currently in stalemate
        int stat_items = STAT(CTF_FLAGSTATUS);
        float fs, fs2, fs3, size1, size2;
        vector e1, e2;
@@ -132,6 +133,8 @@ void HUD_Mod_CTF(vector pos, vector mySize)
 
        ctf_oneflag = (stat_items & CTF_FLAG_NEUTRAL);
 
+       ctf_stalemate = (stat_items & CTF_STALEMATE);
+
        mod_active = (redflag || blueflag || yellowflag || pinkflag || neutralflag || (stat_items & CTF_SHIELDED));
 
        if (autocvar__hud_configure) {
@@ -273,6 +276,8 @@ void HUD_Mod_CTF(vector pos, vector mySize)
 
        #define X(team) MACRO_BEGIN { \
                f = bound(0, team##flag_statuschange_elapsedtime * 2, 1); \
+               if (team##_icon && ctf_stalemate) \
+                       drawpic_aspect_skin(team##flag_pos, "flag_stalemate", flag_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); \
                if (team##_icon_prevstatus && f < 1) \
                        drawpic_aspect_skin_expanding(team##flag_pos, team##_icon_prevstatus, flag_size, '1 1 1', panel_fg_alpha * team##_alpha_prevstatus, DRAWFLAG_NORMAL, f); \
                if (team##_icon) \
index 6794883..e935d0c 100644 (file)
@@ -351,11 +351,11 @@ void HUD_Radar()
 
        draw_teamradar_background(hud_panel_radar_foreground_alpha);
 
-       FOREACH_ENTITY_CLASS("radarlink", true, draw_teamradar_link(it.origin, it.velocity, it.team));
+       IL_EACH(g_radarlinks, true, draw_teamradar_link(it.origin, it.velocity, it.team));
 
-       FOREACH_ENTITY_FLAGS(teamradar_icon, 0xFFFFFF, {
+       IL_EACH(g_radaricons, it.teamradar_icon, {
                if ( hud_panel_radar_mouse )
-               if ( it.health > 0 || !it.health )
+               if ( it.health >= 0 )
                if ( it.team == myteam+1 || gametype == MAPINFO_TYPE_RACE || !(serverflags & SERVERFLAG_TEAMPLAY) )
                {
                        vector coord = teamradar_texcoord_to_2dcoord(teamradar_3dcoord_to_texcoord(it.origin));
index c96b3c8..bd9e82e 100644 (file)
@@ -699,8 +699,9 @@ NET_HANDLE(ENT_CLIENT_SPAWNPOINT, bool is_new)
                        precache_model(this.mdl);
                        setmodel(this, this.mdl);
                        this.drawmask = MASK_NORMAL;
-                       //this.movetype = MOVETYPE_NOCLIP;
+                       //this.move_movetype = MOVETYPE_NOCLIP;
                        //this.draw = Spawn_Draw;
+                       IL_PUSH(g_drawables, this);
                }*/
                if(autocvar_cl_spawn_point_particles)
                {
@@ -718,6 +719,7 @@ NET_HANDLE(ENT_CLIENT_SPAWNPOINT, bool is_new)
                        else { this.cnt = particleeffectnum(EFFECT_SPAWNPOINT_NEUTRAL); }
 
                        this.draw = Spawn_Draw;
+                       if (is_new) IL_PUSH(g_drawables, this);
                        setpredraw(this, Spawn_PreDraw);
                        this.fade_start = autocvar_cl_spawn_point_dist_min;
                        this.fade_end = autocvar_cl_spawn_point_dist_max;
index 15362aa..e1cbbe7 100644 (file)
@@ -85,11 +85,20 @@ entity teamslots[17];    // 17 teams (including "spectator team")
 .float eliminated;
 
 .void(entity) draw;
+IntrusiveList g_drawables;
+STATIC_INIT(g_drawables) { g_drawables = IL_NEW(); }
 .void(entity) draw2d;
+IntrusiveList g_drawables_2d;
+STATIC_INIT(g_drawables_2d) { g_drawables_2d = IL_NEW(); }
 .void(entity) entremove;
 float drawframetime;
 vector view_origin, view_forward, view_right, view_up;
 
+IntrusiveList g_radarlinks;
+STATIC_INIT(g_radarlinks) { g_radarlinks = IL_NEW(); }
+IntrusiveList g_radaricons;
+STATIC_INIT(g_radaricons) { g_radaricons = IL_NEW(); }
+
 bool button_zoom;
 bool spectatorbutton_zoom;
 bool button_attack2;
index a8708f2..ab14cd3 100644 (file)
@@ -203,6 +203,7 @@ NET_HANDLE(ENT_CLIENT_RADARLINK, bool isnew)
 
        this.iflags = IFLAG_VELOCITY | IFLAG_ORIGIN;
        this.classname = "radarlink";
+       if (isnew) IL_PUSH(g_radarlinks, this);
 
        if(sendflags & 1)
        {
index 4ca30d4..1458efe 100644 (file)
@@ -363,6 +363,7 @@ STATIC_INIT(Porto)
 {
        entity e = new_pure(porto);
        e.draw = Porto_Draw;
+       IL_PUSH(g_drawables, e);
        e.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
 }
 
@@ -860,7 +861,7 @@ vector crosshair_getcolor(entity this, float health_stat)
        {
                case 1: // crosshair_color_per_weapon
                {
-                       if(this != WEP_Null)
+                       if(this != WEP_Null && hud == HUD_NORMAL)
                        {
                                wcross_color = this.wpcolor;
                                break;
@@ -942,6 +943,9 @@ void HUD_Crosshair(entity this)
                if (!autocvar_crosshair_enabled) // main toggle for crosshair rendering
                        return;
 
+               if (spectatee_status > 0 && STAT(CAMERA_SPECTATOR) == 2)
+                       return;
+
                if (hud != HUD_NORMAL)
                {
                        HUD_Crosshair_Vehicle(this);
@@ -1459,6 +1463,25 @@ void CSQC_UpdateView(entity this, float w, float h)
        // event chase camera
        if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually, and this code is skipped
        {
+               if(STAT(CAMERA_SPECTATOR))
+               {
+                       if(spectatee_status > 0)
+                       {
+                               if(!autocvar_chase_active)
+                               {
+                                       cvar_set("chase_active", "-2");
+                                       goto skip_eventchase_death;
+                               }
+                       }
+                       else if(autocvar_chase_active == -2)
+                               cvar_set("chase_active", "0");
+
+                       if(autocvar_chase_active == -2)
+                               goto skip_eventchase_death;
+               }
+               else if(autocvar_chase_active == -2)
+                       cvar_set("chase_active", "0");
+
                float vehicle_chase = (hud != HUD_NORMAL && (autocvar_cl_eventchase_vehicle || spectatee_status > 0));
                float ons_roundlost = (gametype == MAPINFO_TYPE_ONSLAUGHT && STAT(ROUNDLOST));
                entity gen = NULL;
@@ -1569,6 +1592,8 @@ void CSQC_UpdateView(entity this, float w, float h)
                eventchase_current_distance = 0;
        }
 
+       LABEL(skip_eventchase_death);
+
        // do lockview after event chase camera so that it still applies whenever necessary.
        if(autocvar_cl_lockview || (!autocvar_hud_cursormode && (autocvar__hud_configure && spectatee_status <= 0 || intermission > 1 || QuickMenu_IsOpened())))
        {
@@ -1847,7 +1872,7 @@ void CSQC_UpdateView(entity this, float w, float h)
           mousepos = mousepos*0.5 + getmousepos();
         */
 
-       FOREACH_ENTITY(it.draw, it.draw(it));
+       IL_EACH(g_drawables, it.draw, it.draw(it));
 
        addentities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS);
        renderscene();
@@ -2177,7 +2202,7 @@ void CSQC_UpdateView(entity this, float w, float h)
          } else */
 
        // draw 2D entities
-       FOREACH_ENTITY(it.draw2d, it.draw2d(it));
+       IL_EACH(g_drawables_2d, it.draw2d, it.draw2d(it));
        Draw_ShowNames_All();
        Debug_Draw();
 
@@ -2234,6 +2259,8 @@ void CSQC_UpdateView(entity this, float w, float h)
        // let's reset the view back to normal for the end
        setproperty(VF_MIN, '0 0 0');
        setproperty(VF_SIZE, '1 0 0' * w + '0 1 0' * h);
+
+       IL_ENDFRAME();
 }
 
 
index b94fddd..01a86bb 100644 (file)
@@ -230,5 +230,6 @@ NET_HANDLE(ENT_CLIENT_WALL, bool isnew)
 
        this.entremove = Ent_Wall_Remove;
        this.draw = Ent_Wall_Draw;
+       if (isnew) IL_PUSH(g_drawables, this);
        setpredraw(this, Ent_Wall_PreDraw);
 }
index 39032cd..4015828 100644 (file)
@@ -18,7 +18,7 @@
 
 void SUB_Stop(entity this, entity toucher)
 {
-       this.move_velocity = this.move_avelocity = '0 0 0';
+       this.velocity = this.avelocity = '0 0 0';
        this.move_movetype = MOVETYPE_NONE;
 }
 
@@ -58,11 +58,11 @@ void Projectile_Draw(entity this)
        float t;
        float a;
 
-       f = this.move_flags;
+       f = this.flags;
 
        if (this.count & 0x80)
        {
-               // this.move_flags &= ~FL_ONGROUND;
+               // UNSET_ONGROUND(this);
                if (this.move_movetype == MOVETYPE_NONE || this.move_movetype == MOVETYPE_FLY)
                        Movetype_Physics_NoMatchServer(this);
                // the trivial movetypes do not have to match the
@@ -72,9 +72,9 @@ void Projectile_Draw(entity this)
                // moving, we might still be ticrate dependent.
                else
                        Movetype_Physics_MatchServer(this, autocvar_cl_projectiles_sloppy);
-               if (!(this.move_flags & FL_ONGROUND))
+               if (!IS_ONGROUND(this))
                        if (this.velocity != '0 0 0')
-                               this.move_angles = this.angles = vectoangles(this.velocity);
+                               this.angles = vectoangles(this.velocity);
        }
        else
        {
@@ -209,9 +209,9 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
        // projectiles no longer being able to lie on a bmodel
        this.move_nomonsters = MOVE_WORLDONLY;
        if (f & 0x40)
-               this.move_flags |= FL_ONGROUND;
+               SET_ONGROUND(this);
        else
-               this.move_flags &= ~FL_ONGROUND;
+               UNSET_ONGROUND(this);
 
        if (!this.move_time)
        {
@@ -243,8 +243,6 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
                                this.gravity = ReadCoord();
                        else
                                this.gravity = 0;  // none
-                       this.move_origin = this.origin;
-                       this.move_velocity = this.velocity;
                }
 
                if (time == this.spawntime || (this.count & 0x80) || (f & 0x08))
@@ -340,12 +338,12 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
                        case PROJECTILE_ELECTRO:
                                // only new engines support sound moving with object
                                loopsound(this, CH_SHOTS_SINGLE, SND(ELECTRO_FLY), VOL_BASE, ATTEN_NORM);
-                               this.mins = '0 0 -4';
-                               this.maxs = '0 0 -4';
+                               this.mins = '-4 -4 -4';
+                               this.maxs = '4 4 4';
                                this.move_movetype = MOVETYPE_BOUNCE;
                                settouch(this, func_null);
-                               this.move_bounce_factor = WEP_CVAR_SEC(electro, bouncefactor);
-                               this.move_bounce_stopspeed = WEP_CVAR_SEC(electro, bouncestop);
+                               this.bouncefactor = WEP_CVAR_SEC(electro, bouncefactor);
+                               this.bouncestop = WEP_CVAR_SEC(electro, bouncestop);
                                break;
                        case PROJECTILE_RPC:
                        case PROJECTILE_ROCKET:
@@ -362,8 +360,8 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
                                this.maxs = '3 3 3';
                                this.move_movetype = MOVETYPE_BOUNCE;
                                settouch(this, func_null);
-                               this.move_bounce_factor = WEP_CVAR(mortar, bouncefactor);
-                               this.move_bounce_stopspeed = WEP_CVAR(mortar, bouncestop);
+                               this.bouncefactor = WEP_CVAR(mortar, bouncefactor);
+                               this.bouncestop = WEP_CVAR(mortar, bouncestop);
                                break;
                        case PROJECTILE_SHAMBLER_LIGHTNING:
                                this.mins = '-8 -8 -8';
@@ -443,9 +441,9 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
                            this.mins = '0 0 -4';
                            this.maxs = '0 0 -4';
                            this.move_movetype = MOVETYPE_BOUNCE;
-                           this.move_touch = func_null;
-                           this.move_bounce_factor = WEP_CVAR_SEC(electro, bouncefactor);
-                           this.move_bounce_stopspeed = WEP_CVAR_SEC(electro, bouncestop);
+                           settouch(this, func_null);
+                           this.bouncefactor = WEP_CVAR_SEC(electro, bouncefactor);
+                           this.bouncestop = WEP_CVAR_SEC(electro, bouncestop);
                            break;
                        */
                        default:
@@ -479,6 +477,7 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
 
        this.classname = "csqcprojectile";
        this.draw = Projectile_Draw;
+       if (isnew) IL_PUSH(g_drawables, this);
        this.entremove = Ent_RemoveProjectile;
 }
 
index ff890af..39cec43 100644 (file)
@@ -28,7 +28,7 @@
 # define TAG_VIEWLOC_NAME viewloc
 # define TAG_VIEWLOC_TYPE entity
 
-# define MOVETYPE_NAME movetype
+# define MOVETYPE_NAME move_movetype
 #endif
 
 // new fields
index 9aca8e7..052e00f 100644 (file)
@@ -100,7 +100,7 @@ bool autocvar_debugdraw;
 //                                             if (it.entnum) break;
 //                                             if (it.drawmask) break;
 //                                             if (it.predraw) break;
-//                                             if (it.movetype) break;
+//                                             if (it.move_movetype) break;
                                                if (it.solid) break;
 //                                             if (it.origin) break;
 //                                             if (it.oldorigin) break;
@@ -223,6 +223,40 @@ GENERIC_COMMAND(version, "Print the current version")
        }
 }
 
+#ifdef CSQC
+void(float bufhandle, string pattern, string antipattern) buf_cvarlist = #517;
+#endif
+GENERIC_COMMAND(cvar_localchanges, "Print locally changed cvars")
+{
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       string s = "";
+                       int h = buf_create();
+                       buf_cvarlist(h, "", "_"); // exclude all _ cvars as they are temporary
+                       int n = buf_getsize(h);
+                       for (int i = 0; i < n; ++i) {
+                               string k = bufstr_get(h, i);
+                               string v = cvar_string(k);
+                               string d = cvar_defstring(k);
+                               if (v == d)
+                                       continue;
+                               s = strcat(s, k, " \"", v, "\" // \"", d, "\"\n");
+                       }
+                       buf_del(h);
+                       LOG_INFO(s);
+                       return;
+               }
+               default:
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " cvar_localchanges"));
+                       return;
+               }
+       }
+}
+
 REGISTER_STAT(TRACE_ENT, int)
 #ifdef SVQC
 bool autocvar_debugtrace;
@@ -275,6 +309,7 @@ STATIC_INIT(TRACE_ENT)
 {
        entity e = TRACE_ENT = new_pure(TRACE_ENT);
        e.draw2d = Trace_draw2d;
+       IL_PUSH(g_drawables_2d, e);
 }
 #endif
 
index 308a7b2..a4ade38 100644 (file)
@@ -49,11 +49,11 @@ void Casing_Delete(entity this)
 
 void Casing_Draw(entity this)
 {
-    if (this.move_flags & FL_ONGROUND)
+    if (IS_ONGROUND(this))
     {
-        this.move_angles_x = 0;
-        this.move_angles_z = 0;
-        UNSET_ONGROUND(this);
+        this.angles_x = 0;
+        this.angles_z = 0;
+        //UNSET_ONGROUND(this);
     }
 
     Movetype_Physics_MatchTicrate(this, autocvar_cl_casings_ticrate, autocvar_cl_casings_sloppy);
@@ -121,8 +121,8 @@ void Casing_Damage(entity this, float thisdmg, int hittype, vector org, vector t
 {
     if (thisforce.z < 0)
         thisforce.z = 0;
-    this.move_velocity = this.move_velocity + thisforce + '0 0 100';
-    this.move_flags &= ~FL_ONGROUND;
+    this.velocity = this.velocity + thisforce + '0 0 100';
+    UNSET_ONGROUND(this);
 }
 
 NET_HANDLE(casings, bool isNew)
@@ -151,10 +151,9 @@ NET_HANDLE(casings, bool isNew)
     casing.drawmask = MASK_NORMAL;
 
     casing.draw = Casing_Draw;
-    casing.move_origin = casing.origin;
-    casing.move_velocity = casing.velocity + 2 * prandomvec();
-    casing.move_angles = casing.angles;
-    casing.move_avelocity = '0 250 0' + 100 * prandomvec();
+    if (isNew) IL_PUSH(g_drawables, casing);
+    casing.velocity = casing.velocity + 2 * prandomvec();
+    casing.avelocity = '0 250 0' + 100 * prandomvec();
     casing.move_movetype = MOVETYPE_BOUNCE;
     settouch(casing, Casing_Touch);
     casing.move_time = time;
index c1144d2..b53b605 100644 (file)
@@ -255,8 +255,8 @@ NET_HANDLE(ENT_CLIENT_DAMAGEINFO, bool isNew)
                if(it.damageforcescale)
                        if(vdist(thisforce, !=, 0))
                        {
-                               it.move_velocity = it.move_velocity + damage_explosion_calcpush(it.damageforcescale * thisforce, it.move_velocity, autocvar_g_balance_damagepush_speedfactor);
-                               it.move_flags &= ~FL_ONGROUND;
+                               it.velocity = it.velocity + damage_explosion_calcpush(it.damageforcescale * thisforce, it.velocity, autocvar_g_balance_damagepush_speedfactor);
+                               UNSET_ONGROUND(it);
                        }
 
                if(w_issilent)
index b88a57f..78f1a27 100644 (file)
@@ -180,6 +180,7 @@ void TossGib (string mdlname, vector safeorg, vector org, vector vconst, vector
        setsize (gib, '-8 -8 -8', '8 8 8');
 
        gib.draw = Gib_Draw;
+       IL_PUSH(g_drawables, gib);
        if(destroyontouch)
                settouch(gib, Gib_Touch);
        else
@@ -192,10 +193,9 @@ void TossGib (string mdlname, vector safeorg, vector org, vector vconst, vector
                org = trace_endpos;
        }
 
-       gib.move_origin = org;
        setorigin(gib, org);
-       gib.move_velocity = vconst * autocvar_cl_gibs_velocity_scale + vrand * autocvar_cl_gibs_velocity_random + '0 0 1' * autocvar_cl_gibs_velocity_up;
-       gib.move_avelocity = prandomvec() * vlen(gib.move_velocity) * autocvar_cl_gibs_avelocity_scale;
+       gib.velocity = vconst * autocvar_cl_gibs_velocity_scale + vrand * autocvar_cl_gibs_velocity_random + '0 0 1' * autocvar_cl_gibs_velocity_up;
+       gib.avelocity = prandomvec() * vlen(gib.velocity) * autocvar_cl_gibs_avelocity_scale;
        gib.move_time = time;
        gib.damageforcescale = autocvar_cl_gibs_damageforcescale;
 
index b906970..8c1ed1c 100644 (file)
 
        #ifdef SVQC
 
-               void _GlobalSound(entity this, entity gs, entity ps, string sample, int chan, int voicetype, bool fake)
+               void _GlobalSound(entity this, entity gs, entity ps, string sample, int chan, float vol, int voicetype, bool fake)
                {
                        if (gs == NULL && ps == NULL && sample == "") return;
                        if(this.classname == "body") return;
                                                if (IS_REAL_CLIENT(msg_entity))
                                                {
                                                        float atten = (msg_entity.cvar_cl_voice_directional == 1) ? ATTEN_MIN : ATTEN_NONE;
-                                                       if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASEVOICE, atten);
-                                                       else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASEVOICE, atten);
-                                                       else soundto(MSG_ONE, this, chan, sample, VOL_BASEVOICE, atten);
+                                                       if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, atten);
+                                                       else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, atten);
+                                                       else soundto(MSG_ONE, this, chan, sample, vol, atten);
                                                }
                                        }
                                        if (voicetype == VOICETYPE_LASTATTACKER_ONLY) break;
                                                MACRO_BEGIN \
                                                { \
                                                        float atten = (msg_entity.cvar_cl_voice_directional == 1) ? ATTEN_MIN : ATTEN_NONE; \
-                                                       if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASEVOICE, atten); \
-                                                       else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASEVOICE, atten); \
-                                                       else soundto(MSG_ONE, this, chan, sample, VOL_BASEVOICE, atten); \
+                                                       if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, atten); \
+                                                       else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, atten); \
+                                                       else soundto(MSG_ONE, this, chan, sample, vol, atten); \
                                                } MACRO_END
 
                                        if (fake) { msg_entity = this; X(); }
                                                                    ? bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, \
                                                                        ATTEN_MAX) \
                                                                        : ATTEN_NONE; \
-                                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASEVOICE, atten); \
-                                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASEVOICE, atten); \
-                                                               else soundto(MSG_ONE, this, chan, sample, VOL_BASEVOICE, atten); \
+                                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, atten); \
+                                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, atten); \
+                                                               else soundto(MSG_ONE, this, chan, sample, vol, atten); \
                                                        } \
                                                } MACRO_END
                                        if (fake)
                                        msg_entity = this;
                                        if (fake)
                                        {
-                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASE, ATTEN_NORM);
-                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASE, ATTEN_NORM);
-                                               else soundto(MSG_ONE, this, chan, sample, VOL_BASE, ATTEN_NORM);
+                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, ATTEN_NORM);
+                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, ATTEN_NORM);
+                                               else soundto(MSG_ONE, this, chan, sample, vol, ATTEN_NORM);
                                        }
                                        else
                                        {
-                                               if (gs) globalsound(MSG_ALL, this, gs, r, chan, VOL_BASE, ATTEN_NORM);
-                                               else if (ps) playersound(MSG_ALL, this, ps, r, chan, VOL_BASE, ATTEN_NORM);
-                                               else _sound(this, chan, sample, VOL_BASE, ATTEN_NORM);
+                                               if (gs) globalsound(MSG_ALL, this, gs, r, chan, vol, ATTEN_NORM);
+                                               else if (ps) playersound(MSG_ALL, this, ps, r, chan, vol, ATTEN_NORM);
+                                               else _sound(this, chan, sample, vol, ATTEN_NORM);
                                        }
                                        break;
                                }
index 44925cd..640d330 100644 (file)
@@ -122,10 +122,10 @@ entity GetVoiceMessage(string type);
 
 #ifdef SVQC
 
-       void _GlobalSound(entity this, entity gs, entity ps, string sample, float chan, float voicetype, bool fake);
-       #define GlobalSound(this, def, chan, voicetype) _GlobalSound(this, def, NULL, string_null, chan, voicetype, false)
-       #define GlobalSound_string(this, def, chan, voicetype) _GlobalSound(this, NULL, NULL, def, chan, voicetype, false)
-       #define PlayerSound(this, def, chan, voicetype) _GlobalSound(this, NULL, def, string_null, chan, voicetype, false)
+       void _GlobalSound(entity this, entity gs, entity ps, string sample, float chan, float vol, float voicetype, bool fake);
+       #define GlobalSound(this, def, chan, vol, voicetype) _GlobalSound(this, def, NULL, string_null, chan, vol, voicetype, false)
+       #define GlobalSound_string(this, def, chan, vol, voicetype) _GlobalSound(this, NULL, NULL, def, chan, vol, voicetype, false)
+       #define PlayerSound(this, def, chan, vol, voicetype) _GlobalSound(this, NULL, def, string_null, chan, vol, voicetype, false)
        #define VoiceMessage(this, def, msg) \
                MACRO_BEGIN \
                { \
@@ -137,7 +137,7 @@ entity GetVoiceMessage(string type);
                        if (IS_SPEC(this) || IS_OBSERVER(this) || flood < 0) fake = true; \
                        else if (flood > 0) fake = false; \
                        else break; \
-                       _GlobalSound(this, NULL, VM, string_null, CH_VOICE, voicetype, fake); \
+                       _GlobalSound(this, NULL, VM, string_null, CH_VOICE, VOL_BASEVOICE, voicetype, fake); \
                } MACRO_END
 
 #endif
index f577762..28b8bb4 100644 (file)
@@ -156,6 +156,7 @@ NET_HANDLE(ENT_CLIENT_MODELEFFECT, bool isnew)
        e.cnt = ReadByte() / 255.0; // actually alpha
 
        e.draw = ModelEffect_Draw;
+       if (isnew) IL_PUSH(g_drawables, e);
 
        if (!isnew) remove(e); // yes, this IS stupid, but I don't need to duplicate all the read* stuff then
        return true;
index 7848b7b..1665e4c 100644 (file)
@@ -8,34 +8,25 @@ class(Rubble).float creationtime;
 
 void RubbleLimit(string cname, float limit, void(entity) deleteproc)
 {
-       entity e;
-       entity oldest;
-       float c;
-       float oldesttime;
-
        // remove rubble of the same type if it's at the limit
        // remove multiple rubble if the limit has been decreased
        while (1)
        {
-               e = findchain(classname, cname);
-               if (e == NULL) break;
                // walk the list and count the entities, find the oldest
                // initialize our search with the first entity
-               c = 1;
-               oldest = e;
-               oldesttime = e.creationtime;
-               e = e.chain;
+               int c = 0;
+               entity oldest = NULL;
+               float oldesttime = 0;
                // compare to all other matching entities
-               while (e)
+               FOREACH_ENTITY_CLASS(cname, true,
                {
-                       c = c + 1;
-                       if (oldesttime > e.creationtime)
+                       ++c;
+                       if(!oldest || oldesttime > it.creationtime)
                        {
-                               oldesttime = e.creationtime;
-                               oldest = e;
+                               oldest = it;
+                               oldesttime = it.creationtime;
                        }
-                       e = e.chain;
-               }
+               });
 
                // stop if there are less than the limit already
                if (c <= limit) break;
index 1636965..35fe31c 100644 (file)
@@ -178,7 +178,7 @@ void GiveBall(entity plyr, entity ball)
        ball.effects &= ~autocvar_g_nexball_basketball_effects_default;
 
        ball.velocity = '0 0 0';
-       ball.movetype = MOVETYPE_NONE;
+       set_movetype(ball, MOVETYPE_NONE);
        settouch(ball, func_null);
        ball.effects |= EF_NOSHADOW;
        ball.scale = 1; // scale down.
@@ -209,7 +209,7 @@ void DropBall(entity ball, vector org, vector vel)
 
        setattachment(ball, NULL, "");
        setorigin(ball, org);
-       ball.movetype = MOVETYPE_BOUNCE;
+       set_movetype(ball, MOVETYPE_BOUNCE);
        UNSET_ONGROUND(ball);
        ball.scale = ball_scale;
        ball.velocity = vel;
@@ -237,7 +237,7 @@ void InitBall(entity this)
 {
        if(gameover) return;
        UNSET_ONGROUND(this);
-       this.movetype = MOVETYPE_BOUNCE;
+       set_movetype(this, MOVETYPE_BOUNCE);
        if(this.classname == "nexball_basketball")
                settouch(this, basketball_touch);
        else if(this.classname == "nexball_football")
@@ -261,7 +261,7 @@ void ResetBall(entity this)
                        bprint("The ", Team_ColoredFullName(this.team), " held the ball for too long.\n");
 
                settouch(this, func_null);
-               this.movetype = MOVETYPE_NOCLIP;
+               set_movetype(this, MOVETYPE_NOCLIP);
                this.velocity = '0 0 0'; // just in case?
                if(!this.cnt)
                        LogNB("resetidle", NULL);
@@ -283,7 +283,7 @@ void ResetBall(entity this)
                                   vtos(this.origin - this.spawnorigin), " Velocity: ", vtos(this.velocity), "\n");
                this.velocity = '0 0 0';
                setorigin(this, this.spawnorigin); // make sure it's positioned correctly anyway
-               this.movetype = MOVETYPE_NONE;
+               set_movetype(this, MOVETYPE_NONE);
                setthink(this, InitBall);
                this.nextthink = max(time, game_starttime) + autocvar_g_nexball_delay_start;
        }
@@ -553,7 +553,7 @@ void SpawnBall(entity this)
                this.glow_trail = true;
        }
 
-       this.movetype = MOVETYPE_FLY;
+       set_movetype(this, MOVETYPE_FLY);
 
        if(!autocvar_g_nexball_sound_bounce)
                this.noise = "";
@@ -822,7 +822,7 @@ void W_Nexball_Attack2(entity actor)
 
        missile.owner = actor;
 
-       missile.movetype = MOVETYPE_FLY;
+       set_movetype(missile, MOVETYPE_FLY);
        PROJECTILE_MAKETRIGGER(missile);
 
        //setmodel(missile, "models/elaser.mdl");  // precision set below
index 8389b22..0134792 100644 (file)
@@ -74,9 +74,9 @@ void cpicon_draw(entity this)
                }
 
                this.angles_x = this.punchangle_x;
-               this.angles_y = this.punchangle_y + this.move_angles_y;
+               this.angles_y = this.punchangle_y + this.angles_y;
                this.angles_z = this.punchangle_z;
-               this.move_angles_y = this.move_angles_y + 45 * frametime;
+               this.angles_y = this.angles_y + 45 * frametime;
        }
 
        setorigin(this, this.cp_origin + this.cp_bob_origin + this.cp_bob_dmg);
@@ -117,17 +117,15 @@ void cpicon_construct(entity this)
                setmodel(this.icon_realmodel, MDL_Null);
                setorigin(this.icon_realmodel, this.origin);
                setsize(this.icon_realmodel, CPICON_MIN, CPICON_MAX);
-               this.icon_realmodel.movetype = MOVETYPE_NOCLIP;
+               this.icon_realmodel.move_movetype = MOVETYPE_NOCLIP;
                this.icon_realmodel.solid = SOLID_NOT;
-               this.icon_realmodel.move_origin = this.icon_realmodel.origin;
        }
 
        if(this.iscaptured) { this.icon_realmodel.solid = SOLID_BBOX; }
 
        this.move_movetype      = MOVETYPE_NOCLIP;
        this.solid                      = SOLID_NOT;
-       this.movetype           = MOVETYPE_NOCLIP;
-       this.move_origin        = this.origin;
+       this.move_movetype              = MOVETYPE_NOCLIP;
        this.move_time          = time;
        this.drawmask           = MASK_NORMAL;
        this.alpha                      = 1;
index 03e81f4..0135f46 100644 (file)
@@ -33,13 +33,13 @@ void ons_generator_ray_spawn(vector org)
        setmodel(e, MDL_ONS_RAY);
        setorigin(e, org);
        e.angles = randomvec() * 360;
-       e.move_origin = org;
-       e.movetype = MOVETYPE_NONE;
+       e.move_movetype = MOVETYPE_NONE;
        e.alpha = 0;
        e.scale = random() * 5 + 8;
        e.move_time = time + 0.05;
        e.drawmask = MASK_NORMAL;
        e.draw = ons_generator_ray_draw;
+       IL_PUSH(g_drawables, e);
 }
 
 void generator_draw(entity this)
@@ -154,8 +154,7 @@ void generator_construct(entity this)
 
        this.move_movetype      = MOVETYPE_NOCLIP;
        this.solid                      = SOLID_BBOX;
-       this.movetype           = MOVETYPE_NOCLIP;
-       this.move_origin        = this.origin;
+       this.move_movetype              = MOVETYPE_NOCLIP;
        this.move_time          = time;
        this.drawmask           = MASK_NORMAL;
        this.alpha                      = 1;
index 6c42f5a..89c5eef 100644 (file)
@@ -211,7 +211,7 @@ void ons_CaptureShield_Spawn(entity generator, bool is_generator)
        settouch(shield, ons_CaptureShield_Touch);
        setcefc(shield, ons_CaptureShield_Customize);
        shield.effects = EF_ADDITIVE;
-       shield.movetype = MOVETYPE_NOCLIP;
+       set_movetype(shield, MOVETYPE_NOCLIP);
        shield.solid = SOLID_TRIGGER;
        shield.avelocity = '7 0 11';
        shield.scale = 1;
@@ -358,13 +358,11 @@ void onslaught_updatelinks()
                }
                ons_ControlPoint_UpdateSprite(l);
        }
-       l = findchain(classname, "ons_captureshield");
-       while(l)
+       FOREACH_ENTITY_CLASS("ons_captureshield", true,
        {
-               l.team = l.enemy.team;
-               l.colormap = l.enemy.colormap;
-               l = l.chain;
-       }
+               it.team = it.enemy.team;
+               it.colormap = it.enemy.colormap;
+       });
 }
 
 
@@ -863,7 +861,7 @@ void ons_ControlPoint_Setup(entity cp)
        cp.netname = "Control point";
        cp.team = 0;
        cp.solid = SOLID_BBOX;
-       cp.movetype = MOVETYPE_NONE;
+       set_movetype(cp, MOVETYPE_NONE);
        settouch(cp, ons_ControlPoint_Touch);
        setthink(cp, ons_ControlPoint_Think);
        cp.nextthink = time + ONS_CP_THINKRATE;
@@ -882,14 +880,14 @@ void ons_ControlPoint_Setup(entity cp)
        if((cp.spawnflags & 1) || cp.noalign) // don't drop to floor, just stay at fixed location
        {
                cp.noalign = true;
-               cp.movetype = MOVETYPE_NONE;
+               set_movetype(cp, MOVETYPE_NONE);
        }
        else // drop to floor, automatically find a platform and set that as spawn origin
        {
                setorigin(cp, cp.origin + '0 0 20');
                cp.noalign = false;
                droptofloor(cp);
-               cp.movetype = MOVETYPE_TOSS;
+               set_movetype(cp, MOVETYPE_TOSS);
        }
 
        // waypointsprites
@@ -1105,7 +1103,7 @@ void ons_GeneratorSetup(entity gen) // called when spawning a generator entity o
        gen.classname = "onslaught_generator";
        gen.solid = SOLID_BBOX;
        gen.team_saved = teamnumber;
-       gen.movetype = MOVETYPE_NONE;
+       set_movetype(gen, MOVETYPE_NONE);
        gen.lasthealth = gen.max_health = gen.health = autocvar_g_onslaught_gen_health;
        gen.takedamage = DAMAGE_AIM;
        gen.bot_attack = true;
@@ -1289,8 +1287,6 @@ void Onslaught_RoundStart()
 
 void havocbot_goalrating_ons_offenseitems(entity this, float ratingscale, vector org, float sradius)
 {
-       entity head;
-       float t, c;
        bool needarmor = false, needweapons = false;
 
        // Needs armor/health?
@@ -1298,7 +1294,7 @@ void havocbot_goalrating_ons_offenseitems(entity this, float ratingscale, vector
                needarmor = true;
 
        // Needs weapons?
-       c = 0;
+       int c = 0;
        FOREACH(Weapons, it != WEP_Null, {
                if(this.weapons & (it.m_wepset))
                if(++c >= 4)
@@ -1315,20 +1311,18 @@ void havocbot_goalrating_ons_offenseitems(entity this, float ratingscale, vector
        LOG_DEBUG(strcat(this.netname, " needs armor ", ftos(needarmor) , "\n"));
 
        // See what is around
-       head = findchainfloat(bot_pickup, true);
-       while (head)
+       FOREACH_ENTITY_FLOAT(bot_pickup, true,
        {
                // gather health and armor only
-               if (head.solid)
-               if ( ((head.health || head.armorvalue) && needarmor) || (head.weapons && needweapons ) )
-               if (vdist(head.origin - org, <, sradius))
+               if (it.solid)
+               if ( ((it.health || it.armorvalue) && needarmor) || (it.weapons && needweapons ) )
+               if (vdist(it.origin - org, <, sradius))
                {
-                       t = head.bot_pickupevalfunc(this, head);
+                       int t = it.bot_pickupevalfunc(this, it);
                        if (t > 0)
-                               navigation_routerating(this, head, t * ratingscale, 500);
+                               navigation_routerating(this, it, t * ratingscale, 500);
                }
-               head = head.chain;
-       }
+       });
 }
 
 void havocbot_role_ons_setrole(entity this, int role)
@@ -1597,26 +1591,22 @@ void havocbot_ons_reset_role(entity this)
  */
 entity ons_Nearest_ControlPoint(entity this, vector pos, float max_dist)
 {
-       entity tmp_entity, closest_target = NULL;
-       tmp_entity = findchain(classname, "onslaught_controlpoint");
-       while(tmp_entity)
+       entity closest_target = NULL;
+       FOREACH_ENTITY_CLASS("onslaught_controlpoint", true,
        {
-               if(SAME_TEAM(tmp_entity, this))
-               if(tmp_entity.iscaptured)
-               if(max_dist <= 0 || vdist(tmp_entity.origin - pos, <=, max_dist))
-               if(vlen2(tmp_entity.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
-                       closest_target = tmp_entity;
-               tmp_entity = tmp_entity.chain;
-       }
-       tmp_entity = findchain(classname, "onslaught_generator");
-       while(tmp_entity)
+               if(SAME_TEAM(it, this))
+               if(it.iscaptured)
+               if(max_dist <= 0 || vdist(it.origin - pos, <=, max_dist))
+               if(vlen2(it.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
+                       closest_target = it;
+       });
+       FOREACH_ENTITY_CLASS("onslaught_generator", true,
        {
-               if(SAME_TEAM(tmp_entity, this))
-               if(max_dist <= 0 || vdist(tmp_entity.origin - pos, <, max_dist))
-               if(vlen2(tmp_entity.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
-                       closest_target = tmp_entity;
-               tmp_entity = tmp_entity.chain;
-       }
+               if(SAME_TEAM(it, this))
+               if(max_dist <= 0 || vdist(it.origin - pos, <, max_dist))
+               if(vlen2(it.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
+                       closest_target = it;
+       });
 
        return closest_target;
 }
@@ -1628,45 +1618,39 @@ entity ons_Nearest_ControlPoint(entity this, vector pos, float max_dist)
  */
 entity ons_Nearest_ControlPoint_2D(entity this, vector pos, float max_dist)
 {
-       entity tmp_entity, closest_target = NULL;
+       entity closest_target = NULL;
        vector delta;
        float smallest_distance = 0, distance;
 
-       tmp_entity = findchain(classname, "onslaught_controlpoint");
-       while(tmp_entity)
+       FOREACH_ENTITY_CLASS("onslaught_controlpoint", true,
        {
-               delta = tmp_entity.origin - pos;
+               delta = it.origin - pos;
                delta_z = 0;
                distance = vlen(delta);
 
-               if(SAME_TEAM(tmp_entity, this))
-               if(tmp_entity.iscaptured)
+               if(SAME_TEAM(it, this))
+               if(it.iscaptured)
                if(max_dist <= 0 || distance <= max_dist)
                if(closest_target == NULL || distance <= smallest_distance )
                {
-                       closest_target = tmp_entity;
+                       closest_target = it;
                        smallest_distance = distance;
                }
-
-               tmp_entity = tmp_entity.chain;
-       }
-       tmp_entity = findchain(classname, "onslaught_generator");
-       while(tmp_entity)
+       });
+       FOREACH_ENTITY_CLASS("onslaught_generator", true,
        {
-               delta = tmp_entity.origin - pos;
+               delta = it.origin - pos;
                delta_z = 0;
                distance = vlen(delta);
 
-               if(SAME_TEAM(tmp_entity, this))
+               if(SAME_TEAM(it, this))
                if(max_dist <= 0 || distance <= max_dist)
                if(closest_target == NULL || distance <= smallest_distance )
                {
-                       closest_target = tmp_entity;
+                       closest_target = it;
                        smallest_distance = distance;
                }
-
-               tmp_entity = tmp_entity.chain;
-       }
+       });
 
        return closest_target;
 }
@@ -1675,23 +1659,18 @@ entity ons_Nearest_ControlPoint_2D(entity this, vector pos, float max_dist)
  */
 int ons_Count_SelfControlPoints(entity this)
 {
-       entity tmp_entity;
-       tmp_entity = findchain(classname, "onslaught_controlpoint");
        int n = 0;
-       while(tmp_entity)
+       FOREACH_ENTITY_CLASS("onslaught_controlpoint", true,
        {
-               if(SAME_TEAM(tmp_entity, this))
-               if(tmp_entity.iscaptured)
+               if(SAME_TEAM(it, this))
+               if(it.iscaptured)
                        n++;
-               tmp_entity = tmp_entity.chain;
-       }
-       tmp_entity = findchain(classname, "onslaught_generator");
-       while(tmp_entity)
+       });
+       FOREACH_ENTITY_CLASS("onslaught_generator", true,
        {
-               if(SAME_TEAM(tmp_entity, this))
+               if(SAME_TEAM(it, this))
                        n++;
-               tmp_entity = tmp_entity.chain;
-       }
+       });
        return n;
 }
 
index 08f7ff9..6d91494 100644 (file)
@@ -29,7 +29,7 @@ CLASS(Pickup, GameItem)
         TC(Pickup, this);
         bool b = Item_GiveTo(item, player);
         if (b) {
-            LOG_TRACEF("entity %i picked up %s\n", player, this.m_name);
+            LOG_DEBUGF("entity %i picked up %s\n", player, this.m_name);
             player.inventory.inv_items[this.m_id]++;
             Inventory_update(player);
         }
index 3d3ef42..1aa748f 100644 (file)
@@ -226,6 +226,7 @@ NET_HANDLE(ENT_CLIENT_MINIGAME, bool isnew)
                {
                        minigame_self = this;
                        activate_minigame(this.owner);
+                       minigame_self = this; // set it again (needed before, but may also be reset)
                }
        }
        MINIGAME_SIMPLELINKED_ENTITIES
index 992eab0..0d0efb0 100644 (file)
@@ -5,9 +5,9 @@ void player_clear_minigame(entity player)
        player.active_minigame = NULL;
        player.minigame_players = NULL;
        if ( IS_PLAYER(player) )
-               player.movetype = MOVETYPE_WALK;
+               set_movetype(player, MOVETYPE_WALK);
        else
-               player.movetype = MOVETYPE_FLY_WORLDONLY;
+               set_movetype(player, MOVETYPE_FLY_WORLDONLY);
        player.team_forced = 0;
 }
 
index 1c34a25..91fb278 100644 (file)
@@ -19,7 +19,7 @@ CLASS(Model, Object)
             LOG_WARNINGF("Missing model: \"%s\"\n", s);
             return;
         }
-        LOG_DEBUGF("precache_model(\"%s\")\n", s);
+        profile(sprintf("precache_model(\"%s\")\n", s));
         precache_model(s);
     }
 ENDCLASS(Model)
index 46a9fb1..65c82ab 100644 (file)
@@ -233,7 +233,7 @@ void M_Mage_Attack_Spike(entity this, vector dir)
        missile.ltime = time + 7;
        missile.nextthink = time;
        missile.solid = SOLID_BBOX;
-       missile.movetype = MOVETYPE_FLYMISSILE;
+       set_movetype(missile, MOVETYPE_FLYMISSILE);
        missile.flags = FL_PROJECTILE;
        setorigin(missile, this.origin + v_forward * 14 + '0 0 30' + v_right * -14);
        setsize(missile, '0 0 0', '0 0 0');
index dd9a61d..afbb954 100644 (file)
@@ -85,10 +85,10 @@ void M_Shambler_Attack_Lightning_Explode(entity this, entity directhitentity)
 
        this.event_damage = func_null;
        this.takedamage = DAMAGE_NO;
-       this.movetype = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        this.velocity = '0 0 0';
 
-       if(this.movetype == MOVETYPE_NONE)
+       if(this.move_movetype == MOVETYPE_NONE)
                this.velocity = this.oldvelocity;
 
        RadiusDamage (this, this.realowner, (autocvar_g_monster_shambler_attack_lightning_damage), (autocvar_g_monster_shambler_attack_lightning_damage), (autocvar_g_monster_shambler_attack_lightning_radius), 
@@ -150,7 +150,7 @@ void M_Shambler_Attack_Lightning(entity this)
        gren.owner = gren.realowner = this;
        gren.bot_dodge = true;
        gren.bot_dodgerating = (autocvar_g_monster_shambler_attack_lightning_damage);
-       gren.movetype = MOVETYPE_BOUNCE;
+       set_movetype(gren, MOVETYPE_BOUNCE);
        PROJECTILE_MAKETRIGGER(gren);
        gren.projectiledeathtype = DEATH_MONSTER_SHAMBLER_ZAP.m_id;
        setorigin(gren, CENTER_OR_VIEWOFS(this));
index b6d41db..c7ffece 100644 (file)
@@ -185,7 +185,7 @@ void M_Spider_Attack_Web(entity this)
 
        //proj.glow_size = 50;
        //proj.glow_color = 45;
-       proj.movetype = MOVETYPE_BOUNCE;
+       set_movetype(proj, MOVETYPE_BOUNCE);
        W_SetupProjVelocity_Explicit(proj, v_forward, v_up, (autocvar_g_monster_spider_attack_web_speed), (autocvar_g_monster_spider_attack_web_speed_up), 0, 0, false);
        settouch(proj, M_Spider_Attack_Web_Touch);
        setsize(proj, '-4 -4 -4', '4 4 4');
index 345d645..53d08ef 100644 (file)
@@ -64,7 +64,7 @@ METHOD(WyvernAttack, wr_think, void(WyvernAttack thiswep, entity actor, .entity
                entity missile = spawn();
                missile.owner = missile.realowner = actor;
                missile.solid = SOLID_TRIGGER;
-               missile.movetype = MOVETYPE_FLYMISSILE;
+               set_movetype(missile, MOVETYPE_FLYMISSILE);
                missile.projectiledeathtype = DEATH_MONSTER_WYVERN.m_id;
                setsize(missile, '-6 -6 -6', '6 6 6');
                setorigin(missile, actor.origin + actor.view_ofs + v_forward * 14);
index 795e031..60c2777 100644 (file)
@@ -50,7 +50,7 @@ void monster_dropitem(entity this, entity attacker)
                e.noalign = true;
                e.monster_loot(e);
                e.gravity = 1;
-               e.movetype = MOVETYPE_TOSS;
+               set_movetype(e, MOVETYPE_TOSS);
                e.reset = SUB_Remove;
                setorigin(e, org);
                e.velocity = randomvec() * 175 + '0 0 325';
@@ -338,7 +338,7 @@ void Monster_Sound(entity this, .string samplefield, float sound_delay, float de
        if(delaytoo)
        if(time < this.msound_delay)
                return; // too early
-       GlobalSound_string(this, this.(samplefield), chan, VOICETYPE_PLAYERSOUND);
+       GlobalSound_string(this, this.(samplefield), chan, VOL_BASE, VOICETYPE_PLAYERSOUND);
 
        this.msound_delay = time + sound_delay;
 }
@@ -763,15 +763,15 @@ void Monster_Move(entity this, float runspeed, float walkspeed, float stpspeed)
                        }
 
 
-                       this.movetype = MOVETYPE_BOUNCE;
+                       set_movetype(this, MOVETYPE_BOUNCE);
                        //this.velocity_z = -200;
 
                        return;
                }
-               else if(this.movetype == MOVETYPE_BOUNCE)
+               else if(this.move_movetype == MOVETYPE_BOUNCE)
                {
                        this.angles_x = 0;
-                       this.movetype = MOVETYPE_WALK;
+                       set_movetype(this, MOVETYPE_WALK);
                }
        }
 
@@ -1010,7 +1010,7 @@ void Monster_Dead(entity this, entity attacker, float gibbed)
        this.takedamage         = DAMAGE_AIM;
        this.deadflag           = DEAD_DEAD;
        this.enemy                      = NULL;
-       this.movetype           = MOVETYPE_TOSS;
+       set_movetype(this, MOVETYPE_TOSS);
        this.moveto                     = this.origin;
        settouch(this, Monster_Touch); // reset incase monster was pouncing
        this.reset                      = func_null;
@@ -1290,6 +1290,9 @@ bool Monster_Spawn(entity this, int mon_id)
 
        if(!autocvar_g_monsters) { Monster_Remove(this); return false; }
 
+       if(!(this.spawnflags & MONSTERFLAG_RESPAWNED))
+               IL_PUSH(g_monsters, this);
+
        if(Monster_Appear_Check(this, mon_id)) { return true; } // return true so the monster isn't removed
 
        if(!this.monster_skill)
@@ -1320,7 +1323,7 @@ bool Monster_Spawn(entity this, int mon_id)
        settouch(this, Monster_Touch);
        this.use                                = Monster_Use;
        this.solid                              = SOLID_BBOX;
-       this.movetype                   = MOVETYPE_WALK;
+       set_movetype(this, MOVETYPE_WALK);
        this.spawnshieldtime    = time + autocvar_g_monsters_spawnshieldtime;
        this.enemy                              = NULL;
        this.velocity                   = '0 0 0';
@@ -1355,7 +1358,7 @@ bool Monster_Spawn(entity this, int mon_id)
        if(mon.spawnflags & MONSTER_TYPE_FLY)
        {
                this.flags |= FL_FLY;
-               this.movetype = MOVETYPE_FLY;
+               set_movetype(this, MOVETYPE_FLY);
        }
 
        if(!(this.spawnflags & MONSTERFLAG_RESPAWNED))
index 921cd03..5c2987e 100644 (file)
@@ -207,7 +207,7 @@ void buff_Respawn(entity this)
 
        setorigin(this, trace_endpos); // attempt to unstick
 
-       this.movetype = MOVETYPE_TOSS;
+       set_movetype(this, MOVETYPE_TOSS);
 
        makevectors(this.angles);
        this.angles = '0 0 0';
@@ -428,7 +428,7 @@ void buff_Init(entity this)
        this.reset = buff_Reset;
        this.nextthink = time + 0.1;
        this.gravity = 1;
-       this.movetype = MOVETYPE_TOSS;
+       set_movetype(this, MOVETYPE_TOSS);
        this.scale = 1;
        this.skin = buff.m_skin;
        this.effects = EF_FULLBRIGHT | EF_STARDUST | EF_NOSHADOW;
@@ -445,7 +445,7 @@ void buff_Init(entity this)
                this.noalign = true;
 
        if(this.noalign)
-               this.movetype = MOVETYPE_NONE; // reset by random location
+               set_movetype(this, MOVETYPE_NONE); // reset by random location
 
        setmodel(this, MDL_BUFF);
        setsize(this, BUFF_MIN, BUFF_MAX);
index 9649070..fbbe603 100644 (file)
@@ -214,13 +214,13 @@ void RaceCarPhysics(entity this)
                }
 
                this.velocity = (neworigin - this.origin) * (1.0 / PHYS_INPUT_TIMELENGTH);
-               this.movetype = MOVETYPE_NOCLIP;
+               set_movetype(this, MOVETYPE_NOCLIP);
        }
        else
        {
                rigvel_z -= PHYS_INPUT_TIMELENGTH * PHYS_GRAVITY(this); // 4x gravity plays better
                this.velocity = rigvel;
-               this.movetype = MOVETYPE_FLY;
+               set_movetype(this, MOVETYPE_FLY);
        }
 
        trace_fraction = 1;
@@ -262,8 +262,6 @@ void RaceCarPhysics(entity this)
        smoothangles = vectoangles2(vf1, vu1);
        this.angles_x = -smoothangles_x;
        this.angles_z =  smoothangles_z;
-
-       PM_ClientMovement_Move(this);
 }
 
 #ifdef SVQC
index 3cca0d9..8de4f2b 100644 (file)
@@ -86,6 +86,7 @@ CLASS(DamageText, Object)
         this.m_group = _group;
         this.m_friendlyfire = _friendlyfire;
         DamageText_update(this, _origin, _health, _armor, _deathtype);
+               IL_PUSH(g_drawables_2d, this);
     }
 ENDCLASS(DamageText)
 #endif
@@ -150,7 +151,7 @@ NET_HANDLE(damagetext, bool isNew)
                 }
             }
         }
-        NEW(DamageText, group, location, health, armor, deathtype, friendlyfire);
+        make_impure(NEW(DamageText, group, location, health, armor, deathtype, friendlyfire));
     }
 }
 #endif
index 0d20ff7..7ddfcea 100644 (file)
@@ -10,6 +10,7 @@
 #define PHYS_DODGING_RAMP_TIME                                 STAT(DODGING_RAMP_TIME, this)
 #define PHYS_DODGING_UP_SPEED                          STAT(DODGING_UP_SPEED, this)
 #define PHYS_DODGING_WALL                                      STAT(DODGING_WALL, this)
+#define PHYS_DODGING_AIR                                       STAT(DODGING_AIR, this)
 #define PHYS_DODGING_PRESSED_KEYS(s)           (s).pressedkeys
 
 #ifdef CSQC
@@ -18,8 +19,6 @@
 #elif defined(SVQC)
        #define PHYS_DODGING_FRAMETIME                          sys_frametime
        #define PHYS_DODGING_TIMEOUT(s)                         s.cvar_cl_dodging_timeout
-
-
 #endif
 
 #ifdef SVQC
@@ -124,6 +123,7 @@ float PM_dodging_checkpressedkeys(entity this)
 
        makevectors(this.angles);
 
+       if(!PHYS_DODGING_AIR)
        if (check_close_to_ground(this, PHYS_DODGING_HEIGHT_THRESHOLD) != 1
                && check_close_to_wall(this, PHYS_DODGING_DISTANCE_THRESHOLD) != 1)
                return true;
@@ -189,7 +189,10 @@ void PM_dodging(entity this)
        }
 
        // make sure v_up, v_right and v_forward are sane
-       makevectors(this.angles);
+       if(PHYS_DODGING_AIR)
+               makevectors(this.v_angle);
+       else
+               makevectors(this.angles);
 
        // if we have e.g. 0.5 sec ramptime and a frametime of 0.25, then the ramp code
        // will be called ramp_time/frametime times = 2 times. so, we need to
@@ -226,7 +229,7 @@ void PM_dodging(entity this)
 
 #ifdef SVQC
                if (autocvar_sv_dodging_sound)
-                       PlayerSound(this, playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+                       PlayerSound(this, playersound_jump, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
 
                animdecide_setaction(this, ANIMACTION_JUMP, true);
 #endif
index 1c4de9a..a504c9b 100644 (file)
@@ -136,13 +136,16 @@ void Item_ItemsTime_SetTimesForAllPlayers()
 float Item_ItemsTime_UpdateTime(entity e, float t)
 {
     bool isavailable = (t == 0);
-    FOREACH_ENTITY(it.itemdef == e.itemdef || ((e.weapons & WEPSET_SUPERWEAPONS) && (it.weapons & WEPSET_SUPERWEAPONS) && clienttype(it) == CLIENTTYPE_NOTACLIENT), LAMBDA(
+    FOREACH_ENTITY_FLOAT(pure_data, false,
+    {
+        if(!(it.itemdef == e.itemdef || ((e.weapons & WEPSET_SUPERWEAPONS) && (it.weapons & WEPSET_SUPERWEAPONS) && clienttype(it) == CLIENTTYPE_NOTACLIENT)))
+            continue;
         if (e == it) continue;
         if (it.scheduledrespawntime <= time)
             isavailable = true;
         else if (t == 0 || it.scheduledrespawntime < t)
             t = it.scheduledrespawntime;
-    ));
+    });
     if (isavailable)
         t = -t; // let know the client there's another available item
     return t;
@@ -153,9 +156,12 @@ MUTATOR_HOOKFUNCTION(itemstime, reset_map_global)
     Item_ItemsTime_ResetTimes();
     // ALL the times need to be reset before .reset()ing each item
     // since Item_Reset schedules respawn of superweapons and powerups
-    FOREACH_ENTITY(IS_NOT_A_CLIENT(it), LAMBDA(
+    FOREACH_ENTITY_FLOAT(pure_data, false,
+    {
+        if(IS_CLIENT(it))
+            continue;
         if (it.reset) Item_ItemsTime_SetTime(it, 0);
-    ));
+    });
     Item_ItemsTime_SetTimesForAllPlayers();
 }
 
index 353baa9..5570a1b 100644 (file)
@@ -94,7 +94,7 @@ MUTATOR_HOOKFUNCTION(cl_nades, EditProjectile)
                proj.maxs = '16 16 16';
        }
        proj.colormod = nade_type.m_color;
-       proj.move_movetype = MOVETYPE_BOUNCE;
+       set_movetype(proj, MOVETYPE_BOUNCE);
        settouch(proj, func_null);
        proj.scale = 1.5;
        proj.avelocity = randomvec() * 720;
@@ -273,7 +273,7 @@ void nade_napalm_ball(entity this)
        proj.team = this.owner.team;
        proj.bot_dodge = true;
        proj.bot_dodgerating = autocvar_g_nades_napalm_ball_damage;
-       proj.movetype = MOVETYPE_BOUNCE;
+       set_movetype(proj, MOVETYPE_BOUNCE);
        proj.projectiledeathtype = DEATH_NADE_NAPALM.m_id;
        PROJECTILE_MAKETRIGGER(proj);
        setmodel(proj, MDL_Null);
@@ -356,7 +356,7 @@ void nade_napalm_boom(entity this)
        fountain.ltime = time + autocvar_g_nades_napalm_fountain_lifetime;
        fountain.pushltime = fountain.ltime;
        fountain.team = this.team;
-       fountain.movetype = MOVETYPE_TOSS;
+       set_movetype(fountain, MOVETYPE_TOSS);
        fountain.projectiledeathtype = DEATH_NADE_NAPALM.m_id;
        fountain.bot_dodge = true;
        fountain.bot_dodgerating = autocvar_g_nades_napalm_fountain_damage;
@@ -448,7 +448,7 @@ void nade_ice_boom(entity this)
        fountain.ltime = time + autocvar_g_nades_ice_freeze_time;
        fountain.pushltime = fountain.wait = fountain.ltime;
        fountain.team = this.team;
-       fountain.movetype = MOVETYPE_TOSS;
+       set_movetype(fountain, MOVETYPE_TOSS);
        fountain.projectiledeathtype = DEATH_NADE_ICE.m_id;
        fountain.bot_dodge = false;
        setsize(fountain, '-16 -16 -16', '16 16 16');
@@ -494,7 +494,7 @@ void nade_spawn_boom(entity this)
        entity spawnloc = spawn();
        setorigin(spawnloc, this.origin);
        setsize(spawnloc, this.realowner.mins, this.realowner.maxs);
-       spawnloc.movetype = MOVETYPE_NONE;
+       set_movetype(spawnloc, MOVETYPE_NONE);
        spawnloc.solid = SOLID_NOT;
        spawnloc.drawonlytoclient = this.realowner;
        spawnloc.effects = EF_STARDUST;
@@ -572,13 +572,11 @@ void nade_entrap_touch(entity this, entity toucher)
                if(!pushdeltatime) return;
 
                // div0: ticrate independent, 1 = identity (not 20)
-#ifdef SVQC
                toucher.velocity = toucher.velocity * pow(autocvar_g_nades_entrap_strength, pushdeltatime);
 
+       #ifdef SVQC
                UpdateCSQCProjectile(toucher);
-#elif defined(CSQC)
-               toucher.move_velocity = toucher.move_velocity * pow(autocvar_g_nades_entrap_strength, pushdeltatime);
-#endif
+       #endif
        }
 
        if ( IS_REAL_CLIENT(toucher) || IS_VEHICLE(toucher) || IS_MONSTER(toucher) )
@@ -767,7 +765,7 @@ void nade_touch(entity this, entity toucher)
        if(autocvar_g_nades_pickup)
        if(time >= this.spawnshieldtime)
        if(!toucher.nade && this.health == this.max_health) // no boosted shot pickups, thank you very much
-       if(!toucher.frozen)
+       if(!STAT(FROZEN, toucher))
        if(CanThrowNade(toucher)) // prevent some obvious things, like dead players
        if(IS_REAL_CLIENT(toucher)) // above checks for IS_PLAYER, don't need to do it here
        {
@@ -909,7 +907,7 @@ void toss_nade(entity e, bool set_owner, vector _velocity, float _time)
                setsize(_nade, '-8 -8 -8', '8 8 8');
        else
                setsize(_nade, '-16 -16 -16', '16 16 16');
-       _nade.movetype = MOVETYPE_BOUNCE;
+       set_movetype(_nade, MOVETYPE_BOUNCE);
 
        tracebox(_nade.origin, _nade.mins, _nade.maxs, _nade.origin, false, _nade);
        if (trace_startsolid)
index af320d9..9488e02 100644 (file)
@@ -29,12 +29,13 @@ void orb_setup(entity e)
        e.orb_radius = e.orb_radius/model_radius*0.6;
 
        e.draw = orb_draw;
+       IL_PUSH(g_drawables, e);
        e.health = 255;
-       e.movetype = MOVETYPE_NONE;
+       e.move_movetype = MOVETYPE_NONE;
        e.solid = SOLID_NOT;
        e.drawmask = MASK_NORMAL;
        e.scale = 0.01;
-       e.avelocity = e.move_avelocity = '7 0 11';
+       e.avelocity = '7 0 11';
        e.renderflags |= RF_ADDITIVE;
 }
 #endif
index a52fc46..27d1795 100644 (file)
@@ -121,6 +121,7 @@ bool nt_IsNewToy(int w)
                case WEP_MINE_LAYER.m_id:
                case WEP_HLAC.m_id:
                case WEP_RIFLE.m_id:
+               case WEP_SHOCKWAVE.m_id:
                        return true;
                default:
                        return false;
index b8fd743..2000ffd 100644 (file)
@@ -90,7 +90,10 @@ void W_HeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weapone
        W_AttachToShotorg(actor, actor.muzzle_flash, '5 0 0');
 
        if (autocvar_g_casings >= 2) // casing code
+       {
+               makevectors(actor.v_angle); // for some reason, this is lost
                SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor);
+       }
 
        int slot = weaponslot(weaponentity);
        ATTACK_FINISHED(actor, slot) = time + WEP_CVAR(hmg, refire) * W_WeaponRateFactor(actor);
index 2fb75b3..ef76ab5 100644 (file)
@@ -130,7 +130,7 @@ void ok_DropItem(entity this, entity targ)
        e.spawnfunc_checked = true;
        spawnfunc_item_armor_small(e);
        if (!wasfreed(e)) { // might have been blocked by a mutator
-        e.movetype = MOVETYPE_TOSS;
+        set_movetype(e, MOVETYPE_TOSS);
         e.gravity = 1;
         e.reset = SUB_Remove;
         setorigin(e, this.origin + '0 0 32');
index b14b6bc..4c59f18 100644 (file)
@@ -129,7 +129,7 @@ void W_RocketPropelledChainsaw_Attack (Weapon thiswep, entity actor)
        missile.health = WEP_CVAR(rpc, health);
        missile.event_damage = W_RocketPropelledChainsaw_Damage;
        missile.damagedbycontents = true;
-       missile.movetype = MOVETYPE_FLY;
+       set_movetype(missile, MOVETYPE_FLY);
 
        missile.projectiledeathtype = WEP_RPC.m_id;
        setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
index 6e4bfa5..8e9d469 100644 (file)
@@ -53,13 +53,13 @@ void physical_item_think(entity this)
                                this.angles = this.spawn_angles;
                                this.solid = SOLID_NOT;
                                this.alpha = -1;
-                               this.movetype = MOVETYPE_NONE;
+                               set_movetype(this, MOVETYPE_NONE);
                        }
                        else
                        {
                                this.alpha = 1;
                                this.solid = SOLID_CORPSE;
-                               this.movetype = MOVETYPE_PHYSICS;
+                               set_movetype(this, MOVETYPE_PHYSICS);
                        }
                }
        }
@@ -109,7 +109,7 @@ MUTATOR_HOOKFUNCTION(physical_items, Item_Spawn)
 
        wep.owner = item;
        wep.solid = SOLID_CORPSE;
-       wep.movetype = MOVETYPE_PHYSICS;
+       set_movetype(wep, MOVETYPE_PHYSICS);
        wep.takedamage = DAMAGE_AIM;
        wep.effects |= EF_NOMODELFLAGS; // disable the spinning
        wep.colormap = item.owner.colormap;
@@ -134,7 +134,7 @@ MUTATOR_HOOKFUNCTION(physical_items, Item_Spawn)
        wep.spawn_angles = item.angles;
 
        item.effects |= EF_NODRAW; // hide the original weapon
-       item.movetype = MOVETYPE_FOLLOW;
+       set_movetype(item, MOVETYPE_FOLLOW);
        item.aiment = wep; // attach the original weapon
        setSendEntity(item, func_null);
 }
index 973ff31..6adc964 100644 (file)
@@ -129,8 +129,8 @@ void sandbox_ObjectAttach_Set(entity e, entity parent, string s)
        sandbox_ObjectAttach_Remove(e);
 
        e.old_solid = e.solid; // persist solidity
-       e.old_movetype = e.movetype; // persist physics
-       e.movetype = MOVETYPE_FOLLOW;
+       e.old_movetype = e.move_movetype; // persist physics
+       set_movetype(e, MOVETYPE_FOLLOW);
        e.solid = SOLID_NOT;
        e.takedamage = DAMAGE_NO;
 
@@ -156,7 +156,7 @@ void sandbox_ObjectAttach_Remove(entity e)
                it.angles = e.angles; // don't allow detached objects to spin or roll
 
                it.solid = it.old_solid; // restore persisted solidity
-               it.movetype = it.old_movetype; // restore persisted physics
+               set_movetype(it, it.old_movetype); // restore persisted physics
                it.takedamage = DAMAGE_AIM;
        });
 }
@@ -169,7 +169,7 @@ entity sandbox_ObjectSpawn(entity this, float database)
        e.takedamage = DAMAGE_AIM;
        e.damageforcescale = 1;
        e.solid = SOLID_BBOX; // SOLID_BSP would be best, but can lag the server badly
-       e.movetype = MOVETYPE_TOSS;
+       set_movetype(e, MOVETYPE_TOSS);
        e.frame = 0;
        e.skin = 0;
        e.material = string_null;
@@ -240,7 +240,7 @@ string sandbox_ObjectPort_Save(entity e, float database)
                {
                        slot = 0;
                        solidity = head.solid; // applied solidity is normal solidity for children
-                       physics = head.movetype; // applied physics are normal physics for parents
+                       physics = head.move_movetype; // applied physics are normal physics for parents
                }
                else if(head.owner == e) // child object, list them in order
                {
@@ -347,7 +347,8 @@ entity sandbox_ObjectPort_Load(entity this, string s, float database)
                e.frame = stof(argv(argv_num)); ++argv_num;
                sandbox_ObjectEdit_Scale(e, stof(argv(argv_num)));      ++argv_num;
                e.solid = e.old_solid = stof(argv(argv_num));   ++argv_num;
-               e.movetype = e.old_movetype = stof(argv(argv_num));     ++argv_num;
+               e.old_movetype = stof(argv(argv_num));  ++argv_num;
+               set_movetype(e, e.old_movetype);
                e.damageforcescale = stof(argv(argv_num));      ++argv_num;
                if(e.material)  strunzone(e.material);  if(argv(argv_num) != "")        e.material = strzone(argv(argv_num));   else    e.material = string_null;       ++argv_num;
                if(database)
@@ -683,13 +684,13 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
                                                        switch(argv(3))
                                                        {
                                                                case "0": // static
-                                                                       e.movetype = MOVETYPE_NONE;
+                                                                       set_movetype(e, MOVETYPE_NONE);
                                                                        break;
                                                                case "1": // movable
-                                                                       e.movetype = MOVETYPE_TOSS;
+                                                                       set_movetype(e, MOVETYPE_TOSS);
                                                                        break;
                                                                case "2": // physical
-                                                                       e.movetype = MOVETYPE_PHYSICS;
+                                                                       set_movetype(e, MOVETYPE_PHYSICS);
                                                                        break;
                                                                default:
                                                                        break;
index c74715e..0fb3d61 100644 (file)
@@ -27,6 +27,7 @@ REGISTER_WAYPOINT(FlagBaseRed, _("Red base"), '0.8 0.8 0', 1);
 REGISTER_WAYPOINT(FlagBaseBlue, _("Blue base"), '0.8 0.8 0', 1);
 REGISTER_WAYPOINT(FlagBaseYellow, _("Yellow base"), '0.8 0.8 0', 1);
 REGISTER_WAYPOINT(FlagBasePink, _("Pink base"), '0.8 0.8 0', 1);
+REGISTER_WAYPOINT(FlagReturn, _("Return flag here"), '0 0.8 0.8', 1);
 
 REGISTER_WAYPOINT(DomNeut, _("Control point"), '0 1 1', 1);
 REGISTER_WAYPOINT(DomRed, _("Control point"), '0 1 1', 1);
index 441173e..4d1ade4 100644 (file)
@@ -100,9 +100,9 @@ bool WaypointSprite_SendEntity(entity this, entity to, float sendflags)
 #endif
 
 #ifdef CSQC
-void Ent_WaypointSprite(entity this);
+void Ent_WaypointSprite(entity this, bool isnew);
 NET_HANDLE(waypointsprites, bool isnew) {
-    Ent_WaypointSprite(this);
+    Ent_WaypointSprite(this, isnew);
     return true;
 }
 
@@ -114,7 +114,7 @@ void Ent_RemoveWaypointSprite(entity this)
 }
 
 /** flags origin [team displayrule] [spritename] [spritename2] [spritename3] [lifetime maxdistance hideable] */
-void Ent_WaypointSprite(entity this)
+void Ent_WaypointSprite(entity this, bool isnew)
 {
     int sendflags = ReadByte();
     this.wp_extra = ReadByte();
@@ -123,6 +123,10 @@ void Ent_WaypointSprite(entity this)
         this.spawntime = time;
 
     this.draw2d = Draw_WaypointSprite;
+    if (isnew) {
+               IL_PUSH(g_drawables_2d, this);
+               IL_PUSH(g_radaricons, this);
+    }
 
     InterpolateOrigin_Undo(this);
     this.iflags |= IFLAG_ORIGIN;
@@ -227,6 +231,7 @@ float spritelookupblinkvalue(entity this, string s)
             return 2;
     }
     if (s == WP_Item.netname) return Items_from(this.wp_extra).m_waypointblink;
+    if(s == WP_FlagReturn.netname) return 2;
 
     return 1;
 }
index fa9f4fb..26e4058 100644 (file)
@@ -108,7 +108,7 @@ vector fixrgbexcess(vector rgb);
 
 void Ent_RemoveWaypointSprite(entity this);
 
-void Ent_WaypointSprite(entity this);
+void Ent_WaypointSprite(entity this, bool isnew);
 
 void WaypointSprite_Load_Frames(string ext);
 
index 42cf6a2..25c7c63 100644 (file)
     MSG_INFO_NOTIF(WEAPON_SEEKER_MURDER_SPRAY,              1,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",       "weaponseeker",             _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Seeker rockets%s%s"), "")
     MSG_INFO_NOTIF(WEAPON_SEEKER_MURDER_TAG,                1,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",       "weaponseeker",             _("^BG%s%s^K1 was tagged by ^BG%s^K1's Seeker%s%s"), "")
     MSG_INFO_NOTIF(WEAPON_SEEKER_SUICIDE,                   1,  2, 1, "s1 s2loc spree_lost", "s1",                      "weaponseeker",             _("^BG%s^K1 played with tiny Seeker rockets%s%s"), "")
-    MSG_INFO_NOTIF(WEAPON_SHOCKWAVE_MURDER,                 1,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",       "weaponshotgun",            _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shockwave%s%s"), "")
+    MSG_INFO_NOTIF(WEAPON_SHOCKWAVE_MURDER,                 1,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",       "weaponshockwave",          _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shockwave%s%s"), "")
     MSG_INFO_NOTIF(WEAPON_SHOCKWAVE_MURDER_SLAP,            1,  3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1",       "notify_melee_shotgun",     _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shockwave%s%s"), "")
     MSG_INFO_NOTIF(WEAPON_SHOTGUN_MURDER,                   1,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",       "weaponshotgun",            _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shotgun%s%s"), "")
     MSG_INFO_NOTIF(WEAPON_SHOTGUN_MURDER_SLAP,              1,  3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1",       "notify_melee_shotgun",     _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shotgun%s%s"), "")
     MULTITEAM_CENTER(CTF_PICKUP_TEAM_VERBOSE, 4,        1,      2, 0, "s1 s2 s1",       CPID_CTF_LOWPRIO,       "0 0",  _("^BGYour %steam mate (^BG%s%s)^BG got the ^TC^TT^BG flag! Protect them!"), "", FLAG)
     MSG_CENTER_NOTIF(CTF_PICKUP_TEAM_NEUTRAL,           1,      1, 0, "s1",             CPID_CTF_LOWPRIO,       "0 0",  _("^BGYour %steam mate^BG got the flag! Protect them!"), "")
     MSG_CENTER_NOTIF(CTF_PICKUP_TEAM_VERBOSE_NEUTRAL,   1,      2, 0, "s1 s2 s1",       CPID_CTF_LOWPRIO,       "0 0",  _("^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"), "")
+    MSG_CENTER_NOTIF(CTF_PICKUP_VISIBLE,                1,      0, 0, "",               CPID_STALEMATE,         "0 0",  _("^BGEnemies can now see you on radar!"), "")
     MULTITEAM_CENTER(CTF_RETURN, 4,                     1,      0, 0, "",               CPID_CTF_LOWPRIO,       "0 0",  _("^BGYou returned the ^TC^TT^BG flag!"), "", FLAG)
     MSG_CENTER_NOTIF(CTF_STALEMATE_CARRIER,             1,      0, 0, "",               CPID_STALEMATE,         "0 0",  _("^BGStalemate! Enemies can now see you on radar!"), "")
     MSG_CENTER_NOTIF(CTF_STALEMATE_OTHER,               1,      0, 0, "",               CPID_STALEMATE,         "0 0",  _("^BGStalemate! Flag carriers can now be seen by enemies on radar!"), "")
index 4effcbd..5cb1d0b 100644 (file)
@@ -1,7 +1,6 @@
 // generated file; do not modify
 #include <common/physics/movetypes/follow.qc>
 #include <common/physics/movetypes/movetypes.qc>
-#include <common/physics/movetypes/push.qc>
 #include <common/physics/movetypes/step.qc>
 #include <common/physics/movetypes/toss.qc>
 #include <common/physics/movetypes/walk.qc>
index 32ae381..1b1241a 100644 (file)
@@ -1,7 +1,6 @@
 // generated file; do not modify
 #include <common/physics/movetypes/follow.qh>
 #include <common/physics/movetypes/movetypes.qh>
-#include <common/physics/movetypes/push.qh>
 #include <common/physics/movetypes/step.qh>
 #include <common/physics/movetypes/toss.qh>
 #include <common/physics/movetypes/walk.qh>
index 322b3c4..70157d1 100644 (file)
@@ -1,4 +1,3 @@
-#include "push.qc"
 #include "toss.qc"
 #include "walk.qc"
 #include "step.qc"
index 421c0e7..5152089 100644 (file)
@@ -4,7 +4,7 @@ void _Movetype_Physics_Follow(entity this) // SV_Physics_Follow
 
        if(e.angles == this.punchangle)
        {
-               this.move_origin = e.origin + this.view_ofs;
+               this.origin = e.origin + this.view_ofs;
        }
        else
        {
@@ -19,11 +19,11 @@ void _Movetype_Physics_Follow(entity this) // SV_Physics_Follow
                ang = e.angles;
                ang_x = -e.angles_x;
                makevectors(ang);
-               this.move_origin_x = v_x * v_forward_x + v_y * v_forward_y + v_z * v_forward_z + e.origin_x;
-               this.move_origin_x = v_x * v_right_x + v_y * v_right_y + v_z * v_right_z + e.origin_y;
-               this.move_origin_x = v_x * v_up_x + v_y * v_up_y + v_z * v_up_z + e.origin_z;
+               this.origin_x = v_x * v_forward_x + v_y * v_forward_y + v_z * v_forward_z + e.origin_x;
+               this.origin_x = v_x * v_right_x + v_y * v_right_y + v_z * v_right_z + e.origin_y;
+               this.origin_x = v_x * v_up_x + v_y * v_up_y + v_z * v_up_z + e.origin_z;
        }
 
-       this.move_angles = e.angles + this.v_angle;
+       this.angles = e.angles + this.v_angle;
        _Movetype_LinkEdict(this, false);
 }
index 78429dd..ccdf2e7 100644 (file)
        #include <server/autocvars.qh>
 #endif
 
+#ifdef SVQC
+void set_movetype(entity this, int mt)
+{
+       if(mt == MOVETYPE_PHYSICS || mt == MOVETYPE_PUSH || mt == MOVETYPE_FAKEPUSH)
+       {
+               this.movetype = this.move_movetype = mt; // we still set move_movetype, for other code that checks movetype
+               this.move_qcphysics = false;
+               return;
+       }
+
+       this.move_movetype = mt;
+
+       if(!this.move_qcphysics)
+               this.movetype = mt;
+}
+#elif defined(CSQC)
+void set_movetype(entity this, int mt)
+{
+       this.move_movetype = mt;
+}
+#endif
+
 void _Movetype_WallFriction(entity this, vector stepnormal)  // SV_WallFriction
 {
        /*float d, i;
@@ -21,11 +43,11 @@ void _Movetype_WallFriction(entity this, vector stepnormal)  // SV_WallFriction
 
        if(d < 0)
        {
-           i = (stepnormal * this.move_velocity);
+           i = (stepnormal * this.velocity);
            into = i * stepnormal;
-           side = this.move_velocity - into;
-           this.move_velocity_x = side.x * (1 * d);
-           this.move_velocity_y = side.y * (1 * d);
+           side = this.velocity - into;
+           this.velocity_x = side.x * (1 * d);
+           this.velocity_y = side.y * (1 * d);
        }*/
 }
 
@@ -46,23 +68,23 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                this.move_didgravity = 1;
                grav = dt * (PHYS_ENTGRAVITY(this) ? PHYS_ENTGRAVITY(this) : 1) * PHYS_GRAVITY(this);
 
-               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(this.move_flags & FL_ONGROUND))
+               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !IS_ONGROUND(this))
                {
                        if(GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                               this.move_velocity_z -= grav * 0.5;
+                               this.velocity_z -= grav * 0.5;
                        else
-                               this.move_velocity_z -= grav;
+                               this.velocity_z -= grav;
                }
        }
 
-       original_velocity = primal_velocity = restore_velocity = this.move_velocity;
+       original_velocity = primal_velocity = restore_velocity = this.velocity;
 
        for(bumpcount = 0;bumpcount < MAX_CLIP_PLANES;bumpcount++)
        {
-               if(this.move_velocity == '0 0 0')
+               if(this.velocity == '0 0 0')
                        break;
 
-               push = this.move_velocity * time_left;
+               push = this.velocity * time_left;
                _Movetype_PushEntity(this, push, true);
                if(trace_startsolid)
                {
@@ -76,7 +98,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                // abort move if we're stuck in the world (and didn't make it out)
                if(trace_startsolid && trace_allsolid)
                {
-                       this.move_velocity = restore_velocity;
+                       this.velocity = restore_velocity;
                        return 3;
                }
 
@@ -99,14 +121,14 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                                        trace_ent = NULL;
                                }
 
-                               this.move_flags |= FL_ONGROUND;
+                               SET_ONGROUND(this);
                                this.move_groundentity = trace_ent;
                        }
                }
                else if(stepheight)
                {
                        // step - handle it immediately
-                       vector org = this.move_origin;
+                       vector org = this.origin;
                        vector steppush = '0 0 1' * stepheight;
 
                        _Movetype_PushEntity(this, steppush, true);
@@ -122,7 +144,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                                break;
                        }
                        float trace2_fraction = trace_fraction;
-                       steppush = '0 0 1' * (org_z - this.move_origin_z);
+                       steppush = '0 0 1' * (org_z - this.origin_z);
                        _Movetype_PushEntity(this, steppush, true);
                        if(trace_startsolid)
                        {
@@ -131,15 +153,15 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                        }
 
                        // accept the new position if it made some progress...
-                       if(fabs(this.move_origin_x - org_x) >= 0.03125 || fabs(this.move_origin_y - org_y) >= 0.03125)
+                       if(fabs(this.origin_x - org_x) >= 0.03125 || fabs(this.origin_y - org_y) >= 0.03125)
                        {
-                               trace_endpos = this.move_origin;
+                               trace_endpos = this.origin;
                                time_left *= 1 - trace2_fraction;
                                numplanes = 0;
                                continue;
                        }
                        else
-                               this.move_origin = org;
+                               this.origin = org;
                }
                else
                {
@@ -153,7 +175,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                if(my_trace_fraction >= 0.001)
                {
                        // actually covered some distance
-                       original_velocity = this.move_velocity;
+                       original_velocity = this.velocity;
                        numplanes = 0;
                }
 
@@ -163,7 +185,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                if(numplanes >= MAX_CLIP_PLANES)
                {
                        // this shouldn't really happen
-                       this.move_velocity = '0 0 0';
+                       this.velocity = '0 0 0';
                        blocked = 3;
                        break;
                }
@@ -192,14 +214,14 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                if(i != numplanes)
                {
                        // go along this plane
-                       this.move_velocity = new_velocity;
+                       this.velocity = new_velocity;
                }
                else
                {
                        // go along the crease
                        if(numplanes != 2)
                        {
-                               this.move_velocity = '0 0 0';
+                               this.velocity = '0 0 0';
                                blocked = 7;
                                break;
                        }
@@ -211,29 +233,29 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                        dir.x *= ilength;
                        dir.y *= ilength;
                        dir.z *= ilength;
-                       float d = (dir * this.move_velocity);
-                       this.move_velocity = dir * d;
+                       float d = (dir * this.velocity);
+                       this.velocity = dir * d;
                }
 
                // if current velocity is against the original velocity,
                // stop dead to avoid tiny occilations in sloping corners
-               if((this.move_velocity * primal_velocity) <= 0)
+               if((this.velocity * primal_velocity) <= 0)
                {
-                       this.move_velocity = '0 0 0';
+                       this.velocity = '0 0 0';
                        break;
                }
        }
 
        // LordHavoc: this came from QW and allows you to get out of water more easily
-       if(GAMEPLAYFIX_EASIERWATERJUMP(this) && (this.move_flags & FL_WATERJUMP) && !(blocked & 8))
-               this.move_velocity = primal_velocity;
+       if(GAMEPLAYFIX_EASIERWATERJUMP(this) && (this.flags & FL_WATERJUMP) && !(blocked & 8))
+               this.velocity = primal_velocity;
 
        if(applygravity)
        {
-               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(this.move_flags & FL_ONGROUND))
+               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !IS_ONGROUND(this))
                {
                        if(GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                               this.move_velocity_z -= grav * 0.5f;
+                               this.velocity_z -= grav * 0.5f;
                }
        }
 
@@ -242,74 +264,74 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
 
 void _Movetype_CheckVelocity(entity this)  // SV_CheckVelocity
 {
-       // if(vlen(this.move_velocity) < 0.0001)
-       // this.move_velocity = '0 0 0';
+       // if(vlen(this.velocity) < 0.0001)
+       // this.velocity = '0 0 0';
 }
 
 bool _Movetype_CheckWater(entity this)  // SV_CheckWater
 {
-       vector point = this.move_origin;
+       vector point = this.origin;
        point.z += this.mins.z + 1;
 
        int nativecontents = pointcontents(point);
-       if(this.move_watertype && this.move_watertype != nativecontents)
+       if(this.watertype && this.watertype != nativecontents)
        {
-               // dprintf("_Movetype_CheckWater(): Original: '%d', New: '%d'\n", this.move_watertype, nativecontents);
+               // dprintf("_Movetype_CheckWater(): Original: '%d', New: '%d'\n", this.watertype, nativecontents);
                if(this.contentstransition)
-                       this.contentstransition(this.move_watertype, nativecontents);
+                       this.contentstransition(this.watertype, nativecontents);
        }
 
-       this.move_waterlevel = WATERLEVEL_NONE;
-       this.move_watertype = CONTENT_EMPTY;
+       this.waterlevel = WATERLEVEL_NONE;
+       this.watertype = CONTENT_EMPTY;
 
        int supercontents = Mod_Q1BSP_SuperContentsFromNativeContents(nativecontents);
        if(supercontents & DPCONTENTS_LIQUIDSMASK)
        {
-               this.move_watertype = nativecontents;
-               this.move_waterlevel = WATERLEVEL_WETFEET;
-               point.z = this.move_origin.z + (this.mins.z + this.maxs.z) * 0.5;
+               this.watertype = nativecontents;
+               this.waterlevel = WATERLEVEL_WETFEET;
+               point.z = this.origin.z + (this.mins.z + this.maxs.z) * 0.5;
                if(Mod_Q1BSP_SuperContentsFromNativeContents(pointcontents(point)) & DPCONTENTS_LIQUIDSMASK)
                {
-                       this.move_waterlevel = WATERLEVEL_SWIMMING;
-                       point.z = this.move_origin.z + this.view_ofs.z;
+                       this.waterlevel = WATERLEVEL_SWIMMING;
+                       point.z = this.origin.z + this.view_ofs.z;
                        if(Mod_Q1BSP_SuperContentsFromNativeContents(pointcontents(point)) & DPCONTENTS_LIQUIDSMASK)
-                               this.move_waterlevel = WATERLEVEL_SUBMERGED;
+                               this.waterlevel = WATERLEVEL_SUBMERGED;
                }
        }
 
-       return this.move_waterlevel > 1;
+       return this.waterlevel > 1;
 }
 
 void _Movetype_CheckWaterTransition(entity ent)  // SV_CheckWaterTransition
 {
-       int contents = pointcontents(ent.move_origin);
+       int contents = pointcontents(ent.origin);
 
-       if(!ent.move_watertype)
+       if(!ent.watertype)
        {
                // just spawned here
-               if(!autocvar_cl_gameplayfix_fixedcheckwatertransition)
+               if(!GAMEPLAYFIX_WATERTRANSITION(ent))
                {
-                       ent.move_watertype = contents;
-                       ent.move_waterlevel = 1;
+                       ent.watertype = contents;
+                       ent.waterlevel = 1;
                        return;
                }
        }
-       else if(ent.move_watertype != contents)
+       else if(ent.watertype != contents)
        {
-               // dprintf("_Movetype_CheckWaterTransition(): Origin: %s, Direct: '%d', Original: '%d', New: '%d'\n", vtos(ent.move_origin), pointcontents(ent.move_origin), ent.move_watertype, contents);
+               // dprintf("_Movetype_CheckWaterTransition(): Origin: %s, Direct: '%d', Original: '%d', New: '%d'\n", vtos(ent.origin), pointcontents(ent.origin), ent.watertype, contents);
                if(ent.contentstransition)
-                       ent.contentstransition(ent.move_watertype, contents);
+                       ent.contentstransition(ent.watertype, contents);
        }
 
        if(contents <= CONTENT_WATER)
        {
-               ent.move_watertype = contents;
-               ent.move_waterlevel = 1;
+               ent.watertype = contents;
+               ent.waterlevel = 1;
        }
        else
        {
-               ent.move_watertype = CONTENT_EMPTY;
-               ent.move_waterlevel = (autocvar_cl_gameplayfix_fixedcheckwatertransition ? 0 : contents);
+               ent.watertype = CONTENT_EMPTY;
+               ent.waterlevel = (GAMEPLAYFIX_WATERTRANSITION(ent) ? 0 : contents);
        }
 }
 
@@ -337,7 +359,7 @@ void _Movetype_LinkEdict_TouchAreaGrid(entity this)  // SV_LinkEdict_TouchAreaGr
                        trace_fraction = 1;
                        trace_inwater = false;
                        trace_inopen = true;
-                       trace_endpos = it.move_origin;
+                       trace_endpos = it.origin;
                        trace_plane_normal = '0 0 1';
                        trace_plane_dist = 0;
                        trace_ent = this;
@@ -361,10 +383,10 @@ void _Movetype_LinkEdict(entity this, bool touch_triggers)  // SV_LinkEdict
                mi = this.mins;
                ma = this.maxs;
        }
-       mi += this.move_origin;
-       ma += this.move_origin;
+       mi += this.origin;
+       ma += this.origin;
 
-       if(this.move_flags & FL_ITEM)
+       if(this.flags & FL_ITEM)
        {
                mi.x -= 15;
                mi.y -= 15;
@@ -394,18 +416,18 @@ entity _Movetype_TestEntityPosition_ent;
 bool _Movetype_TestEntityPosition(vector ofs)  // SV_TestEntityPosition
 {
     entity this = _Movetype_TestEntityPosition_ent;
-//     vector org = this.move_origin + ofs;
+//     vector org = this.origin + ofs;
 
        int cont = this.dphitcontentsmask;
        this.dphitcontentsmask = DPCONTENTS_SOLID;
-       tracebox(this.move_origin, this.mins, this.maxs, this.move_origin, ((this.move_movetype == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), this);
+       tracebox(this.origin, this.mins, this.maxs, this.origin, ((this.move_movetype == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), this);
        this.dphitcontentsmask = cont;
 
        if(trace_startsolid)
                return true;
 
-       if(vdist(trace_endpos - this.move_origin, >, 0.0001))
-               this.move_origin = trace_endpos;
+       if(vdist(trace_endpos - this.origin, >, 0.0001))
+               this.origin = trace_endpos;
        return false;
 }
 
@@ -431,12 +453,12 @@ bool _Movetype_UnstickEntity(entity this)  // SV_UnstickEntity
         #undef X
         {
             LOG_DEBUGF("Can't unstick an entity (edict: %d, classname: %s, origin: %s)\n",
-                etof(this), this.classname, vtos(this.move_origin));
+                etof(this), this.classname, vtos(this.origin));
             return false;
         }
        }
        LOG_DEBUGF("Sucessfully unstuck an entity (edict: %d, classname: %s, origin: %s)\n",
-               etof(this), this.classname, vtos(this.move_origin));
+               etof(this), this.classname, vtos(this.origin));
        _Movetype_LinkEdict(this, true);
        return true;
 }
@@ -454,7 +476,7 @@ vector _Movetype_ClipVelocity(vector vel, vector norm, float f)  // SV_ClipVeloc
 
 void _Movetype_PushEntityTrace(entity this, vector push)
 {
-       vector end = this.move_origin + push;
+       vector end = this.origin + push;
        int type;
        if(this.move_nomonsters)
                type = max(0, this.move_nomonsters);
@@ -467,7 +489,7 @@ void _Movetype_PushEntityTrace(entity this, vector push)
        else
                type = MOVE_NORMAL;
 
-       tracebox(this.move_origin, this.mins, this.maxs, end, type, this);
+       tracebox(this.origin, this.mins, this.maxs, end, type, this);
 }
 
 float _Movetype_PushEntity(entity this, vector push, bool failonstartsolid)  // SV_PushEntity
@@ -477,10 +499,10 @@ float _Movetype_PushEntity(entity this, vector push, bool failonstartsolid)  //
        if(trace_startsolid && failonstartsolid)
                return trace_fraction;
 
-       this.move_origin = trace_endpos;
+       this.origin = trace_endpos;
 
        if(trace_fraction < 1)
-               if(this.solid >= SOLID_TRIGGER && (!(this.move_flags & FL_ONGROUND) || (this.move_groundentity != trace_ent)))
+               if(this.solid >= SOLID_TRIGGER && (!IS_ONGROUND(this) || (this.move_groundentity != trace_ent)))
                        _Movetype_Impact(this, trace_ent);
 
        return trace_fraction;
@@ -551,7 +573,7 @@ void _Movetype_Physics_Frame(entity this, float movedt)
        {
                case MOVETYPE_PUSH:
                case MOVETYPE_FAKEPUSH:
-                       _Movetype_Physics_Pusher(this, movedt);
+                       LOG_DEBUGF("Physics: Lacking QuakeC support for Push movetype, FIX ME by using engine physics!\n");
                        break;
                case MOVETYPE_NONE:
                        break;
@@ -560,8 +582,8 @@ void _Movetype_Physics_Frame(entity this, float movedt)
                        break;
                case MOVETYPE_NOCLIP:
                        _Movetype_CheckWater(this);
-                       this.move_origin = this.move_origin + TICRATE * this.move_velocity;
-                       this.move_angles = this.move_angles + TICRATE * this.move_avelocity;
+                       this.origin = this.origin + movedt * this.velocity;
+                       this.angles = this.angles + movedt * this.avelocity;
                        _Movetype_LinkEdict(this, false);
                        break;
                case MOVETYPE_STEP:
@@ -591,7 +613,7 @@ void _Movetype_Physics_ClientFrame(entity this, float movedt)
        {
                case MOVETYPE_PUSH:
                case MOVETYPE_FAKEPUSH:
-                       _Movetype_Physics_Pusher(this, movedt);
+                       LOG_DEBUGF("Physics: Lacking QuakeC support for Push movetype, FIX ME by using engine physics!\n");
                        break;
                case MOVETYPE_NONE:
                        break;
@@ -600,8 +622,8 @@ void _Movetype_Physics_ClientFrame(entity this, float movedt)
                        break;
                case MOVETYPE_NOCLIP:
                        _Movetype_CheckWater(this);
-                       this.move_origin = this.move_origin + movedt * this.move_velocity;
-                       this.move_angles = this.move_angles + movedt * this.move_avelocity;
+                       this.origin = this.origin + movedt * this.velocity;
+                       this.angles = this.angles + movedt * this.avelocity;
                        _Movetype_LinkEdict(this, false);
                        break;
                case MOVETYPE_STEP:
@@ -623,6 +645,20 @@ void _Movetype_Physics_ClientFrame(entity this, float movedt)
        }
 }
 
+void Movetype_Physics_NoMatchTicrate(entity this, float movedt, bool isclient)  // to be run every move frame
+{
+       this.move_time = time;
+
+       if(isclient)
+               _Movetype_Physics_ClientFrame(this, movedt);
+       else
+               _Movetype_Physics_Frame(this, movedt);
+       if(wasfreed(this))
+               return;
+
+       setorigin(this, this.origin);
+}
+
 void Movetype_Physics_NoMatchServer(entity this)  // optimized
 {
        float movedt = time - this.move_time;
@@ -632,10 +668,7 @@ void Movetype_Physics_NoMatchServer(entity this)  // optimized
        if(wasfreed(this))
                return;
 
-       this.avelocity = this.move_avelocity;
-       this.velocity = this.move_velocity;
-       this.angles = this.move_angles;
-       setorigin(this, this.move_origin);
+       setorigin(this, this.origin);
 }
 
 void Movetype_Physics_MatchServer(entity this, bool sloppy)
@@ -643,11 +676,49 @@ void Movetype_Physics_MatchServer(entity this, bool sloppy)
        Movetype_Physics_MatchTicrate(this, TICRATE, sloppy);
 }
 
+.vector tic_origin;
+.vector tic_velocity;
+.int tic_flags;
+.vector tic_avelocity;
+.vector tic_angles;
+
+.vector tic_saved_origin;
+.vector tic_saved_velocity;
+.int tic_saved_flags;
+.vector tic_saved_avelocity;
+.vector tic_saved_angles;
 void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Physics_Entity
 {
+#define X(s) \
+       if(this.(s) != this.tic_saved_##s) \
+               this.tic_##s = this.(s)
+
+       X(origin);
+       X(velocity);
+       X(flags);
+       X(avelocity);
+       X(angles);
+#undef X
+
        if(tr <= 0)
        {
+               this.flags = this.tic_flags;
+               this.velocity = this.tic_velocity;
+               this.origin = this.tic_origin;
+               this.avelocity = this.tic_avelocity;
+               this.angles = this.tic_angles;
                Movetype_Physics_NoMatchServer(this);
+               this.tic_origin = this.origin;
+               this.tic_velocity = this.velocity;
+               this.tic_avelocity = this.avelocity;
+               this.tic_angles = this.angles;
+               this.tic_flags = this.flags;
+
+               this.tic_saved_flags = this.flags;
+               this.tic_saved_velocity = this.velocity;
+               this.tic_saved_origin = this.origin;
+               this.tic_saved_avelocity = this.avelocity;
+               this.tic_saved_angles = this.angles;
                return;
        }
 
@@ -658,21 +729,31 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
        this.move_time += n * tr;
 
        if(!this.move_didgravity)
-               this.move_didgravity = ((this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS) && !(this.move_flags & FL_ONGROUND));
+               this.move_didgravity = ((this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS) && !(this.tic_flags & FL_ONGROUND));
 
        for (int i = 0; i < n; ++i)
        {
+               this.flags = this.tic_flags;
+               this.velocity = this.tic_velocity;
+               setorigin(this, this.tic_origin);
+               this.avelocity = this.tic_avelocity;
+               this.angles = this.tic_angles;
                _Movetype_Physics_Frame(this, tr);
+               this.tic_origin = this.origin;
+               this.tic_velocity = this.velocity;
+               this.tic_avelocity = this.avelocity;
+               this.tic_angles = this.angles;
+               this.tic_flags = this.flags;
                if(wasfreed(this))
                        return;
        }
 
-       this.avelocity = this.move_avelocity;
+       this.avelocity = this.tic_avelocity;
 
-       if(dt > 0 && this.move_movetype != MOVETYPE_NONE && !(this.move_flags & FL_ONGROUND))
+       if(dt > 0 && this.move_movetype != MOVETYPE_NONE && !(this.tic_flags & FL_ONGROUND))
        {
                // now continue the move from move_time to time
-               this.velocity = this.move_velocity;
+               this.velocity = this.tic_velocity;
 
                if(this.move_didgravity > 0)
                {
@@ -682,15 +763,18 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
                            * PHYS_GRAVITY(this);
                }
 
-               this.angles = this.move_angles + dt * this.avelocity;
+               this.angles = this.tic_angles + dt * this.avelocity;
 
                if(sloppy || this.move_movetype == MOVETYPE_NOCLIP)
                {
-                       setorigin(this, this.move_origin + dt * this.velocity);
+                       setorigin(this, this.tic_origin + dt * this.velocity);
                }
                else
                {
+                       vector oldorg = this.origin;
+                       this.origin = this.tic_origin;
                        _Movetype_PushEntityTrace(this, dt * this.velocity);
+                       this.origin = oldorg;
                        if(!trace_startsolid)
                                setorigin(this, trace_endpos);
                }
@@ -700,8 +784,14 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
        }
        else
        {
-               this.velocity = this.move_velocity;
-               this.angles = this.move_angles;
-               setorigin(this, this.move_origin);
+               this.velocity = this.tic_velocity;
+               this.angles = this.tic_angles;
+               setorigin(this, this.tic_origin);
        }
+
+       this.tic_saved_flags = this.flags;
+       this.tic_saved_velocity = this.velocity;
+       this.tic_saved_origin = this.origin;
+       this.tic_saved_avelocity = this.avelocity;
+       this.tic_saved_angles = this.angles;
 }
index 09b6e4d..cd0f09c 100644 (file)
@@ -5,31 +5,34 @@
 #define SET_ONGROUND(s)                     ((s).flags |= FL_ONGROUND)
 #define UNSET_ONGROUND(s)                   ((s).flags &= ~FL_ONGROUND)
 
-.float move_ltime;
-.void(entity this) move_think;
-.float move_nextthink;
-.void(entity this, entity blocker) move_blocked;
+#ifdef CSQC
+.float bouncestop;
+.float bouncefactor;
+#endif
+
+#ifdef SVQC
+.bool move_qcphysics;
+#endif
+
+void set_movetype(entity this, int mt);
 
 .float move_movetype;
 .float move_time;
-.vector move_origin;
-.vector move_angles;
-.vector move_velocity;
-.vector move_avelocity;
-.int move_flags;
-.int move_watertype;
-.int move_waterlevel;
+//.vector move_origin;
+//.vector move_angles;
+//.vector move_velocity;
+//.vector move_avelocity;
+//.int move_flags;
+//.int move_watertype;
+//.int move_waterlevel;
 .void(float, float)contentstransition;
-.float move_bounce_factor;
-.float move_bounce_stopspeed;
+//.float move_bounce_factor;
+//.float move_bounce_stopspeed;
 .float move_nomonsters;  // -1 for MOVE_NORMAL, otherwise a MOVE_ constant
 
 .entity aiment;
 .vector punchangle;
 
-// should match sv_gameplayfix_fixedcheckwatertransition
-float autocvar_cl_gameplayfix_fixedcheckwatertransition = 1;
-
 .entity move_groundentity;  // FIXME add move_groundnetworkentity?
 .float move_suspendedinair;
 .float move_didgravity;
@@ -46,6 +49,7 @@ void _Movetype_PushEntityTrace(entity this, vector push);
 float _Movetype_PushEntity(entity this, vector push, float failonstartsolid);
 void makevectors_matrix(vector myangles);
 
+void Movetype_Physics_NoMatchTicrate(entity this, float movedt, bool isclient);
 void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy);
 void Movetype_Physics_MatchServer(entity this, bool sloppy);
 void Movetype_Physics_NoMatchServer(entity this);
diff --git a/qcsrc/common/physics/movetypes/push.qc b/qcsrc/common/physics/movetypes/push.qc
deleted file mode 100644 (file)
index 5a0426e..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-void _Movetype_PushMove(entity this, float dt)  // SV_PushMove
-{
-       if (this.move_velocity == '0 0 0' && this.move_avelocity == '0 0 0')
-       {
-               this.move_ltime += dt;
-               return;
-       }
-
-       switch (this.solid)
-       {
-               // LordHavoc: valid pusher types
-               case SOLID_BSP:
-               case SOLID_BBOX:
-               case SOLID_SLIDEBOX:
-               case SOLID_CORPSE:  // LordHavoc: this would be weird...
-                       break;
-               // LordHavoc: no collisions
-               case SOLID_NOT:
-               case SOLID_TRIGGER:
-                       this.move_origin = this.move_origin + dt * this.move_velocity;
-                       this.move_angles = this.move_angles + dt * this.move_avelocity;
-                       this.move_angles_x -= 360.0 * floor(this.move_angles.x * (1.0 / 360.0));
-                       this.move_angles_y -= 360.0 * floor(this.move_angles.y * (1.0 / 360.0));
-                       this.move_angles_z -= 360.0 * floor(this.move_angles.z * (1.0 / 360.0));
-                       this.move_ltime += dt;
-                       _Movetype_LinkEdict(this, true);
-                       return;
-               default:
-                       LOG_TRACEF("_Movetype_PushMove: entity %e, unrecognized solid type %d\n", this, this.solid);
-                       return;
-       }
-
-       bool rotated = (this.move_angles * this.move_angles) + (this.move_avelocity * this.move_avelocity) > 0;
-
-       vector move1 = this.move_velocity * dt;
-       vector moveangle = this.move_avelocity * dt;
-
-       makevectors_matrix(-moveangle);
-
-//     vector pushorig = this.move_origin;
-//     vector pushang = this.move_angles;
-//     float pushltime = this.move_ltime;
-
-// move the pusher to its final position
-
-       this.move_origin = this.move_origin + dt * this.move_velocity;
-       this.move_angles = this.move_angles + dt * this.move_avelocity;
-
-       this.move_ltime += dt;
-       _Movetype_LinkEdict(this, true);
-
-       int savesolid = this.solid;
-
-       if (this.move_movetype != MOVETYPE_FAKEPUSH)
-       {
-           FOREACH_ENTITY_RADIUS(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin), true, {
-                       switch (it.move_movetype)
-                       {
-                               case MOVETYPE_NONE:
-                               case MOVETYPE_PUSH:
-                               case MOVETYPE_FOLLOW:
-                               case MOVETYPE_NOCLIP:
-                               case MOVETYPE_FLY_WORLDONLY:
-                                       continue;
-                               default:
-                                       break;
-                       }
-
-                       if (it.owner == this)
-                               continue;
-
-                       if (this.owner == it)
-                               continue;
-
-                       vector pivot = it.mins + 0.5 * (it.maxs - it.mins);
-                       vector move;
-                       if (rotated)
-                       {
-                               vector org = (it.move_origin - this.move_origin) + pivot;
-                               vector org2;
-                               org2.x = org * v_forward;
-                               org2.y = org * v_right;
-                               org2.z = org * v_up;
-                               move = (org2 - org) + move1;
-                       }
-                       else
-                       {
-                               move = move1;
-                       }
-
-                       // physics objects need better collisions than this code can do
-                       if (it.move_movetype == 32)  // MOVETYPE_PHYSICS
-                       {
-                               it.move_origin = it.move_origin + move;
-                               _Movetype_LinkEdict(it, true);
-                               continue;
-                       }
-
-                       // try moving the contacted entity
-                       this.solid = SOLID_NOT;
-                       bool flag = false;
-                       flag = _Movetype_PushEntity(it, move, true);
-                       if (!flag)
-                       {
-                               // entity "it" got teleported
-                               it.move_angles_y += trace_fraction * moveangle.y;
-                               this.solid = savesolid;
-                               continue;  // pushed enough
-                       }
-                       // FIXME: turn players specially
-                       it.move_angles_y += trace_fraction * moveangle.y;
-                       this.solid = savesolid;
-
-                       // this trace.fraction < 1 check causes items to fall off of pushers
-                       // if they pass under or through a wall
-                       // the groundentity check causes items to fall off of ledges
-                       if (it.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || it.move_groundentity != this))
-                               it.move_flags &= ~FL_ONGROUND;
-        });
-       }
-
-       this.move_angles_x -= 360.0 * floor(this.move_angles.x * (1.0 / 360.0));
-       this.move_angles_y -= 360.0 * floor(this.move_angles.y * (1.0 / 360.0));
-       this.move_angles_z -= 360.0 * floor(this.move_angles.z * (1.0 / 360.0));
-}
-
-void _Movetype_Physics_Pusher(entity this, float dt)  // SV_Physics_Pusher
-{
-       float oldltime = this.move_ltime;
-       float thinktime = this.move_nextthink;
-       float movetime;
-       if (thinktime < this.move_ltime + dt)
-       {
-               movetime = thinktime - this.move_ltime;
-               if (movetime < 0)
-                       movetime = 0;
-       }
-       else
-       {
-               movetime = dt;
-       }
-
-       if (movetime)
-               // advances this.move_ltime if not blocked
-               _Movetype_PushMove(this, movetime);
-
-       if (thinktime > oldltime && thinktime <= this.move_ltime)
-       {
-               this.move_nextthink = 0;
-               this.move_time = time;
-               this.move_think(this);
-       }
-}
index d7a2d56..7eb553b 100644 (file)
@@ -1,10 +1,10 @@
 void _Movetype_Physics_Step(entity this, float dt) // SV_Physics_Step
 {
-       if(this.move_flags & FL_ONGROUND)
+       if(IS_ONGROUND(this))
        {
                if(this.velocity_z >= (1.0 / 32.0) && UPWARD_VELOCITY_CLEARS_ONGROUND(this))
                {
-                       this.move_flags &= ~FL_ONGROUND;
+                       UNSET_ONGROUND(this);
                        _Movetype_CheckVelocity(this);
                        _Movetype_FlyMove(this, dt, true, '0 0 0', 0);
                        _Movetype_LinkEdict(this, true);
index 5bea38c..db3ff72 100644 (file)
@@ -2,11 +2,11 @@
 
 void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
 {
-       if (this.move_flags & FL_ONGROUND)
+       if (IS_ONGROUND(this))
        {
-               if (this.move_velocity.z >= 1 / 32 && UPWARD_VELOCITY_CLEARS_ONGROUND(this))
+               if (this.velocity.z >= 1 / 32 && UPWARD_VELOCITY_CLEARS_ONGROUND(this))
                {
-                       this.move_flags &= ~FL_ONGROUND;
+                       UNSET_ONGROUND(this);
                }
                else if (!this.move_groundentity)
                {
@@ -26,7 +26,7 @@ void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
        /*if (this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS)
        {
                this.move_didgravity = 1;
-               this.move_velocity_z -= (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1)
+               this.velocity_z -= (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1)
                    * dt
                    * (this.gravity ? this.gravity : 1)
                    * PHYS_GRAVITY(this);
@@ -35,15 +35,15 @@ void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
        if (this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS)
        {
                this.move_didgravity = true;
-               this.move_velocity_z -= (((this.gravity) ? this.gravity : 1) * PHYS_GRAVITY(this) * dt);
+               this.velocity_z -= (((this.gravity) ? this.gravity : 1) * PHYS_GRAVITY(this) * dt);
        }
 
-       this.move_angles = this.move_angles + this.move_avelocity * dt;
+       this.angles = this.angles + this.avelocity * dt;
 
        float movetime = dt;
        for (int bump = 0; bump < MAX_CLIP_PLANES && movetime > 0; ++bump)
        {
-               vector move = this.move_velocity * movetime;
+               vector move = this.velocity * movetime;
                _Movetype_PushEntity(this, move, true);
                if (wasfreed(this))
                        return;
@@ -63,45 +63,45 @@ void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
 
                if (this.move_movetype == MOVETYPE_BOUNCEMISSILE)
                {
-                       this.move_velocity = _Movetype_ClipVelocity(this.move_velocity, trace_plane_normal, 2.0);
-                       this.move_flags &= ~FL_ONGROUND;
+                       this.velocity = _Movetype_ClipVelocity(this.velocity, trace_plane_normal, 2.0);
+                       UNSET_ONGROUND(this);
                }
                else if (this.move_movetype == MOVETYPE_BOUNCE)
                {
-                       float bouncefac = this.move_bounce_factor;     if (!bouncefac)  bouncefac = 0.5;
-                       float bouncestop = this.move_bounce_stopspeed; if (!bouncestop) bouncestop = 60 / 800;
-                       bouncestop *= (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
+                       float bouncefac = this.bouncefactor;     if (!bouncefac)  bouncefac = 0.5;
+                       float bstop = this.bouncestop; if (!bstop) bstop = 60 / 800;
+                       bstop *= (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
 
-                       this.move_velocity = _Movetype_ClipVelocity(this.move_velocity, trace_plane_normal, 1 + bouncefac);
+                       this.velocity = _Movetype_ClipVelocity(this.velocity, trace_plane_normal, 1 + bouncefac);
 
-                       float d = trace_plane_normal * this.move_velocity;
-                       if (trace_plane_normal.z > 0.7 && d < bouncestop && d > -bouncestop)
+                       float d = trace_plane_normal * this.velocity;
+                       if (trace_plane_normal.z > 0.7 && d < bstop && d > -bstop)
                        {
-                               this.move_flags |= FL_ONGROUND;
+                               SET_ONGROUND(this);
                                this.move_groundentity = trace_ent;
-                               this.move_velocity = '0 0 0';
-                               this.move_avelocity = '0 0 0';
+                               this.velocity = '0 0 0';
+                               this.avelocity = '0 0 0';
                        }
                        else
                        {
-                               this.move_flags &= ~FL_ONGROUND;
+                               UNSET_ONGROUND(this);
                        }
                }
                else
                {
-                       this.move_velocity = _Movetype_ClipVelocity(this.move_velocity, trace_plane_normal, 1.0);
+                       this.velocity = _Movetype_ClipVelocity(this.velocity, trace_plane_normal, 1.0);
                        if (trace_plane_normal.z > 0.7)
                        {
-                               this.move_flags |= FL_ONGROUND;
+                               SET_ONGROUND(this);
                                this.move_groundentity = trace_ent;
                                if (trace_ent.solid == SOLID_BSP)
                                        this.move_suspendedinair = true;
-                               this.move_velocity = '0 0 0';
-                               this.move_avelocity = '0 0 0';
+                               this.velocity = '0 0 0';
+                               this.avelocity = '0 0 0';
                        }
                        else
                        {
-                               this.move_flags &= ~FL_ONGROUND;
+                               UNSET_ONGROUND(this);
                        }
                }
 
@@ -110,12 +110,12 @@ void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
                        break;
 
                // DP revision 8918 (WHY...)
-               if (this.move_flags & FL_ONGROUND)
+               if (IS_ONGROUND(this))
                        break;
        }
 
-       //if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE && this.move_didgravity > 0 && !(this.move_flags & FL_ONGROUND))
-       //      this.move_velocity_z -= 0.5 * dt * (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
+       //if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE && this.move_didgravity > 0 && !IS_ONGROUND(this))
+       //      this.velocity_z -= 0.5 * dt * (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
 
        _Movetype_CheckWaterTransition(this);
 }
index e926246..45b1dc3 100644 (file)
@@ -9,15 +9,15 @@ void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
        if (GAMEPLAYFIX_UNSTICKPLAYERS(this))
                _Movetype_UnstickEntity(this);
 
-       bool applygravity = (!_Movetype_CheckWater(this) && this.move_movetype == MOVETYPE_WALK && !(this.move_flags & FL_WATERJUMP));
+       bool applygravity = (!_Movetype_CheckWater(this) && this.move_movetype == MOVETYPE_WALK && !(this.flags & FL_WATERJUMP));
 
        _Movetype_CheckVelocity(this);
 
        // do a regular slide move unless it looks like you ran into a step
-       bool oldonground = (this.move_flags & FL_ONGROUND);
+       bool oldonground = IS_ONGROUND(this);
 
-       vector start_origin = this.move_origin;
-       vector start_velocity = this.move_velocity;
+       vector start_origin = this.origin;
+       vector start_velocity = this.velocity;
 
        int clip = _Movetype_FlyMove(this, dt, applygravity, stepnormal, GAMEPLAYFIX_STEPMULTIPLETIMES(this) ? PHYS_STEPHEIGHT(this) : 0);
 
@@ -26,8 +26,8 @@ void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
                // only try this if there was no floor in the way in the trace (no,
                // this check seems to be not REALLY necessary, because if clip & 1,
                // our trace will hit that thing too)
-               vector upmove = this.move_origin + '0 0 1';
-               vector downmove = this.move_origin - '0 0 1';
+               vector upmove = this.origin + '0 0 1';
+               vector downmove = this.origin - '0 0 1';
                int type;
                if (this.move_movetype == MOVETYPE_FLYMISSILE)
                        type = MOVE_MISSILE;
@@ -43,7 +43,7 @@ void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
 
        // if the move did not hit the ground at any point, we're not on ground
        if (!(clip & 1))
-               this.move_flags &= ~FL_ONGROUND;
+               UNSET_ONGROUND(this);
 
        _Movetype_CheckVelocity(this);
        _Movetype_LinkEdict(this, true);
@@ -51,16 +51,16 @@ void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
        if (clip & 8)  // teleport
                return;
 
-       if (this.move_flags & FL_WATERJUMP)
+       if (this.flags & FL_WATERJUMP)
                return;
 
        if (PHYS_NOSTEP(this))
                return;
 
-       vector originalmove_origin = this.move_origin;
-       vector originalmove_velocity = this.move_velocity;
+       vector originalorigin = this.origin;
+       vector originalvelocity = this.velocity;
        // originalmove_clip = clip;
-       int originalmove_flags = this.move_flags;
+       int originalflags = this.flags;
        entity originalmove_groundentity = this.move_groundentity;
 
        // if move didn't block on a step, return
@@ -78,14 +78,14 @@ void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
 
                        // return if attempting to jump while airborn (unless sv_jumpstep)
                        if (!PHYS_JUMPSTEP(this))
-                               if (!oldonground && this.move_waterlevel == 0)
+                               if (!oldonground && this.waterlevel == 0)
                                        return;
                }
 
                // try moving up and forward to go up a step
                // back to start pos
-               this.move_origin = start_origin;
-               this.move_velocity = start_velocity;
+               this.origin = start_origin;
+               this.velocity = start_velocity;
 
                // move up
                vector upmove = '0 0 1' * PHYS_STEPHEIGHT(this);
@@ -99,9 +99,9 @@ void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
                }
 
                // move forward
-               this.move_velocity_z = 0;
+               this.velocity_z = 0;
                clip = _Movetype_FlyMove(this, dt, applygravity, stepnormal, 0);
-               this.move_velocity_z += start_velocity.z;
+               this.velocity_z += start_velocity.z;
                if (clip & 8)
                {
                        // we got teleported when upstepping... must abort the move
@@ -115,15 +115,15 @@ void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
                // check for stuckness, possibly due to the limited precision of floats
                // in the clipping hulls
                if (clip
-                   && fabs(originalmove_origin.y - this.move_origin.y) < 0.03125
-                   && fabs(originalmove_origin.x - this.move_origin.x) < 0.03125)
+                   && fabs(originalorigin.y - this.origin.y) < 0.03125
+                   && fabs(originalorigin.x - this.origin.x) < 0.03125)
                {
                        // Con_Printf("wall\n");
                        // stepping up didn't make any progress, revert to original move
-                       this.move_origin = originalmove_origin;
-                       this.move_velocity = originalmove_velocity;
+                       this.origin = originalorigin;
+                       this.velocity = originalvelocity;
                        // clip = originalmove_clip;
-                       this.move_flags = originalmove_flags;
+                       this.flags = originalflags;
                        this.move_groundentity = originalmove_groundentity;
                        // now try to unstick if needed
                        // clip = SV_TryUnstick (ent, oldvel);
@@ -137,7 +137,7 @@ void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
                        _Movetype_WallFriction(this, stepnormal);
        }
        // don't do the down move if stepdown is disabled, moving upward, not in water, or the move started offground or ended onground
-       else if (!GAMEPLAYFIX_STEPDOWN(this) || this.move_waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0) || !oldonground || (this.move_flags & FL_ONGROUND))
+       else if (!GAMEPLAYFIX_STEPDOWN(this) || this.waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0) || !oldonground || IS_ONGROUND(this))
        {
                return;
        }
@@ -165,9 +165,9 @@ void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
                // if the push down didn't end up on good ground, use the move without
                // the step up.  This happens near wall / slope combinations, and can
                // cause the player to hop up higher on a slope too steep to climb
-               this.move_origin = originalmove_origin;
-               this.move_velocity = originalmove_velocity;
-               this.move_flags = originalmove_flags;
+               this.origin = originalorigin;
+               this.velocity = originalvelocity;
+               this.flags = originalflags;
                this.move_groundentity = originalmove_groundentity;
        }
 
index 8ab8a13..1ef5faa 100644 (file)
@@ -13,7 +13,7 @@ bool Physics_Valid(string thecvar)
        return autocvar_g_physics_clientselect && strhasword(autocvar_g_physics_clientselect_options, thecvar);
 }
 
-float Physics_ClientOption(entity this, string option)
+float Physics_ClientOption(entity this, string option, float defaultval)
 {
        if(Physics_Valid(this.cvar_cl_physics))
        {
@@ -27,40 +27,40 @@ float Physics_ClientOption(entity this, string option)
                if(cvar_type(s) & CVAR_TYPEFLAG_EXISTS)
                        return cvar(s);
        }
-       return cvar(strcat("sv_", option));
+       return defaultval;
 }
 
 void Physics_UpdateStats(entity this, float maxspd_mod)
 {
-       STAT(MOVEVARS_AIRACCEL_QW, this) = AdjustAirAccelQW(Physics_ClientOption(this, "airaccel_qw"), maxspd_mod);
-       STAT(MOVEVARS_AIRSTRAFEACCEL_QW, this) = (Physics_ClientOption(this, "airstrafeaccel_qw"))
-               ? AdjustAirAccelQW(Physics_ClientOption(this, "airstrafeaccel_qw"), maxspd_mod)
+       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)
                : 0;
-       STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, this) = Physics_ClientOption(this, "airspeedlimit_nonqw") * maxspd_mod;
-       STAT(MOVEVARS_MAXSPEED, this) = Physics_ClientOption(this, "maxspeed") * maxspd_mod; // also slow walking
+       STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, this) = Physics_ClientOption(this, "airspeedlimit_nonqw", autocvar_sv_airspeedlimit_nonqw) * maxspd_mod;
+       STAT(MOVEVARS_MAXSPEED, this) = Physics_ClientOption(this, "maxspeed", autocvar_sv_maxspeed) * maxspd_mod; // also slow walking
 
        // old stats
        // fix some new settings
-       STAT(MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, this) = Physics_ClientOption(this, "airaccel_qw_stretchfactor");
-       STAT(MOVEVARS_MAXAIRSTRAFESPEED, this) = Physics_ClientOption(this, "maxairstrafespeed");
-       STAT(MOVEVARS_MAXAIRSPEED, this) = Physics_ClientOption(this, "maxairspeed");
-       STAT(MOVEVARS_AIRSTRAFEACCELERATE, this) = Physics_ClientOption(this, "airstrafeaccelerate");
-       STAT(MOVEVARS_WARSOWBUNNY_TURNACCEL, this) = Physics_ClientOption(this, "warsowbunny_turnaccel");
-       STAT(MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, this) = Physics_ClientOption(this, "airaccel_sideways_friction");
-       STAT(MOVEVARS_AIRCONTROL, this) = Physics_ClientOption(this, "aircontrol");
-       STAT(MOVEVARS_AIRCONTROL_POWER, this) = Physics_ClientOption(this, "aircontrol_power");
-       STAT(MOVEVARS_AIRCONTROL_PENALTY, this) = Physics_ClientOption(this, "aircontrol_penalty");
-       STAT(MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, this) = Physics_ClientOption(this, "warsowbunny_airforwardaccel");
-       STAT(MOVEVARS_WARSOWBUNNY_TOPSPEED, this) = Physics_ClientOption(this, "warsowbunny_topspeed");
-       STAT(MOVEVARS_WARSOWBUNNY_ACCEL, this) = Physics_ClientOption(this, "warsowbunny_accel");
-       STAT(MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, this) = Physics_ClientOption(this, "warsowbunny_backtosideratio");
-       STAT(MOVEVARS_FRICTION, this) = Physics_ClientOption(this, "friction");
-       STAT(MOVEVARS_ACCELERATE, this) = Physics_ClientOption(this, "accelerate");
-       STAT(MOVEVARS_STOPSPEED, this) = Physics_ClientOption(this, "stopspeed");
-       STAT(MOVEVARS_AIRACCELERATE, this) = Physics_ClientOption(this, "airaccelerate");
-       STAT(MOVEVARS_AIRSTOPACCELERATE, this) = Physics_ClientOption(this, "airstopaccelerate");
-       STAT(MOVEVARS_JUMPVELOCITY, this) = Physics_ClientOption(this, "jumpvelocity");
-       STAT(MOVEVARS_TRACK_CANJUMP, this) = Physics_ClientOption(this, "track_canjump");
+       STAT(MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, this) = Physics_ClientOption(this, "airaccel_qw_stretchfactor", autocvar_sv_airaccel_qw_stretchfactor);
+       STAT(MOVEVARS_MAXAIRSTRAFESPEED, this) = Physics_ClientOption(this, "maxairstrafespeed", autocvar_sv_maxairstrafespeed);
+       STAT(MOVEVARS_MAXAIRSPEED, this) = Physics_ClientOption(this, "maxairspeed", autocvar_sv_maxairspeed);
+       STAT(MOVEVARS_AIRSTRAFEACCELERATE, this) = Physics_ClientOption(this, "airstrafeaccelerate", autocvar_sv_airstrafeaccelerate);
+       STAT(MOVEVARS_WARSOWBUNNY_TURNACCEL, this) = Physics_ClientOption(this, "warsowbunny_turnaccel", autocvar_sv_warsowbunny_turnaccel);
+       STAT(MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, this) = Physics_ClientOption(this, "airaccel_sideways_friction", autocvar_sv_airaccel_sideways_friction);
+       STAT(MOVEVARS_AIRCONTROL, this) = Physics_ClientOption(this, "aircontrol", autocvar_sv_aircontrol);
+       STAT(MOVEVARS_AIRCONTROL_POWER, this) = Physics_ClientOption(this, "aircontrol_power", autocvar_sv_aircontrol_power);
+       STAT(MOVEVARS_AIRCONTROL_PENALTY, this) = Physics_ClientOption(this, "aircontrol_penalty", autocvar_sv_aircontrol_penalty);
+       STAT(MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, this) = Physics_ClientOption(this, "warsowbunny_airforwardaccel", autocvar_sv_warsowbunny_airforwardaccel);
+       STAT(MOVEVARS_WARSOWBUNNY_TOPSPEED, this) = Physics_ClientOption(this, "warsowbunny_topspeed", autocvar_sv_warsowbunny_topspeed);
+       STAT(MOVEVARS_WARSOWBUNNY_ACCEL, this) = Physics_ClientOption(this, "warsowbunny_accel", autocvar_sv_warsowbunny_accel);
+       STAT(MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, this) = Physics_ClientOption(this, "warsowbunny_backtosideratio", autocvar_sv_warsowbunny_backtosideratio);
+       STAT(MOVEVARS_FRICTION, this) = Physics_ClientOption(this, "friction", autocvar_sv_friction);
+       STAT(MOVEVARS_ACCELERATE, this) = Physics_ClientOption(this, "accelerate", autocvar_sv_accelerate);
+       STAT(MOVEVARS_STOPSPEED, this) = Physics_ClientOption(this, "stopspeed", autocvar_sv_stopspeed);
+       STAT(MOVEVARS_AIRACCELERATE, this) = Physics_ClientOption(this, "airaccelerate", autocvar_sv_airaccelerate);
+       STAT(MOVEVARS_AIRSTOPACCELERATE, this) = Physics_ClientOption(this, "airstopaccelerate", autocvar_sv_airstopaccelerate);
+       STAT(MOVEVARS_JUMPVELOCITY, this) = Physics_ClientOption(this, "jumpvelocity", autocvar_sv_jumpvelocity);
+       STAT(MOVEVARS_TRACK_CANJUMP, this) = Physics_ClientOption(this, "track_canjump", autocvar_sv_track_canjump);
 }
 #endif
 
@@ -118,24 +118,25 @@ void PM_ClientMovement_Unstick(entity this)
        #undef X
 }
 
-void PM_ClientMovement_UpdateStatus(entity this, bool ground)
+void PM_ClientMovement_UpdateStatus(entity this)
 {
 #ifdef CSQC
        if(!IS_PLAYER(this))
                return;
-       // make sure player is not stuck
-       if(autocvar_cl_movement == 3)
-               PM_ClientMovement_Unstick(this);
 
        // set crouched
        bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
        if(this.hook && !wasfreed(this.hook))
                do_crouch = false;
+       if(this.waterlevel >= WATERLEVEL_SWIMMING)
+               do_crouch = false;
        if(hud != HUD_NORMAL)
                do_crouch = false;
        if(STAT(FROZEN, this))
                do_crouch = false;
-       if((activeweapon == WEP_SHOCKWAVE || activeweapon == WEP_SHOTGUN) && viewmodel.animstate_startframe == viewmodel.anim_fire2_x && time < viewmodel.weapon_nextthink)
+       if((activeweapon.spawnflags & WEP_TYPE_MELEE_PRI) && viewmodel.animstate_startframe == viewmodel.anim_fire1_x && time < viewmodel.weapon_nextthink)
+               do_crouch = false;
+       if((activeweapon.spawnflags & WEP_TYPE_MELEE_SEC) && viewmodel.animstate_startframe == viewmodel.anim_fire2_x && time < viewmodel.weapon_nextthink)
                do_crouch = false;
 
        if (do_crouch)
@@ -153,148 +154,11 @@ void PM_ClientMovement_UpdateStatus(entity this, bool ground)
                }
        }
 
-       // set onground
-       vector origin1 = this.origin + '0 0 1';
-       vector origin2 = this.origin - '0 0 1';
-
-       if (ground && autocvar_cl_movement == 3)
-       {
-               tracebox(origin1, this.mins, this.maxs, origin2, MOVE_NORMAL, this);
-               if (trace_fraction < 1.0 && trace_plane_normal.z > 0.7)
-               {
-                       SET_ONGROUND(this);
-
-                       // this code actually "predicts" an impact; so let's clip velocity first
-                       this.velocity -= this.velocity * trace_plane_normal * trace_plane_normal;
-               }
-               else
-                       UNSET_ONGROUND(this);
-       }
-
-       if(autocvar_cl_movement == 3)
-       {
-               // set watertype/waterlevel
-               origin1 = this.origin;
-               origin1.z += this.mins_z + 1;
-               this.waterlevel = WATERLEVEL_NONE;
-
-               int thepoint = pointcontents(origin1);
-
-               this.watertype = (thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME);
-
-               if (this.watertype)
-               {
-                       this.waterlevel = WATERLEVEL_WETFEET;
-                       origin1.z = this.origin.z + (this.mins.z + this.maxs.z) * 0.5;
-                       thepoint = pointcontents(origin1);
-                       if (thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME)
-                       {
-                               this.waterlevel = WATERLEVEL_SWIMMING;
-                               origin1.z = this.origin.z + 22;
-                               thepoint = pointcontents(origin1);
-                               if (thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME)
-                                       this.waterlevel = WATERLEVEL_SUBMERGED;
-                       }
-               }
-       }
-
        if (IS_ONGROUND(this) || this.velocity.z <= 0 || pmove_waterjumptime <= 0)
                pmove_waterjumptime = 0;
 #endif
 }
 
-void PM_ClientMovement_Move(entity this)
-{
-#ifdef CSQC
-
-       PM_ClientMovement_UpdateStatus(this, false);
-       if(autocvar_cl_movement == 1)
-               return;
-
-       int bump;
-       float t;
-       float f;
-       vector neworigin;
-       vector currentorigin2;
-       vector neworigin2;
-       vector primalvelocity;
-
-       vector trace1_endpos = '0 0 0';
-       vector trace2_endpos = '0 0 0';
-       vector trace3_endpos = '0 0 0';
-       float trace1_fraction = 0;
-       float trace2_fraction = 0;
-       float trace3_fraction = 0;
-       vector trace1_plane_normal = '0 0 0';
-       vector trace2_plane_normal = '0 0 0';
-       vector trace3_plane_normal = '0 0 0';
-
-       primalvelocity = this.velocity;
-       for(bump = 0, t = PHYS_INPUT_TIMELENGTH; bump < 8 && (this.velocity * this.velocity) > 0; bump++)
-       {
-               neworigin = this.origin + t * this.velocity;
-               tracebox(this.origin, this.mins, this.maxs, neworigin, MOVE_NORMAL, this);
-               trace1_endpos = trace_endpos;
-               trace1_fraction = trace_fraction;
-               trace1_plane_normal = trace_plane_normal;
-               if(trace1_fraction < 1 && trace1_plane_normal_z == 0)
-               {
-                       // may be a step or wall, try stepping up
-                       // first move forward at a higher level
-                       currentorigin2 = this.origin;
-                       currentorigin2_z += PHYS_STEPHEIGHT(this);
-                       neworigin2 = neworigin;
-                       neworigin2_z += PHYS_STEPHEIGHT(this);
-                       tracebox(currentorigin2, this.mins, this.maxs, neworigin2, MOVE_NORMAL, this);
-                       trace2_endpos = trace_endpos;
-                       trace2_fraction = trace_fraction;
-                       trace2_plane_normal = trace_plane_normal;
-                       if(!trace_startsolid)
-                       {
-                               // then move down from there
-                               currentorigin2 = trace2_endpos;
-                               neworigin2 = trace2_endpos;
-                               neworigin2_z = this.origin_z;
-                               tracebox(currentorigin2, this.mins, this.maxs, neworigin2, MOVE_NORMAL, this);
-                               trace3_endpos = trace_endpos;
-                               trace3_fraction = trace_fraction;
-                               trace3_plane_normal = trace_plane_normal;
-                               // accept the new trace if it made some progress
-                               if(fabs(trace3_endpos_x - trace1_endpos_x) >= 0.03125 || fabs(trace3_endpos_y - trace1_endpos_y) >= 0.03125)
-                               {
-                                       trace1_endpos = trace2_endpos;
-                                       trace1_fraction = trace2_fraction;
-                                       trace1_plane_normal = trace2_plane_normal;
-                                       trace1_endpos = trace3_endpos;
-                               }
-                       }
-               }
-
-               // check if it moved at all
-               if(trace1_fraction >= 0.001)
-                       setorigin(this, trace1_endpos);
-
-               // check if it moved all the way
-               if(trace1_fraction == 1)
-                       break;
-
-               // this is only really needed for nogravityonground combined with gravityunaffectedbyticrate
-               // <LordHavoc> I'm pretty sure I commented it out solely because it seemed redundant
-               // this got commented out in a change that supposedly makes the code match QW better
-               // so if this is broken, maybe put it in an if(cls.protocol != PROTOCOL_QUAKEWORLD) block
-               if(trace1_plane_normal_z > 0.7)
-                       SET_ONGROUND(this);
-
-               t -= t * trace1_fraction;
-
-               f = (this.velocity * trace1_plane_normal);
-               this.velocity = this.velocity + -f * trace1_plane_normal;
-       }
-       if(PHYS_TELEPORT_TIME(this) > 0)
-               this.velocity = primalvelocity;
-#endif
-}
-
 void CPM_PM_Aircontrol(entity this, vector wishdir, float wishspeed)
 {
        float k = 32 * (2 * IsMoveInDirection(this.movement, 0) - 1);
@@ -541,7 +405,7 @@ bool PlayerJump(entity this)
        animdecide_setaction(this, ANIMACTION_JUMP, true);
 
        if (autocvar_g_jump_grunt)
-               PlayerSound(this, playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+               PlayerSound(this, playersound_jump, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
 #endif
        return true;
 }
@@ -781,7 +645,8 @@ void PM_check_hitground(entity this)
     entity gs = (trace_dphitq3surfaceflags & Q3SURFACEFLAG_METALSTEPS)
        ? GS_FALL_METAL
        : GS_FALL;
-    GlobalSound(this, gs, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+    float vol = ((IS_DUCKED(this)) ? VOL_MUFFLED : VOL_BASE);
+    GlobalSound(this, gs, CH_PLAYER, vol, VOICETYPE_PLAYERSOUND);
 #endif
 }
 
@@ -801,7 +666,7 @@ void PM_Footsteps(entity this)
                entity gs = (trace_dphitq3surfaceflags & Q3SURFACEFLAG_METALSTEPS)
                        ? GS_STEP_METAL
                        : GS_STEP;
-               GlobalSound(this, gs, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+               GlobalSound(this, gs, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
        }
 #endif
 }
@@ -832,9 +697,10 @@ void PM_fly(entity this, float maxspd_mod)
        float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(this) * maxspd_mod);
 #ifdef SVQC
        if(time >= PHYS_TELEPORT_TIME(this))
+#elif defined(CSQC)
+       if(pmove_waterjumptime <= 0)
 #endif
                PM_Accelerate(this, wishdir, wishspeed, wishspeed, PHYS_ACCELERATE(this) * maxspd_mod, 1, 0, 0, 0);
-       PM_ClientMovement_Move(this);
 }
 
 void PM_swim(entity this, float maxspd_mod)
@@ -861,31 +727,27 @@ void PM_swim(entity this, float maxspd_mod)
                        {
                                this.velocity = forward * 50;
                                this.velocity_z = 310;
-                       #ifdef CSQC
-                               pmove_waterjumptime = 2;
-                       #endif
                                UNSET_ONGROUND(this);
                                SET_JUMP_HELD(this);
                        }
                }
        }
        makevectors(this.v_angle);
+       float wishdown = this.movement.z;
+       if(PHYS_INPUT_BUTTON_CROUCH(this))
+               wishdown = -PHYS_MAXSPEED(this);
        //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;
+                                       + '0 0 1' * wishdown;
        if(this.viewloc)
                wishvel.z = -160; // drift anyway
        else if (wishvel == '0 0 0')
                wishvel = '0 0 -60'; // drift towards bottom
 
-
        vector wishdir = normalize(wishvel);
        float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(this) * maxspd_mod) * 0.7;
 
-       if (IS_DUCKED(this))
-       wishspeed *= 0.5;
-
 //     if (pmove_waterjumptime <= 0) // TODO: use
     {
                // water friction
@@ -912,6 +774,9 @@ void PM_swim(entity this, float maxspd_mod)
                        {
                                if (IS_NEXUIZ_DERIVED(gamemode))
 #endif
+                               if(this.waterlevel >= WATERLEVEL_SUBMERGED)
+                                       this.velocity_z = PHYS_MAXSPEED(this);
+                               else
                                        this.velocity_z = 200;
 #if 0
                                else
@@ -933,7 +798,6 @@ void PM_swim(entity this, float maxspd_mod)
        {
                // water acceleration
                PM_Accelerate(this, wishdir, wishspeed, wishspeed, PHYS_ACCELERATE(this) * maxspd_mod, 1, 0, 0, 0);
-               PM_ClientMovement_Move(this);
        }
 }
 
@@ -985,10 +849,13 @@ void PM_ladder(entity this, float maxspd_mod)
        // acceleration
        vector wishdir = normalize(wishvel);
        float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(this) * maxspd_mod);
+#ifdef SVQC
        if(time >= PHYS_TELEPORT_TIME(this))
+#elif defined(CSQC)
+       if(pmove_waterjumptime <= 0)
+#endif
                // water acceleration
                PM_Accelerate(this, wishdir, wishspeed, wishspeed, PHYS_ACCELERATE(this)*maxspd_mod, 1, 0, 0, 0);
-       PM_ClientMovement_Move(this);
 }
 
 void PM_jetpack(entity this, float maxspd_mod)
@@ -1012,11 +879,15 @@ void PM_jetpack(entity this, float maxspd_mod)
        float a_up = PHYS_JETPACK_ACCEL_UP(this);
        float a_add = PHYS_JETPACK_ANTIGRAVITY(this) * PHYS_GRAVITY(this);
 
+       if(PHYS_JETPACK_REVERSE_THRUST(this) && PHYS_INPUT_BUTTON_CROUCH(self)) { a_up = PHYS_JETPACK_REVERSE_THRUST(this); }
+
        wishvel_x *= a_side;
        wishvel_y *= a_side;
        wishvel_z *= a_up;
        wishvel_z += a_add;
 
+       if(PHYS_JETPACK_REVERSE_THRUST(this) && PHYS_INPUT_BUTTON_CROUCH(self)) { wishvel_z *= -1; }
+
        float best = 0;
        //////////////////////////////////////////////////////////////////////////////////////
        // finding the maximum over all vectors of above form
@@ -1093,24 +964,6 @@ void PM_jetpack(entity this, float maxspd_mod)
                this.pauseregen_finished = max(this.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen);
 #endif
        }
-
-#ifdef CSQC
-       float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(this) * PHYS_INPUT_TIMELENGTH;
-       if(autocvar_cl_movement == 3)
-       {
-               if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                       this.velocity_z -= g * 0.5;
-               else
-                       this.velocity_z -= g;
-       }
-       PM_ClientMovement_Move(this);
-       if(autocvar_cl_movement == 3)
-       {
-               if (!IS_ONGROUND(this) || !(GAMEPLAYFIX_NOGRAVITYONGROUND))
-                       if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                               this.velocity_z -= g * 0.5;
-       }
-#endif
 }
 
 void PM_walk(entity this, float maxspd_mod)
@@ -1185,22 +1038,6 @@ void PM_walk(entity this, float maxspd_mod)
                const float accelspeed = min(PHYS_ACCELERATE(this) * PHYS_INPUT_TIMELENGTH * wishspeed, addspeed);
                this.velocity += accelspeed * wishdir;
        }
-#ifdef CSQC
-       float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(this) * PHYS_INPUT_TIMELENGTH;
-       if(autocvar_cl_movement == 3)
-       {
-               if (!(GAMEPLAYFIX_NOGRAVITYONGROUND))
-                       this.velocity_z -= g * (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1);
-       }
-       if (vdist(this.velocity, >, 0))
-               PM_ClientMovement_Move(this);
-       if(autocvar_cl_movement == 3)
-       {
-               if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                       if (!IS_ONGROUND(this) || !GAMEPLAYFIX_NOGRAVITYONGROUND)
-                               this.velocity_z -= g * 0.5;
-       }
-#endif
 }
 
 void PM_air(entity this, float buttons_prev, float maxspd_mod)
@@ -1267,21 +1104,6 @@ void PM_air(entity this, float buttons_prev, float maxspd_mod)
                if (PHYS_AIRCONTROL(this))
                        CPM_PM_Aircontrol(this, wishdir, wishspeed2);
        }
-#ifdef CSQC
-       float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(this) * PHYS_INPUT_TIMELENGTH;
-       if(autocvar_cl_movement == 3)
-       if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-               this.velocity_z -= g * 0.5;
-       else
-               this.velocity_z -= g;
-#endif
-       PM_ClientMovement_Move(this);
-#ifdef CSQC
-       if(autocvar_cl_movement == 3)
-       if (!IS_ONGROUND(this) || !(GAMEPLAYFIX_NOGRAVITYONGROUND))
-               if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                       this.velocity_z -= g * 0.5;
-#endif
 }
 
 // used for calculating airshots
@@ -1312,7 +1134,7 @@ void PM_Main(entity this)
                UNSET_JUMP_HELD(this); // canjump = true
        pmove_waterjumptime -= PHYS_INPUT_TIMELENGTH;
 
-       PM_ClientMovement_UpdateStatus(this, true);
+       PM_ClientMovement_UpdateStatus(this);
 #endif
 
        this.oldmovement = this.movement;
@@ -1372,24 +1194,24 @@ void PM_Main(entity this)
                if (!allowed_to_move)
                {
                        this.velocity = '0 0 0';
-                       this.movetype = MOVETYPE_NONE;
+                       set_movetype(this, MOVETYPE_NONE);
                        this.disableclientprediction = 2;
                }
                else if (this.disableclientprediction == 2)
                {
-                       if (this.movetype == MOVETYPE_NONE)
-                               this.movetype = MOVETYPE_WALK;
+                       if (this.move_movetype == MOVETYPE_NONE)
+                               set_movetype(this, MOVETYPE_WALK);
                        this.disableclientprediction = 0;
                }
        }
 #endif
 
 #ifdef SVQC
-       if (this.movetype == MOVETYPE_NONE)
+       if (this.move_movetype == MOVETYPE_NONE)
                return;
 
        // when we get here, disableclientprediction cannot be 2
-       this.disableclientprediction = 0;
+       this.disableclientprediction = (this.move_qcphysics) ? -1 : 0;
 #endif
 
        viewloc_PlayerPhysics(this);
@@ -1496,16 +1318,19 @@ void PM_Main(entity this)
        {
                this.velocity_x = this.movedir.x;
                this.velocity_y = this.movedir.y;
-               if (time > PHYS_TELEPORT_TIME(this) || this.waterlevel == WATERLEVEL_NONE
+               if (this.waterlevel == WATERLEVEL_NONE
                #ifdef CSQC
                        || pmove_waterjumptime <= 0
+               #elif defined(SVQC)
+                       || time > PHYS_TELEPORT_TIME(this)
                #endif
                        )
                {
                        this.flags &= ~FL_WATERJUMP;
-                       PHYS_TELEPORT_TIME(this) = 0;
                #ifdef CSQC
                        pmove_waterjumptime = 0;
+               #elif defined(CSQC)
+                       PHYS_TELEPORT_TIME(this) = 0;
                #endif
                }
        }
@@ -1514,7 +1339,7 @@ void PM_Main(entity this)
                { }
 
 #ifdef SVQC
-       else if (this.movetype == MOVETYPE_NOCLIP || this.movetype == MOVETYPE_FLY || this.movetype == MOVETYPE_FLY_WORLDONLY || MUTATOR_CALLHOOK(IsFlying, this))
+       else if (this.move_movetype == MOVETYPE_NOCLIP || this.move_movetype == MOVETYPE_FLY || this.move_movetype == MOVETYPE_FLY_WORLDONLY || MUTATOR_CALLHOOK(IsFlying, this))
 #elif defined(CSQC)
        else if (this.move_movetype == MOVETYPE_NOCLIP || this.move_movetype == MOVETYPE_FLY || this.move_movetype == MOVETYPE_FLY_WORLDONLY || MUTATOR_CALLHOOK(IsFlying, this))
 #endif
@@ -1555,4 +1380,8 @@ void CSQC_ClientMovement_PlayerMove_Frame(entity this)
 #endif
 {
        PM_Main(this);
+
+#ifdef SVQC
+       this.pm_frametime = frametime;
+#endif
 }
index fd1b610..c74602d 100644 (file)
@@ -3,6 +3,8 @@
 
 // Client/server mappings
 
+.float pm_frametime;
+
 .entity conveyor;
 
 .float race_penalty;
@@ -35,6 +37,7 @@ bool IsFlying(entity a);
 #define GAMEPLAYFIX_STEPDOWN(s)             STAT(GAMEPLAYFIX_STEPDOWN, s)
 #define GAMEPLAYFIX_STEPMULTIPLETIMES(s)    STAT(GAMEPLAYFIX_STEPMULTIPLETIMES, s)
 #define GAMEPLAYFIX_UNSTICKPLAYERS(s)       STAT(GAMEPLAYFIX_UNSTICKPLAYERS, s)
+#define GAMEPLAYFIX_WATERTRANSITION(s) STAT(GAMEPLAYFIX_WATERTRANSITION, s)
 
 #define PHYS_ACCELERATE(s)                  STAT(MOVEVARS_ACCELERATE, s)
 #define PHYS_AIRACCELERATE(s)               STAT(MOVEVARS_AIRACCELERATE, s)
@@ -67,6 +70,7 @@ bool IsFlying(entity a);
 #define PHYS_JETPACK_FUEL(s)                STAT(JETPACK_FUEL, s)
 #define PHYS_JETPACK_MAXSPEED_SIDE(s)       STAT(JETPACK_MAXSPEED_SIDE, s)
 #define PHYS_JETPACK_MAXSPEED_UP(s)         STAT(JETPACK_MAXSPEED_UP, s)
+#define PHYS_JETPACK_REVERSE_THRUST(s)         STAT(JETPACK_REVERSE_THRUST, s)
 
 #define PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS(s) STAT(MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS, s)
 #define PHYS_JUMPSTEP(s)                    STAT(MOVEVARS_JUMPSTEP, s)
index 90b2758..519f910 100644 (file)
@@ -35,6 +35,7 @@ const float ATTEN_MAX = 3.984375;
 
 const float VOL_BASE = 0.7;
 const float VOL_BASEVOICE = 1.0;
+const float VOL_MUFFLED = 0.35;
 
 // Play all sounds via sound7, for access to the extra channels.
 // Otherwise, channels 8 to 15 would be blocked for a weird QW feature.
@@ -125,7 +126,7 @@ CLASS(Sound, Object)
            TC(Sound, this);
                string s = Sound_fixpath(this);
                if (!s) return;
-               LOG_DEBUGF("precache_sound(\"%s\")\n", s);
+               profile(sprintf("precache_sound(\"%s\")\n", s));
                precache_sound(s);
        }
 ENDCLASS(Sound)
index 0ffe55e..7c68820 100644 (file)
@@ -15,6 +15,12 @@ void PlayerState_detach(entity this)
     PlayerState ps = PS(this);
        if (!ps) return;  // initial connect
        PS(this) = NULL;
+
+       ps.m_switchweapon = WEP_Null;
+       ps.m_weapon = WEP_Null;
+       ps.m_switchingweapon = WEP_Null;
+       ps.ps_push(ps, this);
+
        if (ps.m_client != this) return;  // don't own state, spectator
        FOREACH_CLIENT(PS(it) == ps, { PS(it) = NULL; });
        remove(ps);
index 2c471f0..bbf3151 100644 (file)
@@ -174,12 +174,21 @@ REGISTER_STAT(BUGRIGS_SPEED_POW, float, g_bugrigs_speed_pow)
 REGISTER_STAT(BUGRIGS_SPEED_REF, float, g_bugrigs_speed_ref)
 REGISTER_STAT(BUGRIGS_STEER, float, g_bugrigs_steer)
 
-REGISTER_STAT(GAMEPLAYFIX_DOWNTRACEONGROUND, int, cvar("sv_gameplayfix_downtracesupportsongroundflag"))
-REGISTER_STAT(GAMEPLAYFIX_EASIERWATERJUMP, int, cvar("sv_gameplayfix_easierwaterjump"))
-REGISTER_STAT(GAMEPLAYFIX_STEPDOWN, int, cvar("sv_gameplayfix_stepdown"))
-REGISTER_STAT(GAMEPLAYFIX_STEPMULTIPLETIMES, int, cvar("sv_gameplayfix_stepmultipletimes"))
-REGISTER_STAT(GAMEPLAYFIX_UNSTICKPLAYERS, int, cvar("sv_gameplayfix_unstickplayers"))
+#ifdef SVQC
+int autocvar_sv_gameplayfix_downtracesupportsongroundflag;
+int autocvar_sv_gameplayfix_easierwaterjump;
+int autocvar_sv_gameplayfix_stepdown;
+int autocvar_sv_gameplayfix_stepmultipletimes;
+int autocvar_sv_gameplayfix_unstickplayers;
+int autocvar_sv_gameplayfix_fixedcheckwatertransition;
+#endif
+REGISTER_STAT(GAMEPLAYFIX_DOWNTRACEONGROUND, int, autocvar_sv_gameplayfix_downtracesupportsongroundflag)
+REGISTER_STAT(GAMEPLAYFIX_EASIERWATERJUMP, int, autocvar_sv_gameplayfix_easierwaterjump)
+REGISTER_STAT(GAMEPLAYFIX_STEPDOWN, int, autocvar_sv_gameplayfix_stepdown)
+REGISTER_STAT(GAMEPLAYFIX_STEPMULTIPLETIMES, int, autocvar_sv_gameplayfix_stepmultipletimes)
+REGISTER_STAT(GAMEPLAYFIX_UNSTICKPLAYERS, int, autocvar_sv_gameplayfix_unstickplayers)
 REGISTER_STAT(GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND, int, autocvar_sv_gameplayfix_upwardvelocityclearsongroundflag)
+REGISTER_STAT(GAMEPLAYFIX_WATERTRANSITION, int, autocvar_sv_gameplayfix_fixedcheckwatertransition)
 
 REGISTER_STAT(MOVEVARS_JUMPSTEP, int, cvar("sv_jumpstep"))
 REGISTER_STAT(NOSTEP, int, cvar("sv_nostep"))
@@ -205,6 +214,7 @@ float autocvar_sv_dodging_horiz_speed_frozen;
 float autocvar_sv_dodging_ramp_time;
 float autocvar_sv_dodging_up_speed;
 bool autocvar_sv_dodging_wall_dodging;
+bool autocvar_sv_dodging_air_dodging;
 #endif
 
 REGISTER_STAT(DODGING, int, g_dodging)
@@ -219,7 +229,8 @@ REGISTER_STAT(DODGING_RAMP_TIME, float, autocvar_sv_dodging_ramp_time)
 /** cvar loopback */
 REGISTER_STAT(DODGING_TIMEOUT, float)
 REGISTER_STAT(DODGING_UP_SPEED, float, autocvar_sv_dodging_up_speed)
-REGISTER_STAT(DODGING_WALL, int, autocvar_sv_dodging_wall_dodging)
+REGISTER_STAT(DODGING_WALL, bool, autocvar_sv_dodging_wall_dodging)
+REGISTER_STAT(DODGING_AIR, bool, autocvar_sv_dodging_air_dodging)
 
 REGISTER_STAT(JETPACK_ACCEL_SIDE, float, autocvar_g_jetpack_acceleration_side)
 REGISTER_STAT(JETPACK_ACCEL_UP, float, autocvar_g_jetpack_acceleration_up)
@@ -227,6 +238,7 @@ REGISTER_STAT(JETPACK_ANTIGRAVITY, float, autocvar_g_jetpack_antigravity)
 REGISTER_STAT(JETPACK_FUEL, float, autocvar_g_jetpack_fuel)
 REGISTER_STAT(JETPACK_MAXSPEED_SIDE, float, autocvar_g_jetpack_maxspeed_side)
 REGISTER_STAT(JETPACK_MAXSPEED_UP, float, autocvar_g_jetpack_maxspeed_up)
+REGISTER_STAT(JETPACK_REVERSE_THRUST, float, autocvar_g_jetpack_reverse_thrust)
 
 REGISTER_STAT(MOVEVARS_HIGHSPEED, float, autocvar_g_movement_highspeed)
 
@@ -246,6 +258,8 @@ REGISTER_STAT(DOM_PPS_PINK, float)
 REGISTER_STAT(TELEPORT_MAXSPEED, float, autocvar_g_teleport_maxspeed)
 REGISTER_STAT(TELEPORT_TELEFRAG_AVOID, int, autocvar_g_telefrags_avoid)
 
+REGISTER_STAT(CAMERA_SPECTATOR, int)
+
 REGISTER_STAT(SPECTATORSPEED, float)
 
 #ifdef SVQC
index 2ab3d61..8563349 100644 (file)
@@ -68,18 +68,18 @@ void ItemDraw(entity this)
     if(this.gravity)
     {
         Movetype_Physics_MatchServer(this, false);
-        if(this.move_flags & FL_ONGROUND)
-        { // For some reason move_avelocity gets set to '0 0 0' here ...
+        if(IS_ONGROUND(this))
+        { // For some reason avelocity gets set to '0 0 0' here ...
             this.oldorigin = this.origin;
             this.gravity = 0;
 
             if(autocvar_cl_animate_items)
             { // ... so reset it if animations are requested.
                 if(this.ItemStatus & ITS_ANIMATE1)
-                    this.move_avelocity = '0 180 0';
+                    this.avelocity = '0 180 0';
 
                 if(this.ItemStatus & ITS_ANIMATE2)
-                    this.move_avelocity = '0 -90 0';
+                    this.avelocity = '0 -90 0';
             }
         }
     }
@@ -87,13 +87,13 @@ void ItemDraw(entity this)
     {
         if(this.ItemStatus & ITS_ANIMATE1)
         {
-            this.angles += this.move_avelocity * frametime;
+            this.angles += this.avelocity * frametime;
             setorigin(this, '0 0 10' + this.oldorigin + '0 0 8' * sin(time * 2));
         }
 
         if(this.ItemStatus & ITS_ANIMATE2)
         {
-            this.angles += this.move_avelocity * frametime;
+            this.angles += this.avelocity * frametime;
             setorigin(this, '0 0 8' + this.oldorigin + '0 0 4' * sin(time * 3));
         }
     }
@@ -107,7 +107,7 @@ void ItemDrawSimple(entity this)
     {
         Movetype_Physics_MatchServer(this, false);
 
-        if(this.move_flags & FL_ONGROUND)
+        if(IS_ONGROUND(this))
             this.gravity = 0;
     }
 
@@ -164,7 +164,6 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
         this.angles_x = ReadAngle();
         this.angles_y = ReadAngle();
         this.angles_z = ReadAngle();
-        this.move_angles = this.angles;
     }
 
     if(sf & ISF_SIZE)
@@ -196,9 +195,10 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
     {
         this.drawmask  = MASK_NORMAL;
                this.move_movetype = MOVETYPE_TOSS;
+               if (isnew) IL_PUSH(g_drawables, this);
         this.draw       = ItemDraw;
         this.solid = SOLID_TRIGGER;
-        //this.move_flags |= FL_ITEM;
+        //this.flags |= FL_ITEM;
 
         bool use_bigsize = ReadByte();
 
@@ -253,13 +253,12 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
     {
         this.gravity = 1;
         this.pushable = true;
-        //this.move_angles = '0 0 0';
+        //this.angles = '0 0 0';
         this.move_movetype = MOVETYPE_TOSS;
-        this.move_velocity_x = ReadCoord();
-        this.move_velocity_y = ReadCoord();
-        this.move_velocity_z = ReadCoord();
-        this.velocity = this.move_velocity;
-        this.move_origin = this.oldorigin;
+        this.velocity_x = ReadCoord();
+        this.velocity_y = ReadCoord();
+        this.velocity_z = ReadCoord();
+        setorigin(this, this.oldorigin);
 
         if(!this.move_time)
         {
@@ -273,10 +272,10 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
     if(autocvar_cl_animate_items)
     {
         if(this.ItemStatus & ITS_ANIMATE1)
-            this.move_avelocity = '0 180 0';
+            this.avelocity = '0 180 0';
 
         if(this.ItemStatus & ITS_ANIMATE2)
-            this.move_avelocity = '0 -90 0';
+            this.avelocity = '0 -90 0';
     }
 
     this.entremove = ItemRemove;
@@ -1079,7 +1078,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default
        {
                this.reset = SUB_Remove;
                // it's a dropped weapon
-               this.movetype = MOVETYPE_TOSS;
+               set_movetype(this, MOVETYPE_TOSS);
 
                // Savage: remove thrown items after a certain period of time ("garbage collection")
                setthink(this, RemoveItem);
@@ -1120,9 +1119,9 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default
                if(this.spawnflags & 1)
                        this.noalign = 1;
                if (this.noalign > 0)
-                       this.movetype = MOVETYPE_NONE;
+                       set_movetype(this, MOVETYPE_NONE);
                else
-                       this.movetype = MOVETYPE_TOSS;
+                       set_movetype(this, MOVETYPE_TOSS);
                // do item filtering according to game mode and other things
                if (this.noalign <= 0)
                {
@@ -1449,7 +1448,7 @@ void target_items_use(entity this, entity actor, entity trigger)
 
 spawnfunc(target_items)
 {
-       float n, i;
+       int n, j;
        string s;
 
        this.use = target_items_use;
@@ -1467,20 +1466,20 @@ spawnfunc(target_items)
        }
        else
        {
-               for(i = 0; i < n; ++i)
+               for(j = 0; j < n; ++j)
                {
-                       if     (argv(i) == "unlimited_ammo")         this.items |= IT_UNLIMITED_AMMO;
-                       else if(argv(i) == "unlimited_weapon_ammo")  this.items |= IT_UNLIMITED_WEAPON_AMMO;
-                       else if(argv(i) == "unlimited_superweapons") this.items |= IT_UNLIMITED_SUPERWEAPONS;
-                       else if(argv(i) == "strength")               this.items |= ITEM_Strength.m_itemid;
-                       else if(argv(i) == "invincible")             this.items |= ITEM_Shield.m_itemid;
-                       else if(argv(i) == "superweapons")           this.items |= IT_SUPERWEAPON;
-                       else if(argv(i) == "jetpack")                this.items |= ITEM_Jetpack.m_itemid;
-                       else if(argv(i) == "fuel_regen")             this.items |= ITEM_JetpackRegen.m_itemid;
+                       if     (argv(j) == "unlimited_ammo")         this.items |= IT_UNLIMITED_AMMO;
+                       else if(argv(j) == "unlimited_weapon_ammo")  this.items |= IT_UNLIMITED_WEAPON_AMMO;
+                       else if(argv(j) == "unlimited_superweapons") this.items |= IT_UNLIMITED_SUPERWEAPONS;
+                       else if(argv(j) == "strength")               this.items |= ITEM_Strength.m_itemid;
+                       else if(argv(j) == "invincible")             this.items |= ITEM_Shield.m_itemid;
+                       else if(argv(j) == "superweapons")           this.items |= IT_SUPERWEAPON;
+                       else if(argv(j) == "jetpack")                this.items |= ITEM_Jetpack.m_itemid;
+                       else if(argv(j) == "fuel_regen")             this.items |= ITEM_JetpackRegen.m_itemid;
                        else
                        {
                                FOREACH(Weapons, it != WEP_Null, {
-                                       s = W_UndeprecateName(argv(i));
+                                       s = W_UndeprecateName(argv(j));
                                        if(s == it.netname)
                                        {
                                                this.weapons |= (it.m_wepset);
@@ -1541,9 +1540,9 @@ spawnfunc(target_items)
        //print(this.netname, "\n");
 
        n = tokenize_console(this.netname);
-       for(i = 0; i < n; ++i)
+       for(j = 0; j < n; ++j)
        {
-               FOREACH(Weapons, it != WEP_Null && argv(i) == it.netname, {
+               FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(argv(j)) == it.netname, {
             it.wr_init(it);
             break;
                });
@@ -1766,7 +1765,7 @@ float GiveItems(entity e, float beginarg, float endarg)
                                got += GiveValue(e, ammo_fuel, op, val);
                                break;
                        default:
-                               FOREACH(Weapons, it != WEP_Null && cmd == it.netname, {
+                               FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(cmd) == it.netname, {
                     got += GiveWeapon(e, it.m_id, op, val);
                     break;
                                });
index 1a65710..6763701 100644 (file)
@@ -59,7 +59,7 @@ void LaunchDebris (entity this, string debrisname, vector force)
        dbr.skin = this.debrisskin;
        dbr.colormap = this.colormap; // inherit team colors
        dbr.owner = this; // do not be affected by our own explosion
-       dbr.movetype = this.debrismovetype;
+       set_movetype(dbr, this.debrismovetype);
        dbr.solid = this.debrissolid;
        if(dbr.solid != SOLID_BSP) // SOLID_BSP has exact collision, MAYBE this works? TODO check this out
                setsize(dbr, '0 0 0', '0 0 0'); // needed for performance, until engine can deal better with it
index ab4cc12..8bd6016 100644 (file)
@@ -140,7 +140,7 @@ spawnfunc(func_conveyor)
 {
        SetMovedir(this);
        InitMovingBrushTrigger(this);
-       this.movetype = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        conveyor_init(this);
 }
 
@@ -151,12 +151,12 @@ void conveyor_draw(entity this) { conveyor_think(this); }
 void conveyor_init(entity this)
 {
        this.draw = conveyor_draw;
+       IL_PUSH(g_drawables, this);
        this.drawmask = MASK_NORMAL;
 
-       this.movetype = MOVETYPE_NONE;
+       this.move_movetype = MOVETYPE_NONE;
        this.model = "";
        this.solid = SOLID_TRIGGER;
-       this.move_origin = this.origin;
        this.move_time = time;
 }
 
index 2b3decf..a0fb12a 100644 (file)
@@ -441,7 +441,7 @@ void door_spawnfield(entity this, vector fmins, vector fmaxs)
        vector  t1 = fmins, t2 = fmaxs;
 
        trigger = new(doortriggerfield);
-       trigger.movetype = MOVETYPE_NONE;
+       set_movetype(trigger, MOVETYPE_NONE);
        trigger.solid = SOLID_TRIGGER;
        trigger.owner = this;
 #ifdef SVQC
@@ -815,7 +815,7 @@ NET_HANDLE(ENT_CLIENT_DOOR, bool isnew)
                this.SUB_LTIME = ReadCoord();
 
                this.solid = SOLID_BSP;
-               this.movetype = MOVETYPE_PUSH;
+               this.move_movetype = MOVETYPE_PUSH;
                this.use = door_use;
 
                LinkDoors(this);
@@