]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'Mario/showspecs' into 'master'
authorTimePath <andrew.hardaker1995@gmail.com>
Sat, 6 Aug 2016 06:46:36 +0000 (06:46 +0000)
committerTimePath <andrew.hardaker1995@gmail.com>
Sat, 6 Aug 2016 06:46:36 +0000 (06:46 +0000)
Merge branch Mario/showspecs (M merge request)

Shows who's spectating you (disabled by default).

See merge request !340

301 files changed:
.gitlab-ci.yml
_hud_common.cfg
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
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
hud_luma.cfg
hud_luminos.cfg
hud_luminos_minimal.cfg
hud_luminos_minimal_xhair.cfg
qcsrc/client/announcer.qc
qcsrc/client/commands/cl_cmd.qc
qcsrc/client/csqc_constants.qh
qcsrc/client/csqcmodel_hooks.qc
qcsrc/client/hud/panel/infomessages.qc
qcsrc/client/hud/panel/modicons.qc
qcsrc/client/hud/panel/radar.qc
qcsrc/client/hud/panel/vote.qc
qcsrc/client/main.qc
qcsrc/client/main.qh
qcsrc/client/mapvoting.qc
qcsrc/client/scoreboard.qc
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/all.qc
qcsrc/common/effects/qc/casings.qc
qcsrc/common/effects/qc/damageeffects.qc
qcsrc/common/effects/qc/gibs.qc
qcsrc/common/effects/qc/modeleffects.qc
qcsrc/common/effects/qc/rubble.qh
qcsrc/common/ent_cs.qc
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/inventory.qh
qcsrc/common/minigames/cl_minigames.qc
qcsrc/common/minigames/cl_minigames_hud.qc
qcsrc/common/minigames/minigame/bd.qc
qcsrc/common/minigames/minigame/c4.qc
qcsrc/common/minigames/minigame/nmm.qc
qcsrc/common/minigames/minigame/pong.qc
qcsrc/common/minigames/minigame/pp.qc
qcsrc/common/minigames/minigame/ps.qc
qcsrc/common/minigames/minigame/snake.qc
qcsrc/common/minigames/minigame/ttt.qc
qcsrc/common/minigames/sv_minigames.qc
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/instagib/instagib.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/superspec/superspec.qc
qcsrc/common/mutators/mutator/touchexplode/touchexplode.qc
qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc
qcsrc/common/mutators/mutator/waypoints/waypointsprites.qh
qcsrc/common/notifications/all.inc
qcsrc/common/notifications/all.qc
qcsrc/common/notifications/all.qh
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/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/target/speaker.qc
qcsrc/common/triggers/teleporters.qc
qcsrc/common/triggers/trigger/gamestart.qc
qcsrc/common/triggers/trigger/gravity.qc
qcsrc/common/triggers/trigger/impulse.qc
qcsrc/common/triggers/trigger/jumppads.qc
qcsrc/common/triggers/trigger/keylock.qc
qcsrc/common/triggers/trigger/secret.qc
qcsrc/common/triggers/trigger/swamp.qc
qcsrc/common/triggers/trigger/teleport.qc
qcsrc/common/triggers/trigger/viewloc.qc
qcsrc/common/triggers/triggers.qc
qcsrc/common/turrets/cl_turrets.qc
qcsrc/common/turrets/sv_turrets.qc
qcsrc/common/turrets/targettrigger.qc
qcsrc/common/turrets/turret/ewheel.qc
qcsrc/common/turrets/turret/flac.qc
qcsrc/common/turrets/turret/flac_weapon.qc
qcsrc/common/turrets/turret/fusionreactor.qc
qcsrc/common/turrets/turret/hellion.qc
qcsrc/common/turrets/turret/hellion_weapon.qc
qcsrc/common/turrets/turret/hk.qc
qcsrc/common/turrets/turret/hk_weapon.qc
qcsrc/common/turrets/turret/machinegun.qc
qcsrc/common/turrets/turret/mlrs.qc
qcsrc/common/turrets/turret/phaser.qc
qcsrc/common/turrets/turret/phaser_weapon.qc
qcsrc/common/turrets/turret/plasma.qc
qcsrc/common/turrets/turret/plasma_dual.qc
qcsrc/common/turrets/turret/tesla.qc
qcsrc/common/turrets/turret/tesla_weapon.qc
qcsrc/common/turrets/turret/walker.qc
qcsrc/common/turrets/util.qc
qcsrc/common/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.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/tuba.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/dpdefs/doc.md
qcsrc/dpdefs/menudefs.qh
qcsrc/dpdefs/post.qh
qcsrc/dpdefs/pre.qh
qcsrc/ecs/README.md
qcsrc/ecs/_lib.inc
qcsrc/ecs/_lib.qh [new file with mode: 0644]
qcsrc/ecs/components/input.qh
qcsrc/ecs/components/physics.qh
qcsrc/ecs/events/_mod.inc
qcsrc/ecs/events/_mod.qh
qcsrc/ecs/events/physics.qc [new file with mode: 0644]
qcsrc/ecs/events/physics.qh [new file with mode: 0644]
qcsrc/ecs/systems/_mod.inc
qcsrc/ecs/systems/_mod.qh
qcsrc/ecs/systems/cl_physics.qc [new file with mode: 0644]
qcsrc/ecs/systems/input.qc [new file with mode: 0644]
qcsrc/ecs/systems/input.qh [new file with mode: 0644]
qcsrc/ecs/systems/physics.qc
qcsrc/ecs/systems/physics.qh
qcsrc/ecs/systems/sv_physics.qc [new file with mode: 0644]
qcsrc/lib/_all.inc
qcsrc/lib/arraylist.qh
qcsrc/lib/counting.qh
qcsrc/lib/csqcmodel/cl_player.qc
qcsrc/lib/csqcmodel/cl_player.qh
qcsrc/lib/defer.qh
qcsrc/lib/intrusivelist.qh [new file with mode: 0644]
qcsrc/lib/iter.qh
qcsrc/lib/linkedlist.qh
qcsrc/lib/log.qh
qcsrc/lib/matrix/matrix.qc
qcsrc/lib/net.qh
qcsrc/lib/oo.qh
qcsrc/lib/registry.qh
qcsrc/lib/self.qh
qcsrc/lib/spawnfunc.qh
qcsrc/lib/stats.qh
qcsrc/lib/urllib.qc
qcsrc/lib/vector.qh
qcsrc/lib/warpzone/client.qc
qcsrc/lib/warpzone/common.qc
qcsrc/lib/warpzone/server.qc
qcsrc/lib/warpzone/util_server.qc
qcsrc/menu/anim/animhost.qc
qcsrc/menu/menu.qc
qcsrc/menu/xonotic/dialog_multiplayer_join.qc
qcsrc/menu/xonotic/gametypelist.qc
qcsrc/menu/xonotic/gametypelist.qh
qcsrc/menu/xonotic/keybinder.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/command/radarmap.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.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/ipban.qc
qcsrc/server/item_key.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/mutator/gamemode_assault.qc
qcsrc/server/mutators/mutator/gamemode_ca.qc
qcsrc/server/mutators/mutator/gamemode_ctf.qc
qcsrc/server/mutators/mutator/gamemode_cts.qc
qcsrc/server/mutators/mutator/gamemode_domination.qc
qcsrc/server/mutators/mutator/gamemode_freezetag.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/mutators/mutator/gamemode_tdm.qc
qcsrc/server/pathlib/main.qc
qcsrc/server/pathlib/movenode.qc
qcsrc/server/pathlib/path_waypoint.qc
qcsrc/server/pathlib/pathlib.qh
qcsrc/server/playerdemo.qc
qcsrc/server/portals.qc
qcsrc/server/race.qc
qcsrc/server/round_handler.qc
qcsrc/server/scores.qc
qcsrc/server/scores_rules.qc
qcsrc/server/scores_rules.qh
qcsrc/server/steerlib.qc
qcsrc/server/sv_main.qc
qcsrc/server/sys-post.qh
qcsrc/server/sys-pre.qh
qcsrc/server/teamplay.qc
qcsrc/server/tests.qc
qcsrc/server/weapons/accuracy.qc
qcsrc/server/weapons/csqcprojectile.qc
qcsrc/server/weapons/selection.qc
qcsrc/server/weapons/spawning.qc
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/weaponsystem.qc
qcsrc/uncrustify.cfg

index 7909c3286a6dcbd28402519f993afc9a33a59f16..db275cd39edfd04ef89f812477015dd701d2dfe5 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=56bf79831a0a35ab6a3a420e26b09945
     - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
       | tee /dev/stderr
       | grep '^:'
index 7bf9111cd4dab6c5d3d655e4ed3bc765c074ce49..8d954f3d878e815c9e7d4a661d13fe6e2b722571 100644 (file)
@@ -95,6 +95,9 @@ seta hud_panel_quickmenu_file "" "load the quick menu from this file (empty or 0
 seta hud_panel_quickmenu_translatecommands 0 "when the game is translated, translate strings inside commands too (useful for chat commands)"
 seta hud_panel_quickmenu_time 5 "quickmenu expires after this number of seconds in the same page"
 
+seta hud_panel_infomessages_group_time 6 "number of seconds a message of a group lasts before it gets changed"
+seta hud_panel_infomessages_group_fadetime 0.4 "group message fade in/out time"
+
 // hud panel aliases
 alias quickmenu "cl_cmd hud quickmenu ${* ?}"
 
index 9bfca55f37ed586b8ee44cc5e1f00fd1baa441e9..5979b78b84947acfbd6ca3790b0bb7e76ec7f4c1 100644 (file)
@@ -2,7 +2,7 @@
 set g_balance_blaster_primary_animtime 0.2
 set g_balance_blaster_primary_damage 25
 set g_balance_blaster_primary_delay 0
-set g_balance_blaster_primary_edgedamage 17
+set g_balance_blaster_primary_edgedamage 12.5
 set g_balance_blaster_primary_force 300
 set g_balance_blaster_primary_force_zscale 1.25
 set g_balance_blaster_primary_lifetime 5
@@ -34,8 +34,8 @@ set g_balance_blaster_weaponthrowable 0
 // {{{ #2: Shotgun
 set g_balance_shotgun_primary_ammo 1
 set g_balance_shotgun_primary_animtime 0.2
-set g_balance_shotgun_primary_bullets 8
-set g_balance_shotgun_primary_damage 6
+set g_balance_shotgun_primary_bullets 12
+set g_balance_shotgun_primary_damage 4
 set g_balance_shotgun_primary_force 15
 set g_balance_shotgun_primary_refire 0.75
 set g_balance_shotgun_primary_solidpenetration 3.8
@@ -43,7 +43,7 @@ set g_balance_shotgun_primary_spread 0.12
 set g_balance_shotgun_reload_ammo 0
 set g_balance_shotgun_reload_time 2
 set g_balance_shotgun_secondary 1
-set g_balance_shotgun_secondary_animtime 1
+set g_balance_shotgun_secondary_animtime 1.15
 set g_balance_shotgun_secondary_damage 70
 set g_balance_shotgun_secondary_force 200
 set g_balance_shotgun_secondary_melee_delay 0.25
@@ -61,7 +61,7 @@ set g_balance_shotgun_secondary_alt_refire 1.2
 set g_balance_shotgun_switchdelay_drop 0.2
 set g_balance_shotgun_switchdelay_raise 0.2
 set g_balance_shotgun_weaponreplace ""
-set g_balance_shotgun_weaponstart 1
+set g_balance_shotgun_weaponstart 0
 set g_balance_shotgun_weaponstartoverride -1
 set g_balance_shotgun_weaponthrowable 1
 // }}}
@@ -92,7 +92,7 @@ set g_balance_machinegun_sustained_refire 0.1
 set g_balance_machinegun_sustained_spread 0.03
 set g_balance_machinegun_switchdelay_drop 0.2
 set g_balance_machinegun_switchdelay_raise 0.2
-set g_balance_machinegun_weaponreplace ""
+set g_balance_machinegun_weaponreplace "arc"
 set g_balance_machinegun_weaponstart 0
 set g_balance_machinegun_weaponstartoverride -1
 set g_balance_machinegun_weaponthrowable 1
@@ -102,7 +102,7 @@ set g_balance_mortar_bouncefactor 0.5
 set g_balance_mortar_bouncestop 0.075
 set g_balance_mortar_primary_ammo 2
 set g_balance_mortar_primary_animtime 0.3
-set g_balance_mortar_primary_damage 40
+set g_balance_mortar_primary_damage 55
 set g_balance_mortar_primary_damageforcescale 0
 set g_balance_mortar_primary_edgedamage 25
 set g_balance_mortar_primary_force 250
@@ -192,8 +192,8 @@ set g_balance_electro_primary_edgedamage 20
 set g_balance_electro_primary_force 200
 set g_balance_electro_primary_lifetime 5
 set g_balance_electro_primary_midaircombo_explode 1
-set g_balance_electro_primary_midaircombo_interval 0.3
-set g_balance_electro_primary_midaircombo_radius 150
+set g_balance_electro_primary_midaircombo_interval 0.1
+set g_balance_electro_primary_midaircombo_radius 0
 set g_balance_electro_primary_radius 100
 set g_balance_electro_primary_refire 0.6
 set g_balance_electro_primary_speed 2500
@@ -218,8 +218,9 @@ set g_balance_electro_secondary_refire2 1.6
 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_touchexplode 0
+set g_balance_electro_secondary_spread 0
+set g_balance_electro_secondary_stick 1
+set g_balance_electro_secondary_touchexplode 1
 set g_balance_electro_switchdelay_drop 0.2
 set g_balance_electro_switchdelay_raise 0.2
 set g_balance_electro_weaponreplace ""
@@ -232,7 +233,7 @@ set g_balance_crylink_primary_ammo 3
 set g_balance_crylink_primary_animtime 0.3
 set g_balance_crylink_primary_bouncedamagefactor 0.5
 set g_balance_crylink_primary_bounces 1
-set g_balance_crylink_primary_damage 8
+set g_balance_crylink_primary_damage 12
 set g_balance_crylink_primary_edgedamage 6
 set g_balance_crylink_primary_force -50
 set g_balance_crylink_primary_joindelay 0.1
@@ -242,7 +243,7 @@ set g_balance_crylink_primary_joinexplode_edgedamage 0
 set g_balance_crylink_primary_joinexplode_force 0
 set g_balance_crylink_primary_joinexplode_radius 0
 set g_balance_crylink_primary_joinspread 0.2
-set g_balance_crylink_primary_linkexplode 1
+set g_balance_crylink_primary_linkexplode 0
 set g_balance_crylink_primary_middle_fadetime 5
 set g_balance_crylink_primary_middle_lifetime 5
 set g_balance_crylink_primary_other_fadetime 5
@@ -259,9 +260,9 @@ set g_balance_crylink_secondary_ammo 2
 set g_balance_crylink_secondary_animtime 0.2
 set g_balance_crylink_secondary_bouncedamagefactor 0.5
 set g_balance_crylink_secondary_bounces 0
-set g_balance_crylink_secondary_damage 10
+set g_balance_crylink_secondary_damage 35
 set g_balance_crylink_secondary_edgedamage 5
-set g_balance_crylink_secondary_force -200
+set g_balance_crylink_secondary_force -300
 set g_balance_crylink_secondary_joindelay 0
 set g_balance_crylink_secondary_joinexplode 0
 set g_balance_crylink_secondary_joinexplode_damage 0
@@ -276,7 +277,7 @@ set g_balance_crylink_secondary_other_fadetime 5
 set g_balance_crylink_secondary_other_lifetime 5
 set g_balance_crylink_secondary_radius 100
 set g_balance_crylink_secondary_refire 0.7
-set g_balance_crylink_secondary_shots 5
+set g_balance_crylink_secondary_shots 1
 set g_balance_crylink_secondary_speed 3000
 set g_balance_crylink_secondary_spread 0.01
 set g_balance_crylink_secondary_spreadtype 1
@@ -288,11 +289,11 @@ set g_balance_crylink_weaponstartoverride -1
 set g_balance_crylink_weaponthrowable 1
 // }}}
 // {{{ #8: Vortex
-set g_balance_vortex_charge 1
+set g_balance_vortex_charge 0
 set g_balance_vortex_charge_animlimit 0.5
 set g_balance_vortex_charge_limit 1
 set g_balance_vortex_charge_maxspeed 800
-set g_balance_vortex_charge_mindmg 50
+set g_balance_vortex_charge_mindmg 40
 set g_balance_vortex_charge_minspeed 400
 set g_balance_vortex_charge_rate 0.6
 set g_balance_vortex_charge_rot_pause 0
@@ -302,12 +303,12 @@ set g_balance_vortex_charge_start 0.5
 set g_balance_vortex_charge_velocity_rate 0
 set g_balance_vortex_primary_ammo 6
 set g_balance_vortex_primary_animtime 0.4
-set g_balance_vortex_primary_damage 80
+set g_balance_vortex_primary_damage 70
 set g_balance_vortex_primary_damagefalloff_forcehalflife 0
 set g_balance_vortex_primary_damagefalloff_halflife 0
 set g_balance_vortex_primary_damagefalloff_maxdist 0
 set g_balance_vortex_primary_damagefalloff_mindist 0
-set g_balance_vortex_primary_force 450
+set g_balance_vortex_primary_force 400
 set g_balance_vortex_primary_refire 1.5
 set g_balance_vortex_reload_ammo 0
 set g_balance_vortex_reload_time 2
@@ -324,8 +325,8 @@ set g_balance_vortex_secondary_damagefalloff_maxdist 0
 set g_balance_vortex_secondary_damagefalloff_mindist 0
 set g_balance_vortex_secondary_force 0
 set g_balance_vortex_secondary_refire 0
-set g_balance_vortex_switchdelay_drop 0.2
-set g_balance_vortex_switchdelay_raise 0.2
+set g_balance_vortex_switchdelay_drop 0.25
+set g_balance_vortex_switchdelay_raise 0.25
 set g_balance_vortex_weaponreplace ""
 set g_balance_vortex_weaponstart 0
 set g_balance_vortex_weaponstartoverride -1
@@ -360,14 +361,14 @@ set g_balance_hagar_secondary_load_animtime 0.2
 set g_balance_hagar_secondary_load_hold 4
 set g_balance_hagar_secondary_load_linkexplode 0
 set g_balance_hagar_secondary_load_max 4
-set g_balance_hagar_secondary_load_releasedeath 1
+set g_balance_hagar_secondary_load_releasedeath 0
 set g_balance_hagar_secondary_load_speed 0.5
 set g_balance_hagar_secondary_load_spread 0.075
 set g_balance_hagar_secondary_load_spread_bias 0.5
 set g_balance_hagar_secondary_radius 80
 set g_balance_hagar_secondary_refire 0.5
 set g_balance_hagar_secondary_speed 2000
-set g_balance_hagar_secondary_spread 0.05
+set g_balance_hagar_secondary_spread 0
 set g_balance_hagar_switchdelay_drop 0.2
 set g_balance_hagar_switchdelay_raise 0.2
 set g_balance_hagar_weaponreplace ""
@@ -382,7 +383,7 @@ set g_balance_devastator_damage 80
 set g_balance_devastator_damageforcescale 1
 set g_balance_devastator_detonatedelay 0.02
 set g_balance_devastator_edgedamage 40
-set g_balance_devastator_force 450
+set g_balance_devastator_force 400
 set g_balance_devastator_guidedelay 0.2
 set g_balance_devastator_guidegoal 512
 set g_balance_devastator_guiderate 90
@@ -390,21 +391,21 @@ set g_balance_devastator_guideratedelay 0.01
 set g_balance_devastator_guidestop 0
 set g_balance_devastator_health 30
 set g_balance_devastator_lifetime 10
-set g_balance_devastator_radius 150
+set g_balance_devastator_radius 110
 set g_balance_devastator_refire 1.1
 set g_balance_devastator_reload_ammo 0
 set g_balance_devastator_reload_time 2
 set g_balance_devastator_remote_damage 70
 set g_balance_devastator_remote_edgedamage 35
-set g_balance_devastator_remote_force 400
+set g_balance_devastator_remote_force 450
 set g_balance_devastator_remote_jump_damage 70
 set g_balance_devastator_remote_jump_radius 0
 set g_balance_devastator_remote_jump_velocity_z_add 400
 set g_balance_devastator_remote_jump_velocity_z_max 1500
 set g_balance_devastator_remote_jump_velocity_z_min 400
-set g_balance_devastator_remote_radius 150
-set g_balance_devastator_speed 1200
-set g_balance_devastator_speedaccel 1200
+set g_balance_devastator_remote_radius 110
+set g_balance_devastator_speed 1300
+set g_balance_devastator_speedaccel 1300
 set g_balance_devastator_speedstart 1000
 set g_balance_devastator_switchdelay_drop 0.2
 set g_balance_devastator_switchdelay_raise 0.2
@@ -433,6 +434,7 @@ set g_balance_porto_weaponthrowable 1
 // {{{ #12: Vaporizer
 set g_balance_vaporizer_primary_ammo 10
 set g_balance_vaporizer_primary_animtime 0.3
+set g_balance_vaporizer_primary_damage 150
 set g_balance_vaporizer_primary_refire 1
 set g_balance_vaporizer_reload_ammo 0
 set g_balance_vaporizer_reload_time 0
@@ -674,23 +676,23 @@ set g_balance_seeker_weaponthrowable 1
 // }}}
 // {{{ #19: Shockwave (MUTATOR WEAPON)
 set g_balance_shockwave_blast_animtime 0.3
-set g_balance_shockwave_blast_damage 20
+set g_balance_shockwave_blast_damage 40
 set g_balance_shockwave_blast_distance 1000
 set g_balance_shockwave_blast_edgedamage 0
-set g_balance_shockwave_blast_force 200
+set g_balance_shockwave_blast_force 15
 set g_balance_shockwave_blast_force_forwardbias 50
-set g_balance_shockwave_blast_force_zscale 2
+set g_balance_shockwave_blast_force_zscale 1
 set g_balance_shockwave_blast_jump_damage 20
 set g_balance_shockwave_blast_jump_edgedamage 0
-set g_balance_shockwave_blast_jump_force 300
-set g_balance_shockwave_blast_jump_force_velocitybias 0
-set g_balance_shockwave_blast_jump_force_zscale 1.25
+set g_balance_shockwave_blast_jump_force 100
+set g_balance_shockwave_blast_jump_force_velocitybias 1
+set g_balance_shockwave_blast_jump_force_zscale 1
 set g_balance_shockwave_blast_jump_multiplier_accuracy 0.5
 set g_balance_shockwave_blast_jump_multiplier_distance 0.5
 set g_balance_shockwave_blast_jump_multiplier_min 0
 set g_balance_shockwave_blast_jump_radius 150
-set g_balance_shockwave_blast_multiplier_accuracy 0.5
-set g_balance_shockwave_blast_multiplier_distance 0.5
+set g_balance_shockwave_blast_multiplier_accuracy 0.45
+set g_balance_shockwave_blast_multiplier_distance 0.2
 set g_balance_shockwave_blast_multiplier_min 0
 set g_balance_shockwave_blast_refire 0.75
 set g_balance_shockwave_blast_splash_damage 15
@@ -719,37 +721,50 @@ set g_balance_shockwave_melee_traces 10
 set g_balance_shockwave_switchdelay_drop 0.2
 set g_balance_shockwave_switchdelay_raise 0.2
 set g_balance_shockwave_weaponreplace ""
-set g_balance_shockwave_weaponstart 0
+set g_balance_shockwave_weaponstart 1
 set g_balance_shockwave_weaponstartoverride -1
 set g_balance_shockwave_weaponthrowable 0
 // }}}
 // {{{ #20: Arc
-set g_balance_arc_beam_ammo 4
-set g_balance_arc_beam_animtime 0.2
+set g_balance_arc_beam_ammo 6
+set g_balance_arc_beam_animtime 0.1
 set g_balance_arc_beam_botaimlifetime 0
 set g_balance_arc_beam_botaimspeed 0
-set g_balance_arc_beam_damage 115
+set g_balance_arc_beam_damage 100
 set g_balance_arc_beam_degreespersegment 1
 set g_balance_arc_beam_distancepersegment 0
 set g_balance_arc_beam_falloff_halflifedist 0
 set g_balance_arc_beam_falloff_maxdist 0
 set g_balance_arc_beam_falloff_mindist 0
-set g_balance_arc_beam_force 900
-set g_balance_arc_beam_healing_amax 100
+set g_balance_arc_beam_force 600
+set g_balance_arc_beam_healing_amax 0
 set g_balance_arc_beam_healing_aps 50
 set g_balance_arc_beam_healing_hmax 150
 set g_balance_arc_beam_healing_hps 50
 set g_balance_arc_cooldown 2.5
+set g_balance_arc_cooldown_release 0
 set g_balance_arc_overheat_max 5
 set g_balance_arc_overheat_min 3
-set g_balance_arc_beam_heat 1
+set g_balance_arc_beam_heat 0
 set g_balance_arc_burst_heat 5
 set g_balance_arc_beam_maxangle 10
 set g_balance_arc_beam_nonplayerdamage 80
 set g_balance_arc_beam_range 1000
-set g_balance_arc_beam_refire 0.5
+set g_balance_arc_beam_refire 0.25
 set g_balance_arc_beam_returnspeed 8
 set g_balance_arc_beam_tightness 0.5
+set g_balance_arc_bolt 1
+set g_balance_arc_bolt_ammo 1
+set g_balance_arc_bolt_damage 25
+set g_balance_arc_bolt_damageforcescale 0
+set g_balance_arc_bolt_edgedamage 12.5
+set g_balance_arc_bolt_force 120
+set g_balance_arc_bolt_health 15
+set g_balance_arc_bolt_lifetime 5
+set g_balance_arc_bolt_radius 65
+set g_balance_arc_bolt_refire 0.16667
+set g_balance_arc_bolt_speed 2300
+set g_balance_arc_bolt_spread 0
 set g_balance_arc_burst_ammo 15
 set g_balance_arc_burst_damage 250
 set g_balance_arc_burst_healing_aps 100
index 8a47e40d50dc73ebf56bf40bbf450c8f6c2afbe0..d4b47594d7061462769246cb79af1a180c4b84d1 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 d0cfa361d269c1aae66c89cefc2e3e660f65dd24..d7463338aa0f2746550ab2c40468fa8838e89e7a 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 af2234f0d6c898c02d110d98273a46019bdb7c9d..fe3b9ed8711e62bb64ba564310ae573008677f6c 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 931a63c6a2264d068110f90817f63be68fc5ac64..c9bdb2aa367e5b11629c5778825d3c895e4f0539 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 779c7129c68009e6493df50b05af29aef33c6581..64d79e150aee00e1e9abfbb90d420edede443993 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 779c7129c68009e6493df50b05af29aef33c6581..64d79e150aee00e1e9abfbb90d420edede443993 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 9995e5ec5c8f47c8792823590560569e3fe40331..022d62eaa0ff475cb8ec1d6d73f3c5734fe8d749 100644 (file)
@@ -2,8 +2,8 @@ g_mod_balance Mario
 
 // {{{ starting gear
 set g_balance_health_start 100
-set g_balance_armor_start 50
-set g_start_ammo_shells 20
+set g_balance_armor_start 0
+set g_start_ammo_shells 15
 set g_start_ammo_nails 0
 set g_start_ammo_rockets 0
 set g_start_ammo_cells 0
@@ -44,7 +44,7 @@ set g_balance_nix_ammoincr_fuel 2
 // {{{ pickup items
 set g_pickup_ammo_anyway 1
 set g_pickup_weapons_anyway 1
-set g_pickup_shells 20
+set g_pickup_shells 15
 set g_pickup_shells_weapon 15
 set g_pickup_shells_max 60
 set g_pickup_nails 80
@@ -138,7 +138,7 @@ set g_balance_fuel_limit 999
 // }}}
 
 // {{{ misc
-set g_balance_selfdamagepercent 0.5
+set g_balance_selfdamagepercent 0.65
 set g_weaponspeedfactor 1 "weapon projectile speed multiplier"
 set g_weaponratefactor 1 "weapon fire rate multiplier"
 set g_weapondamagefactor 1 "weapon damage multiplier"
@@ -175,8 +175,8 @@ set g_projectiles_spread_style 7
 // 7: forward + circle with (1-r)(2-r) falloff
 set g_balance_falldamage_deadminspeed 250
 set g_balance_falldamage_minspeed 900
-set g_balance_falldamage_factor 0.07
-set g_balance_falldamage_maxdamage 250
+set g_balance_falldamage_factor 0.20
+set g_balance_falldamage_maxdamage 40
 set g_balance_damagepush_speedfactor 2.5
 set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
index eca60f67d98a3076a6f66c922de78f85e3582ba2..afa60ccf6a19488d963abc4165a04d9cb91f122c 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
@@ -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"
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 2c5229aa93667f6556a8bbcee3d0b80cf68330cb..1609b782c95a5b778ca9b9365f3fd65251e5eb4a 100644 (file)
Binary files a/gfx/hud/luma/flag_blue_lost.tga and b/gfx/hud/luma/flag_blue_lost.tga differ
index e6fd5c5bc0f2d20ae3eaae6281fe2f01ac7558bd..85ef904c58ab80a4119bcecce6f494c3649258d1 100644 (file)
Binary files a/gfx/hud/luma/flag_neutral_lost.tga and b/gfx/hud/luma/flag_neutral_lost.tga differ
index 0cd5467199b07afc3fa0d50986e66250963e8d6d..f636620b59650ebc9793e9976c6f842c081df95b 100644 (file)
Binary files a/gfx/hud/luma/flag_pink_lost.tga and b/gfx/hud/luma/flag_pink_lost.tga differ
index 014a4163c1f6111b87b68b5f2125efd732ad605f..7260275eaf385c8aa3a57c196077a84d0d68b764 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 bd5f3def21975de5898d52aee631fc4c9cb938b1..ec45f11740e295d9506f6b448688e121ca28131c 100644 (file)
Binary files a/gfx/hud/luma/flag_yellow_lost.tga and b/gfx/hud/luma/flag_yellow_lost.tga differ
index 2c5229aa93667f6556a8bbcee3d0b80cf68330cb..1609b782c95a5b778ca9b9365f3fd65251e5eb4a 100644 (file)
Binary files a/gfx/hud/luma/notify_blue_lost.tga and b/gfx/hud/luma/notify_blue_lost.tga differ
index e6fd5c5bc0f2d20ae3eaae6281fe2f01ac7558bd..85ef904c58ab80a4119bcecce6f494c3649258d1 100644 (file)
Binary files a/gfx/hud/luma/notify_neutral_lost.tga and b/gfx/hud/luma/notify_neutral_lost.tga differ
index 0cd5467199b07afc3fa0d50986e66250963e8d6d..f636620b59650ebc9793e9976c6f842c081df95b 100644 (file)
Binary files a/gfx/hud/luma/notify_pink_lost.tga and b/gfx/hud/luma/notify_pink_lost.tga differ
index 014a4163c1f6111b87b68b5f2125efd732ad605f..7260275eaf385c8aa3a57c196077a84d0d68b764 100644 (file)
Binary files a/gfx/hud/luma/notify_red_lost.tga and b/gfx/hud/luma/notify_red_lost.tga differ
index bd5f3def21975de5898d52aee631fc4c9cb938b1..ec45f11740e295d9506f6b448688e121ca28131c 100644 (file)
Binary files a/gfx/hud/luma/notify_yellow_lost.tga and b/gfx/hud/luma/notify_yellow_lost.tga differ
index 2f4f31e92b7290f7f2852a69ffdc1dc8272915ff..0034f8a17f90a044fb5d594031a4576a1398fae7 100644 (file)
@@ -230,7 +230,7 @@ seta hud_panel_engineinfo_bg_padding ""
 seta hud_panel_engineinfo_framecounter_time "0.1"
 seta hud_panel_engineinfo_framecounter_decimals "0"
 
-seta hud_panel_infomessages_pos "0.720000 0.100000"
+seta hud_panel_infomessages_pos "0.680000 0.100000"
 seta hud_panel_infomessages_size "0.280000 0.080000"
 seta hud_panel_infomessages_bg "0"
 seta hud_panel_infomessages_bg_color ""
index 3d259ebf394d7b104f848c37e8a35058c8b6aec0..20dd47befca60fc88178b2c3632d8a6d68ebf60c 100644 (file)
@@ -230,7 +230,7 @@ seta hud_panel_engineinfo_bg_padding ""
 seta hud_panel_engineinfo_framecounter_time "0.1"
 seta hud_panel_engineinfo_framecounter_decimals "0"
 
-seta hud_panel_infomessages_pos "0.720000 0.100000"
+seta hud_panel_infomessages_pos "0.680000 0.100000"
 seta hud_panel_infomessages_size "0.280000 0.080000"
 seta hud_panel_infomessages_bg "0"
 seta hud_panel_infomessages_bg_color ""
index c1ac51b7ab854ddf345f7e11023b64713dccc810..f9250b98612e1a47b2c8e28cab1d660b3e245215 100644 (file)
@@ -231,7 +231,7 @@ seta hud_panel_engineinfo_framecounter_time "0.1"
 seta hud_panel_engineinfo_framecounter_decimals "0"
 
 seta hud_panel_infomessages_pos "0.710000 0"
-seta hud_panel_infomessages_size "0.290000 0.100000"
+seta hud_panel_infomessages_size "0.280000 0.090000"
 seta hud_panel_infomessages_bg "0"
 seta hud_panel_infomessages_bg_color ""
 seta hud_panel_infomessages_bg_color_team ""
index d6125985b8a42e180e753e91a4b3ee584bddf932..a7bbce68769da59a79678bdaec0051344570105b 100644 (file)
@@ -231,7 +231,7 @@ seta hud_panel_engineinfo_framecounter_time "0.1"
 seta hud_panel_engineinfo_framecounter_decimals "0"
 
 seta hud_panel_infomessages_pos "0.710000 0"
-seta hud_panel_infomessages_size "0.290000 0.100000"
+seta hud_panel_infomessages_size "0.280000 0.090000"
 seta hud_panel_infomessages_bg "0"
 seta hud_panel_infomessages_bg_color ""
 seta hud_panel_infomessages_bg_color_team ""
index 0a0959b87ae09bb088725c13a4a8c970a5876264..9107add6c87c1b694998ba858717ebb242328362 100644 (file)
@@ -24,7 +24,7 @@ void Announcer_Countdown(entity this)
        if(roundstarttime == -1)
        {
                Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_ROUNDSTOP);
-               remove(this);
+               delete(this);
                announcer_countdown = NULL;
                return;
        }
@@ -40,7 +40,7 @@ void Announcer_Countdown(entity this)
        {
                Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_BEGIN);
                Local_Notification(MSG_MULTI, MULTI_COUNTDOWN_BEGIN);
-               remove(this);
+               delete(this);
                announcer_countdown = NULL;
                return;
        }
@@ -87,7 +87,7 @@ void Announcer_Gamestart()
                        centerprint_kill(ORDINAL(CPID_ROUND));
                        if(announcer_countdown)
                        {
-                               remove(announcer_countdown);
+                               delete(announcer_countdown);
                                announcer_countdown = NULL;
                        }
                }
index dce058c816da9f2c4abbfae97c4bad68d34931dd..100bebf5fa697bd5c0cd3d57acf11ee0dd6fa147 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 2ea1e746f7c60e12104563d3dd2751ff66bb2fcc..d8906b12ba466a2f0bef24b191e4935e0e30a58e 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 30148bdd44e7f4be1fb88b33d406ae203b525788..6eeb6c8bd8c2ef1771a79e68ae67384a1c613aa2 100644 (file)
@@ -142,7 +142,7 @@ void CSQCPlayer_ModelAppearance_Apply(entity this, bool islocalplayer)
                _setmodel(e, cvar_defstring("_cl_playermodel"));
                forceplayermodels_goodmodel = e.model;
                forceplayermodels_goodmodelindex = e.modelindex;
-               remove(e);
+               delete(e);
        }
 
        // first, try finding it from the server
@@ -175,7 +175,7 @@ void CSQCPlayer_ModelAppearance_Apply(entity this, bool islocalplayer)
                forceplayermodels_model = e.model;
                forceplayermodels_modelindex = e.modelindex;
                forceplayermodels_skin = autocvar__cl_playerskin;
-               remove(e);
+               delete(e);
        }
 
        if(autocvar_cl_forcemyplayermodel != "" && autocvar_cl_forcemyplayermodel != forceplayermodels_mymodel)
@@ -185,7 +185,7 @@ void CSQCPlayer_ModelAppearance_Apply(entity this, bool islocalplayer)
                forceplayermodels_myisgoodmodel = fexists(e.model);
                forceplayermodels_mymodel = e.model;
                forceplayermodels_mymodelindex = e.modelindex;
-               remove(e);
+               delete(e);
        }
 
        // apply it
index 2df27e715aba8876e42266f6a56a6501c34d0b93..1839263a4563b7f1cd7a73bc3f2db8abad12c15e 100644 (file)
@@ -5,12 +5,53 @@
 
 // Info messages panel (#14)
 
-#define drawInfoMessage(s) MACRO_BEGIN {                                                                                                                                                       \
-       if(autocvar_hud_panel_infomessages_flip)                                                                                                                                                \
-               o.x = pos.x + mySize.x - stringwidth(s, true, fontsize);                                                                                                        \
-       drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);                                                                                                               \
-       o.y += fontsize.y;                                                                                                                                                                                              \
+float autocvar_hud_panel_infomessages_group_fadetime = 0.4;
+float autocvar_hud_panel_infomessages_group_time = 6;
+const int IMG_COUNT = 1; // number of InfoMessage Groups
+float img_fade[IMG_COUNT];
+int img_cur_msg[IMG_COUNT];
+float img_time[IMG_COUNT];
+
+int img_select(int group_id)
+{
+       float fadetime = max(0.001, autocvar_hud_panel_infomessages_group_fadetime);
+       if(time > img_time[group_id])
+       {
+               img_fade[group_id] = max(0, img_fade[group_id] - frametime / fadetime);
+               if(!img_fade[group_id])
+               {
+                       ++img_cur_msg[group_id];
+                       img_time[group_id] = floor(time) + autocvar_hud_panel_infomessages_group_time;
+               }
+       }
+       else
+               img_fade[group_id] = min(1, img_fade[group_id] + frametime / fadetime);
+       return img_cur_msg[group_id];
+}
+
+float stringwidth_colors(string s, vector theSize);
+vector InfoMessages_drawstring(string s, vector pos, vector sz, float a, vector fontsize)
+{
+       getWrappedLine_remaining = s;
+       float offset = 0;
+       while(getWrappedLine_remaining)
+       {
+               s = getWrappedLine(sz.x - offset, fontsize, stringwidth_colors);
+               if(autocvar_hud_panel_infomessages_flip)
+                       offset = sz.x - stringwidth_colors(s, fontsize) - offset;
+               drawcolorcodedstring(pos + eX * offset, s, fontsize, a, DRAWFLAG_NORMAL);
+               pos.y += fontsize.y;
+               offset = fontsize.x;
+       }
+       pos.y += fontsize.y * 0.25;
+       return pos;
+}
+
+#define InfoMessage(s) MACRO_BEGIN { \
+       pos = InfoMessages_drawstring(s, pos, mySize, ((img_curr_group >= 0) ? panel_fg_alpha * img_fade[img_curr_group] : panel_fg_alpha), fontsize); \
+       img_curr_group = -1; \
 } MACRO_END
+
 void HUD_InfoMessages()
 {
        if(!autocvar__hud_configure)
@@ -34,60 +75,40 @@ void HUD_InfoMessages()
                mySize -= '2 2 0' * panel_bg_padding;
        }
 
-       // always force 5:1 aspect
-       vector newSize = '0 0 0';
-       if(mySize.x/mySize.y > 5)
-       {
-               newSize.x = 5 * mySize.y;
-               newSize.y = mySize.y;
-
-               pos.x = pos.x + (mySize.x - newSize.x) / 2;
-       }
-       else
-       {
-               newSize.y = 1/5 * mySize.x;
-               newSize.x = mySize.x;
-
-               pos.y = pos.y + (mySize.y - newSize.y) / 2;
-       }
-
-       mySize = newSize;
-       entity tm;
-       vector o;
-       o = pos;
-
-       vector fontsize;
-       fontsize = '0.20 0.20 0' * mySize.y;
-
-       float a;
-       a = panel_fg_alpha;
-
+       vector fontsize = '0.2 0.2 0' * mySize.y;
        string s;
+       int img_curr_group = -1;
        if(!autocvar__hud_configure)
        {
                if(spectatee_status)
                {
-                       a = 1;
                        if(spectatee_status == -1)
                                s = _("^1Observing");
                        else
                                s = sprintf(_("^1Spectating: ^7%s"), entcs_GetName(current_player));
-                       drawInfoMessage(s);
+                       InfoMessage(s);
 
-                       if(spectatee_status == -1)
-                               s = sprintf(_("^1Press ^3%s^1 to spectate"), getcommandkey("primary fire", "+fire"));
-                       else
-                               s = sprintf(_("^1Press ^3%s^1 or ^3%s^1 for next or previous player"), getcommandkey("next weapon", "weapnext"), getcommandkey("previous weapon", "weapprev"));
-                       drawInfoMessage(s);
-
-                       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"));
-                       drawInfoMessage(s);
-
-                       s = sprintf(_("^1Press ^3%s^1 for gamemode info"), getcommandkey("server info", "+show_info"));
-                       drawInfoMessage(s);
+                       img_curr_group = 0;
+                       switch(img_select(img_curr_group) % 3)
+                       {
+                               default:
+                               case 0:
+                                       if(spectatee_status == -1)
+                                               s = sprintf(_("^1Press ^3%s^1 to spectate"), getcommandkey(_("primary fire"), "+fire"));
+                                       else
+                                               s = sprintf(_("^1Press ^3%s^1 or ^3%s^1 for next or previous player"), getcommandkey(_("next weapon"), "weapnext"), getcommandkey(_("previous weapon"), "weapprev"));
+                                       break;
+                               case 1:
+                                       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, ^3%s^1 to change camera mode"), getcommandkey(_("secondary fire"), "+fire2"), getcommandkey(_("drop weapon"), "dropweapon"));
+                                       break;
+                               case 2:
+                                       s = sprintf(_("^1Press ^3%s^1 for gamemode info"), getcommandkey(_("server info"), "+show_info"));
+                                       break;
+                       }
+                       InfoMessage(s);
 
                        if(gametype == MAPINFO_TYPE_LMS)
                        {
@@ -98,11 +119,11 @@ void HUD_InfoMessages()
                                else if(sk.(scores[ps_primary]) > 0)
                                        s = _("^1You have no more lives left");
                                else
-                                       s = sprintf(_("^1Press ^3%s^1 to join"), getcommandkey("jump", "+jump"));
+                                       s = sprintf(_("^1Press ^3%s^1 to join"), getcommandkey(_("jump"), "+jump"));
                        }
                        else
-                               s = sprintf(_("^1Press ^3%s^1 to join"), getcommandkey("jump", "+jump"));
-                       drawInfoMessage(s);
+                               s = sprintf(_("^1Press ^3%s^1 to join"), getcommandkey(_("jump"), "+jump"));
+                       InfoMessage(s);
                }
 
                if (time < STAT(GAMESTARTTIME))
@@ -110,13 +131,13 @@ void HUD_InfoMessages()
                        //we need to ceil, otherwise the countdown would be off by .5 when using round()
                        float countdown = ceil(STAT(GAMESTARTTIME) - time);
                        s = sprintf(_("^1Game starts in ^3%d^1 seconds"), countdown);
-                       drawInfoMessage(s);
+                       InfoMessage(s);
                }
 
                if(warmup_stage)
                {
                        s = _("^2Currently in ^1warmup^2 stage!");
-                       drawInfoMessage(s);
+                       InfoMessage(s);
                }
 
                string blinkcolor;
@@ -130,9 +151,9 @@ void HUD_InfoMessages()
                        if(ready_waiting_for_me)
                        {
                                if(warmup_stage)
-                                       s = sprintf(_("%sPress ^3%s%s to end warmup"), blinkcolor, getcommandkey("ready", "ready"), blinkcolor);
+                                       s = sprintf(_("%sPress ^3%s%s to end warmup"), blinkcolor, getcommandkey(_("ready"), "ready"), blinkcolor);
                                else
-                                       s = sprintf(_("%sPress ^3%s%s once you are ready"), blinkcolor, getcommandkey("ready", "ready"), blinkcolor);
+                                       s = sprintf(_("%sPress ^3%s%s once you are ready"), blinkcolor, getcommandkey(_("ready"), "ready"), blinkcolor);
                        }
                        else
                        {
@@ -141,18 +162,18 @@ void HUD_InfoMessages()
                                else
                                        s = _("^2Waiting for others to ready up...");
                        }
-                       drawInfoMessage(s);
+                       InfoMessage(s);
                }
                else if(warmup_stage && !spectatee_status)
                {
-                       s = sprintf(_("^2Press ^3%s^2 to end warmup"), getcommandkey("ready", "ready"));
-                       drawInfoMessage(s);
+                       s = sprintf(_("^2Press ^3%s^2 to end warmup"), getcommandkey(_("ready"), "ready"));
+                       InfoMessage(s);
                }
 
                if(teamplay && !spectatee_status && gametype != MAPINFO_TYPE_CA && teamnagger)
                {
                        float ts_min = 0, ts_max = 0;
-                       tm = teams.sort_next;
+                       entity tm = teams.sort_next;
                        if (tm)
                        {
                                for (; tm.sort_next; tm = tm.sort_next)
@@ -168,11 +189,9 @@ void HUD_InfoMessages()
                                {
                                        s = strcat(blinkcolor, _("Teamnumbers are unbalanced!"));
                                        tm = GetTeam(myteam, false);
-                                       if (tm)
-                                       if (tm.team != NUM_SPECTATOR)
-                                       if (tm.team_size == ts_max)
-                                               s = strcat(s, sprintf(_(" Press ^3%s%s to adjust"), getcommandkey("team menu", "menu_showteamselect"), blinkcolor));
-                                       drawInfoMessage(s);
+                                       if (tm && tm.team != NUM_SPECTATOR && tm.team_size == ts_max)
+                                               s = strcat(s, sprintf(_(" Press ^3%s%s to adjust"), getcommandkey(_("team menu"), "menu_showteamselect"), blinkcolor));
+                                       InfoMessage(s);
                                }
                        }
                }
@@ -197,13 +216,9 @@ void HUD_InfoMessages()
        }
        else
        {
-               s = _("^7Press ^3ESC ^7to show HUD options.");
-               drawInfoMessage(s);
-               s = _("^3Doubleclick ^7a panel for panel-specific options.");
-               drawInfoMessage(s);
-               s = _("^3CTRL ^7to disable collision testing, ^3SHIFT ^7and");
-               drawInfoMessage(s);
-               s = _("^3ALT ^7+ ^3ARROW KEYS ^7for fine adjustments.");
-               drawInfoMessage(s);
+               InfoMessage(_("^7Press ^3ESC ^7to show HUD options."));
+               InfoMessage(_("^3Doubleclick ^7a panel for panel-specific options."));
+               InfoMessage(_("^3CTRL ^7to disable collision testing, ^3SHIFT ^7and"));
+               InfoMessage(_("^3ALT ^7+ ^3ARROW KEYS ^7for fine adjustments."));
        }
 }
index b869f96194534954de800f66802e31917832e309..5901a16326ca40047480f5e71d67ae7d783f7cfd 100644 (file)
@@ -108,6 +108,7 @@ void HUD_Mod_CTF_Reset()
        redflag_statuschange_time = blueflag_statuschange_time = yellowflag_statuschange_time = pinkflag_statuschange_time = neutralflag_statuschange_time = 0;
 }
 
+int autocvar__teams_available;
 void HUD_Mod_CTF(vector pos, vector mySize)
 {
        vector redflag_pos, blueflag_pos, yellowflag_pos, pinkflag_pos, neutralflag_pos;
@@ -122,6 +123,8 @@ void HUD_Mod_CTF(vector pos, vector mySize)
        float fs, fs2, fs3, size1, size2;
        vector e1, e2;
 
+       int nteams = autocvar__teams_available;
+
        redflag = (stat_items/CTF_RED_FLAG_TAKEN) & 3;
        blueflag = (stat_items/CTF_BLUE_FLAG_TAKEN) & 3;
        yellowflag = (stat_items/CTF_YELLOW_FLAG_TAKEN) & 3;
@@ -137,9 +140,9 @@ void HUD_Mod_CTF(vector pos, vector mySize)
        if (autocvar__hud_configure) {
                redflag = 1;
                blueflag = 2;
-               if (team_count >= 3)
+               if (nteams & BIT(2))
                        yellowflag = 2;
-               if (team_count >= 4)
+               if (nteams & BIT(3))
                        pinkflag = 3;
                ctf_oneflag = neutralflag = 0; // disable neutral flag in hud editor?
        }
@@ -201,18 +204,24 @@ void HUD_Mod_CTF(vector pos, vector mySize)
                                break; \
                } \
        } MACRO_END
-       X(red, myteam != NUM_TEAM_1);
-       X(blue, myteam != NUM_TEAM_2);
-       X(yellow, myteam != NUM_TEAM_3 && team_count >= 3);
-       X(pink, myteam != NUM_TEAM_4 && team_count >= 4);
+       X(red, myteam != NUM_TEAM_1 && (nteams & BIT(0)));
+       X(blue, myteam != NUM_TEAM_2 && (nteams & BIT(1)));
+       X(yellow, myteam != NUM_TEAM_3 && (nteams & BIT(2)));
+       X(pink, myteam != NUM_TEAM_4 && (nteams & BIT(3)));
        X(neutral, ctf_oneflag);
        #undef X
 
+       int tcount = 2;
+       if(nteams & BIT(2))
+               tcount = 3;
+       if(nteams & BIT(3))
+               tcount = 4;
+
        if (ctf_oneflag) {
                // hacky, but these aren't needed
                red_icon = red_icon_prevstatus = blue_icon = blue_icon_prevstatus = yellow_icon = yellow_icon_prevstatus = pink_icon = pink_icon_prevstatus = string_null;
                fs = fs2 = fs3 = 1;
-       } else switch (team_count) {
+       } else switch (tcount) {
                default:
                case 2: fs = 0.5; fs2 = 0.5; fs3 = 0.5; break;
                case 3: fs = 1; fs2 = 0.35; fs3 = 0.35; break;
@@ -267,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 ad0fa28f15765d9d4e2c2da5050849aed8894cdc..e935d0cb2b27eba1b395593ca192b412afc13c2e 100644 (file)
@@ -351,9 +351,9 @@ 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 )
                if ( it.team == myteam+1 || gametype == MAPINFO_TYPE_RACE || !(serverflags & SERVERFLAG_TEAMPLAY) )
index d7d4d252bec67441f178311e5f593bde24220536..a732b0c5ee7a2073c8a32e00ca054633fcb2c320 100644 (file)
@@ -72,7 +72,6 @@ void HUD_Vote()
                panel_size = eX * 0.4 * vid_conwidth + eY * 0.3 * vid_conheight;
        }
 
-    // these must be below above block
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -119,10 +118,10 @@ void HUD_Vote()
        drawcolorcodedstring_aspect(pos + eY * (2/8) * mySize.y, s, eX * mySize.x + eY * (1.75/8) * mySize.y, a, DRAWFLAG_NORMAL);
 
        // print the yes/no counts
-    s = sprintf(_("Yes (%s): %d"), getcommandkey("vyes", "vyes"), vote_yescount);
-       drawstring_aspect(pos + eY * (4/8) * mySize.y, s, eX * 0.5 * mySize.x + eY * (1.5/8) * mySize.y, '0 1 0', a, DRAWFLAG_NORMAL);
-    s = sprintf(_("No (%s): %d"), getcommandkey("vno", "vno"), vote_nocount);
-       drawstring_aspect(pos + eX * 0.5 * mySize.x + eY * (4/8) * mySize.y, s, eX * 0.5 * mySize.x + eY * (1.5/8) * mySize.y, '1 0 0', a, DRAWFLAG_NORMAL);
+       s = sprintf("^2%s ^7(%d)", getcommandkey_forcename(_("Yes"), "vyes"), vote_yescount);
+       drawcolorcodedstring_aspect(pos + eY * (4/8) * mySize.y, s, eX * 0.5 * mySize.x + eY * (1.5/8) * mySize.y, a, DRAWFLAG_NORMAL);
+       s = sprintf("^1%s ^7(%d)", getcommandkey_forcename(_("No"), "vno"), vote_nocount);
+       drawcolorcodedstring_aspect(pos + eX * 0.5 * mySize.x + eY * (4/8) * mySize.y, s, eX * 0.5 * mySize.x + eY * (1.5/8) * mySize.y, a, DRAWFLAG_NORMAL);
 
        // draw the progress bar backgrounds
        drawpic_skin(pos + eY * (5/8) * mySize.y, "voteprogress_back", eX * mySize.x + eY * (3/8) * mySize.y, '1 1 1', a, DRAWFLAG_NORMAL);
index 9637c98c55542fd7b173019550e2714885e3a7ac..2905b8b2da90e8ff51c6e135e6bac8206586a846 100644 (file)
@@ -185,8 +185,8 @@ void Shutdown()
 {
        WarpZone_Shutdown();
 
-       remove(teams);
-       remove(players);
+       delete(teams);
+       delete(players);
        db_close(binddb);
        db_close(tempdb);
        if(autocvar_cl_db_saveasdump)
@@ -715,8 +715,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)
                {
@@ -734,6 +735,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;
@@ -888,7 +890,7 @@ void CSQC_Ent_Remove(entity this)
                return;
        }
        if (this.enttype) Ent_Remove(this);
-       remove(this);
+       delete(this);
 }
 
 void Gamemode_Init()
@@ -1236,13 +1238,13 @@ NET_HANDLE(TE_CSQC_WEAPONCOMPLAIN, bool isNew)
        }
 }
 
-string getcommandkey(string text, string command)
+string _getcommandkey(string cmd_name, string command, bool forcename)
 {
        string keys;
        float n, j, k, l = 0;
 
        if (!autocvar_hud_showbinds)
-               return text;
+               return cmd_name;
 
        keys = db_get(binddb, command);
        if (keys == "")
@@ -1276,12 +1278,12 @@ string getcommandkey(string text, string command)
 
        if (keys == "NO_KEY") {
                if (autocvar_hud_showbinds > 1)
-                       return sprintf(_("%s (not bound)"), text);
+                       return sprintf(_("%s (not bound)"), cmd_name);
                else
-                       return text;
+                       return cmd_name;
        }
-       else if (autocvar_hud_showbinds > 1)
-               return sprintf("%s (%s)", text, keys);
+       else if (autocvar_hud_showbinds > 1 || forcename)
+               return sprintf("%s (%s)", cmd_name, keys);
        else
                return keys;
 }
index bc6b5afec0d4059f446ba60df7443b035d7d4163..b47836f23caca4f5ec4b3fb400d5f5e1034d5ee1 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;
@@ -103,7 +112,9 @@ float warmup_stage;
 
 void Fog_Force();
 
-string getcommandkey(string text, string command);
+string _getcommandkey(string text, string command, bool forcename);
+#define getcommandkey(cmd_name, command) _getcommandkey(cmd_name, command, false)
+#define getcommandkey_forcename(cmd_name, command) _getcommandkey(cmd_name, command, true)
 
 string vote_called_vote;
 float ready_waiting;
index bfc25e99c134116524b39fe0934773484e1627f7..cfd3f61ee5def2a7f1954d09d2241acca39c1bfc 100644 (file)
@@ -177,11 +177,11 @@ void GameTypeVote_DrawGameTypeItem(vector pos, float maxh, float tsize, string g
                drawstring(last.origin+offset, last.message, gtv_text_size_small, '1 1 1', alpha, DRAWFLAG_NORMAL);
                next = last;
                last = last.chain;
-               remove(next);
+               delete(next);
        }
 
        // Cleanup
-       remove(title);
+       delete(title);
 }
 
 void MapVote_DrawMapItem(vector pos, float isize, float tsize, string map, string pic, float _count, int id)
index b86e0d8f6ad51a29f0f4159c39ff00f19f52d6e8..5e51e9b7ffe7198921cbecac40cfa1dbcb0169b6 100644 (file)
@@ -1507,7 +1507,7 @@ void HUD_DrawScoreboard()
                        );
                }
                else if(time >= respawn_time)
-                       str = sprintf(_("You are dead, press ^2%s^7 to respawn"), getcommandkey("jump", "+jump"));
+                       str = sprintf(_("You are dead, press ^2%s^7 to respawn"), getcommandkey(_("jump"), "+jump"));
 
                pos.y += 1.2 * hud_fontsize.y;
                drawcolorcodedstring(pos + '0.5 0 0' * (sbwidth - stringwidth(str, true, hud_fontsize)), str, hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
index a8708f2460f809a579f96db0428fbc1522432c61..ab14cd3bf38d04a89d48ead845339bcbf582e271 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 4ca30d4a8de656478a7bc75ebf54ee4b33c9b73b..1458efe15f13563e9e869cb653c9e5c80791318c 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 b94fddd8d81e91ce4283c915dad6ab56ed0dc149..01a86bb1ee44d2490402cac124a41b35c1229715 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 39032cd70d782aad8606f3d73addccbe61dde822..6d58ac77a2d1a01f72688513ecc2708750d93622 100644 (file)
@@ -18,8 +18,8 @@
 
 void SUB_Stop(entity this, entity toucher)
 {
-       this.move_velocity = this.move_avelocity = '0 0 0';
-       this.move_movetype = MOVETYPE_NONE;
+       this.velocity = this.avelocity = '0 0 0';
+       set_movetype(this, MOVETYPE_NONE);
 }
 
 void Projectile_ResetTrail(entity this, vector to)
@@ -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))
@@ -332,7 +330,7 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
                this.maxs = '0 0 0';
                this.colormod = '0 0 0';
                settouch(this, SUB_Stop);
-               this.move_movetype = MOVETYPE_TOSS;
+               set_movetype(this, MOVETYPE_TOSS);
                this.alphamod = 1;
 
                switch (this.cnt)
@@ -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.move_movetype = MOVETYPE_BOUNCE;
+                               this.mins = '-4 -4 -4';
+                               this.maxs = '4 4 4';
+                               set_movetype(this, 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:
@@ -360,10 +358,10 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
                        case PROJECTILE_GRENADE_BOUNCING:
                                this.mins = '-3 -3 -3';
                                this.maxs = '3 3 3';
-                               this.move_movetype = MOVETYPE_BOUNCE;
+                               set_movetype(this, 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';
@@ -378,21 +376,21 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
                        case PROJECTILE_PORTO_RED:
                                this.colormod = '2 1 1';
                                this.alphamod = 0.5;
-                               this.move_movetype = MOVETYPE_BOUNCE;
+                               set_movetype(this, MOVETYPE_BOUNCE);
                                settouch(this, func_null);
                                break;
                        case PROJECTILE_PORTO_BLUE:
                                this.colormod = '1 1 2';
                                this.alphamod = 0.5;
-                               this.move_movetype = MOVETYPE_BOUNCE;
+                               set_movetype(this, MOVETYPE_BOUNCE);
                                settouch(this, func_null);
                                break;
                        case PROJECTILE_HAGAR_BOUNCING:
-                               this.move_movetype = MOVETYPE_BOUNCE;
+                               set_movetype(this, MOVETYPE_BOUNCE);
                                settouch(this, func_null);
                                break;
                        case PROJECTILE_CRYLINK_BOUNCING:
-                               this.move_movetype = MOVETYPE_BOUNCE;
+                               set_movetype(this, MOVETYPE_BOUNCE);
                                settouch(this, func_null);
                                break;
                        case PROJECTILE_FIREBALL:
@@ -402,7 +400,7 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
                                break;
                        case PROJECTILE_FIREMINE:
                                loopsound(this, CH_SHOTS_SINGLE, SND(FIREBALL_FLY), VOL_BASE, ATTEN_NORM);
-                               this.move_movetype = MOVETYPE_BOUNCE;
+                               set_movetype(this, MOVETYPE_BOUNCE);
                                settouch(this, func_null);
                                this.mins = '-4 -4 -4';
                                this.maxs = '4 4 4';
@@ -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:
@@ -462,16 +460,16 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
        if (this.gravity)
        {
                if (this.move_movetype == MOVETYPE_FLY)
-                       this.move_movetype = MOVETYPE_TOSS;
+                       set_movetype(this, MOVETYPE_TOSS);
                if (this.move_movetype == MOVETYPE_BOUNCEMISSILE)
-                       this.move_movetype = MOVETYPE_BOUNCE;
+                       set_movetype(this, MOVETYPE_BOUNCE);
        }
        else
        {
                if (this.move_movetype == MOVETYPE_TOSS)
-                       this.move_movetype = MOVETYPE_FLY;
+                       set_movetype(this, MOVETYPE_FLY);
                if (this.move_movetype == MOVETYPE_BOUNCE)
-                       this.move_movetype = MOVETYPE_BOUNCEMISSILE;
+                       set_movetype(this, MOVETYPE_BOUNCEMISSILE);
        }
 
        if (!(this.count & 0x80))
@@ -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 ff890afec629db9f70bf333cc0fbbc053659afc3..39cec43225ea9ff430422133ea0d7ae91df4a844 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 9aca8e774c34a669cf3439f6656914c703b7a0a3..052e00f07c4df4e0548c5c3fdba01b02bceff18c 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 b6f378d47221e8892c85503685ab7b539c0f61a6..d229b05100a751fb50a8795dbc11997d52a953c9 100644 (file)
@@ -76,7 +76,7 @@ void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
        net_eff.eent_eff_trail = eff.eent_eff_trail;
 
        FOREACH_CLIENT(IS_REAL_CLIENT(it), Net_Write_Effect(net_eff, it, 0));
-       remove(net_eff);
+       delete(net_eff);
 }
 
 void Send_Effect_(string eff_name, vector eff_loc, vector eff_vel, int eff_cnt)
index 308a7b219422cef29c6a43c9080d92ba11fff6a9..46d1a8c614af90667111182acdfeeac66fecc309 100644 (file)
@@ -44,16 +44,16 @@ class(Casing) .float cnt;
 
 void Casing_Delete(entity this)
 {
-    remove(this);
+    delete(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,11 +151,10 @@ 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();
-    casing.move_movetype = MOVETYPE_BOUNCE;
+    if (isNew) IL_PUSH(g_drawables, casing);
+    casing.velocity = casing.velocity + 2 * prandomvec();
+    casing.avelocity = '0 250 0' + 100 * prandomvec();
+    set_movetype(casing, MOVETYPE_BOUNCE);
     settouch(casing, Casing_Touch);
     casing.move_time = time;
     casing.event_damage = Casing_Damage;
index c1144d2616c9b58991d5d6e5d5c1af89b340314e..d17502e81ba99fcf0c11eb49c2182c0a0c4fce1d 100644 (file)
@@ -81,7 +81,7 @@ void DamageEffect_Think(entity this)
        {
                // time is up or the player got gibbed / disconnected
                this.owner.total_damages = max(0, this.owner.total_damages - 1);
-               remove(this);
+               delete(this);
                return;
        }
        if(this.state && !this.owner.csqcmodel_isdead)
@@ -89,7 +89,7 @@ void DamageEffect_Think(entity this)
                // if the player was dead but is now alive, it means he respawned
                // if so, clear his damage effects, or damages from his dead body will be copied back
                this.owner.total_damages = max(0, this.owner.total_damages - 1);
-               remove(this);
+               delete(this);
                return;
        }
        this.state = this.owner.csqcmodel_isdead;
@@ -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 b88a57f4d9aeb8483ee8e9c3255efe7bada6e6c9..d1e3d9880da4244206e9ea38ef037c38a828653b 100644 (file)
@@ -46,7 +46,7 @@ void Violence_GibSplash_At(vector org, vector dir, float type, float amount, ent
        e.oldorigin_x = compressShortVector(e.velocity);
 
        FOREACH_CLIENT(IS_REAL_CLIENT(it), Violence_GibSplash_SendEntity(e, it, 0));
-       remove(e);
+       delete(e);
 }
 
 void Violence_GibSplash(entity source, float type, float amount, entity attacker)
@@ -70,7 +70,7 @@ void Violence_GibSplash(entity source, float type, float amount, entity attacker
 
 void Gib_Delete(entity this)
 {
-       remove(this);
+       delete(this);
 }
 
 string species_prefix(int specnum);
@@ -170,7 +170,7 @@ void TossGib (string mdlname, vector safeorg, vector org, vector vconst, vector
 
        // TODO remove some gibs according to cl_nogibs
        gib = RubbleNew("gib");
-       gib.move_movetype = MOVETYPE_BOUNCE;
+       set_movetype(gib, MOVETYPE_BOUNCE);
        gib.gravity = 1;
        gib.solid = SOLID_CORPSE;
        gib.cnt = specnum;
@@ -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;
 
@@ -311,7 +311,7 @@ NET_HANDLE(net_gibsplash, bool isNew)
                        // no gibs in gentle mode, sorry
                        break;
        }
-       remove(this);
+       delete(this);
 }
 #endif
 
index f577762906b6737427a9f0edd2289123f78729ac..8fbef5b587e9c56a7ed1f7cbc20d445cd32dab4f 100644 (file)
@@ -103,7 +103,7 @@ void ModelEffect_Draw(entity this)
        this.alpha = this.cnt * bound(0, 1 - (time - this.lifetime) / this.fadetime, 1);
        if(this.alpha < ALPHA_MIN_VISIBLE)
        {
-               remove(this);
+               delete(this);
                return;
        }
        this.drawmask = MASK_NORMAL;
@@ -156,8 +156,9 @@ 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
+       if (!isnew) delete(e); // yes, this IS stupid, but I don't need to duplicate all the read* stuff then
        return true;
 }
 #endif
index 7848b7b1f3a31d34d6069c9920ed81359f608952..1665e4ccef38e8c37db1d984dacea596214ff6b2 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 e69998563d281f1f49f344bd361e7b6e146c2c95..2a7b3f80c485ef413e246028834d20ad38d8156b 100644 (file)
        void entcs_detach(entity player)
        {
                if (!player.entcs) return;
-               remove(player.entcs);
+               delete(player.entcs);
                player.entcs = NULL;
        }
 
                int n = this.sv_entnum;
                entity e = entcs_receiver(n);
                entcs_receiver(n, NULL);
-               if (e != this) remove(e);
+               if (e != this) delete(e);
        }
 
        void entcs_think(entity this)
index 07479cc19714a13487c7ed49fc49ae41bc93e089..b65b558fdb1027352b45ab0bca37dc1a104b6b23 100644 (file)
@@ -72,7 +72,7 @@ float OtherTeam(float t)  //works only if there are two teams on the map!
 const float ST_NEXBALL_GOALS = 1;
 const float SP_NEXBALL_GOALS = 4;
 const float SP_NEXBALL_FAULTS = 5;
-void nb_ScoreRules(float teams)
+void nb_ScoreRules(int teams)
 {
        ScoreRules_basics(teams, 0, 0, true);
        ScoreInfo_SetLabel_TeamScore(   ST_NEXBALL_GOALS,  "goals", SFL_SORT_PRIO_PRIMARY);
@@ -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;
        }
@@ -376,7 +376,7 @@ void GoalTouch(entity this, entity toucher)
        EXACTTRIGGER_TOUCH(this, toucher);
 
 
-       if(nb_teams == 2)
+       if(NumTeams(nb_teams) == 2)
                otherteam = OtherTeam(ball.team);
        else
                otherteam = 0;
@@ -395,7 +395,7 @@ void GoalTouch(entity this, entity toucher)
        else if(this.team == GOAL_FAULT)
        {
                LogNB("fault", ball.pusher);
-               if(nb_teams == 2)
+               if(NumTeams(nb_teams) == 2)
                        bprint(Team_ColoredFullName(otherteam), " gets a point due to ", pname, "^7's silliness.\n");
                else
                        bprint(Team_ColoredFullName(ball.team), " loses a point due to ", pname, "^7's silliness.\n");
@@ -421,7 +421,7 @@ void GoalTouch(entity this, entity toucher)
 
        if(ball.team && pscore)
        {
-               if(nb_teams == 2 && pscore < 0)
+               if(NumTeams(nb_teams) == 2 && pscore < 0)
                        TeamScore_AddToTeam(otherteam, ST_NEXBALL_GOALS, -pscore);
                else
                        TeamScore_AddToTeam(ball.team, ST_NEXBALL_GOALS, pscore);
@@ -453,7 +453,7 @@ spawnfunc(nexball_team)
 {
        if(!g_nexball)
        {
-               remove(this);
+               delete(this);
                return;
        }
        this.team = this.cnt + 1;
@@ -466,7 +466,7 @@ void nb_spawnteam(string teamname, float teamcolor)
        e.netname = teamname;
        e.cnt = teamcolor;
        e.team = e.cnt + 1;
-       nb_teams += 1;
+       //nb_teams += 1;
 }
 
 void nb_spawnteams()
@@ -481,6 +481,7 @@ void nb_spawnteams()
                        if(!t_red)
                        {
                                nb_spawnteam("Red", e.team-1)   ;
+                               nb_teams |= BIT(0);
                                t_red = true;
                        }
                        break;
@@ -489,6 +490,7 @@ void nb_spawnteams()
                        {
                                nb_spawnteam("Blue", e.team-1)  ;
                                t_blue = true;
+                               nb_teams |= BIT(1);
                        }
                        break;
                case NUM_TEAM_3:
@@ -496,6 +498,7 @@ void nb_spawnteams()
                        {
                                nb_spawnteam("Yellow", e.team-1);
                                t_yellow = true;
+                               nb_teams |= BIT(2);
                        }
                        break;
                case NUM_TEAM_4:
@@ -503,6 +506,7 @@ void nb_spawnteams()
                        {
                                nb_spawnteam("Pink", e.team-1)  ;
                                t_pink = true;
+                               nb_teams |= BIT(3);
                        }
                        break;
                }
@@ -523,7 +527,7 @@ void nb_delayedinit(entity this)
 
 void SpawnBall(entity this)
 {
-       if(!g_nexball) { remove(this); return; }
+       if(!g_nexball) { delete(this); return; }
 
 //     balls += 4; // using the remaining bits to count balls will leave more than the max edict count, so it's fine
 
@@ -549,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 = "";
@@ -620,7 +624,7 @@ bool nb_Goal_Customize(entity this, entity client)
 
 void SpawnGoal(entity this)
 {
-       if(!g_nexball) { remove(this); return; }
+       if(!g_nexball) { delete(this); return; }
 
        EXACTTRIGGER_INIT;
 
@@ -757,7 +761,7 @@ void W_Nexball_Touch(entity this, entity toucher)
                                GiveBall(attacker, toucher.ballcarried);
                        }
                }
-       remove(this);
+       delete(this);
 }
 
 void W_Nexball_Attack(entity actor, float t)
@@ -818,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
@@ -833,6 +837,7 @@ void W_Nexball_Attack2(entity actor)
 
        missile.effects = EF_BRIGHTFIELD | EF_LOWPRECISION;
        missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
 
        CSQCProjectile(missile, true, PROJECTILE_ELECTRO, true);
 }
index 8389b22dae1ee0945aceb633a91592dadaeb8917..fb8cb71719a2e4acea5a10718a737eb4f54d50bb 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;
+               set_movetype(this.icon_realmodel, 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;
+       set_movetype(this, MOVETYPE_NOCLIP);
        this.solid                      = SOLID_NOT;
-       this.movetype           = MOVETYPE_NOCLIP;
-       this.move_origin        = this.origin;
+       set_movetype(this, MOVETYPE_NOCLIP);
        this.move_time          = time;
        this.drawmask           = MASK_NORMAL;
        this.alpha                      = 1;
index 03e81f4bdea092deee9f965d104cf4f3d4c8f2af..2b9470f7750ab2b9fecac82a5abe51590811e6bb 100644 (file)
@@ -14,7 +14,7 @@ void ons_generator_ray_draw(entity this)
 
        if(this.count > 10)
        {
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -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;
+       set_movetype(e, 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)
@@ -152,10 +152,9 @@ void generator_construct(entity this)
        setmodel(this, MDL_ONS_GEN);
        setsize(this, GENERATOR_MIN, GENERATOR_MAX);
 
-       this.move_movetype      = MOVETYPE_NOCLIP;
+       set_movetype(this, MOVETYPE_NOCLIP);
        this.solid                      = SOLID_BBOX;
-       this.movetype           = MOVETYPE_NOCLIP;
-       this.move_origin        = this.origin;
+       set_movetype(this, MOVETYPE_NOCLIP);
        this.move_time          = time;
        this.drawmask           = MASK_NORMAL;
        this.alpha                      = 1;
index 7d9c93d94c24f2602ed0e83f2e115ef10a2dd133..d3c52e04b21290b08dc80cf2b7eab74165e0f28a 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;
+       });
 }
 
 
@@ -553,7 +551,7 @@ void ons_ControlPoint_Icon_Damage(entity this, entity inflictor, entity attacker
                        setmodel_fixsize(this.owner, MDL_ONS_CP_PAD1);
                //setsize(this, '-32 -32 0', '32 32 8');
 
-               remove(this);
+               delete(this);
        }
 
        this.SendFlags |= CPSF_STATUS;
@@ -821,7 +819,7 @@ void ons_ControlPoint_Think(entity this)
 void ons_ControlPoint_Reset(entity this)
 {
        if(this.goalentity)
-               remove(this.goalentity);
+               delete(this.goalentity);
 
        this.goalentity = NULL;
        this.team = 0;
@@ -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;
 }
 
@@ -1944,7 +1923,7 @@ void ons_MonsterSpawn_Delayed(entity this)
 {
        entity own = this.owner;
 
-       if(!own) { remove(this); return; }
+       if(!own) { delete(this); return; }
 
        if(own.targetname)
        {
@@ -1957,7 +1936,7 @@ void ons_MonsterSpawn_Delayed(entity this)
                }
        }
 
-       remove(this);
+       delete(this);
 }
 
 MUTATOR_HOOKFUNCTION(ons, MonsterSpawn)
@@ -1973,7 +1952,7 @@ void ons_TurretSpawn_Delayed(entity this)
 {
        entity own = this.owner;
 
-       if(!own) { remove(this); return; }
+       if(!own) { delete(this); return; }
 
        if(own.targetname)
        {
@@ -1987,7 +1966,7 @@ void ons_TurretSpawn_Delayed(entity this)
                }
        }
 
-       remove(this);
+       delete(this);
 }
 
 MUTATOR_HOOKFUNCTION(ons, TurretSpawn)
@@ -2199,7 +2178,7 @@ keys:
  */
 spawnfunc(onslaught_link)
 {
-       if(!g_onslaught) { remove(this); return; }
+       if(!g_onslaught) { delete(this); return; }
 
        if (this.target == "" || this.target2 == "")
                objerror(this, "target and target2 must be set\n");
@@ -2224,7 +2203,7 @@ keys:
 
 spawnfunc(onslaught_controlpoint)
 {
-       if(!g_onslaught) { remove(this); return; }
+       if(!g_onslaught) { delete(this); return; }
 
        ons_ControlPoint_Setup(this);
 }
@@ -2240,7 +2219,7 @@ keys:
  */
 spawnfunc(onslaught_generator)
 {
-       if(!g_onslaught) { remove(this); return; }
+       if(!g_onslaught) { delete(this); return; }
        if(!this.team) { objerror(this, "team must be set"); }
 
        ons_GeneratorSetup(this);
@@ -2250,7 +2229,12 @@ spawnfunc(onslaught_generator)
 void ons_ScoreRules()
 {
        CheckAllowedTeams(NULL);
-       ScoreRules_basics(((c4>=0) ? 4 : (c3>=0) ? 3 : 2), SFL_SORT_PRIO_PRIMARY, 0, true);
+       int teams = 0;
+       if(c1 >= 0) teams |= BIT(0);
+       if(c2 >= 0) teams |= BIT(1);
+       if(c3 >= 0) teams |= BIT(2);
+       if(c4 >= 0) teams |= BIT(3);
+       ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, true);
        ScoreInfo_SetLabel_TeamScore  (ST_ONS_CAPS,     "destroyed", SFL_SORT_PRIO_PRIMARY);
        ScoreInfo_SetLabel_PlayerScore(SP_ONS_CAPS,     "caps",      SFL_SORT_PRIO_SECONDARY);
        ScoreInfo_SetLabel_PlayerScore(SP_ONS_TAKES,    "takes",     0);
index 934271059ba55ed6cc464e9c7122cdd970bc65eb..c7f602e653835d6b519843bea740acc2ca0caf10 100644 (file)
@@ -71,7 +71,7 @@ void Inventory_new(entity e)
     inv.drawonlytoclient = e;
     Net_LinkEntity((inv.owner = e).inventory = inv, false, 0, Inventory_Send);
 }
-void Inventory_delete(entity e) { remove(e.inventory.inventory); remove(e.inventory); }
+void Inventory_delete(entity e) { delete(e.inventory.inventory); delete(e.inventory); }
 void Inventory_update(entity e) { e.inventory.SendFlags = 0xFFFFFF; }
 #endif
 
index 1aa748faab08c38ebc7955b3a12c88f4475c3ab2..daca237b94b2ae54ad2fb8b8fb33ee707797aefe 100644 (file)
@@ -75,7 +75,7 @@ MINIGAME_SIMPLELINKED_ENTITIES
 void minigame_autoclean_entity(entity e)
 {
        LOG_DEBUG("CL Auto-cleaned: ",ftos(etof(e)), " (",e.classname,")\n");
-       remove(e);
+       delete(e);
 }
 
 void HUD_MinigameMenu_CurrentButton();
index c26109bfd39e488179eddba303a3d5f5b974aac2..90f1b2252ec2c816bea0c566a63725be73424891 100644 (file)
@@ -143,7 +143,7 @@ void HUD_MinigameMenu_EraseEntry ( entity e )
        if ( HUD_MinigameMenu_activeitem == e )
                HUD_MinigameMenu_activeitem = NULL;
 
-       remove(e);
+       delete(e);
 }
 
 // Minigame menu options: create entry
@@ -193,7 +193,7 @@ bool HUD_MinigameMenu_Click_ExpandCollapse(entity this)
                        if ( e.flags & 2 )
                                HUD_MinigameMenu_Click(e);
                        this.list_next = e.list_next;
-                       remove(e);
+                       delete(e);
                }
                if ( this.list_next )
                        this.list_next.list_prev = this;
@@ -351,7 +351,7 @@ void HUD_MinigameMenu_Close(entity this, entity actor, entity trigger)
                for ( e = HUD_MinigameMenu_entries; e != NULL; e = p )
                {
                        p = e.list_next;
-                       remove(e);
+                       delete(e);
                }
                HUD_MinigameMenu_entries = NULL;
                HUD_MinigameMenu_last_entry = NULL;
index db25c2959e02470d85a6b5d3b23b022f24488d6a..041e56339c3039be7f7207c642510a7638202951 100644 (file)
@@ -259,7 +259,7 @@ void bd_editor_place(entity minigame, entity player, string pos, int thetile, st
                                        return; // how?!
 
                                if(piece.netname) { strunzone(piece.netname); }
-                               remove(piece);
+                               delete(piece);
                                minigame_server_sendflags(minigame,MINIG_SF_UPDATE);
                                return;
                        }
@@ -313,12 +313,12 @@ void bd_unfill_recurse(entity minigame, entity player, int thetype, int letter,
        if(targ && thetype == targ.bd_tiletype)
        {
                if(targ.netname) { strunzone(targ.netname); }
-               remove(targ);
+               delete(targ);
        }
        else if(piece && thetype == piece.bd_tiletype)
        {
                if(piece.netname) { strunzone(piece.netname); }
-               remove(piece);
+               delete(piece);
        }
        else return;
 
@@ -393,7 +393,7 @@ void bd_setup_pieces(entity minigame)
                if(e.classname == "minigame_board_piece")
                {
                        if(e.netname) { strunzone(e.netname); }
-                       remove(e);
+                       delete(e);
                }
 
        bd_load_level(minigame);
@@ -631,7 +631,7 @@ int bd_server_event(entity minigame, string event, ...)
                        if(e.classname == "minigame_board_piece")
                        {
                                if(e.netname) { strunzone(e.netname); }
-                               remove(e);
+                               delete(e);
                        }
 
                        if(minigame.bd_nextlevel) { strunzone(minigame.bd_nextlevel); }
index 3c2beacb6fc20c3f1e0c87ecfbb93cab7ff41e39..497ef2afc394d24bbe2a46ee0292a94ff0941e11 100644 (file)
@@ -201,7 +201,7 @@ int c4_server_event(entity minigame, string event, ...)
                        if(e.classname == "minigame_board_piece")
                        {
                                if(e.netname) { strunzone(e.netname); }
-                               remove(e);
+                               delete(e);
                        }
                        return false;
                }
index 8f8e3da2eab0719526230920994af4c81407a1e3..d36c5cd3f617d6cdffe475caaf54b466f27e8a83 100644 (file)
@@ -123,7 +123,7 @@ void nmm_kill_tiles(entity minig)
                        strunzone(e.netname);
                        strunzone(e.nmm_tile_hmill);
                        strunzone(e.nmm_tile_vmill);
-                       remove(e);
+                       delete(e);
                }
 }
 
index 602cad22d3d103b277ec0d3d00369e6943d15678..d535b8c85dca031a59c460d118aee7838f001c66 100644 (file)
@@ -442,8 +442,8 @@ int pong_server_event(entity minigame, string event, ...)
                                                                paddle.realowner.classname == "pong_ai" )
                                                        {
                                                                minigame.pong_paddles[i] = NULL;
-                                                               remove(paddle.realowner);
-                                                               remove(paddle);
+                                                               delete(paddle.realowner);
+                                                               delete(paddle);
                                                                return true;
                                                        }
                                                }
index 7d4048d61b58bcd2de5c21520286fb6ec3105a31..f9e0f79b9a92c29459333113448238a826764404 100644 (file)
@@ -121,7 +121,7 @@ void pp_move(entity minigame, entity player, string pos )
                        if(existing)
                        {
                                if(existing.netname) { strunzone(existing.netname); }
-                               remove(existing);
+                               delete(existing);
                        }
 
                        entity piece = msle_spawn(minigame,"minigame_board_piece");
@@ -186,7 +186,7 @@ void pp_next_match(entity minigame, entity player)
                entity e = NULL;
                while ( ( e = findentity(e,owner,minigame) ) )
                        if ( e.classname == "minigame_board_piece" )
-                               remove(e);
+                               delete(e);
                minigame.pp_team1_score = 0;
                minigame.pp_team2_score = 0;
 
@@ -215,7 +215,7 @@ int pp_server_event(entity minigame, string event, ...)
                        if(e.classname == "minigame_board_piece")
                        {
                                if(e.netname) { strunzone(e.netname); }
-                               remove(e);
+                               delete(e);
                        }
                        return false;
                }
index 2a612c599a8317acdbd846d5505c1dded4a9ed81..c9ef8bd67a4ae9fad1bed23776646f2485b1bad1 100644 (file)
@@ -139,7 +139,7 @@ bool ps_move_piece(entity minigame, entity piece, string pos, int leti, int numb
                return false;
 
        if(middle.netname) { strunzone(middle.netname); }
-       remove(middle);
+       delete(middle);
 
        if(piece.netname) { strunzone(piece.netname); }
        piece.netname = strzone(pos);
@@ -232,7 +232,7 @@ int ps_server_event(entity minigame, string event, ...)
                        if(e.classname == "minigame_board_piece")
                        {
                                if(e.netname) { strunzone(e.netname); }
-                               remove(e);
+                               delete(e);
                        }
                        return false;
                }
index 617ed957ca635f84081282dbeee62f664fb67ea9..4248d589a13391c0f6218d518a155f0cf5727556 100644 (file)
@@ -287,7 +287,7 @@ void snake_eat_team(entity minigame, int pteam)
                if ( e.classname == "minigame_board_piece" && e.cnt && e.team == pteam )
                {
                        if(e.netname) { strunzone(e.netname); }
-                       remove(e);
+                       delete(e);
                }
 
        if(minigame.snake_lives[pteam] <= 0)
@@ -354,7 +354,7 @@ void snake_move_head(entity minigame, entity head)
        if(ate_mouse)
        {
                if(hit.netname) { strunzone(hit.netname); }
-               remove(hit);
+               delete(hit);
 
                snake_new_mouse(minigame);
        }
@@ -425,7 +425,7 @@ int snake_server_event(entity minigame, string event, ...)
                        if(e.classname == "minigame_board_piece")
                        {
                                if(e.netname) { strunzone(e.netname); }
-                               remove(e);
+                               delete(e);
                        }
                        return false;
                }
index b5248467f5908d8aca373cca211c87cc6f204726..630462aa9fda2bc060f0605bb40e6e00e68a8560 100644 (file)
@@ -123,7 +123,7 @@ void ttt_next_match(entity minigame, entity player)
                entity e = NULL;
                while ( ( e = findentity(e,owner,minigame) ) )
                        if ( e.classname == "minigame_board_piece" )
-                               remove(e);
+                               delete(e);
        }
 }
 
@@ -147,7 +147,7 @@ int ttt_server_event(entity minigame, string event, ...)
                        if(e.classname == "minigame_board_piece")
                        {
                                if(e.netname) { strunzone(e.netname); }
-                               remove(e);
+                               delete(e);
                        }
                        return false;
                }
index 992eab054b0b6aa1fe3a497080b50e10ee0a8e64..299c831dc8faa470e1d12b7bea565a0ef1034e7c 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;
 }
 
@@ -27,7 +27,7 @@ void minigame_rmplayer(entity minigame_session, entity player)
                GameLogEcho(strcat(":minigame:part:",minigame_session.netname,":",
                        ftos(etof(player)),":",player.netname));
                minigame_session.minigame_players = p.list_next;
-               remove ( p );
+               delete ( p );
                player_clear_minigame(player);
        }
        else
@@ -40,7 +40,7 @@ void minigame_rmplayer(entity minigame_session, entity player)
                                GameLogEcho(strcat(":minigame:part:",minigame_session.netname,":",
                                        ftos(etof(player)),":",player.netname));
                                p.list_next = e.list_next;
-                               remove(e);
+                               delete(e);
                                player_clear_minigame(player);
                                return;
                        }
@@ -153,7 +153,7 @@ int minigame_addplayer(entity minigame_session, entity player)
 
                minigame_resend(minigame_session);
        }
-       else { remove(player_pointer); }
+       else { delete(player_pointer); }
        GameLogEcho(strcat(":minigame:join",(mgteam?"":"fail"),":",minigame_session.netname,":",
                ftos(etof(player)),":",player.netname));
 
@@ -236,7 +236,7 @@ void end_minigame(entity minigame_session)
                if ( e.minigame_autoclean )
                {
                        LOG_TRACE("SV Auto-cleaned: ",ftos(etof(e)), " (",e.classname,")\n");
-                       remove(e);
+                       delete(e);
                }
 
        entity p;
@@ -244,11 +244,11 @@ void end_minigame(entity minigame_session)
        {
                p = e.list_next;
                player_clear_minigame(e.minigame_players);
-               remove(e);
+               delete(e);
        }
 
        strunzone(minigame_session.netname);
-       remove(minigame_session);
+       delete(minigame_session);
 }
 
 void end_minigames()
index 46a9fb18e41b7d6a45385067249e8adfeab1bdfa..02a01eff9efee4ea36dca28b26e29a32f9b064a1 100644 (file)
@@ -157,7 +157,7 @@ void M_Mage_Attack_Spike_Explode(entity this, entity directhitentity)
        Send_Effect(EFFECT_EXPLOSION_SMALL, this.origin, '0 0 0', 1);
        RadiusDamage (this, this.realowner, (autocvar_g_monster_mage_attack_spike_damage), (autocvar_g_monster_mage_attack_spike_damage) * 0.5, (autocvar_g_monster_mage_attack_spike_radius), NULL, NULL, 0, DEATH_MONSTER_MAGE.m_id, directhitentity);
 
-       remove (this);
+       delete (this);
 }
 
 void M_Mage_Attack_Spike_Touch(entity this, entity toucher)
@@ -233,8 +233,9 @@ 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;
+       IL_PUSH(g_projectiles, missile);
        setorigin(missile, this.origin + v_forward * 14 + '0 0 30' + v_right * -14);
        setsize(missile, '0 0 0', '0 0 0');
        missile.velocity = dir * 400;
index dd9a61d4183a5765b34a69628739e619a4bf5b74..3018741b09be4b64e1bba83abebcc1065e896311 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));
@@ -173,6 +173,7 @@ void M_Shambler_Attack_Lightning(entity this)
 
        gren.angles = vectoangles (gren.velocity);
        gren.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, gren);
 
        CSQCProjectile(gren, true, PROJECTILE_SHAMBLER_LIGHTNING, true);
 }
index b6d41dbb424b76b7c85ae3ef4beb2af9fe5d0aeb..0270119cff01c7816b5c630b058099dc81509b01 100644 (file)
@@ -148,7 +148,7 @@ void M_Spider_Attack_Web_Explode(entity this)
                        it.spider_slowness = time + (autocvar_g_monster_spider_attack_web_damagetime);
                });
 
-               remove(this);
+               delete(this);
        }
 }
 
@@ -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');
@@ -194,6 +194,7 @@ void M_Spider_Attack_Web(entity this)
        proj.health = 500;
        proj.event_damage = func_null;
        proj.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, proj);
        proj.damagedbycontents = true;
 
        proj.bouncefactor = 0.3;
index 345d6459cda6a374638121d8d6a66bf7ffd152bf..5d2103b6aed03243a5504008cd1f4efa556a8d3a 100644 (file)
@@ -64,11 +64,12 @@ 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);
                missile.flags = FL_PROJECTILE;
+        IL_PUSH(g_projectiles, missile);
                missile.velocity = w_shotdir * (autocvar_g_monster_wyvern_attack_fireball_speed);
                missile.avelocity = '300 300 300';
                missile.nextthink = time + 5;
@@ -113,7 +114,7 @@ void M_Wyvern_Attack_Fireball_Explode(entity this)
                        Fire_AddDamage(it, own, 5 * MONSTER_SKILLMOD(own), autocvar_g_monster_wyvern_attack_fireball_damagetime, this.projectiledeathtype);
        });
 
-       remove(this);
+       delete(this);
 }
 
 void M_Wyvern_Attack_Fireball_Touch(entity this, entity toucher)
index 005f128b9b5a469451c98b5c7c60029b3f8632eb..8508d57089f85f453cddbbb8bb52b56ab80c92e7 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';
@@ -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);
                }
        }
 
@@ -903,10 +903,10 @@ void Monster_Remove(entity this)
        if(!MUTATOR_CALLHOOK(MonsterRemove, this))
                Send_Effect(EFFECT_ITEM_PICKUP, this.origin, '0 0 0', 1);
 
-       if(this.(weaponentity)) { remove(this.(weaponentity)); }
-       if(this.iceblock) { remove(this.iceblock); }
+       if(this.(weaponentity)) { delete(this.(weaponentity)); }
+       if(this.iceblock) { delete(this.iceblock); }
        WaypointSprite_Kill(this.sprite);
-       remove(this);
+       delete(this);
 }
 
 void Monster_Dead_Think(entity this)
@@ -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 921cd03cd39dadbcf043cdfbcb8a203644f1ea02..e27fa3d7f4f82537570caa3f1ea7082ffe3748d4 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';
@@ -411,7 +411,7 @@ bool buff_Customize(entity this, entity client)
 
 void buff_Init(entity this)
 {
-       if(!cvar("g_buffs")) { remove(this); return; }
+       if(!cvar("g_buffs")) { delete(this); return; }
 
        if(!teamplay && this.team) { this.team = 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);
@@ -480,7 +480,7 @@ void buff_Vengeance_DelayedDamage(entity this)
        if(this.enemy)
                Damage(this.enemy, this.owner, this.owner, this.dmg, DEATH_BUFF.m_id, this.enemy.origin, '0 0 0');
 
-       remove(this);
+       delete(this);
        return;
 }
 
@@ -690,7 +690,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerDies)
 
                if(frag_target.buff_model)
                {
-                       remove(frag_target.buff_model);
+                       delete(frag_target.buff_model);
                        frag_target.buff_model = NULL;
                }
        }
@@ -788,7 +788,7 @@ bool buffs_RemovePlayer(entity player)
 {
        if(player.buff_model)
        {
-               remove(player.buff_model);
+               delete(player.buff_model);
                player.buff_model = NULL;
        }
 
@@ -986,7 +986,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
                }
                else
                {
-                       remove(player.buff_model);
+                       delete(player.buff_model);
                        player.buff_model = NULL;
 
                        player.effects &= ~(EF_NOSHADOW);
index 96490700e567ee5eb356678641f334e204639021..fbbe6035043af2fbfe6bc1a087d38f8e56f85961 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 3cca0d9d113b6a44aa385658f87d760f6123c6e2..c705ea0d1c03ff67eb4e75ac5bf77e4a8987bdf5 100644 (file)
@@ -49,7 +49,7 @@ CLASS(DamageText, Object)
         this.time_prev = time;
         setorigin(this, this.origin + dt * this.velocity);
         this.alpha -= dt * this.fade_rate;
-        if (this.alpha < 0) remove(this);
+        if (this.alpha < 0) delete(this);
         vector pos = project_3d_to_2d(this.origin) + autocvar_cl_damagetext_offset;
         if (pos.z >= 0 && this.m_size > 0) {
             pos.z = 0;
@@ -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 64312727e4e0cc682743643eefbb8e9af4d06f4b..7ddfcea2ba770f027f55672766155697be635620 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
index 34f3825680445139c5de7e07396304589e55fed2..25edbb225c89b7f6fa045b9c7e3fb6e1630abffa 100644 (file)
@@ -24,7 +24,7 @@ REGISTER_MUTATOR(mutator_instagib, cvar("g_instagib") && !g_nexball);
 
 spawnfunc(item_minst_cells)
 {
-       if (!g_instagib) { remove(this); return; }
+       if (!g_instagib) { delete(this); return; }
        if (!this.ammo_cells) this.ammo_cells = autocvar_g_instagib_ammo_drop;
        StartItem(this, ITEM_VaporizerCells);
 }
index 1c4de9a4e2f5104d61cd6948c84f9452bb8ee91c..c6afa33161c954d70f75fda41e2841afa4f20273 100644 (file)
@@ -130,19 +130,22 @@ void Item_ItemsTime_SetTime(entity e, float t)
 
 void Item_ItemsTime_SetTimesForAllPlayers()
 {
-    FOREACH_CLIENT(IS_REAL_CLIENT(it) && (warmup_stage || !IS_PLAYER(it)), LAMBDA(Item_ItemsTime_SetTimesForPlayer(it)));
+    FOREACH_CLIENT(IS_REAL_CLIENT(it) && (warmup_stage || !IS_PLAYER(it) || autocvar_sv_itemstime == 2), LAMBDA(Item_ItemsTime_SetTimesForPlayer(it)));
 }
 
 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();
 }
 
@@ -174,14 +180,14 @@ MUTATOR_HOOKFUNCTION(itemstime, ClientConnect, CBC_ORDER_LAST)
        {
                // client became player on connection skipping putObserverInServer step
                if (IS_REAL_CLIENT(player))
-               if (warmup_stage)
+               if (warmup_stage || autocvar_sv_itemstime == 2)
                        Item_ItemsTime_SetTimesForPlayer(player);
        }
 }
 
 MUTATOR_HOOKFUNCTION(itemstime, PlayerSpawn)
 {
-    if (warmup_stage) return;
+    if (warmup_stage || autocvar_sv_itemstime == 2) return;
     entity player = M_ARGV(0, entity);
 
     Item_ItemsTime_ResetTimesForPlayer(player);
@@ -264,7 +270,7 @@ void HUD_ItemsTime()
     {
         if (!(
             (autocvar_hud_panel_itemstime == 1 && spectatee_status != 0)
-        ||     (autocvar_hud_panel_itemstime == 2 && (spectatee_status != 0 || warmup_stage))
+        ||     (autocvar_hud_panel_itemstime == 2 && (spectatee_status != 0 || warmup_stage || STAT(ITEMSTIME) == 2))
             )) { return; }
     }
     else
index fd9a4226a788eacfb05401106e9fab2f25b4f1b6..14e2b01ac089706b6cd01f2ed8f4647f0e56692e 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;
@@ -163,7 +163,7 @@ void nade_timer_think(entity this)
        this.skin = 8 - (this.owner.wait - time) / (autocvar_g_nades_nade_lifetime / 10);
        this.nextthink = time;
        if(!this.owner || wasfreed(this.owner))
-               remove(this);
+               delete(this);
 }
 
 void nade_burn_spawn(entity _nade)
@@ -232,13 +232,13 @@ void napalm_ball_think(entity this)
        if(round_handler_IsActive())
        if(!round_handler_IsRoundStarted())
        {
-               remove(this);
+               delete(this);
                return;
        }
 
        if(time > this.pushltime)
        {
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -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);
@@ -294,6 +294,7 @@ void nade_napalm_ball(entity this)
 
        proj.angles = vectoangles(proj.velocity);
        proj.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, proj);
        proj.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_ARC;
 
        //CSQCProjectile(proj, true, PROJECTILE_NAPALM_FIRE, true);
@@ -306,13 +307,13 @@ void napalm_fountain_think(entity this)
        if(round_handler_IsActive())
        if(!round_handler_IsRoundStarted())
        {
-               remove(this);
+               delete(this);
                return;
        }
 
        if(time >= this.ltime)
        {
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -356,7 +357,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;
@@ -379,7 +380,7 @@ void nade_ice_think(entity this)
        if(round_handler_IsActive())
        if(!round_handler_IsRoundStarted())
        {
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -396,7 +397,7 @@ void nade_ice_think(entity this)
                        Damage_DamageInfo(this.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
                                autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, this.projectiledeathtype, 0, this);
                }
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -448,7 +449,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 +495,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;
@@ -502,7 +503,7 @@ void nade_spawn_boom(entity this)
 
        if(this.realowner.nade_spawnloc)
        {
-               remove(this.realowner.nade_spawnloc);
+               delete(this.realowner.nade_spawnloc);
                this.realowner.nade_spawnloc = NULL;
        }
 
@@ -513,7 +514,7 @@ void nades_orb_think(entity this)
 {
        if(time >= this.ltime)
        {
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -572,13 +573,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) )
@@ -739,7 +738,7 @@ void nade_boom(entity this)
                        RemoveGrapplingHook(it.realowner);
        });
 
-       remove(this);
+       delete(this);
 }
 
 void spawn_held_nade(entity player, entity nowner, float ntime, int ntype, string pntype);
@@ -773,7 +772,7 @@ void nade_touch(entity this, entity toucher)
        {
                nade_pickup(toucher, this);
                sound(this, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, 0.5 *(ATTEN_LARGE + ATTEN_MAX));
-               remove(this);
+               delete(this);
                return;
        }
        /*float is_weapclip = 0;
@@ -788,7 +787,7 @@ void nade_touch(entity this, entity toucher)
                        if(it.classname == "grapplinghook")
                                RemoveGrapplingHook(it.realowner);
                });
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -886,7 +885,7 @@ void toss_nade(entity e, bool set_owner, vector _velocity, float _time)
        entity _nade = e.nade;
        e.nade = NULL;
 
-       remove(e.fake_nade);
+       delete(e.fake_nade);
        e.fake_nade = NULL;
 
        makevectors(e.v_angle);
@@ -909,7 +908,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)
@@ -943,6 +942,7 @@ void toss_nade(entity e, bool set_owner, vector _velocity, float _time)
        _nade.damagedbycontents = true;
        _nade.angles = vectoangles(_nade.velocity);
        _nade.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, _nade);
        _nade.projectiledeathtype = DEATH_NADE.m_id;
        _nade.toss_time = time;
        _nade.solid = SOLID_CORPSE; //((_nade.nade_type == NADE_TYPE_TRANSLOCATE) ? SOLID_CORPSE : SOLID_BBOX);
@@ -1067,10 +1067,10 @@ void nade_prime(entity this)
                return; // only allow bonus nades
 
        if(this.nade)
-               remove(this.nade);
+               delete(this.nade);
 
        if(this.fake_nade)
-               remove(this.fake_nade);
+               delete(this.fake_nade);
 
        int ntype;
        string pntype = this.pokenade_type;
@@ -1151,9 +1151,9 @@ void nades_CheckThrow(entity this)
 void nades_Clear(entity player)
 {
        if(player.nade)
-               remove(player.nade);
+               delete(player.nade);
        if(player.fake_nade)
-               remove(player.fake_nade);
+               delete(player.fake_nade);
 
        player.nade = player.fake_nade = NULL;
        player.nade_timer = 0;
@@ -1351,7 +1351,7 @@ MUTATOR_HOOKFUNCTION(nades, PlayerSpawn)
 
                if(player.nade_spawnloc.cnt <= 0)
                {
-                       remove(player.nade_spawnloc);
+                       delete(player.nade_spawnloc);
                        player.nade_spawnloc = NULL;
                }
        }
index af320d9c15555c866f30505e72dee4d0c41c237a..e2659c7af85307fb2e30529e1318b83e35a12746 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;
+       set_movetype(e, 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 a52fc46704e9edaeb5bcd3f752e4f087d2db9663..27d1795062cefb8c73275a4eabbb2cceef74643c 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 b8fd7430988464796cd9e9f7aa8af43dfd11b2c9..2000ffd5dd758ccdeb05beb2ce6ee099662e57bf 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 2fb75b3f8d9696b8ce644748f5f837d0e19a89f5..2aeab7be48d56ee905066587790f78a6198fea13 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');
@@ -157,7 +157,7 @@ MUTATOR_HOOKFUNCTION(ok, MonsterDropItem)
        entity olditem = M_ARGV(1, entity);
        entity frag_attacker = M_ARGV(2, entity);
 
-       remove(olditem);
+       delete(olditem);
 
        M_ARGV(1, entity) = NULL;
 
index b14b6bce49131db750ec735987ce58290b9af0d2..d9e68f20f2a9b79ea5b8a21f5f7258e455291479 100644 (file)
@@ -57,7 +57,7 @@ void W_RocketPropelledChainsaw_Explode(entity this, entity directhitentity)
 
        RadiusDamage (this, this.realowner, WEP_CVAR(rpc, damage), WEP_CVAR(rpc, edgedamage), WEP_CVAR(rpc, radius), NULL, NULL, WEP_CVAR(rpc, force), this.projectiledeathtype, directhitentity);
 
-       remove (this);
+       delete (this);
 }
 
 void W_RocketPropelledChainsaw_Explode_think(entity this)
@@ -92,7 +92,7 @@ void W_RocketPropelledChainsaw_Think(entity this)
 {
        if(this.cnt <= time)
        {
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -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
@@ -143,6 +143,7 @@ void W_RocketPropelledChainsaw_Attack (Weapon thiswep, entity actor)
        missile.cnt = time + WEP_CVAR(rpc, lifetime);
        missile.nextthink = time;
        missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
 
        CSQCProjectile(missile, true, PROJECTILE_RPC, false);
 
index 6e4bfa566192ac65e5a83dba324d201bb4151fc1..56705cbd290c5a80b4cdba7a0f48dff31cbfe65e 100644 (file)
@@ -53,19 +53,19 @@ 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);
                        }
                }
        }
 
        if(!this.owner.modelindex)
-               remove(this); // the real item is gone, remove this
+               delete(this); // the real item is gone, remove this
 }
 
 void physical_item_touch(entity this, entity toucher)
@@ -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 973ff3151c739b2b5aec2cdc0c56ca83eedc8c1e..577e29c6b07c21b497a1b93391cdade5525e280e 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;
@@ -217,7 +217,7 @@ void sandbox_ObjectRemove(entity e)
        if(e.netname)   {       strunzone(e.netname);   e.netname = string_null;        }
        if(e.message)   {       strunzone(e.message);   e.message = string_null;        }
        if(e.message2)  {       strunzone(e.message2);  e.message2 = string_null;       }
-       remove(e);
+       delete(e);
        e = NULL;
 
        object_count -= 1;
@@ -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 786796866cdc0e0335b4f091223418393682d6d8..cf6a7bf5e2dbe59f3a44c8888691011d9e96a04d 100644 (file)
@@ -383,7 +383,7 @@ void superspec_hello(entity this)
        if(this.enemy.crypto_idfp == "")
                Send_Notification(NOTIF_ONE_ONLY, this.enemy, MSG_INFO, INFO_SUPERSPEC_MISSING_UID);
 
-       remove(this);
+       delete(this);
 }
 
 MUTATOR_HOOKFUNCTION(superspec, ClientConnect)
index 67e14403c5cfea8d47eda8c705cbf975d6c83e56..c585e7e9061872460920bc0ea3f6fc660c8ff374 100644 (file)
@@ -19,7 +19,7 @@ void PlayerTouchExplode(entity p1, entity p2)
        entity e = spawn();
        setorigin(e, org);
        RadiusDamage(e, NULL, autocvar_g_touchexplode_damage, autocvar_g_touchexplode_edgedamage, autocvar_g_touchexplode_radius, NULL, NULL, autocvar_g_touchexplode_force, DEATH_TOUCHEXPLODE.m_id, NULL);
-       remove(e);
+       delete(e);
 }
 
 MUTATOR_HOOKFUNCTION(touchexplode, PlayerPreThink)
index 56c4c5b5daa313b9914ea88918a1847e4b88fb14..91869de77062531e76be4f9db6dc783948be642a 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;
@@ -482,7 +486,7 @@ void Draw_WaypointSprite(entity this)
         case SPRITERULE_SPECTATOR:
             if (!(
                 (autocvar_g_waypointsprite_itemstime == 1 && t == NUM_SPECTATOR + 1)
-            || (autocvar_g_waypointsprite_itemstime == 2 && (t == NUM_SPECTATOR + 1 || warmup_stage))
+            || (autocvar_g_waypointsprite_itemstime == 2 && (t == NUM_SPECTATOR + 1 || warmup_stage || STAT(ITEMSTIME) == 2))
                 ))
                 return;
             spriteimage = this.netname;
@@ -884,7 +888,7 @@ void WaypointSprite_Kill(entity wp)
 {
     if (!wp) return;
     if (wp.owner) wp.owner.(wp.owned_by_field) = NULL;
-    remove(wp);
+    delete(wp);
 }
 
 void WaypointSprite_Disown(entity wp, float fadetime)
@@ -935,7 +939,7 @@ bool WaypointSprite_visible_for_player(entity this, entity player, entity view)
     {
         if (!autocvar_sv_itemstime)
             return false;
-        if (!warmup_stage && IS_PLAYER(view))
+        if (!warmup_stage && IS_PLAYER(view) && autocvar_sv_itemstime != 2)
             return false;
     }
     else if (this.team && this.rule == SPRITERULE_DEFAULT)
@@ -1017,7 +1021,7 @@ entity WaypointSprite_Spawn(
     if (own)
     {
         if (own.(ownfield))
-            remove(own.(ownfield));
+            delete(own.(ownfield));
         own.(ownfield) = wp;
         wp.owned_by_field = ownfield;
     }
index fa9f4fbdf6571f0cdfbfda2187eddeeaafe0752d..26e4058d24975ba686619ca785271826065e6a0d 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 4ffa885beb042d95e64307cc17fe4157affb3e5f..b9f7b36a91302663bb27857caae3fb061d9c0452 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"), "")
     MSG_CENTER_NOTIF(CTF_PASS_OTHER_NEUTRAL,            1,      2, 0, "s1 s2",          CPID_CTF_PASS,          "0 0",  _("^BG%s^BG passed the flag to %s"), "")
     MULTITEAM_CENTER(CTF_PASS_RECEIVED, 4,              1,      1, 0, "s1",             CPID_CTF_PASS,          "0 0",  _("^BGYou received the ^TC^TT^BG flag from %s"), "", FLAG)
     MSG_CENTER_NOTIF(CTF_PASS_RECEIVED_NEUTRAL,         1,      1, 0, "s1",             CPID_CTF_PASS,          "0 0",  _("^BGYou received the flag from %s"), "")
-    MSG_CENTER_NOTIF(CTF_PASS_REQUESTED,                1,      1, 0, "s1 pass_key",    CPID_CTF_PASS,          "0 0",  _("^BG%s^BG requests you to pass the flag%s"), "")
+    MSG_CENTER_NOTIF(CTF_PASS_REQUESTED,                1,      1, 0, "pass_key s1",    CPID_CTF_PASS,          "0 0",  _("^BGPress ^F2%s^BG to receive the flag from %s^BG"), "")
     MSG_CENTER_NOTIF(CTF_PASS_REQUESTING,               1,      1, 0, "s1",             CPID_CTF_PASS,          "0 0",  _("^BGRequesting %s^BG to pass you the flag"), "")
     MULTITEAM_CENTER(CTF_PASS_SENT, 4,                  1,      1, 0, "s1",             CPID_CTF_PASS,          "0 0",  _("^BGYou passed the ^TC^TT^BG flag to %s"), "", FLAG)
     MSG_CENTER_NOTIF(CTF_PASS_SENT_NEUTRAL,             1,      1, 0, "s1",             CPID_CTF_PASS,          "0 0",  _("^BGYou passed the flag to %s"), "")
     MSG_CENTER_NOTIF(ONS_GENERATOR_SHIELDED,            1,      0, 0, "",               CPID_ONS_CAPSHIELD,     "0 0",  _("^BGThe enemy generator cannot be destroyed yet\n^F2Capture some control points to unshield it"), "")
     MULTITEAM_CENTER(ONS_NOTSHIELDED, 4,                1,      0, 0, "",               CPID_ONSLAUGHT,         "0 0",  _("^BGThe ^TCenemy^BG generator is no longer shielded!"), "", NAME)
     MSG_CENTER_NOTIF(ONS_NOTSHIELDED_TEAM,              1,      0, 0, "",               CPID_ONSLAUGHT,         "0 0",  _("^K1Your generator is NOT shielded!\n^BGRe-capture control points to shield it!"), "")
-    MSG_CENTER_NOTIF(ONS_TELEPORT,                      1,      0, 0, "pass_key",       CPID_ONSLAUGHT,         "0 0",  _("^BGPress ^F2DROPFLAG%s^BG to teleport"), "")
+    MSG_CENTER_NOTIF(ONS_TELEPORT,                      1,      0, 0, "pass_key",       CPID_ONSLAUGHT,         "0 0",  _("^BGPress ^F2%s^BG to teleport"), "")
     MSG_CENTER_NOTIF(ONS_TELEPORT_ANTISPAM,             1,      0, 1, "f1secs",         CPID_ONSLAUGHT,         "0 0",  _("^BGTeleporting disabled for %s"), "")
 
     MSG_CENTER_NOTIF(OVERTIME_FRAG,                     1,      0, 0, "",               CPID_OVERTIME,          "0 0",  _("^F2Now playing ^F4OVERTIME^F2!\nKeep fragging until we have a winner!"), _("^F2Now playing ^F4OVERTIME^F2!\nKeep scoring until we have a winner!"))
 
     MSG_CENTER_NOTIF(JOIN_PREVENT_MINIGAME,             1,      0, 0, "",               CPID_Null,              "0 0",  _("^K1Cannot join given minigame session!"), "" )
 
-    MSG_CENTER_NOTIF(VEHICLE_ENTER,                     1,      0, 0, "pass_key",       CPID_VEHICLES,          "0 0",  _("^BGPress ^F2DROPFLAG%s^BG to enter/exit the vehicle"), "")
-    MSG_CENTER_NOTIF(VEHICLE_ENTER_GUNNER,              1,      0, 0, "pass_key",       CPID_VEHICLES,          "0 0",  _("^BGPress ^F2DROPFLAG%s^BG to enter the vehicle gunner"), "")
-    MSG_CENTER_NOTIF(VEHICLE_ENTER_STEAL,               1,      0, 0, "pass_key",       CPID_VEHICLES,          "0 0",  _("^BGPress ^F2DROPFLAG%s^BG to steal this vehicle"), "")
+    MSG_CENTER_NOTIF(VEHICLE_ENTER,                     1,      0, 0, "pass_key",       CPID_VEHICLES,          "0 0",  _("^BGPress ^F2%s^BG to enter/exit the vehicle"), "")
+    MSG_CENTER_NOTIF(VEHICLE_ENTER_GUNNER,              1,      0, 0, "pass_key",       CPID_VEHICLES,          "0 0",  _("^BGPress ^F2%s^BG to enter the vehicle gunner"), "")
+    MSG_CENTER_NOTIF(VEHICLE_ENTER_STEAL,               1,      0, 0, "pass_key",       CPID_VEHICLES,          "0 0",  _("^BGPress ^F2%s^BG to steal this vehicle"), "")
     MSG_CENTER_NOTIF(VEHICLE_STEAL,                     1,      0, 0, "",               CPID_VEHICLES_OTHER,    "0 0",  _("^F2The enemy is stealing one of your vehicles!\n^F4Stop them!"), "")
     MSG_CENTER_NOTIF(VEHICLE_STEAL_SELF,                1,      0, 0, "",               CPID_VEHICLES_OTHER,    "4 0",  _("^F2You have stolen the enemy's vehicle, you are now visible on their radar!"), "")
 
index 853280d6e023410758388258c2543e15beff954d..d1aa1dbf96deaabea08599cdad263c8ae8c3c8a9 100644 (file)
@@ -153,7 +153,7 @@ void Destroy_Notification_Entity(entity notif)
        if (notif.nent_icon != "") strunzone(notif.nent_icon);
        if (notif.nent_durcnt != "") strunzone(notif.nent_durcnt);
        if (notif.nent_string != "") strunzone(notif.nent_string);
-       remove(notif);
+       delete(notif);
 }
 
 void Destroy_All_Notifications()
@@ -1491,7 +1491,7 @@ void Net_Notification_Remove(entity this)
        ));
        #endif
        for (int i = 0; i < this.nent_stringcount; ++i) { if (this.nent_strings[i]) strunzone(this.nent_strings[i]); }
-       remove(this);
+       delete(this);
 }
 
 bool Net_Write_Notification(entity this, entity client, int sf)
index 7dcfec3534549fa9462be965e25abe06795d6f04..4ff276c78b416c6f2460c24d43a60c8ff523200d 100644 (file)
@@ -408,7 +408,7 @@ string BUFF_NAME(int i);
        ARG_CASE(ARG_CS_SV,     "race_col",      CCR(((f1 == 1) ? "^F1" : "^F2"))) \
        ARG_CASE(ARG_CS_SV,     "race_diff",     ((f2 > f3) ? sprintf(CCR("^1[+%s]"), mmssss(f2 - f3)) : sprintf(CCR("^2[-%s]"), mmssss(f3 - f2)))) \
        ARG_CASE(ARG_CS,        "missing_teams", notif_arg_missing_teams(f1)) \
-       ARG_CASE(ARG_CS,        "pass_key",      ((((tmp_s = getcommandkey("pass", "+use")) != "pass") && !(strstrofs(tmp_s, "not bound", 0) >= 0)) ? sprintf(CCR(_(" ^F1(Press %s)")), tmp_s) : "")) \
+       ARG_CASE(ARG_CS,        "pass_key",      getcommandkey(_("drop flag"), "+use")) \
        ARG_CASE(ARG_CS,        "frag_ping",     notif_arg_frag_ping(true, f2)) \
        ARG_CASE(ARG_CS,        "frag_stats",    notif_arg_frag_stats(f2, f3, f4)) \
        /*ARG_CASE(ARG_CS,      "frag_pos",      ((Should_Print_Score_Pos(f1)) ? sprintf("\n^BG%s", Read_Score_Pos(f1)) : ""))*/ \
index 4effcbd04a0a983e4d4bac87e760ada7f99d4928..5cb1d0bc4e99ac3840142341505923e501a3d5dc 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 32ae3813c8ea37976b4f1bb2abb3befd08c135d3..1b1241a0aa8e2451dc8db4f243179ff5e67e0f4f 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 322b3c4de13de003a1218820aa57ea0dea1a3941..70157d1862746141158ee5c31ee903ded84e7edb 100644 (file)
@@ -1,4 +1,3 @@
-#include "push.qc"
 #include "toss.qc"
 #include "walk.qc"
 #include "step.qc"
index 421c0e73f62daa67a65cef9f14d98fe191eeaefe..51520898705e99e3d9a9c8ca1f7da9a00c948ee3 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 78429dda97100b517462121029605caab979cbb0..0b27f727a5ac6eb5e81ed95105a802bb0d17b2d5 100644 (file)
        #include <server/autocvars.qh>
 #endif
 
+#ifdef SVQC
+void set_movetype(entity this, int mt)
+{
+       this.move_movetype = mt;
+       if (mt == MOVETYPE_PHYSICS || mt == MOVETYPE_PUSH || mt == MOVETYPE_FAKEPUSH) {
+               this.move_qcphysics = false;
+       }
+       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 +39,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 +64,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 +94,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 +117,14 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                                        trace_ent = NULL;
                                }
 
-                               this.move_flags |= FL_ONGROUND;
-                               this.move_groundentity = trace_ent;
+                               SET_ONGROUND(this);
+                               this.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 +140,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 +149,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 +171,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 +181,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 +210,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 +229,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 +260,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 +355,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 +379,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 +412,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 +449,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 +472,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 +485,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 +495,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.groundentity != trace_ent)))
                        _Movetype_Impact(this, trace_ent);
 
        return trace_fraction;
@@ -551,7 +569,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 +578,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 +609,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 +618,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 +641,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 +664,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 +672,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 +725,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 +759,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 +780,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 09b6e4d96d0cc17a6c36a7313b39002d285ff056..35a73d3331755d5f24b04ef175ce3f3208bf7420 100644 (file)
@@ -5,32 +5,31 @@
 #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
+
+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?
+.entity groundentity;  // FIXME add move_groundnetworkentity?
 .float move_suspendedinair;
 .float move_didgravity;
 
@@ -46,6 +45,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);
@@ -75,6 +75,9 @@ const int MOVETYPE_FLY_WORLDONLY    = 33;
 
 const int FL_ITEM                   = 256;
 const int FL_ONGROUND                          = 512;
+#elif defined(SVQC)
+const int MOVETYPE_ANGLENOCLIP      = 1;
+const int MOVETYPE_ANGLECLIP        = 2;
 #endif
 
 const int MOVETYPE_FAKEPUSH         = 13;
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 d7a2d562747ebd2aa8967daef7028fb150b6eaee..7eb553bfaa983cbffc9eb28e352a5a7f2e3ced52 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 5bea38c5b806d97f49594f911be68d64636ceeda..4821e34f6ac8929ae610ddc00ab35cd188223ce6 100644 (file)
@@ -2,19 +2,19 @@
 
 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)
+               else if (!this.groundentity)
                {
                        return;
                }
-               else if (this.move_suspendedinair && wasfreed(this.move_groundentity))
+               else if (this.move_suspendedinair && wasfreed(this.groundentity))
                {
-                       this.move_groundentity = NULL;
+                       this.groundentity = NULL;
                        return;
                }
        }
@@ -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;
-                               this.move_groundentity = trace_ent;
-                               this.move_velocity = '0 0 0';
-                               this.move_avelocity = '0 0 0';
+                               SET_ONGROUND(this);
+                               this.groundentity = trace_ent;
+                               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;
-                               this.move_groundentity = trace_ent;
+                               SET_ONGROUND(this);
+                               this.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 e926246266c6761215058a7f293adc421e18562a..bf58ca5824419938d4b7ff5dd598273507860516 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,17 +51,17 @@ 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;
-       entity originalmove_groundentity = this.move_groundentity;
+       int originalflags = this.flags;
+       entity originalmove_groundentity = this.groundentity;
 
        // if move didn't block on a step, return
        if (clip & 2)
@@ -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,16 +115,16 @@ 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.move_groundentity = originalmove_groundentity;
+                       this.flags = originalflags;
+                       this.groundentity = originalmove_groundentity;
                        // now try to unstick if needed
                        // clip = SV_TryUnstick (ent, oldvel);
                        return;
@@ -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,10 +165,10 @@ 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.move_groundentity = originalmove_groundentity;
+               this.origin = originalorigin;
+               this.velocity = originalvelocity;
+               this.flags = originalflags;
+               this.groundentity = originalmove_groundentity;
        }
 
        _Movetype_CheckVelocity(this);
index 36c5bdad40cbf19b18568263b76e87200f97da24..74a44252fe8bd6d7fc8a11a177ca7ad9c1dfd8ee 100644 (file)
@@ -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,145 +154,8 @@ 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;
+       if (IS_ONGROUND(this) || this.velocity.z <= 0 || PHYS_WATERJUMP_TIME(this) <= 0)
+               PHYS_WATERJUMP_TIME(this) = 0;
 #endif
 }
 
@@ -570,7 +434,7 @@ void CheckWaterJump(entity this)
                #ifdef SVQC
                        PHYS_TELEPORT_TIME(this) = time + 2;    // safety net
                #elif defined(CSQC)
-                       pmove_waterjumptime = 2;
+                       PHYS_WATERJUMP_TIME(this) = 2;
                #endif
                }
        }
@@ -817,180 +681,7 @@ void PM_check_blocked(entity this)
 #endif
 }
 
-void PM_fly(entity this, float maxspd_mod)
-{
-       // noclipping or flying
-       UNSET_ONGROUND(this);
-
-       this.velocity = this.velocity * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this));
-       makevectors(this.v_angle);
-       //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;
-       // acceleration
-       vector wishdir = normalize(wishvel);
-       float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(this) * maxspd_mod);
-#ifdef SVQC
-       if(time >= PHYS_TELEPORT_TIME(this))
-#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)
-{
-       // swimming
-       UNSET_ONGROUND(this);
-
-       float jump = PHYS_INPUT_BUTTON_JUMP(this);
-       // water jump only in certain situations
-       // this mimics quakeworld code
-       if (jump && this.waterlevel == WATERLEVEL_SWIMMING && this.velocity_z >= -180 && !this.viewloc)
-       {
-               vector yawangles = '0 1 0' * this.v_angle.y;
-               makevectors(yawangles);
-               vector forward = v_forward;
-               vector spot = this.origin + 24 * forward;
-               spot_z += 8;
-               traceline(spot, spot, MOVE_NOMONSTERS, this);
-               if (trace_startsolid)
-               {
-                       spot_z += 24;
-                       traceline(spot, spot, MOVE_NOMONSTERS, this);
-                       if (!trace_startsolid)
-                       {
-                               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);
-       //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;
-       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
-               float f = 1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this);
-               f = min(max(0, f), 1);
-               this.velocity *= f;
-
-               f = wishspeed - this.velocity * wishdir;
-               if (f > 0)
-               {
-                       float accelspeed = min(PHYS_ACCELERATE(this) * PHYS_INPUT_TIMELENGTH * wishspeed, f);
-                       this.velocity += accelspeed * wishdir;
-               }
-
-               // holding jump button swims upward slowly
-               if (jump && !this.viewloc)
-               {
-#if 0
-                       if (this.watertype & CONTENT_LAVA)
-                               this.velocity_z =  50;
-                       else if (this.watertype & CONTENT_SLIME)
-                               this.velocity_z =  80;
-                       else
-                       {
-                               if (IS_NEXUIZ_DERIVED(gamemode))
-#endif
-                                       this.velocity_z = 200;
-#if 0
-                               else
-                                       this.velocity_z = 100;
-                       }
-#endif
-               }
-       }
-       if(this.viewloc)
-       {
-               const float addspeed = wishspeed - this.velocity * wishdir;
-               if (addspeed > 0)
-               {
-                       const float accelspeed = min(PHYS_ACCELERATE(this) * PHYS_INPUT_TIMELENGTH * wishspeed, addspeed);
-                       this.velocity += accelspeed * wishdir;
-               }
-       }
-       else
-       {
-               // water acceleration
-               PM_Accelerate(this, wishdir, wishspeed, wishspeed, PHYS_ACCELERATE(this) * maxspd_mod, 1, 0, 0, 0);
-               PM_ClientMovement_Move(this);
-       }
-}
-
 .vector oldmovement;
-void PM_ladder(entity this, float maxspd_mod)
-{
-       // on a spawnfunc_func_ladder or swimming in spawnfunc_func_water
-       UNSET_ONGROUND(this);
-
-       float g;
-       g = PHYS_GRAVITY(this) * PHYS_INPUT_TIMELENGTH;
-       if (PHYS_ENTGRAVITY(this))
-               g *= PHYS_ENTGRAVITY(this);
-       if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-       {
-               g *= 0.5;
-               this.velocity_z += g;
-       }
-
-       this.velocity = this.velocity * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this));
-       makevectors(this.v_angle);
-       //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;
-       if(this.viewloc)
-               wishvel.z = this.oldmovement.x;
-       this.velocity_z += g;
-       if (this.ladder_entity.classname == "func_water")
-       {
-               float f = vlen(wishvel);
-               if (f > this.ladder_entity.speed)
-                       wishvel *= (this.ladder_entity.speed / f);
-
-               this.watertype = this.ladder_entity.skin;
-               f = this.ladder_entity.origin_z + this.ladder_entity.maxs_z;
-               if ((this.origin_z + this.view_ofs_z) < f)
-                       this.waterlevel = WATERLEVEL_SUBMERGED;
-               else if ((this.origin_z + (this.mins_z + this.maxs_z) * 0.5) < f)
-                       this.waterlevel = WATERLEVEL_SWIMMING;
-               else if ((this.origin_z + this.mins_z + 1) < f)
-                       this.waterlevel = WATERLEVEL_WETFEET;
-               else
-               {
-                       this.waterlevel = WATERLEVEL_NONE;
-                       this.watertype = CONTENT_EMPTY;
-               }
-       }
-       // acceleration
-       vector wishdir = normalize(wishvel);
-       float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(this) * maxspd_mod);
-       if(time >= PHYS_TELEPORT_TIME(this))
-               // 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)
 {
@@ -1098,195 +789,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)
-{
-       if (!WAS_ONGROUND(this))
-       {
-#ifdef SVQC
-               if (autocvar_speedmeter)
-                       LOG_TRACE(strcat("landing velocity: ", vtos(this.velocity), " (abs: ", ftos(vlen(this.velocity)), ")\n"));
-#endif
-               if (this.lastground < time - 0.3)
-                       this.velocity *= (1 - PHYS_FRICTION_ONLAND(this));
-#ifdef SVQC
-               if (this.jumppadcount > 1)
-                       LOG_TRACE(strcat(ftos(this.jumppadcount), "x jumppad combo\n"));
-               this.jumppadcount = 0;
-#endif
-       }
-
-       // walking
-       makevectors(this.v_angle.y * '0 1 0');
-       const vector wishvel = v_forward * this.movement.x
-                                               + v_right * this.movement.y;
-       // acceleration
-       const vector wishdir = normalize(wishvel);
-       float wishspeed = vlen(wishvel);
-       wishspeed = min(wishspeed, PHYS_MAXSPEED(this) * maxspd_mod);
-       if (IS_DUCKED(this)) wishspeed *= 0.5;
-
-       // apply edge friction
-       const float f2 = vlen2(vec2(this.velocity));
-       if (f2 > 0)
-       {
-               trace_dphitq3surfaceflags = 0;
-               tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
-               // TODO: apply edge friction
-               // apply ground friction
-               const int realfriction = (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK)
-                       ? PHYS_FRICTION_SLICK(this)
-                       : PHYS_FRICTION(this);
-
-               float f = sqrt(f2);
-               f = 1 - PHYS_INPUT_TIMELENGTH * realfriction * ((f < PHYS_STOPSPEED(this)) ? (PHYS_STOPSPEED(this) / f) : 1);
-               f = max(0, f);
-               this.velocity *= f;
-               /*
-                  Mathematical analysis time!
-
-                  Our goal is to invert this mess.
-
-                  For the two cases we get:
-                       v = v0 * (1 - PHYS_INPUT_TIMELENGTH * (PHYS_STOPSPEED(this) / v0) * PHYS_FRICTION(this))
-                         = v0 - PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED(this) * PHYS_FRICTION(this)
-                       v0 = v + PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED(this) * PHYS_FRICTION(this)
-                  and
-                       v = v0 * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this))
-                       v0 = v / (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this))
-
-                  These cases would be chosen ONLY if:
-                       v0 < PHYS_STOPSPEED(this)
-                       v + PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED(this) * PHYS_FRICTION(this) < PHYS_STOPSPEED(this)
-                       v < PHYS_STOPSPEED(this) * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this))
-                  and, respectively:
-                       v0 >= PHYS_STOPSPEED(this)
-                       v / (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this)) >= PHYS_STOPSPEED(this)
-                       v >= PHYS_STOPSPEED(this) * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this))
-                */
-       }
-       const float addspeed = wishspeed - this.velocity * wishdir;
-       if (addspeed > 0)
-       {
-               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)
-{
-       makevectors(this.v_angle.y * '0 1 0');
-       vector wishvel = v_forward * this.movement.x
-                                       + v_right * this.movement.y;
-       // acceleration
-       vector wishdir = normalize(wishvel);
-       float wishspeed = vlen(wishvel);
-
-#ifdef SVQC
-       if(time >= PHYS_TELEPORT_TIME(this))
-#elif defined(CSQC)
-       if(pmove_waterjumptime <= 0)
-#endif
-       {
-               float maxairspd = PHYS_MAXAIRSPEED(this) * min(maxspd_mod, 1);
-
-               // apply air speed limit
-               float airaccelqw = PHYS_AIRACCEL_QW(this);
-               float wishspeed0 = wishspeed;
-               wishspeed = min(wishspeed, maxairspd);
-               if (IS_DUCKED(this))
-                       wishspeed *= 0.5;
-               float airaccel = PHYS_AIRACCELERATE(this) * min(maxspd_mod, 1);
-
-               float accelerating = (this.velocity * wishdir > 0);
-               float wishspeed2 = wishspeed;
-
-               // CPM: air control
-               if (PHYS_AIRSTOPACCELERATE(this))
-               {
-                       vector curdir = normalize(vec2(this.velocity));
-                       airaccel += (PHYS_AIRSTOPACCELERATE(this)*maxspd_mod - airaccel) * max(0, -(curdir * wishdir));
-               }
-               // note that for straight forward jumping:
-               // step = accel * PHYS_INPUT_TIMELENGTH * wishspeed0;
-               // accel  = bound(0, wishspeed - vel_xy_current, step) * accelqw + step * (1 - accelqw);
-               // -->
-               // dv/dt = accel * maxspeed (when slow)
-               // dv/dt = accel * maxspeed * (1 - accelqw) (when fast)
-               // log dv/dt = logaccel + logmaxspeed (when slow)
-               // log dv/dt = logaccel + logmaxspeed + log(1 - accelqw) (when fast)
-               float strafity = IsMoveInDirection(this.movement, -90) + IsMoveInDirection(this.movement, +90); // if one is nonzero, other is always zero
-               if (PHYS_MAXAIRSTRAFESPEED(this))
-                       wishspeed = min(wishspeed, GeomLerp(PHYS_MAXAIRSPEED(this)*maxspd_mod, strafity, PHYS_MAXAIRSTRAFESPEED(this)*maxspd_mod));
-               if (PHYS_AIRSTRAFEACCELERATE(this))
-                       airaccel = GeomLerp(airaccel, strafity, PHYS_AIRSTRAFEACCELERATE(this)*maxspd_mod);
-               if (PHYS_AIRSTRAFEACCEL_QW(this))
-                       airaccelqw =
-               (((strafity > 0.5 ? PHYS_AIRSTRAFEACCEL_QW(this) : PHYS_AIRACCEL_QW(this)) >= 0) ? +1 : -1)
-               *
-               (1 - GeomLerp(1 - fabs(PHYS_AIRACCEL_QW(this)), strafity, 1 - fabs(PHYS_AIRSTRAFEACCEL_QW(this))));
-               // !CPM
-
-               if (PHYS_WARSOWBUNNY_TURNACCEL(this) && accelerating && this.movement.y == 0 && this.movement.x != 0)
-                       PM_AirAccelerate(this, wishdir, wishspeed2);
-               else {
-                   float sidefric = maxairspd ? (PHYS_AIRACCEL_SIDEWAYS_FRICTION(this) / maxairspd) : 0;
-                       PM_Accelerate(this, wishdir, wishspeed, wishspeed0, airaccel, airaccelqw, PHYS_AIRACCEL_QW_STRETCHFACTOR(this), sidefric, PHYS_AIRSPEEDLIMIT_NONQW(this));
-        }
-
-               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
@@ -1302,262 +804,17 @@ bool IsFlying(entity this)
        return true;
 }
 
-void PM_Main(entity this)
-{
-       int buttons = PHYS_INPUT_BUTTON_MASK(this);
-#ifdef CSQC
-       this.items = STAT(ITEMS);
-
-       this.movement = PHYS_INPUT_MOVEVALUES(this);
-
-       this.spectatorspeed = STAT(SPECTATORSPEED);
-
-       this.team = myteam + 1; // is this correct?
-       if (!(PHYS_INPUT_BUTTON_JUMP(this))) // !jump
-               UNSET_JUMP_HELD(this); // canjump = true
-       pmove_waterjumptime -= PHYS_INPUT_TIMELENGTH;
-
-       PM_ClientMovement_UpdateStatus(this, true);
-#endif
-
-       this.oldmovement = this.movement;
-
-
-#ifdef SVQC
-       WarpZone_PlayerPhysics_FixVAngle(this);
-#endif
-       float maxspeed_mod = 1;
-       maxspeed_mod *= PHYS_HIGHSPEED(this);
-
-#ifdef SVQC
-       Physics_UpdateStats(this, maxspeed_mod);
-
-       if (this.PlayerPhysplug)
-               if (this.PlayerPhysplug(this))
-                       return;
-#elif defined(CSQC)
-       if(hud != HUD_NORMAL)
-               return; // no vehicle prediction (yet)
-#endif
-
-#ifdef SVQC
-       anticheat_physics(this);
-#endif
-
-       if (PM_check_specialcommand(this, buttons))
-               return;
-#ifdef SVQC
-       if (sv_maxidle > 0)
-       {
-               if (buttons != this.buttons_old || this.movement != this.movement_old || this.v_angle != this.v_angle_old)
-                       this.parm_idlesince = time;
-       }
-#endif
-       int buttons_prev = this.buttons_old;
-       this.buttons_old = buttons;
-       this.movement_old = this.movement;
-       this.v_angle_old = this.v_angle;
-
-       PM_check_nickspam(this);
-
-       PM_check_punch(this);
-#ifdef SVQC
-       if (IS_BOT_CLIENT(this))
-       {
-               if (playerdemo_read(this))
-                       return;
-               bot_think(this);
-       }
-#endif
-
-#ifdef SVQC
-       if (IS_PLAYER(this))
-       {
-               const bool allowed_to_move = (time >= game_starttime);
-               if (!allowed_to_move)
-               {
-                       this.velocity = '0 0 0';
-                       this.movetype = MOVETYPE_NONE;
-                       this.disableclientprediction = 2;
-               }
-               else if (this.disableclientprediction == 2)
-               {
-                       if (this.movetype == MOVETYPE_NONE)
-                               this.movetype = MOVETYPE_WALK;
-                       this.disableclientprediction = 0;
-               }
-       }
-#endif
-
-#ifdef SVQC
-       if (this.movetype == MOVETYPE_NONE)
-               return;
-
-       // when we get here, disableclientprediction cannot be 2
-       this.disableclientprediction = 0;
-#endif
-
-       viewloc_PlayerPhysics(this);
-
-       PM_check_frozen(this);
-
-       PM_check_blocked(this);
-
-       maxspeed_mod = 1;
-
-       if (this.in_swamp)
-               maxspeed_mod *= this.swamp_slowdown; //cvar("g_balance_swamp_moverate");
-
-       // conveyors: first fix velocity
-       if (this.conveyor.state)
-               this.velocity -= this.conveyor.movedir;
-
-       MUTATOR_CALLHOOK(PlayerPhysics, this);
-
-       if (!IS_PLAYER(this))
-       {
-#ifdef SVQC
-               maxspeed_mod = autocvar_sv_spectator_speed_multiplier;
-               if (!this.spectatorspeed)
-                       this.spectatorspeed = maxspeed_mod;
-               if (this.impulse && this.impulse <= 19 || (this.impulse >= 200 && this.impulse <= 209) || (this.impulse >= 220 && this.impulse <= 229))
-               {
-                       if (this.lastclassname != STR_PLAYER)
-                       {
-                               if (this.impulse == 10 || this.impulse == 15 || this.impulse == 18 || (this.impulse >= 200 && this.impulse <= 209))
-                                       this.spectatorspeed = bound(1, this.spectatorspeed + 0.5, 5);
-                               else if (this.impulse == 11)
-                                       this.spectatorspeed = maxspeed_mod;
-                               else if (this.impulse == 12 || this.impulse == 16  || this.impulse == 19 || (this.impulse >= 220 && this.impulse <= 229))
-                                       this.spectatorspeed = bound(1, this.spectatorspeed - 0.5, 5);
-                               else if (this.impulse >= 1 && this.impulse <= 9)
-                                       this.spectatorspeed = 1 + 0.5 * (this.impulse - 1);
-                       } // otherwise just clear
-                       this.impulse = 0;
-               }
-#endif
-               maxspeed_mod = this.spectatorspeed;
-       }
-#ifdef SVQC
-
-       float spd = max(PHYS_MAXSPEED(this), PHYS_MAXAIRSPEED(this)) * maxspeed_mod;
-       if(this.speed != spd)
-       {
-               this.speed = spd;
-               string temps = ftos(spd);
-               stuffcmd(this, strcat("cl_forwardspeed ", temps, "\n"));
-               stuffcmd(this, strcat("cl_backspeed ", temps, "\n"));
-               stuffcmd(this, strcat("cl_sidespeed ", temps, "\n"));
-               stuffcmd(this, strcat("cl_upspeed ", temps, "\n"));
-       }
-
-       if(this.jumpspeedcap_min != autocvar_sv_jumpspeedcap_min)
-       {
-               this.jumpspeedcap_min = autocvar_sv_jumpspeedcap_min;
-               stuffcmd(this, sprintf("\ncl_jumpspeedcap_min \"%s\"\n", autocvar_sv_jumpspeedcap_min));
-       }
-       if(this.jumpspeedcap_max != autocvar_sv_jumpspeedcap_max)
-       {
-               this.jumpspeedcap_max = autocvar_sv_jumpspeedcap_max;
-               stuffcmd(this, sprintf("\ncl_jumpspeedcap_max \"%s\"\n", autocvar_sv_jumpspeedcap_max));
-       }
-#endif
-
-       if(IS_DEAD(this))
-       {
-               // handle water here
-               vector midpoint = ((this.absmin + this.absmax) * 0.5);
-               if(pointcontents(midpoint) == CONTENT_WATER)
-               {
-                       this.velocity = this.velocity * 0.5;
-
-                       // do we want this?
-                       //if(pointcontents(midpoint + '0 0 2') == CONTENT_WATER)
-                               //{ this.velocity_z = 70; }
-               }
-               goto end;
-       }
-
-#ifdef SVQC
-       if (!this.fixangle)
-               this.angles = '0 1 0' * this.v_angle.y;
-#endif
-
-       if (IS_PLAYER(this) && IS_ONGROUND(this))
-       {
-               PM_check_hitground(this);
-               PM_Footsteps(this);
-       }
-
-#ifdef SVQC
-       if(IsFlying(this))
-               this.wasFlying = 1;
-#endif
-
-       if (IS_PLAYER(this))
-               CheckPlayerJump(this);
-
-       if (this.flags & FL_WATERJUMP)
-       {
-               this.velocity_x = this.movedir.x;
-               this.velocity_y = this.movedir.y;
-               if (time > PHYS_TELEPORT_TIME(this) || this.waterlevel == WATERLEVEL_NONE
-               #ifdef CSQC
-                       || pmove_waterjumptime <= 0
-               #endif
-                       )
-               {
-                       this.flags &= ~FL_WATERJUMP;
-                       PHYS_TELEPORT_TIME(this) = 0;
-               #ifdef CSQC
-                       pmove_waterjumptime = 0;
-               #endif
-               }
-       }
-
-       else if (MUTATOR_CALLHOOK(PM_Physics, this, maxspeed_mod))
-               { }
-
-#ifdef SVQC
-       else if (this.movetype == MOVETYPE_NOCLIP || this.movetype == MOVETYPE_FLY || this.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
-               PM_fly(this, maxspeed_mod);
-
-       else if (this.waterlevel >= WATERLEVEL_SWIMMING)
-               PM_swim(this, maxspeed_mod);
-
-       else if (time < this.ladder_time)
-               PM_ladder(this, maxspeed_mod);
-
-       else if (ITEMS_STAT(this) & IT_USING_JETPACK)
-               PM_jetpack(this, maxspeed_mod);
-
-       else if (IS_ONGROUND(this))
-               PM_walk(this, maxspeed_mod);
-
-       else
-               PM_air(this, buttons_prev, maxspeed_mod);
-
-LABEL(end)
-       if (IS_ONGROUND(this))
-               this.lastground = time;
-
-       // conveyors: then break velocity again
-       if(this.conveyor.state)
-               this.velocity += this.conveyor.movedir;
-
-       this.lastflags = this.flags;
-
-       this.lastclassname = this.classname;
-}
 
+void sys_phys_update(entity this, float dt);
 #if defined(SVQC)
 void SV_PlayerPhysics(entity this)
 #elif defined(CSQC)
 void CSQC_ClientMovement_PlayerMove_Frame(entity this)
 #endif
 {
-       PM_Main(this);
+       sys_phys_update(this, PHYS_INPUT_TIMELENGTH);
+
+#ifdef SVQC
+       this.pm_frametime = frametime;
+#endif
 }
index de76bb8d8c234cbe8b17c35ed17711ec5f843f75..f120e9fe6cff8ebe5866250663aa8c9f314d6dff 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)
@@ -157,14 +160,18 @@ STATIC_INIT(PHYS_INPUT_BUTTON_JETPACK)
 #define ITEMS_STAT(s)                       ((s).items)
 
 .float teleport_time;
+#define PHYS_TELEPORT_TIME(s)               ((s).teleport_time)
+
+.float waterjump_time;
+#define PHYS_WATERJUMP_TIME(s)               ((s).waterjump_time)
 
 #ifdef CSQC
 
+       #define PHYS_FIXANGLE(s) ('0 0 0')
+
        string autocvar_cl_jumpspeedcap_min;
        string autocvar_cl_jumpspeedcap_max;
 
-       noref float pmove_waterjumptime;
-
        const int FL_WATERJUMP = 2048;  // player jumping out of water
        const int FL_JUMPRELEASED = 4096;  // for jump debouncing
 
@@ -188,8 +195,6 @@ STATIC_INIT(PHYS_INPUT_BUTTON_JETPACK)
 
        #define PHYS_GRAVITY(s)                     STAT(MOVEVARS_GRAVITY, s)
 
-       #define PHYS_TELEPORT_TIME(s)               ((s).teleport_time)
-
        #define TICRATE                             ticrate
 
        #define PHYS_INPUT_ANGLES(s)                input_angles
@@ -238,6 +243,8 @@ STATIC_INIT(PHYS_INPUT_BUTTON_JETPACK)
 
 #elif defined(SVQC)
 
+       #define PHYS_FIXANGLE(s) ((s).fixangle)
+
        bool Physics_Valid(string thecvar);
 
        .float stat_sv_airspeedlimit_nonqw = _STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW);
@@ -247,8 +254,6 @@ STATIC_INIT(PHYS_INPUT_BUTTON_JETPACK)
        .string jumpspeedcap_min;
        .string jumpspeedcap_max;
 
-       #define PHYS_TELEPORT_TIME(s)               ((s).teleport_time)
-
        #define PHYS_GRAVITY(s)                     autocvar_sv_gravity
 
        #define TICRATE sys_frametime
index 7c6882088dba4a604998fe824b866a66a16f2d68..e73bfa24fd481eacec76cc216f84f3693c9a25e7 100644 (file)
@@ -23,7 +23,7 @@ void PlayerState_detach(entity this)
 
        if (ps.m_client != this) return;  // don't own state, spectator
        FOREACH_CLIENT(PS(it) == ps, { PS(it) = NULL; });
-       remove(ps);
+       delete(ps);
 
     Inventory_delete(this);
 }
@@ -73,7 +73,7 @@ void PlayerScore_Detach(entity this);
 
 void ClientState_detach(entity this)
 {
-       remove(CS(this));
+       delete(CS(this));
        this._cs = NULL;
 
     GetCvars(this, -1);  // free cvars
index 2ed679e30f4e975b1590bddfcb643d1282de91e0..c7fc313a8802b082147098b3c1e391570ebff0ab 100644 (file)
@@ -124,6 +124,7 @@ REGISTER_STAT(BUFF_TIME, float)
 REGISTER_STAT(CTF_FLAGSTATUS, int)
 REGISTER_STAT(ENTRAP_ORB, float)
 REGISTER_STAT(ENTRAP_ORB_ALPHA, float)
+REGISTER_STAT(ITEMSTIME, int, autocvar_sv_itemstime)
 
 #ifdef SVQC
 int autocvar_g_multijump;
@@ -174,12 +175,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 +215,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 +230,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)
@@ -247,6 +259,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 e722c96c6d562c2323312a9c0d7a3bdc98fadb32..f7c81629544dc15e91b2c2781fc097f6fdca9a9c 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)
@@ -195,10 +194,11 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
     if(sf & ISF_MODEL)
     {
         this.drawmask  = MASK_NORMAL;
-               this.move_movetype = MOVETYPE_TOSS;
+               set_movetype(this, 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.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.angles = '0 0 0';
+        set_movetype(this, MOVETYPE_TOSS);
+        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;
@@ -769,7 +768,7 @@ void Item_Touch(entity this, entity toucher)
        {
                if (ITEM_TOUCH_NEEDKILL())
                {
-                       remove(this);
+                       delete(this);
                        return;
                }
        }
@@ -818,7 +817,7 @@ LABEL(pickup)
        _sound (toucher, (this.itemdef.instanceOfPowerup ? CH_TRIGGER_SINGLE : CH_TRIGGER), (this.item_pickupsound ? this.item_pickupsound : Sound_fixpath(this.item_pickupsound_ent)), VOL_BASE, ATTEN_NORM);
 
        if (this.classname == "droppedweapon")
-               remove (this);
+               delete (this);
        else if (this.spawnshieldtime)
        {
                entity e;
@@ -905,7 +904,7 @@ void RemoveItem(entity this)
 {
        if(wasfreed(this) || !this) { return; }
        Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
-       remove(this);
+       delete(this);
 }
 
 // pickup evaluation functions
@@ -1070,7 +1069,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default
        if(MUTATOR_CALLHOOK(FilterItem, this)) // error means we do not want the item
        {
                startitem_failed = true;
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -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);
@@ -1099,7 +1098,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default
                if (trace_dpstartcontents & DPCONTENTS_NODROP)
                {
                        startitem_failed = true;
-                       remove(this);
+                       delete(this);
                        return;
                }
        }
@@ -1108,7 +1107,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default
                if(!have_pickup_item(this))
                {
                        startitem_failed = true;
-                       remove (this);
+                       delete (this);
                        return;
                }
 
@@ -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)
                {
@@ -1227,7 +1226,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default
        if (MUTATOR_CALLHOOK(Item_Spawn, this))
        {
                startitem_failed = true;
-               remove(this);
+               delete(this);
                return;
        }
 }
@@ -1424,7 +1423,7 @@ void target_items_use(entity this, entity actor, entity trigger)
        if(actor.classname == "droppedweapon")
        {
                EXACTTRIGGER_TOUCH(this, trigger);
-               remove(actor);
+               delete(actor);
                return;
        }
 
@@ -1440,7 +1439,7 @@ void target_items_use(entity this, entity actor, entity trigger)
        FOREACH_ENTITY_ENT(enemy, actor,
        {
                if(it.classname == "droppedweapon")
-                       remove(it);
+                       delete(it);
        });
 
        if(GiveItems(actor, 0, tokenize_console(this.netname)))
index 1a65710a98346fcd1115b60ca06887e6282b7f87..6763701d31fa91d52468af4e71f657d0986313e7 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 ab4cc12d5ac27abf6a1cc530947086a13625023b..73ceb639408ea20361504d6489d80fc569223a12 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;
+       set_movetype(this, MOVETYPE_NONE);
        this.model = "";
        this.solid = SOLID_TRIGGER;
-       this.move_origin = this.origin;
        this.move_time = time;
 }
 
index 2b3decf64ff3dcda89bf58bfeaaf8412de15e37f..f89f67d7f396cacd2877de25c36948a866ca0ed3 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;
+               set_movetype(this, MOVETYPE_PUSH);
                this.use = door_use;
 
                LinkDoors(this);
@@ -824,10 +824,7 @@ NET_HANDLE(ENT_CLIENT_DOOR, bool isnew)
                        door_init_startopen(this);
 
                this.move_time = time;
-               this.move_origin = this.origin;
-               this.move_movetype = MOVETYPE_PUSH;
-               this.move_angles = this.angles;
-               this.move_blocked = door_blocked;
+               set_movetype(this, MOVETYPE_PUSH);
        }
 
        if(sf & SF_TRIGGER_RESET)
@@ -841,7 +838,6 @@ NET_HANDLE(ENT_CLIENT_DOOR, bool isnew)
                this.origin_y = ReadCoord();
                this.origin_z = ReadCoord();
                setorigin(this, this.origin);
-               this.move_origin = this.origin;
 
                this.pos1_x = ReadCoord();
                this.pos1_y = ReadCoord();
index 6f7ebaad31522130f7b69bf3509346c2e1e5098c..396636e8cd214cf8c96e8f7f95b0ae90a920e192 100644 (file)
@@ -168,17 +168,16 @@ NET_HANDLE(ENT_CLIENT_PLAT, bool isnew)
 
                this.classname = "plat";
                this.solid = SOLID_BSP;
-               this.movetype = MOVETYPE_PUSH;
+               set_movetype(this, MOVETYPE_PUSH);
                this.drawmask = MASK_NORMAL;
                this.draw = plat_draw;
+               if (isnew) IL_PUSH(g_drawables, this);
                this.use = plat_use;
                this.entremove = trigger_remove_generic;
 
                plat_reset(this); // also called here
 
-               this.move_movetype = MOVETYPE_PUSH;
-               this.move_origin = this.origin;
-               this.move_angles = this.angles;
+               set_movetype(this, MOVETYPE_PUSH);
                this.move_time = time;
 
                plat_spawn_inside_trigger(this);
@@ -188,8 +187,6 @@ NET_HANDLE(ENT_CLIENT_PLAT, bool isnew)
        {
                plat_reset(this);
 
-               this.move_origin = this.origin;
-               this.move_angles = this.angles;
                this.move_time = time;
        }
        return true;
index 1705d4081ead4bafe1a874992dbe379843e5f5b8..0cf0615da8e66fae26ea186239ede6f0c28ca7b0 100644 (file)
@@ -378,6 +378,7 @@ NET_HANDLE(ENT_CLIENT_POINTPARTICLES, bool isnew)
        setsize(this, this.mins, this.maxs);
        this.solid = SOLID_NOT;
        this.draw = Draw_PointParticles;
+       if (isnew) IL_PUSH(g_drawables, this);
        this.entremove = Ent_PointParticles_Remove;
 }
 #endif
index 265d45e0a992768b33a982f5000d4e1ad7065739..cc7dc09228b872efe428a0704d62764e353f6889 100644 (file)
@@ -35,7 +35,7 @@ spawnfunc(func_rain)
        if (!this.dest)
                this.dest = '0 0 -700';
        this.angles = '0 0 0';
-       this.movetype = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        this.solid = SOLID_NOT;
        SetBrushEntityModel(this);
        if (!this.cnt)
@@ -73,7 +73,7 @@ spawnfunc(func_snow)
        if (!this.dest)
                this.dest = '0 0 -300';
        this.angles = '0 0 0';
-       this.movetype = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        this.solid = SOLID_NOT;
        SetBrushEntityModel(this);
        if (!this.cnt)
@@ -134,6 +134,7 @@ NET_HANDLE(ENT_CLIENT_RAINSNOW, bool isnew)
        setorigin(this, this.origin);
        setsize(this, this.mins, this.maxs);
        this.solid = SOLID_NOT;
+       if (isnew) IL_PUSH(g_drawables, this);
        if(this.impulse)
                this.draw = Draw_Rain;
        else
index 3f6af7d00185dd256bc1c77253ae66d66bd67f05..247bfb0fc1e5e34703fc23f42e751e0d57be681a 100644 (file)
@@ -307,9 +307,10 @@ NET_HANDLE(ENT_CLIENT_TRAIN, bool isnew)
 
                this.classname = "func_train";
                this.solid = SOLID_BSP;
-               this.movetype = MOVETYPE_PUSH;
+               set_movetype(this, MOVETYPE_PUSH);
                this.drawmask = MASK_NORMAL;
                this.draw = train_draw;
+               if (isnew) IL_PUSH(g_drawables, this);
                this.entremove = trigger_remove_generic;
 
                if(set_platmovetype(this, this.platmovetype))
@@ -322,13 +323,9 @@ NET_HANDLE(ENT_CLIENT_TRAIN, bool isnew)
                //func_train_find();
 
                // but we will need these
-               //this.move_nextthink = this.move_ltime + 0.1;
-               //this.move_think = train_next;
                train_next(this);
 
-               this.move_movetype = MOVETYPE_PUSH;
-               this.move_origin = this.origin;
-               this.move_angles = this.angles;
+               set_movetype(this, MOVETYPE_PUSH);
                this.move_time = time;
        }
 
index 69222bf2d81a2ecf03113904c6c97c8053e4a0ac..d19d9da0853c856dd5132dff40fa42d22945c042 100644 (file)
@@ -41,13 +41,13 @@ void follow_init(entity this)
                }
 
                dst.solid = SOLID_NOT; // solid doesn't work with attachment
-               remove(this);
+               delete(this);
        }
        else
        {
                if(this.spawnflags & 2)
                {
-                       dst.movetype = MOVETYPE_FOLLOW;
+                       set_movetype(dst, MOVETYPE_FOLLOW);
                        dst.aiment = src;
                        // dst.punchangle = '0 0 0'; // keep unchanged
                        dst.view_ofs = dst.origin;
@@ -58,7 +58,7 @@ void follow_init(entity this)
                        follow_sameorigin(dst, src);
                }
 
-               remove(this);
+               delete(this);
        }
 }
 
index 399ba5baf5b9f134476ae64fcba2147ccbbd3b62..d10ff11280b2aa82efd6babfd450c7e996786422 100644 (file)
@@ -377,5 +377,6 @@ NET_HANDLE(ENT_CLIENT_LASER, bool isnew)
 
        InterpolateOrigin_Note(this);
        this.draw = Draw_Laser;
+       if (isnew) IL_PUSH(g_drawables, this);
 }
 #endif
index c1f481f8af515a262c516ac2b56c3ea698d22148..7b9ffd9c5007d573e724e8c0462c83698bbc2ccd 100644 (file)
@@ -23,7 +23,7 @@ void plat_spawn_inside_trigger(entity this)
 
        trigger = spawn();
        settouch(trigger, plat_center_touch);
-       trigger.movetype = MOVETYPE_NONE;
+       set_movetype(trigger, MOVETYPE_NONE);
        trigger.solid = SOLID_TRIGGER;
        trigger.enemy = this;
 
@@ -53,7 +53,7 @@ void plat_spawn_inside_trigger(entity this)
                        }
 
        // otherwise, something is fishy...
-       remove(trigger);
+       delete(trigger);
        objerror(this, "plat_spawn_inside_trigger: platform has odd size or lip, can't spawn");
 }
 
@@ -128,13 +128,8 @@ void plat_outside_touch(entity this, entity toucher)
 
 void plat_trigger_use(entity this, entity actor, entity trigger)
 {
-#ifdef SVQC
        if (getthink(this))
                return;         // already activated
-#elif defined(CSQC)
-       if(this.move_think)
-               return;
-#endif
        plat_go_down(this);
 }
 
index 51ef002736a32201d391cc9831b9a4f84f06389f..66f0253d95e1bcce3987fc33c2f1f50943905e4b 100644 (file)
@@ -14,7 +14,7 @@ Applies some friction to this
 void SUB_Friction (entity this)
 {
        this.SUB_NEXTTHINK = time;
-       if(this.SUB_FLAGS & FL_ONGROUND)
+       if(IS_ONGROUND(this))
                this.SUB_VELOCITY = this.SUB_VELOCITY * (1 - frametime * this.friction);
 }
 
@@ -40,7 +40,7 @@ void SUB_VanishOrRemove (entity ent)
        else
        {
                // remove
-               remove (ent);
+               delete (ent);
        }
 }
 
@@ -144,7 +144,7 @@ void SUB_CalcMove_controller_think (entity this)
                // derivative: delta + 2 * delta2 (e.g. for angle positioning)
                entity own = this.owner;
                SUB_THINK(own, this.think1);
-               remove(this);
+               delete(this);
                SUB_THUNK(own)(own);
        }
 }
index 1ce3ea2e9e842864e7315270fab82622a784af81..096022c848644ac499c5c674e4f0fe1c709079e1 100644 (file)
@@ -1,42 +1,15 @@
 #ifndef SUBS_H
 #define SUBS_H
 
-#ifdef SVQC
-
-       #define SUB_ANGLES(s)           (s).angles
-       #define SUB_VELOCITY            velocity
-       #define SUB_AVELOCITY           avelocity
-       #define SUB_ORIGIN                      origin
-       #define SUB_SETORIGIN(s,v)      setorigin((s), (v))
-       #define SUB_NEXTTHINK           nextthink
-       #define SUB_THINK(e, f)     setthink(e, f)
-       #define SUB_THUNK(e)        getthink(e)
-       #define SUB_LTIME                       ltime
-       #define SUB_FLAGS                       flags
-
-#elif defined(CSQC)
-
-       void _Movetype_LinkEdict(entity this, float touch_triggers);
-
-       #define SUB_ANGLES(s)   (s).move_angles
-       #define SUB_VELOCITY    move_velocity
-       #define SUB_AVELOCITY   move_avelocity
-       #define SUB_ORIGIN              move_origin
-       #define SUB_NEXTTHINK   move_nextthink
-       #define SUB_THINK(e, f) ((e).move_think = (f))
-       #define SUB_THUNK(e)    ((e).move_think)
-       #define SUB_LTIME               move_ltime
-       #define SUB_FLAGS               move_flags
-
-.vector move_origin;
-
-       void SUB_SETORIGIN(entity s, vector v)
-       {
-               s.move_origin = v;
-               _Movetype_LinkEdict(s, true);
-       }
-
-#endif
+#define SUB_ANGLES(s)          (s).angles
+#define SUB_VELOCITY           velocity
+#define SUB_AVELOCITY          avelocity
+#define SUB_ORIGIN                     origin
+#define SUB_SETORIGIN(s,v)     setorigin((s), (v))
+#define SUB_NEXTTHINK          nextthink
+#define SUB_THINK(e, f)     setthink(e, f)
+#define SUB_THUNK(e)        getthink(e)
+#define SUB_LTIME                      ltime
 
 
 void SUB_SetFade (entity ent, float when, float fading_time);
index 7db93a3d1e46c665227b15b5d7223e6003651376..f8f1c0ace5d32f38da5e6f3086b1f82011618eab 100644 (file)
@@ -115,7 +115,7 @@ spawnfunc(target_speaker)
        else if(this.spawnflags & 1) // LOOPED_ON
        {
                ambientsound (this.origin, this.noise, VOL_BASE * this.volume, this.atten);
-               remove(this);
+               delete(this);
        }
        else if(this.spawnflags & 2) // LOOPED_OFF
        {
@@ -125,7 +125,7 @@ spawnfunc(target_speaker)
        {
                // Quake/Nexuiz fallback
                ambientsound (this.origin, this.noise, VOL_BASE * this.volume, this.atten);
-               remove(this);
+               delete(this);
        }
 }
 #endif
index 20f618aa2477392872f2c2c12cdd8e7a256591cb..a1a38d39e1a95e24459d2a2c4c1a5bb857c7de27 100644 (file)
@@ -124,22 +124,20 @@ void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angle
        UpdateCSQCProjectileAfterTeleport(player);
        UpdateItemAfterTeleport(player);
 #elif defined(CSQC)
-       from = player.move_origin;
-       player.move_origin = to;
-       player.move_angles = to_angles;
-       player.move_velocity = to_velocity;
-       player.move_flags &= ~FL_ONGROUND;
+       from = player.origin;
+       setorigin(player, to);
+       player.angles = to_angles;
+       player.velocity = to_velocity;
+       UNSET_ONGROUND(player);
        player.iflags |= IFLAG_TELEPORTED | IFLAG_V_ANGLE | IFLAG_ANGLES;
        player.csqcmodel_teleported = 1;
        player.v_angle = to_angles;
 
-       if(player.isplayermodel) // not for anything but the main player
+       if(player == csqcplayer) // not for anything but the main player
        {
-               setproperty(VF_ANGLES, player.move_angles);
-               setproperty(VF_CL_VIEWANGLES, player.move_angles);
+               setproperty(VF_ANGLES, player.angles);
+               setproperty(VF_CL_VIEWANGLES, player.angles);
        }
-
-       makevectors(player.move_angles);
 #endif
 
 #ifdef SVQC
@@ -213,35 +211,17 @@ entity Simple_TeleportPlayer(entity teleporter, entity player)
 
        makevectors(e.mangle);
 
-#ifdef SVQC
        if(e.speed)
                if(vdist(player.velocity, >, e.speed))
                        player.velocity = normalize(player.velocity) * max(0, e.speed);
-#elif defined(CSQC)
-       if(e.speed)
-               if(vdist(player.move_velocity, >, e.speed))
-                       player.move_velocity = normalize(player.move_velocity) * max(0, e.speed);
-#endif
 
-#ifdef SVQC
        if(STAT(TELEPORT_MAXSPEED, player))
                if(vdist(player.velocity, >, STAT(TELEPORT_MAXSPEED, player)))
                        player.velocity = normalize(player.velocity) * max(0, STAT(TELEPORT_MAXSPEED, player));
-#elif defined(CSQC)
-       if(STAT(TELEPORT_MAXSPEED, player))
-               if(vdist(player.move_velocity, >, STAT(TELEPORT_MAXSPEED, player)))
-                       player.move_velocity = normalize(player.move_velocity) * max(0, STAT(TELEPORT_MAXSPEED, player));
-#endif
 
-#ifdef SVQC
        locout = e.origin + '0 0 1' * (1 - player.mins.z - 24);
 
        TeleportPlayer(teleporter, player, locout, e.mangle, v_forward * vlen(player.velocity), '0 0 0', '0 0 0', TELEPORT_FLAGS_TELEPORTER);
-#elif defined(CSQC)
-       locout = e.origin + '0 0 1' * (1 - player.mins.z - 24);
-
-       TeleportPlayer(teleporter, player, locout, e.mangle, v_forward * vlen(player.move_velocity), '0 0 0', '0 0 0', TELEPORT_FLAGS_TELEPORTER);
-#endif
 
        return e;
 }
@@ -254,7 +234,7 @@ void teleport_findtarget(entity this)
        {
                ++n;
 #ifdef SVQC
-               if(e.movetype == MOVETYPE_NONE)
+               if(e.move_movetype == MOVETYPE_NONE)
                        waypoint_spawnforteleporter(this, e.origin, 0);
                if(e.classname != "info_teleport_destination")
                        LOG_INFO("^3MAPPER ERROR: teleporter does target an invalid teleport destination entity. Angles will not work.\n");
@@ -310,7 +290,7 @@ void WarpZone_PostTeleportPlayer_Callback(entity pl)
        #ifdef SVQC
                if(!(pl.flags & FL_PROJECTILE))
        #elif defined(CSQC)
-               if(!(pl.move_flags & BIT(15))) // FL_PROJECTILE
+               if(!(pl.flags & BIT(15))) // FL_PROJECTILE
        #endif
                        LOG_INFO("A non-projectile got through a warpzone and its owner cleared. It's a ", pl.classname, ".\n");
                pl.owner = NULL;
index efddf8c77f89eb99787af0075e448e1035ad4082..62b21e66f4fe4dbe8bcc5010c83e1b6c1500ce8d 100644 (file)
@@ -2,7 +2,7 @@
 void gamestart_use(entity this, entity actor, entity trigger)
 {
        SUB_UseTargets(this, this, trigger);
-       remove(this);
+       delete(this);
 }
 
 void gamestart_use_this(entity this)
index cef8cb8bbe5f94838504e47b154e8f7e052549c7..88b73c4dfcdd1d15c979c3bf2cebda4172ce0020 100644 (file)
@@ -6,7 +6,7 @@ void trigger_gravity_remove(entity own)
        {
                UpdateCSQCProjectile(own);
                own.gravity = own.trigger_gravity_check.gravity;
-               remove(own.trigger_gravity_check);
+               delete(own.trigger_gravity_check);
        }
        else
                backtrace("Removing a trigger_gravity_check with no valid owner");
@@ -22,7 +22,7 @@ void trigger_gravity_check_think(entity this)
                if(this.owner.trigger_gravity_check == this)
                        trigger_gravity_remove(this.owner);
                else
-                       remove(this);
+                       delete(this);
                return;
        }
        else
index 3d9a87a465f877d9a7ab68d8bef364d122af3f03..43bac947e127908930ca816e0f9115b82b5f4127 100644 (file)
@@ -17,15 +17,11 @@ void trigger_impulse_touch1(entity this, entity toucher)
        if(!targ)
        {
                objerror(this, "trigger_force without a (valid) .target!\n");
-               remove(this);
+               delete(this);
                return;
        }
 
-#ifdef SVQC
        str = min(this.radius, vlen(this.origin - toucher.origin));
-#elif defined(CSQC)
-       str = min(this.radius, vlen(this.origin - toucher.move_origin));
-#endif
 
        if(this.falloff == 1)
                str = (str / this.radius) * this.strength;
@@ -41,35 +37,20 @@ void trigger_impulse_touch1(entity this, entity toucher)
 
        if(this.spawnflags & 64)
        {
-#ifdef SVQC
                float addspeed = str - toucher.velocity * normalize(targ.origin - this.origin);
                if (addspeed > 0)
                {
                        float accelspeed = min(8 * pushdeltatime * str, addspeed);
                        toucher.velocity += accelspeed * normalize(targ.origin - this.origin);
                }
-#elif defined(CSQC)
-               float addspeed = str - toucher.move_velocity * normalize(targ.origin - this.origin);
-               if (addspeed > 0)
-               {
-                       float accelspeed = min(8 * pushdeltatime * str, addspeed);
-                       toucher.move_velocity += accelspeed * normalize(targ.origin - this.origin);
-               }
-#endif
        }
        else
-#ifdef SVQC
                toucher.velocity = toucher.velocity + normalize(targ.origin - this.origin) * str * pushdeltatime;
-#elif defined(CSQC)
-               toucher.move_velocity = toucher.move_velocity + normalize(targ.origin - this.origin) * str * pushdeltatime;
-#endif
 
-#ifdef SVQC
        UNSET_ONGROUND(toucher);
 
+#ifdef SVQC
        UpdateCSQCProjectile(toucher);
-#elif defined(CSQC)
-       toucher.move_flags &= ~FL_ONGROUND;
 #endif
 }
 
@@ -92,12 +73,10 @@ void trigger_impulse_touch2(entity this, entity toucher)
        if(!pushdeltatime) return;
 
        // div0: ticrate independent, 1 = identity (not 20)
-#ifdef SVQC
        toucher.velocity = toucher.velocity * pow(this.strength, pushdeltatime);
 
+#ifdef SVQC
        UpdateCSQCProjectile(toucher);
-#elif defined(CSQC)
-       toucher.move_velocity = toucher.move_velocity * pow(this.strength, pushdeltatime);
 #endif
 }
 
@@ -122,11 +101,7 @@ void trigger_impulse_touch3(entity this, entity toucher)
 
        setsize(this, '-1 -1 -1' * this.radius,'1 1 1' * this.radius);
 
-#ifdef SVQC
        str = min(this.radius, vlen(this.origin - toucher.origin));
-#elif defined(CSQC)
-       str = min(this.radius, vlen(this.origin - toucher.move_origin));
-#endif
 
        if(this.falloff == 1)
                str = (1 - str / this.radius) * this.strength; // 1 in the inside
@@ -135,12 +110,10 @@ void trigger_impulse_touch3(entity this, entity toucher)
        else
                str = this.strength;
 
-#ifdef SVQC
        toucher.velocity = toucher.velocity + normalize(toucher.origin - this.origin) * str * pushdeltatime;
 
+#ifdef SVQC
        UpdateCSQCProjectile(toucher);
-#elif defined(CSQC)
-       toucher.move_velocity = toucher.move_velocity + normalize(toucher.move_origin - this.origin) * str * pushdeltatime;
 #endif
 }
 
index 88f785f39ecf62296fe0ffbd45c8ff4946ccd81e..519ba2691586fb5e5d0d99a99021361310b8c5bb 100644 (file)
@@ -146,7 +146,6 @@ void trigger_push_touch(entity this, entity toucher)
        if(this.enemy)
        {
                toucher.velocity = trigger_push_calculatevelocity(toucher.origin, this.enemy, this.height);
-               toucher.move_velocity = toucher.velocity;
        }
        else if(this.target && this.target != "")
        {
@@ -160,30 +159,26 @@ void trigger_push_touch(entity this, entity toucher)
                                RandomSelection_Add(e, 0, string_null, 1, 1);
                }
                toucher.velocity = trigger_push_calculatevelocity(toucher.origin, RandomSelection_chosen_ent, this.height);
-               toucher.move_velocity = toucher.velocity;
        }
        else
        {
                toucher.velocity = this.movedir;
-               toucher.move_velocity = toucher.velocity;
        }
 
-#ifdef SVQC
        UNSET_ONGROUND(toucher);
-#elif defined(CSQC)
-       toucher.move_flags &= ~FL_ONGROUND;
 
+#ifdef CSQC
        if (toucher.flags & FL_PROJECTILE)
        {
-               toucher.move_angles = vectoangles (toucher.move_velocity);
+               toucher.angles = vectoangles (toucher.velocity);
                switch(toucher.move_movetype)
                {
                        case MOVETYPE_FLY:
-                               toucher.move_movetype = MOVETYPE_TOSS;
+                               set_movetype(toucher, MOVETYPE_TOSS);
                                toucher.gravity = 1;
                                break;
                        case MOVETYPE_BOUNCEMISSILE:
-                               toucher.move_movetype = MOVETYPE_BOUNCE;
+                               set_movetype(toucher, MOVETYPE_BOUNCE);
                                toucher.gravity = 1;
                                break;
                }
@@ -240,14 +235,15 @@ void trigger_push_touch(entity this, entity toucher)
        if (toucher.flags & FL_PROJECTILE)
        {
                toucher.angles = vectoangles (toucher.velocity);
-               switch(toucher.movetype)
+               toucher.com_phys_gravity_factor = 1;
+               switch(toucher.move_movetype)
                {
                        case MOVETYPE_FLY:
-                               toucher.movetype = MOVETYPE_TOSS;
+                               set_movetype(toucher, MOVETYPE_TOSS);
                                toucher.gravity = 1;
                                break;
                        case MOVETYPE_BOUNCEMISSILE:
-                               toucher.movetype = MOVETYPE_BOUNCE;
+                               set_movetype(toucher, MOVETYPE_BOUNCE);
                                toucher.gravity = 1;
                                break;
                }
@@ -294,9 +290,9 @@ void trigger_push_findtarget(entity this)
                        setsize(e, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL));
                        e.velocity = trigger_push_calculatevelocity(org, t, this.height);
                        tracetoss(e, e);
-                       if(e.movetype == MOVETYPE_NONE)
+                       if(e.move_movetype == MOVETYPE_NONE)
                                waypoint_spawnforteleporter(this, trace_endpos, vlen(trace_endpos - org) / vlen(e.velocity));
-                       remove(e);
+                       delete(e);
 #endif
                }
 
@@ -328,7 +324,7 @@ void trigger_push_findtarget(entity this)
                e.velocity = this.movedir;
                tracetoss(e, e);
                waypoint_spawnforteleporter(this, trace_endpos, vlen(trace_endpos - org) / vlen(e.velocity));
-               remove(e);
+               delete(e);
        }
 
        trigger_push_link(this);
index 2cc81e597c0815a6de9d60b5780a24c240dfc210..eabb84f57ac4bb5c06960e855659ba34a1bbce96 100644 (file)
@@ -15,7 +15,7 @@ void trigger_keylock_kill(string s)
 {
        entity t;
        for(t = NULL; (t = find(t, targetname, s)); )
-               remove(t);
+               delete(t);
 }
 
 void trigger_keylock_touch(entity this, entity toucher)
@@ -74,7 +74,7 @@ void trigger_keylock_touch(entity this, entity toucher)
                if(this.killtarget)
                        trigger_keylock_kill(this.killtarget);
 
-               remove(this);
+               delete(this);
        }
 
 }
@@ -121,7 +121,7 @@ message2 and noise2 will be resent to the player every 2 seconds while he is in
 */
 spawnfunc(trigger_keylock)
 {
-       if(!this.itemkeys) { remove(this); return; }
+       if(!this.itemkeys) { delete(this); return; }
 
        // set unlocked message
        if(this.message == "")
index b54f99dcd411eead96c2cfcc723767ba3b087850..9260c01ac2817e1f6920139f1f7b9c1c42895056 100644 (file)
@@ -34,7 +34,7 @@ void trigger_secret_touch(entity this, entity toucher)
 
        // handle normal trigger features
        multi_touch(this, toucher);
-       remove(this);
+       delete(this);
 }
 
 /*QUAKED trigger_secret (.5 .5 .5) ?
index 0f8d1a73eebb46b4780f2b2e1758fbeda3d7aff2..99eb846c7305be7dafb0c711bfd28637241c3eed 100644 (file)
@@ -45,7 +45,7 @@ void swampslug_think(entity this)
        if(this.health <= 0)
        {
                this.owner.in_swamp = 0;
-               remove(this);
+               delete(this);
                //centerprint(this.owner,"Killing slug...\n");
                return;
        }
index 484daeedf9d3f0b645f50094c830e79713bfebf8..69e2c49c1d9c83b3ceb2b13fb3a14bc9f96e8f65 100644 (file)
@@ -114,7 +114,7 @@ NET_HANDLE(ENT_CLIENT_TRIGGER_TELEPORT, bool isnew)
 
        this.entremove = trigger_remove_generic;
        this.solid = SOLID_TRIGGER;
-       //this.move_touch = trigger_push_touch;
+       //settouch(this, trigger_push_touch);
        this.move_time = time;
        defer(this, 0.25, teleport_findtarget);
 
index 9d675bbc734dbba6ad08ea4a549b005297b779cc..f2a0e86cc33be9aadae80058f36ddd603e53ac0b 100644 (file)
@@ -71,7 +71,7 @@ void viewloc_init(entity this)
                        break;
                }
 
-       if(!this.enemy) { LOG_INFO("^1FAIL!\n"); remove(this); return; }
+       if(!this.enemy) { LOG_INFO("^1FAIL!\n"); delete(this); return; }
 
        if(!this.goalentity)
                this.goalentity = this.enemy; // make them match so CSQC knows what to do
@@ -85,7 +85,7 @@ void viewloc_init(entity this)
 spawnfunc(trigger_viewlocation)
 {
        // we won't check target2 here yet, as it may not even need to exist
-       if(this.target == "") { LOG_INFO("^1FAIL!\n"); remove(this); return; }
+       if(this.target == "") { LOG_INFO("^1FAIL!\n"); delete(this); return; }
 
        EXACTTRIGGER_INIT;
        InitializeEntity(this, viewloc_init, INITPRIO_FINDTARGET);
index a9050357f6e97b5bf7851968239bb266404b5f57..849d3e8acb27ef9efba748c6ab5bab0b14178ab7 100644 (file)
@@ -5,7 +5,7 @@ void SUB_UseTargets(entity this, entity actor, entity trigger);
 void DelayThink(entity this)
 {
        SUB_UseTargets (this, this.enemy, NULL);
-       remove(this);
+       delete(this);
 }
 
 void FixSize(entity e)
@@ -225,7 +225,7 @@ void SUB_UseTargets(entity this, entity actor, entity trigger)
        if (s != "")
        {
                for(entity t = NULL; (t = find(t, targetname, s)); )
-                       remove(t);
+                       delete(t);
        }
 #endif
 
index 55719cb3f59eb38fe30ef856de28f90dfe568b8f..79f1f216fff93bcf18ad7ded7fae17cb5c9ced43 100644 (file)
@@ -1,6 +1,6 @@
 void turret_remove(entity this)
 {
-       remove(this.tur_head);
+       delete(this.tur_head);
        //remove(this.enemy);
        this.tur_head = NULL;
 }
@@ -34,7 +34,7 @@ void turret_draw(entity this)
        if(dt <= 0)
                return;
 
-       this.tur_head.angles += dt * this.tur_head.move_avelocity;
+       this.tur_head.angles += dt * this.tur_head.avelocity;
 
        if (this.health < 127)
        {
@@ -224,20 +224,21 @@ void turret_construct(entity this)
 
        this.tur_head.classname                 = "turret_head";
        this.tur_head.owner                             = this;
-       this.tur_head.move_movetype             = MOVETYPE_NOCLIP;
-       this.move_movetype                              = MOVETYPE_NOCLIP;
+       set_movetype(this.tur_head, MOVETYPE_NOCLIP);
+       set_movetype(this, MOVETYPE_NOCLIP);
        this.tur_head.angles                    = this.angles;
        this.health                                             = 255;
        this.solid                                              = SOLID_BBOX;
        this.tur_head.solid                             = SOLID_NOT;
-       this.movetype                                   = MOVETYPE_NOCLIP;
-       this.tur_head.movetype                  = MOVETYPE_NOCLIP;
+       set_movetype(this, MOVETYPE_NOCLIP);
+       set_movetype(this.tur_head, MOVETYPE_NOCLIP);
        this.draw                                               = turret_draw;
        this.entremove                                  = turret_remove;
        this.drawmask                                   = MASK_NORMAL;
        this.tur_head.drawmask                  = MASK_NORMAL;
        this.anim_start_time                    = 0;
        this.draw2d = turret_draw2d;
+       IL_PUSH(g_drawables_2d, this);
        this.maxdistance = autocvar_g_waypointsprite_turrets_maxdist;
        this.teamradar_color = '1 0 0';
        this.alpha = 1;
@@ -258,14 +259,14 @@ void turret_gib_draw(entity this)
                if(time >= this.nextthink)
                {
                        turret_gibboom(this);
-                       remove(this);
+                       delete(this);
                }
        }
        else
        {
                this.alpha = bound(0, this.nextthink - time, 1);
                if(this.alpha < ALPHA_MIN_VISIBLE)
-                       remove(this);
+                       delete(this);
        }
 }
 
@@ -303,11 +304,10 @@ entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, flo
                gib.nextthink = time + autocvar_cl_gibs_lifetime * (1 + prandom() * 0.15);
 
        gib.gravity              = 1;
-       gib.move_movetype   = MOVETYPE_BOUNCE;
-       gib.move_origin  = _from;
+       set_movetype(gib, MOVETYPE_BOUNCE);
        setorigin(gib,          _from);
-       gib.move_velocity   = _to;
-       gib.move_avelocity  = prandomvec() * 32;
+       gib.velocity   = _to;
+       gib.avelocity  = prandomvec() * 32;
        gib.move_time      = time;
        gib.damageforcescale = 1;
 
@@ -341,9 +341,9 @@ void turret_die(entity this)
                        entity headgib = turret_gibtoss((get_turretinfo(this.m_id)).head_model, this.origin + '0 0 32', '0 0 200' + randomvec() * 200, '-1 -1 -1', true);
                        if(headgib)
                        {
-                               headgib.angles = headgib.move_angles = this.tur_head.angles;
-                               headgib.avelocity = headgib.move_avelocity = this.tur_head.move_avelocity + randomvec() * 45;
-                               headgib.avelocity_y = headgib.move_avelocity_y = headgib.move_avelocity_y * 5;
+                               headgib.angles = this.tur_head.angles;
+                               headgib.avelocity = this.tur_head.avelocity + randomvec() * 45;
+                               headgib.avelocity_y = headgib.avelocity_y * 5;
                                headgib.gravity = 0.5;
                        }
                }
@@ -382,10 +382,9 @@ NET_HANDLE(ENT_CLIENT_TURRET, bool isnew)
                if(this.tur_head == NULL) // aparenly this can happpen before TNSF_SETUP. great.
                        this.tur_head = spawn();
 
-               this.tur_head.move_angles_x = ReadShort();
-               this.tur_head.move_angles_y = ReadShort();
-               //this.tur_head.angles = this.angles + this.tur_head.move_angles;
-               this.tur_head.angles = this.tur_head.move_angles;
+               this.tur_head.angles_x = ReadShort();
+               this.tur_head.angles_y = ReadShort();
+               //this.tur_head.angles = this.angles + this.tur_head.angles;
        }
 
        if(sf & TNSF_AVEL)
@@ -393,8 +392,8 @@ NET_HANDLE(ENT_CLIENT_TURRET, bool isnew)
                if(this.tur_head == NULL) // aparenly this can happpen before TNSF_SETUP. great.
                        this.tur_head = spawn();
 
-               this.tur_head.move_avelocity_x = ReadShort();
-               this.tur_head.move_avelocity_y = ReadShort();
+               this.tur_head.avelocity_x = ReadShort();
+               this.tur_head.avelocity_y = ReadShort();
        }
 
        if(sf & TNSF_MOVE)
@@ -408,11 +407,9 @@ NET_HANDLE(ENT_CLIENT_TURRET, bool isnew)
                this.velocity_y = ReadShort();
                this.velocity_z = ReadShort();
 
-               this.move_angles_y = ReadShort();
+               this.angles_y = ReadShort();
 
                this.move_time   = time;
-               this.move_velocity = this.velocity;
-               this.move_origin   = this.origin;
        }
 
        if(sf & TNSF_ANIM)
index 1f8450f3951b07ed0595c523a7241777d6c26013..f1515d070a96fdd55dfd92321dcea1e2fbd814e9 100644 (file)
@@ -32,7 +32,7 @@ vector turret_aim_generic(entity this)
 
                        if(this.aim_flags & TFL_AIM_ZPREDICT)
                        if(!IS_ONGROUND(this.enemy))
-                       if(this.enemy.movetype == MOVETYPE_WALK || this.enemy.movetype == MOVETYPE_TOSS || this.enemy.movetype == MOVETYPE_BOUNCE)
+                       if(this.enemy.move_movetype == MOVETYPE_WALK || this.enemy.move_movetype == MOVETYPE_TOSS || this.enemy.move_movetype == MOVETYPE_BOUNCE)
                        {
                                float vz;
                                prep_z = pre_pos_z;
@@ -193,8 +193,8 @@ void turret_die(entity this)
        {
                tur.tr_death(tur, this);
 
-               remove(this.tur_head);
-               remove(this);
+               delete(this.tur_head);
+               delete(this);
        }
        else
        {
@@ -440,7 +440,7 @@ void turret_projectile_explode(entity this)
 #else
        RadiusDamage (this, this.realowner, this.owner.shot_dmg, 0, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.totalfrags, NULL);
 #endif
-       remove(this);
+       delete(this);
 }
 
 void turret_projectile_touch(entity this, entity toucher)
@@ -474,9 +474,10 @@ entity turret_projectile(entity actor, Sound _snd, float _size, float _health, f
        setthink(proj, turret_projectile_explode);
        settouch(proj, turret_projectile_touch);
        proj.nextthink    = time + 9;
-       proj.movetype           = MOVETYPE_FLYMISSILE;
+       set_movetype(proj, MOVETYPE_FLYMISSILE);
        proj.velocity           = normalize(actor.tur_shotdir_updated + randomvec() * actor.shot_spread) * actor.shot_speed;
-       proj.flags                = FL_PROJECTILE;
+       proj.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, proj);
        proj.enemy                = actor.enemy;
        proj.totalfrags  = _death;
        PROJECTILE_MAKETRIGGER(proj);
@@ -1199,7 +1200,8 @@ void turrets_manager_think(entity this)
 
        if (autocvar_g_turrets_reloadcvars == 1)
        {
-               FOREACH_ENTITY(IS_TURRET(it), {
+               IL_EACH(g_turrets, true,
+               {
                        load_unit_settings(it, true);
                        Turret tur = get_turretinfo(it.m_id);
                        tur.tr_think(tur, it);
@@ -1248,6 +1250,7 @@ bool turret_initialize(entity this, Turret tur)
        // if tur_head exists, we can assume this turret re-spawned
        if(!this.tur_head) {
                tur.tr_precache(tur);
+               IL_PUSH(g_turrets, this);
        }
 
        entity e = find(NULL, classname, "turret_manager");
@@ -1329,7 +1332,7 @@ bool turret_initialize(entity this, Turret tur)
        this.ammo_recharge                 *= this.ticrate;
        this.solid                                      = SOLID_BBOX;
        this.takedamage                         = DAMAGE_AIM;
-       this.movetype                           = MOVETYPE_NOCLIP;
+       set_movetype(this, MOVETYPE_NOCLIP);
        this.view_ofs                           = '0 0 0';
        this.turret_firecheckfunc       = turret_firecheck;
        this.event_damage                       = turret_damage;
@@ -1349,7 +1352,7 @@ bool turret_initialize(entity this, Turret tur)
        this.tur_head.owner                     = this;
        this.tur_head.takedamage        = DAMAGE_NO;
        this.tur_head.solid                     = SOLID_NOT;
-       this.tur_head.movetype          = this.movetype;
+       set_movetype(this.tur_head, this.move_movetype);
 
        if(!this.tur_defend)
        if(this.target != "")
index 62ed2fb722dc6cca55a20d4460f391681cc058e3..ca94f2b4e1fbee55b2a219b1959d2f5bd8c9c94f 100644 (file)
@@ -16,7 +16,7 @@ void turret_targettrigger_touch(entity this, entity toucher)
 */
 spawnfunc(turret_targettrigger)
 {
-    if(!autocvar_g_turrets) { remove(this); return; }
+    if(!autocvar_g_turrets) { delete(this); return; }
 
     InitTrigger(this);
 
index a72a9f016ca35f111b661d813dde11213bcc8354..f0590f818b0c9928bdfe29f3452ed357640fa2ed 100644 (file)
@@ -133,7 +133,7 @@ void ewheel_move_idle(entity this)
         movelib_brake_simple(this, (autocvar_g_turrets_unit_ewheel_speed_stop));
 }
 
-spawnfunc(turret_ewheel) { if(!turret_initialize(this, TUR_EWHEEL)) remove(this); }
+spawnfunc(turret_ewheel) { if(!turret_initialize(this, TUR_EWHEEL)) delete(this); }
 
 METHOD(EWheel, tr_think, void(EWheel thistur, entity it))
 {
@@ -184,7 +184,7 @@ METHOD(EWheel, tr_setup, void(EWheel this, entity it))
 {
     entity e;
 
-    if(it.movetype == MOVETYPE_WALK)
+    if(it.move_movetype == MOVETYPE_WALK)
     {
         it.velocity = '0 0 0';
         it.enemy = NULL;
@@ -218,7 +218,7 @@ METHOD(EWheel, tr_setup, void(EWheel this, entity it))
     it.iscreature                              = true;
     it.teleportable                    = TELEPORT_NORMAL;
     it.damagedbycontents               = true;
-    it.movetype                                = MOVETYPE_WALK;
+    set_movetype(it, MOVETYPE_WALK);
     it.solid                                   = SOLID_SLIDEBOX;
     it.takedamage                              = DAMAGE_AIM;
     it.idle_aim                                = '0 0 0';
@@ -247,8 +247,7 @@ void ewheel_draw(entity this)
 
     fixedmakevectors(this.angles);
     setorigin(this, this.origin + this.velocity * dt);
-    this.tur_head.angles += dt * this.tur_head.move_avelocity;
-    this.angles_y = this.move_angles_y;
+    this.tur_head.angles += dt * this.tur_head.avelocity;
 
     if (this.health < 127)
     if(random() < 0.05)
@@ -258,9 +257,7 @@ void ewheel_draw(entity this)
         METHOD(EWheel, tr_setup, void(EWheel this, entity it))
         {
             it.gravity         = 1;
-            it.movetype                = MOVETYPE_BOUNCE;
-            it.move_movetype   = MOVETYPE_BOUNCE;
-            it.move_origin     = it.origin;
+            set_movetype(it, MOVETYPE_BOUNCE);
             it.move_time               = time;
             it.draw                    = ewheel_draw;
         }
index 64b32d4a7c53f6cbd34210cf958ff18f024ef6c0..20eeb7759589b5d415a386b141954ce9e1456e5b 100644 (file)
@@ -22,7 +22,7 @@ REGISTER_TURRET(FLAC, NEW(Flac));
 
 #ifdef SVQC
 
-spawnfunc(turret_flac) { if (!turret_initialize(this, TUR_FLAC)) remove(this); }
+spawnfunc(turret_flac) { if (!turret_initialize(this, TUR_FLAC)) delete(this); }
 
 METHOD(Flac, tr_setup, void(Flac this, entity it))
 {
index 3037f65d0d3c9554abb200494c193abfa9657f15..2462433374c1a155e73c55dec73bc19b7a51a65e 100644 (file)
@@ -49,7 +49,7 @@ void turret_flac_projectile_think_explode(entity this)
 #else
     RadiusDamage (this, this.realowner, this.owner.shot_dmg, this.owner.shot_dmg, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.totalfrags, NULL);
 #endif
-    remove(this);
+    delete(this);
 }
 
 #endif
index 945b35dd0a4af2839772a953bfb7d7ac2c348385..cd7dbec72d34bc62fc573875d4244eb767694c55 100644 (file)
@@ -46,7 +46,7 @@ bool turret_fusionreactor_firecheck(entity this)
     return true;
 }
 
-spawnfunc(turret_fusionreactor) { if (!turret_initialize(this, TUR_FUSIONREACTOR)) remove(this); }
+spawnfunc(turret_fusionreactor) { if (!turret_initialize(this, TUR_FUSIONREACTOR)) delete(this); }
 
 METHOD(FusionReactor, tr_attack, void(FusionReactor this, entity it))
 {
index fde81bfea02e8dd5b8acac71edb090efa8efd902..61203ddf75cb5a599a517251e76d3636f5e0311f 100644 (file)
@@ -22,7 +22,7 @@ REGISTER_TURRET(HELLION, NEW(Hellion));
 
 #ifdef SVQC
 
-spawnfunc(turret_hellion) { if (!turret_initialize(this, TUR_HELLION)) remove(this); }
+spawnfunc(turret_hellion) { if (!turret_initialize(this, TUR_HELLION)) delete(this); }
 
 METHOD(Hellion, tr_think, void(Hellion thistur, entity it))
 {
index 9e737ea6cf12e921fb2e48828b739ef382a5f0e3..bc8e581e084061c656037bd8a1a2a2dfc087d836 100644 (file)
@@ -33,7 +33,6 @@ METHOD(HellionAttack, wr_think, void(entity thiswep, entity actor, .entity weapo
         te_explosion (missile.origin);
         setthink(missile, turret_hellion_missile_think);
         missile.nextthink      = time;
-        missile.flags          = FL_PROJECTILE;
         missile.max_health   = time + 9;
         missile.tur_aimpos   = randomvec() * 128;
         missile.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
index da107922f19e5c9cc46cf0a6d3d71e93f9b9ef55..9cb60df4c63a227932d91be5bb7d5b716db05523 100644 (file)
@@ -28,7 +28,7 @@ REGISTER_TURRET(HK, NEW(HunterKiller));
 .float atime;
 #endif
 
-spawnfunc(turret_hk) { if(!turret_initialize(this, TUR_HK)) remove(this); }
+spawnfunc(turret_hk) { if(!turret_initialize(this, TUR_HK)) delete(this); }
 
 METHOD(HunterKiller, tr_think, void(HunterKiller thistur, entity it))
 {
index dc6f49cab35dcf3a4b5bfc49d1dbd1e83783206d..c2e9d6a14691dc5d5d3be5e31bd9e8bd75e87c1c 100644 (file)
@@ -31,7 +31,7 @@ METHOD(HunterKillerAttack, wr_think, void(entity thiswep, entity actor, .entity
 
         setthink(missile, turret_hk_missile_think);
         missile.nextthink = time + 0.25;
-        missile.movetype = MOVETYPE_BOUNCEMISSILE;
+        set_movetype(missile, MOVETYPE_BOUNCEMISSILE);
         missile.velocity = actor.tur_shotdir_updated * (actor.shot_speed * 0.75);
         missile.angles = vectoangles(missile.velocity);
         missile.cnt = time + 30;
@@ -207,7 +207,7 @@ void turret_hk_missile_think(entity this)
     {
         this.cnt = time + 0.25;
         this.nextthink = 0;
-        this.movetype           = MOVETYPE_BOUNCE;
+        set_movetype(this, MOVETYPE_BOUNCE);
         return;
     }
 
index 5dac49efc785a3d76f8236659f39bd4ae22f9f9c..8addd9542802a4c07cf80c750187cada65fafcdf 100644 (file)
@@ -22,7 +22,7 @@ REGISTER_TURRET(MACHINEGUN, NEW(MachineGunTurret));
 
 #ifdef SVQC
 
-spawnfunc(turret_machinegun) { if (!turret_initialize(this, TUR_MACHINEGUN)) remove(this); }
+spawnfunc(turret_machinegun) { if (!turret_initialize(this, TUR_MACHINEGUN)) delete(this); }
 
 METHOD(MachineGunTurret, tr_setup, void(MachineGunTurret this, entity it))
 {
index bce27118a2ce34dc9ba605aa47d1adf78ea416c2..0d6e9e9e901814599a608b5a8fd107d45c62e1e5 100644 (file)
@@ -22,7 +22,7 @@ REGISTER_TURRET(MLRS, NEW(MLRSTurret));
 
 #ifdef SVQC
 
-spawnfunc(turret_mlrs) { if (!turret_initialize(this, TUR_MLRS)) remove(this); }
+spawnfunc(turret_mlrs) { if (!turret_initialize(this, TUR_MLRS)) delete(this); }
 
 METHOD(MLRSTurret, tr_think, void(MLRSTurret thistur, entity it))
 {
index f604b0466953707f98a59082ae7b0258cc06e665..7c5d336212694b662262ee9da99372b2857d6ace 100644 (file)
@@ -22,7 +22,7 @@ REGISTER_TURRET(PHASER, NEW(PhaserTurret));
 
 #ifdef SVQC
 
-spawnfunc(turret_phaser) { if (!turret_initialize(this, TUR_PHASER)) remove(this); }
+spawnfunc(turret_phaser) { if (!turret_initialize(this, TUR_PHASER)) delete(this); }
 
 .int fireflag;
 
index ea48a6479024734fd4a425f044c37548d40118e9..0ddfd153d000c72d12544a3a8bcd1ae8aaa2ed93 100644 (file)
@@ -33,7 +33,7 @@ METHOD(PhaserTurretAttack, wr_think, void(entity thiswep, entity actor, .entity
         beam.owner = actor;
         beam.shot_dmg = actor.shot_dmg / (actor.shot_speed / beam.ticrate);
         beam.scale = actor.target_range / 256;
-        beam.movetype = MOVETYPE_NONE;
+        set_movetype(beam, MOVETYPE_NONE);
         beam.enemy = actor.enemy;
         beam.bot_dodge = true;
         beam.bot_dodgerating = beam.shot_dmg;
@@ -60,7 +60,7 @@ void beam_think(entity this)
         this.owner.fireflag = 2;
         this.owner.tur_head.frame = 10;
         sound (this, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM);
-        remove(this);
+        delete(this);
         return;
     }
 
index 7b71ccfc7fa78be080d7b1fa1dba7f189550111d..82aa1abe67cbf198bfcd51c58e97af98741d5174 100644 (file)
@@ -22,7 +22,7 @@ REGISTER_TURRET(PLASMA, NEW(PlasmaTurret));
 
 #ifdef SVQC
 
-spawnfunc(turret_plasma) { if (!turret_initialize(this, TUR_PLASMA)) remove(this); }
+spawnfunc(turret_plasma) { if (!turret_initialize(this, TUR_PLASMA)) delete(this); }
 
 METHOD(PlasmaTurret, tr_attack, void(PlasmaTurret this, entity it))
 {
index 86df15059bfc136ae83102ac93ed6cae39dbcbc1..9430bc69211147c6fb125330c2b9976c4c7c3d18 100644 (file)
@@ -28,7 +28,7 @@ REGISTER_TURRET(PLASMA_DUAL, NEW(DualPlasmaTurret));
 
 #ifdef SVQC
 
-spawnfunc(turret_plasma_dual) { if (!turret_initialize(this, TUR_PLASMA_DUAL)) remove(this); }
+spawnfunc(turret_plasma_dual) { if (!turret_initialize(this, TUR_PLASMA_DUAL)) delete(this); }
 
 METHOD(DualPlasmaTurret, tr_attack, void(DualPlasmaTurret thistur, entity it))
 {
index cdc6ba3ceb95a7d4fba543e26a0532d01dcdda4d..b0755f32b57d03e0371bb13734df96ca22b41886 100644 (file)
@@ -22,7 +22,7 @@ REGISTER_TURRET(TESLA, NEW(TeslaCoil));
 
 #ifdef SVQC
 
-spawnfunc(turret_tesla) { if (!turret_initialize(this, TUR_TESLA)) remove(this); }
+spawnfunc(turret_tesla) { if (!turret_initialize(this, TUR_TESLA)) delete(this); }
 
 METHOD(TeslaCoil, tr_think, void(TeslaCoil thistur, entity it))
 {
index e21cd498f71738dc66921e209e83b28282ebbb55..4fe5109d7d37ed368bdfd96e597f12e62b12eecf 100644 (file)
@@ -27,7 +27,7 @@ METHOD(TeslaCoilTurretAttack, wr_think, void(entity thiswep, entity actor, .enti
         actor.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK;
 
         entity t = toast(actor, e,r,d);
-        remove(e);
+        delete(e);
 
         if (t == NULL) return;
 
@@ -42,12 +42,10 @@ METHOD(TeslaCoilTurretAttack, wr_think, void(entity thiswep, entity actor, .enti
 
         }
 
-        e = findchainfloat(railgunhit, 1);
-        while (e) {
-            e.railgunhit = 0;
-            e = e.chain;
-        }
-
+        FOREACH_ENTITY_FLOAT(railgunhit, 1,
+        {
+            it.railgunhit = 0;
+        });
     }
 }
 
index 0294952767e68221b164ac42d258a3cf39428894..ff2ce88c7d8b8cd19553707e4c3d56333276bac8 100644 (file)
@@ -100,7 +100,7 @@ void walker_setnoanim(entity this)
 void walker_rocket_explode(entity this)
 {
     RadiusDamage (this, this.owner, (autocvar_g_turrets_unit_walker_rocket_damage), 0, (autocvar_g_turrets_unit_walker_rocket_radius), this, NULL, (autocvar_g_turrets_unit_walker_rocket_force), DEATH_TURRET_WALK_ROCKET.m_id, NULL);
-    remove (this);
+    delete (this);
 }
 
 void walker_rocket_touch(entity this, entity toucher)
@@ -255,11 +255,12 @@ void walker_fire_rocket(entity this, vector org)
     rocket.event_damage           = walker_rocket_damage;
 
     rocket.nextthink             = time;
-    rocket.movetype               = MOVETYPE_FLY;
+    set_movetype(rocket, MOVETYPE_FLY);
     rocket.velocity               = normalize((v_forward + v_up * 0.5) + (randomvec() * 0.2)) * (autocvar_g_turrets_unit_walker_rocket_speed);
     rocket.angles                       = vectoangles(rocket.velocity);
     settouch(rocket, walker_rocket_touch);
-    rocket.flags                         = FL_PROJECTILE;
+    rocket.flags = FL_PROJECTILE;
+    IL_PUSH(g_projectiles, rocket);
     rocket.solid                         = SOLID_BBOX;
     rocket.max_health           = time + 9;
     rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
@@ -344,7 +345,7 @@ void walker_move_path(entity this)
 #endif
 }
 
-spawnfunc(turret_walker) { if(!turret_initialize(this, TUR_WALKER)) remove(this); }
+spawnfunc(turret_walker) { if(!turret_initialize(this, TUR_WALKER)) delete(this); }
 
 METHOD(WalkerTurret, tr_think, void(WalkerTurret thistur, entity it))
 {
@@ -571,7 +572,7 @@ METHOD(WalkerTurret, tr_setup, void(WalkerTurret this, entity it))
     entity e;
 
     // Respawn is called & first spawn to, to set team. need to make sure we do not move the initial spawn.
-    if(it.movetype == MOVETYPE_WALK)
+    if(it.move_movetype == MOVETYPE_WALK)
     {
         if(it.pos1)
             setorigin(it, it.pos1);
@@ -590,7 +591,7 @@ METHOD(WalkerTurret, tr_setup, void(WalkerTurret this, entity it))
     it.damagedbycontents = true;
     it.solid = SOLID_SLIDEBOX;
     it.takedamage = DAMAGE_AIM;
-    if(it.movetype != MOVETYPE_WALK)
+    if(it.move_movetype != MOVETYPE_WALK)
     {
         setorigin(it, it.origin);
         tracebox(it.origin + '0 0 128', it.mins, it.maxs, it.origin - '0 0 10000', MOVE_NORMAL, it);
@@ -598,7 +599,7 @@ METHOD(WalkerTurret, tr_setup, void(WalkerTurret this, entity it))
         it.pos1 = it.origin;
         it.pos2 = it.angles;
     }
-    it.movetype = MOVETYPE_WALK;
+    set_movetype(it, MOVETYPE_WALK);
     it.idle_aim = '0 0 0';
     it.turret_firecheckfunc = walker_firecheck;
 
@@ -642,8 +643,7 @@ void walker_draw(entity this)
     fixedmakevectors(this.angles);
     movelib_groundalign4point(this, 300, 100, 0.25, 45);
     setorigin(this, this.origin + this.velocity * dt);
-    this.tur_head.angles += dt * this.tur_head.move_avelocity;
-    this.angles_y = this.move_angles_y;
+    this.tur_head.angles += dt * this.tur_head.avelocity;
 
     if (this.health < 127)
     if(random() < 0.15)
@@ -653,9 +653,7 @@ void walker_draw(entity this)
         METHOD(WalkerTurret, tr_setup, void(WalkerTurret this, entity it))
         {
             it.gravity         = 1;
-            it.movetype                = MOVETYPE_BOUNCE;
-            it.move_movetype   = MOVETYPE_BOUNCE;
-            it.move_origin     = it.origin;
+            set_movetype(it, MOVETYPE_BOUNCE);
             it.move_time               = time;
             it.draw                    = walker_draw;
         }
index 4928262f2f4ef85c355e875c7a1c2097a1bdd58d..2c33c165a7fa3a2acf39e375a46c17f393969fe0 100644 (file)
@@ -115,7 +115,7 @@ void mark_error(vector where,float lifetime)
        entity err = new(error_marker);
        setmodel(err, MDL_MARKER);
        setorigin(err, where);
-       err.movetype = MOVETYPE_NONE;
+       set_movetype(err, MOVETYPE_NONE);
        setthink(err, marker_think);
        err.nextthink = time;
        err.skin = 0;
@@ -128,7 +128,7 @@ void mark_info(vector where,float lifetime)
        entity err = spawn(info_marker);
        setmodel(err, MDL_MARKER);
        setorigin(err, where);
-       err.movetype = MOVETYPE_NONE;
+       set_movetype(err, MOVETYPE_NONE);
        setthink(err, marker_think);
        err.nextthink = time;
        err.skin = 1;
@@ -141,7 +141,7 @@ entity mark_misc(vector where,float lifetime)
        entity err = spawn(mark_misc);
        setmodel(err, MDL_MARKER);
        setorigin(err, where);
-       err.movetype = MOVETYPE_NONE;
+       set_movetype(err, MOVETYPE_NONE);
        setthink(err, marker_think);
        err.nextthink = time;
        err.skin = 3;
@@ -167,7 +167,7 @@ void paint_target(entity onwho, float f_size, vector v_color, float f_time)
        //setattachment(e,onwho,"");
        setorigin(e, onwho.origin + '0 0 1');
        e.alpha = 0.15;
-       e.movetype = MOVETYPE_FLY;
+       set_movetype(e, MOVETYPE_FLY);
 
        e.velocity = (v_color * 32); // + '0 0 1' * 64;
 
@@ -186,7 +186,7 @@ void paint_target2(entity onwho, float f_size, vector v_color, float f_time)
 
        setorigin(e, onwho.origin + '0 0 1');
        e.alpha = 0.15;
-       e.movetype = MOVETYPE_FLY;
+       set_movetype(e, MOVETYPE_FLY);
 
        e.velocity = (v_color * 32); // + '0 0 1' * 64;
        e.avelocity_x = -128;
@@ -203,7 +203,7 @@ void paint_target3(vector where, float f_size, vector v_color, float f_time)
        e.scale = (f_size/512);
        setsize(e, '0 0 0', '0 0 0');
        setorigin(e, where + '0 0 1');
-       e.movetype = MOVETYPE_NONE;
+       set_movetype(e, MOVETYPE_NONE);
        e.velocity = '0 0 0';
        e.colormod = v_color;
        SUB_SetFade(e,time,f_time);
index d04fdecd68dc791f05a8fe93878ed0e6185822b4..70ecc3340e0b2fc3681ea4ab20a1af6d88f37bbb 100644 (file)
@@ -635,7 +635,7 @@ int cvar_settemp_restore()
                        cvar_set(it.netname, it.message);
                        strunzone(it.netname);
                        strunzone(it.message);
-                       remove(it);
+                       delete(it);
                        ++j;
                }
                else
@@ -649,7 +649,7 @@ int cvar_settemp_restore()
                if(cvar_type(e.netname))
                {
                        cvar_set(e.netname, e.message);
-                       remove(e);
+                       delete(e);
                        ++j;
                }
                else
index 57f5990bb77a3915f9296c4f530074dad7485af8..e08490976d15b253e303441933f2b122c69cac4c 100644 (file)
@@ -33,7 +33,7 @@ void AuxiliaryXhair_Draw2D(entity this)
                return;
 
        vector size = draw_getimagesize(this.axh_image) * autocvar_cl_vehicles_crosshair_size;
-       vector pos = project_3d_to_2d(this.move_origin) - 0.5 * size;
+       vector pos = project_3d_to_2d(this.origin) - 0.5 * size;
 
        if (!(pos.z < 0 || pos.x < 0 || pos.y < 0 || pos.x > vid_conwidth || pos.y > vid_conheight))
        {
@@ -48,12 +48,14 @@ void AuxiliaryXhair_Draw2D(entity this)
 
 NET_HANDLE(ENT_CLIENT_AUXILIARYXHAIR, bool isnew)
 {
+       int sf = ReadByte();
+
        int axh_id      = bound(0, ReadByte(), MAX_AXH);
-       entity axh              = AuxiliaryXhair[axh_id];
+       entity axh = AuxiliaryXhair[axh_id];
 
-       if(axh == NULL || wasfreed(axh))  // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
+       if(axh == NULL || wasfreed(axh))
        {
-               axh                                     = spawn();
+               axh                                     = new(auxiliary_crosshair);
                axh.draw2d                      = func_null;
                axh.drawmask            = MASK_NORMAL;
                axh.axh_drawflag        = DRAWFLAG_ADDITIVE;
@@ -61,14 +63,23 @@ NET_HANDLE(ENT_CLIENT_AUXILIARYXHAIR, bool isnew)
                axh.axh_image           = vCROSS_HINT;
                axh.alpha                       = 1;
                AuxiliaryXhair[axh_id] = axh;
+               IL_PUSH(g_drawables_2d, axh);
+       }
+
+       if(sf & 2)
+       {
+               axh.origin_x = ReadCoord();
+               axh.origin_y = ReadCoord();
+               axh.origin_z = ReadCoord();
+       }
+
+       if(sf & 4)
+       {
+               axh.colormod_x = ReadByte() / 255;
+               axh.colormod_y = ReadByte() / 255;
+               axh.colormod_z = ReadByte() / 255;
        }
 
-       axh.move_origin_x       = ReadCoord();
-       axh.move_origin_y       = ReadCoord();
-       axh.move_origin_z       = ReadCoord();
-       axh.colormod_x          = ReadByte() / 255;
-       axh.colormod_y          = ReadByte() / 255;
-       axh.colormod_z          = ReadByte() / 255;
        axh.cnt                         = time;
        axh.draw2d                      = AuxiliaryXhair_Draw2D;
        return true;
@@ -80,10 +91,22 @@ NET_HANDLE(TE_CSQC_VEHICLESETUP, bool isnew)
        return = true;
 
        // hud_id == 0 means we exited a vehicle, so stop alarm sound/s
-       if(hud_id == 0)
+       // note: HUD_NORMAL is set to 0 currently too, but we'll check both just in case
+       if(hud_id == 0 || hud_id == HUD_NORMAL)
        {
                sound(this, CH_TRIGGER_SINGLE, SND_Null, VOL_BASEVOICE, ATTEN_NONE);
                sound(this, CH_PAIN_SINGLE, SND_Null, VOL_BASEVOICE, ATTEN_NONE);
+
+               for(int i = 0; i < MAX_AXH; ++i)
+               {
+                       entity axh = AuxiliaryXhair[i];
+
+                       if(axh != NULL && !wasfreed(axh))
+                       {
+                               AuxiliaryXhair[i] = NULL;
+                               delete(axh);
+                       }
+               }
                return;
        }
 
@@ -93,7 +116,7 @@ NET_HANDLE(TE_CSQC_VEHICLESETUP, bool isnew)
                entity axh = AuxiliaryXhair[i];
 
                if(axh != NULL && !wasfreed(axh))  // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
-                       remove(axh);
+                       delete(axh);
 
                axh              = spawn();
                axh.draw2d       = func_null;
@@ -103,6 +126,7 @@ NET_HANDLE(TE_CSQC_VEHICLESETUP, bool isnew)
                axh.axh_image    = vCROSS_HINT;
                axh.alpha        = 1;
                AuxiliaryXhair[i] = axh;
+               IL_PUSH(g_drawables_2d, axh);
        }
 
        if(hud_id == HUD_BUMBLEBEE_GUN)
@@ -163,7 +187,7 @@ void Vehicles_drawHUD(
                tmpPos.x = vehicleHud_Pos.x + vehicleHud_Size.x * (96/256) - tmpSize.x;
                tmpPos.y = vehicleHud_Pos.y;
                tmpSize = '1 1 1' * hud_fontsize;
-               drawstring(tmpPos, sprintf(_("Press %s"), getcommandkey("dropweapon", "dropweapon")), tmpSize, '1 0 0' + '0 1 1' * tmpblinkValue, hudAlpha, DRAWFLAG_NORMAL);
+               drawstring(tmpPos, sprintf(_("Press %s"), getcommandkey(_("drop weapon"), "dropweapon")), tmpSize, '1 0 0' + '0 1 1' * tmpblinkValue, hudAlpha, DRAWFLAG_NORMAL);
        }
 
        // Model
index fc2a06241310e21b495049d51996fe901ef4dafa..9f02cf21bcecfd5992ca151f81613d5ef6006416 100644 (file)
@@ -3,20 +3,30 @@
 bool SendAuxiliaryXhair(entity this, entity to, int sf)
 {
        WriteHeader(MSG_ENTITY, ENT_CLIENT_AUXILIARYXHAIR);
+       WriteByte(MSG_ENTITY, sf);
 
        WriteByte(MSG_ENTITY, this.cnt);
 
-       WriteCoord(MSG_ENTITY, this.origin_x);
-       WriteCoord(MSG_ENTITY, this.origin_y);
-       WriteCoord(MSG_ENTITY, this.origin_z);
+       if(sf & 2)
+       {
+               WriteCoord(MSG_ENTITY, this.origin_x);
+               WriteCoord(MSG_ENTITY, this.origin_y);
+               WriteCoord(MSG_ENTITY, this.origin_z);
+       }
 
-       WriteByte(MSG_ENTITY, rint(this.colormod_x * 255));
-       WriteByte(MSG_ENTITY, rint(this.colormod_y * 255));
-       WriteByte(MSG_ENTITY, rint(this.colormod_z * 255));
+       if(sf & 4)
+       {
+               WriteByte(MSG_ENTITY, rint(this.colormod_x * 255));
+               WriteByte(MSG_ENTITY, rint(this.colormod_y * 255));
+               WriteByte(MSG_ENTITY, rint(this.colormod_z * 255));
+       }
 
        return true;
 }
 
+.vector axh_prevorigin;
+.vector axh_prevcolors;
+
 void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, int axh_id)
 {
        if(!IS_REAL_CLIENT(own))
@@ -27,17 +37,26 @@ void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, int axh_id)
 
        if(axh == NULL || wasfreed(axh))  // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist? Mario: because of sloppy code like this)
        {
-               axh                                      = spawn();
-               axh.cnt                          = axh_id;
-               axh.drawonlytoclient    = own;
-               axh.owner                          = own;
+               axh = new(auxiliary_xhair);
+               axh.cnt = axh_id;
+               axh.drawonlytoclient = own;
+               axh.owner = own;
                Net_LinkEntity(axh, false, 0, SendAuxiliaryXhair);
        }
 
-       setorigin(axh, loc);
-       axh.colormod                    = clr;
-       axh.SendFlags              = 0x01;
-       own.(AuxiliaryXhair[axh_id]) = axh;
+       if(loc != axh.axh_prevorigin)
+       {
+               setorigin(axh, loc);
+               axh.SendFlags |= 2;
+       }
+
+       if(clr != axh.axh_prevcolors)
+       {
+               axh.colormod = clr;
+               axh.SendFlags |= 4;
+       }
+
+       own.(AuxiliaryXhair[axh_id]) = axh; // set it anyway...?
 }
 
 void CSQCVehicleSetup(entity own, int vehicle_id)
@@ -195,7 +214,7 @@ void vehicles_projectile_explode(entity this, entity toucher)
        this.event_damage = func_null;
        RadiusDamage (this, this.realowner, this.shot_dmg, 0, this.shot_radius, this, NULL, this.shot_force, this.totalfrags, toucher);
 
-       remove (this);
+       delete (this);
 }
 
 void vehicles_projectile_explode_think(entity this)
@@ -227,8 +246,9 @@ entity vehicles_projectile(entity this, string _mzlfx, Sound _mzlsound,
        proj.shot_force    = _force;
        proj.totalfrags    = _deahtype;
        proj.solid                      = SOLID_BBOX;
-       proj.movetype            = MOVETYPE_FLYMISSILE;
-       proj.flags                      = FL_PROJECTILE;
+       set_movetype(proj, MOVETYPE_FLYMISSILE);
+       proj.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, proj);
        proj.bot_dodge          = true;
        proj.bot_dodgerating  = _dmg;
        proj.velocity            = _vel;
@@ -246,7 +266,7 @@ entity vehicles_projectile(entity this, string _mzlfx, Sound _mzlsound,
                proj.health                = _health;
        }
        else
-               proj.flags                 = FL_PROJECTILE | FL_NOTARGET;
+               proj.flags |= FL_NOTARGET;
 
        if(_mzlsound != SND_Null)
                sound (this, CH_WEAPON_A, _mzlsound, VOL_BASE, ATTEN_NORM);
@@ -266,7 +286,7 @@ void vehicles_gib_explode(entity this)
        sound (this, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
        Send_Effect(EFFECT_EXPLOSION_SMALL, randomvec() * 80 + (this.origin + '0 0 100'), '0 0 0', 1);
        Send_Effect(EFFECT_EXPLOSION_SMALL, this.wp00.origin + '0 0 64', '0 0 0', 1);
-       remove(this);
+       delete(this);
 }
 
 void vehicles_gib_touch(entity this, entity toucher)
@@ -278,7 +298,7 @@ void vehicles_gib_think(entity this)
 {
        this.alpha -= 0.1;
        if(this.cnt >= time)
-               remove(this);
+               delete(this);
        else
                this.nextthink = time + 0.1;
 }
@@ -290,7 +310,7 @@ entity vehicle_tossgib(entity this, entity _template, vector _vel, string _tag,
        vector org = gettaginfo(this, gettagindex(this, _tag));
        setorigin(_gib, org);
        _gib.velocity = _vel;
-       _gib.movetype = MOVETYPE_TOSS;
+       set_movetype(_gib, MOVETYPE_TOSS);
        _gib.solid = SOLID_CORPSE;
        _gib.colormod = '-0.5 -0.5 -0.5';
        _gib.effects = EF_LOWPRECISION;
@@ -438,7 +458,7 @@ void vehicles_return(entity this)
        if(this.waypointsprite_attached)
                WaypointSprite_Kill(this.waypointsprite_attached);
 
-       remove(this);
+       delete(this);
 }
 
 void vehicles_showwp_goaway(entity this)
@@ -446,7 +466,7 @@ void vehicles_showwp_goaway(entity this)
        if(this.waypointsprite_attached)
                WaypointSprite_Kill(this.waypointsprite_attached);
 
-       remove(this);
+       delete(this);
 }
 
 void vehicles_showwp(entity this)
@@ -777,7 +797,7 @@ void vehicles_exit(entity vehic, bool eject)
 
                player.takedamage               = DAMAGE_AIM;
                player.solid                    = SOLID_SLIDEBOX;
-               player.movetype         = MOVETYPE_WALK;
+               set_movetype(player, MOVETYPE_WALK);
                player.effects             &= ~EF_NODRAW;
                player.teleportable     = TELEPORT_NORMAL;
                player.alpha                    = 1;
@@ -947,7 +967,8 @@ void vehicles_enter(entity pl, entity veh)
        pl.angles                       = veh.angles;
        pl.takedamage           = DAMAGE_NO;
        pl.solid                        = SOLID_NOT;
-       pl.movetype                     = MOVETYPE_NOCLIP;
+       pl.disableclientprediction = 1; // physics is no longer run, so this won't be reset
+       set_movetype(pl, MOVETYPE_NOCLIP);
        pl.teleportable         = false;
        pl.alpha                        = -1;
        pl.event_damage         = func_null;
@@ -1051,7 +1072,7 @@ void vehicles_spawn(entity this)
        this.iscreature                 = true;
        this.teleportable               = false; // no teleporting for vehicles, too buggy
        this.damagedbycontents  = true;
-       this.movetype                   = MOVETYPE_WALK;
+       set_movetype(this, MOVETYPE_WALK);
        this.solid                              = SOLID_SLIDEBOX;
        this.takedamage                 = DAMAGE_AIM;
        this.deadflag                   = DEAD_NO;
@@ -1095,7 +1116,10 @@ bool vehicle_initialize(entity this, Vehicle info, bool nodrop)
                return false;
 
        if(!this.tur_head)
+       {
                info.vr_precache(info);
+               IL_PUSH(g_vehicles, this);
+       }
 
        if(this.targetname && this.targetname != "")
        {
index a0c0dd2eccfd562e45f7fa10594361e7b356701e..91964a9d598cc6d81ab23c97bf7565ea58a5019a 100644 (file)
@@ -46,6 +46,7 @@ float autocvar_g_vehicle_bumblebee_turnspeed = 120;
 float autocvar_g_vehicle_bumblebee_pitchspeed = 60;
 float autocvar_g_vehicle_bumblebee_pitchlimit = 60;
 float autocvar_g_vehicle_bumblebee_friction = 0.5;
+bool autocvar_g_vehicle_bumblebee_swim = false;
 
 float autocvar_g_vehicle_bumblebee_energy = 500;
 float autocvar_g_vehicle_bumblebee_energy_regen = 50;
@@ -138,7 +139,7 @@ bool bumblebee_gunner_frame(entity this)
                        gun.enemy = NULL;
 
                if(trace_ent)
-                       if(trace_ent.movetype)
+                       if(trace_ent.move_movetype)
                                if(trace_ent.takedamage)
                                        if(!IS_DEAD(trace_ent) && !STAT(FROZEN, trace_ent))
                                        {
@@ -156,7 +157,7 @@ bool bumblebee_gunner_frame(entity this)
 
                vector vf = real_origin(gun.enemy);
                vector _vel = gun.enemy.velocity;
-               if(gun.enemy.movetype == MOVETYPE_WALK)
+               if(gun.enemy.move_movetype == MOVETYPE_WALK)
                        _vel.z *= 0.1;
 
 
@@ -256,7 +257,7 @@ void bumblebee_gunner_exit(entity this, int _exitflag)
 
        player.takedamage     = DAMAGE_AIM;
        player.solid          = SOLID_SLIDEBOX;
-       player.movetype       = MOVETYPE_WALK;
+       set_movetype(player, MOVETYPE_WALK);
        player.effects       &= ~EF_NODRAW;
        player.alpha          = 1;
        player.PlayerPhysplug = func_null;
@@ -319,7 +320,7 @@ bool bumblebee_gunner_enter(entity this, entity player)
        player.takedamage               = DAMAGE_NO;
        player.solid                    = SOLID_NOT;
        player.alpha                    = -1;
-       player.movetype                 = MOVETYPE_NOCLIP;
+       set_movetype(player, MOVETYPE_NOCLIP);
        player.event_damage     = func_null;
        player.view_ofs                 = '0 0 0';
        player.hud                              = gunner.hud;
@@ -330,7 +331,7 @@ bool bumblebee_gunner_enter(entity this, entity player)
        player.vehicle_reload1  = vehic.vehicle_reload1;
        player.vehicle_reload2  = vehic.vehicle_reload2;
        player.vehicle_energy   = vehic.vehicle_energy;
-       player.flags               &= ~FL_ONGROUND;
+       UNSET_ONGROUND(player);
 
        RemoveGrapplingHook(player);
 
@@ -510,7 +511,7 @@ bool bumblebee_pilot_frame(entity this)
                        vehic.tur_head.enemy = NULL;
 
                if(trace_ent)
-               if(trace_ent.movetype)
+               if(trace_ent.move_movetype)
                if(trace_ent.takedamage)
                if(!IS_DEAD(trace_ent) && !STAT(FROZEN, trace_ent))
                {
@@ -660,7 +661,7 @@ void bumblebee_exit(entity this, int eject)
                this.nextthink  = time;
        }
 
-       this.movetype = MOVETYPE_TOSS;
+       set_movetype(this, MOVETYPE_TOSS);
 
        if(!this.owner)
                return;
@@ -700,7 +701,7 @@ void bumblebee_blowup(entity this)
        if(this.owner.deadflag == DEAD_DYING)
                this.owner.deadflag = DEAD_DEAD;
 
-       remove(this);
+       delete(this);
 }
 
 void bumblebee_dead_touch(entity this, entity toucher)
@@ -724,8 +725,8 @@ void bumblebee_diethink(entity this)
 
 spawnfunc(vehicle_bumblebee)
 {
-       if(!autocvar_g_vehicle_bumblebee) { remove(this); return; }
-       if(!vehicle_initialize(this, VEH_BUMBLEBEE, false)) { remove(this); return; }
+       if(!autocvar_g_vehicle_bumblebee) { delete(this); return; }
+       if(!vehicle_initialize(this, VEH_BUMBLEBEE, false)) { delete(this); return; }
 }
 
 METHOD(Bumblebee, vr_impact, void(Bumblebee thisveh, entity instance))
@@ -737,7 +738,7 @@ METHOD(Bumblebee, vr_enter, void(Bumblebee thisveh, entity instance))
 {
     settouch(instance, bumblebee_touch);
     instance.nextthink = 0;
-    instance.movetype = MOVETYPE_BOUNCEMISSILE;
+    set_movetype(instance, MOVETYPE_BOUNCEMISSILE);
 }
 METHOD(Bumblebee, vr_gunner_enter, void(Bumblebee thisveh, entity instance, entity actor))
 {
@@ -824,7 +825,7 @@ METHOD(Bumblebee, vr_death, void(Bumblebee thisveh, entity instance))
     instance.solid                     = SOLID_NOT;
     instance.takedamage                = DAMAGE_NO;
     instance.deadflag          = DEAD_DYING;
-    instance.movetype          = MOVETYPE_NONE;
+    set_movetype(instance, MOVETYPE_NONE);
     instance.effects           = EF_NODRAW;
     instance.colormod          = '0 0 0';
     instance.avelocity         = '0 0 0';
@@ -901,10 +902,13 @@ METHOD(Bumblebee, vr_spawn, void(Bumblebee thisveh, entity instance))
         }
     }
 
+    if(!autocvar_g_vehicle_bumblebee_swim)
+       instance.dphitcontentsmask |= DPCONTENTS_LIQUIDSMASK;
+
     instance.vehicle_health = autocvar_g_vehicle_bumblebee_health;
     instance.vehicle_shield = autocvar_g_vehicle_bumblebee_shield;
     instance.solid = SOLID_BBOX;
-    instance.movetype = MOVETYPE_TOSS;
+    set_movetype(instance, MOVETYPE_TOSS);
     instance.damageforcescale = 0.025;
 
     instance.PlayerPhysplug = bumblebee_pilot_frame;
index b2e838f944b92ccec09440b3e37a6b3781e4c762..9cb8b74c2b5ed03c8b1b083c26f7640dfb614e3e 100644 (file)
@@ -50,6 +50,8 @@ bool bumble_raygun_send(entity this, entity to, float sf)
 
 void bumble_raygun_draw(entity this);
 
+.vector bumble_origin;
+
 NET_HANDLE(ENT_CLIENT_BUMBLE_RAYGUN, bool isnew)
 {
     int sf = ReadByte();
@@ -69,6 +71,7 @@ NET_HANDLE(ENT_CLIENT_BUMBLE_RAYGUN, bool isnew)
         this.lip = particleeffectnum(EFFECT_BUMBLEBEE_HEAL_IMPACT);
 
         this.draw = bumble_raygun_draw;
+        if (isnew) IL_PUSH(g_drawables, this);
     }
 
 
@@ -82,9 +85,9 @@ NET_HANDLE(ENT_CLIENT_BUMBLE_RAYGUN, bool isnew)
 
     if(sf & BRG_END)
     {
-        this.move_origin_x = ReadCoord();
-        this.move_origin_y = ReadCoord();
-        this.move_origin_z = ReadCoord();
+        this.bumble_origin_x = ReadCoord();
+        this.bumble_origin_y = ReadCoord();
+        this.bumble_origin_z = ReadCoord();
     }
     return true;
 }
@@ -96,13 +99,13 @@ void bumble_raygun_draw(entity this)
     vector _dir;
     vector _vtmp1, _vtmp2;
 
-    _len = vlen(this.origin - this.move_origin);
-    _dir = normalize(this.move_origin - this.origin);
+    _len = vlen(this.origin - this.bumble_origin);
+    _dir = normalize(this.bumble_origin - this.origin);
 
     if(this.bumble_raygun_nextdraw < time)
     {
         boxparticles(particleeffectnum(Effects_from(this.traileffect)), this, this.origin, this.origin + _dir * -64, _dir * -_len , _dir * -_len, 1, PARTICLES_USEALPHA);
-        boxparticles(this.lip, this, this.move_origin, this.move_origin + _dir * -64, _dir * -200 , _dir * -200, 1, PARTICLES_USEALPHA);
+        boxparticles(this.lip, this, this.bumble_origin, this.bumble_origin + _dir * -64, _dir * -200 , _dir * -200, 1, PARTICLES_USEALPHA);
         this.bumble_raygun_nextdraw = time + 0.1;
     }
 
@@ -124,7 +127,7 @@ void bumble_raygun_draw(entity this)
         _vtmp1 += randomvec() * (_len * 0.2) * (frametime * 10);     //this.raygun_l3;
         Draw_CylindricLine(_vtmp2, _vtmp1, sz, "gfx/colors/white.tga", 1, 1, this.colormod, al, df, view_origin);
 
-        Draw_CylindricLine(_vtmp1, this.move_origin +  randomvec() * 32, sz, "gfx/colors/white.tga", 1, 1, this.colormod, al, df, view_origin);
+        Draw_CylindricLine(_vtmp1, this.bumble_origin +  randomvec() * 32, sz, "gfx/colors/white.tga", 1, 1, this.colormod, al, df, view_origin);
     }
 }
 
index 334320b3214542c438cbbae8f76c8491d3f7c9d4..367e8b7e41bafb870e4d4ca8eeba2c55ec72cc30 100644 (file)
@@ -439,7 +439,7 @@ void racer_exit(entity this, int eject)
 
        setthink(this, racer_think);
        this.nextthink  = time;
-       this.movetype   = MOVETYPE_BOUNCE;
+       set_movetype(this, MOVETYPE_BOUNCE);
        sound (this.tur_head, CH_TRIGGER_SINGLE, SND_Null, VOL_VEHICLEENGINE, ATTEN_NORM);
 
        if(!this.owner)
@@ -490,7 +490,7 @@ void racer_blowup(entity this)
 
        this.nextthink  = time + autocvar_g_vehicle_racer_respawntime;
        setthink(this, vehicles_spawn);
-       this.movetype   = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        this.effects    = EF_NODRAW;
        this.solid = SOLID_NOT;
 
@@ -521,47 +521,12 @@ void racer_deadtouch(entity this, entity toucher)
 
 spawnfunc(vehicle_racer)
 {
-       if(!autocvar_g_vehicle_racer) { remove(this); return; }
-       if(!vehicle_initialize(this, VEH_RACER, false)) { remove(this); return; }
+       if(!autocvar_g_vehicle_racer) { delete(this); return; }
+       if(!vehicle_initialize(this, VEH_RACER, false)) { delete(this); return; }
 }
 
 #endif // SVQC
 
-#ifdef CSQC
-#if 0
-void racer_draw(entity this)
-{
-       float pushdeltatime = time - this.lastpushtime;
-       if (pushdeltatime > 0.15) pushdeltatime = 0;
-       this.lastpushtime = time;
-       if(!pushdeltatime) return;
-
-       tracebox(this.move_origin, this.mins, this.maxs, this.move_origin - ('0 0 1' * STAT(VEH_RACER_SPRINGLENGTH)), MOVE_NOMONSTERS, this);
-
-       vector df = this.move_velocity * -STAT(VEH_RACER_FRICTION);
-       df_z += (1 - trace_fraction) * STAT(VEH_RACER_HOVERPOWER) + sin(time * 2) * (STAT(VEH_RACER_SPRINGLENGTH) * 2);
-
-       float forced = STAT(VEH_RACER_UPFORCEDAMPER);
-
-       int cont = pointcontents(this.move_origin - '0 0 64');
-       if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
-       {
-               forced = STAT(VEH_RACER_WATER_UPFORCEDAMPER);
-               this.move_velocity_z += 200;
-       }
-
-       this.move_velocity += df * pushdeltatime;
-       if(this.move_velocity_z > 0)
-               this.move_velocity_z *= 1 - forced * pushdeltatime;
-
-       this.move_angles_x *= 1 - (STAT(VEH_RACER_ANGLESTABILIZER) * pushdeltatime);
-       this.move_angles_z *= 1 - (STAT(VEH_RACER_ANGLESTABILIZER) * pushdeltatime);
-
-       Movetype_Physics_MatchServer(this, false);
-}
-#endif
-#endif
-
 METHOD(Racer, vr_impact, void(Racer thisveh, entity instance))
 {
 #ifdef SVQC
@@ -573,14 +538,14 @@ METHOD(Racer, vr_impact, void(Racer thisveh, entity instance))
 METHOD(Racer, vr_enter, void(Racer thisveh, entity instance))
 {
 #ifdef SVQC
-    instance.movetype = MOVETYPE_BOUNCE;
+    set_movetype(instance, MOVETYPE_BOUNCE);
     instance.owner.vehicle_health = (instance.vehicle_health / autocvar_g_vehicle_racer_health)  * 100;
     instance.owner.vehicle_shield = (instance.vehicle_shield / autocvar_g_vehicle_racer_shield)  * 100;
 
     if(instance.owner.flagcarried)
        setorigin(instance.owner.flagcarried, '-190 0 96');
 #elif defined(CSQC)
-    instance.move_movetype = MOVETYPE_BOUNCE;
+    set_movetype(instance, MOVETYPE_BOUNCE);
 #endif
 }
 
@@ -607,7 +572,7 @@ METHOD(Racer, vr_spawn, void(Racer thisveh, entity instance))
     instance.vehicle_health = autocvar_g_vehicle_racer_health;
     instance.vehicle_shield = autocvar_g_vehicle_racer_shield;
 
-    instance.movetype    = MOVETYPE_TOSS;
+    set_movetype(instance, MOVETYPE_TOSS);
     instance.solid               = SOLID_SLIDEBOX;
     instance.delay               = time;
     instance.scale               = 0.5;
@@ -631,7 +596,7 @@ METHOD(Racer, vr_death, void(Racer thisveh, entity instance))
     instance.solid                     = SOLID_CORPSE;
     instance.takedamage                = DAMAGE_NO;
     instance.deadflag          = DEAD_DYING;
-    instance.movetype          = MOVETYPE_BOUNCE;
+    set_movetype(instance, MOVETYPE_BOUNCE);
     instance.wait                      = time;
     instance.delay                     = 2 + time + random() * 3;
     instance.cnt                       = 1 + random() * 2;
index 562f522f3e111bdcbc368731f7c1e722ae5e9d58..6b33f8c1a3b7837cba0f340206225ac41f811bf9 100644 (file)
@@ -96,7 +96,7 @@ void raptor_land(entity this)
 
        if(hgt < 16)
        {
-               this.movetype = MOVETYPE_TOSS;
+               set_movetype(this, MOVETYPE_TOSS);
                setthink(this, vehicles_think);
                this.frame      = 0;
        }
@@ -287,7 +287,7 @@ bool raptor_frame(entity this)
                        vehic.gun1.enemy = NULL;
 
                if(trace_ent)
-               if(trace_ent.movetype)
+               if(trace_ent.move_movetype)
                if(trace_ent.takedamage)
                if(!IS_DEAD(trace_ent) && !STAT(FROZEN, trace_ent))
                {
@@ -313,7 +313,7 @@ bool raptor_frame(entity this)
                        vf = real_origin(vehic.gun1.enemy);
                        UpdateAuxiliaryXhair(this, vf, '1 0 0', 1);
                        vector _vel = vehic.gun1.enemy.velocity;
-                       if(vehic.gun1.enemy.movetype == MOVETYPE_WALK)
+                       if(vehic.gun1.enemy.move_movetype == MOVETYPE_WALK)
                                _vel_z *= 0.1;
 
                        if(autocvar_g_vehicle_raptor_cannon_predicttarget)
@@ -430,9 +430,8 @@ bool raptor_frame(entity this)
        if(vehic.bomb1.cnt < time)
        {
                bool incoming = false;
-               FOREACH_ENTITY_ENT(enemy, vehic,
+               IL_EACH(g_projectiles, it.enemy == vehic,
                {
-                       if(it.flags & FL_PROJECTILE)
                        if(MISSILE_IS_TRACKING(it))
                        if(vdist(vehic.origin - it.origin, <, 2 * autocvar_g_vehicle_raptor_flare_range))
                        {
@@ -517,7 +516,7 @@ void raptor_blowup(entity this, entity toucher)
        RadiusDamage (this, this.enemy, 250, 15, 250, NULL, NULL, 250, DEATH_VH_RAPT_DEATH.m_id, NULL);
 
        this.alpha                = -1;
-       this.movetype      = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        this.effects            = EF_NODRAW;
        this.colormod      = '0 0 0';
        this.avelocity    = '0 0 0';
@@ -600,8 +599,8 @@ bool raptor_impulse(entity this, int _imp)
 
 spawnfunc(vehicle_raptor)
 {
-       if(!autocvar_g_vehicle_raptor) { remove(this); return; }
-       if(!vehicle_initialize(this, VEH_RAPTOR, false)) { remove(this); return; }
+       if(!autocvar_g_vehicle_raptor) { delete(this); return; }
+       if(!vehicle_initialize(this, VEH_RAPTOR, false)) { delete(this); return; }
 }
 
 METHOD(Raptor, vr_impact, void(Raptor thisveh, entity instance))
@@ -613,7 +612,7 @@ METHOD(Raptor, vr_enter, void(Raptor thisveh, entity instance))
 {
     instance.vehicle_weapon2mode = RSM_BOMB;
     instance.owner.PlayerPhysplug = raptor_takeoff;
-    instance.movetype     = MOVETYPE_BOUNCEMISSILE;
+    set_movetype(instance, MOVETYPE_BOUNCEMISSILE);
     instance.solid               = SOLID_SLIDEBOX;
     instance.owner.vehicle_health = (instance.vehicle_health / autocvar_g_vehicle_raptor_health) * 100;
     instance.owner.vehicle_shield = (instance.vehicle_shield / autocvar_g_vehicle_raptor_shield) * 100;
@@ -635,7 +634,7 @@ METHOD(Raptor, vr_death, void(Raptor thisveh, entity instance))
     instance.solid                             = SOLID_CORPSE;
     instance.takedamage                        = DAMAGE_NO;
     instance.deadflag                  = DEAD_DYING;
-    instance.movetype                  = MOVETYPE_BOUNCE;
+    set_movetype(instance, MOVETYPE_BOUNCE);
     setthink(instance, raptor_diethink);
     instance.nextthink                 = time;
     instance.wait                              = time + 5 + (random() * 5);
@@ -702,7 +701,7 @@ METHOD(Raptor, vr_spawn, void(Raptor thisveh, entity instance))
         spinner.owner = instance;
         setmodel(spinner, MDL_VEH_RAPTOR_PROP);
         setattachment(spinner, instance, "engine_left");
-        spinner.movetype = MOVETYPE_NOCLIP;
+        set_movetype(spinner, MOVETYPE_NOCLIP);
         spinner.avelocity = '0 90 0';
         instance.bomb1.gun1 = spinner;
 
@@ -710,7 +709,7 @@ METHOD(Raptor, vr_spawn, void(Raptor thisveh, entity instance))
         spinner.owner = instance;
         setmodel(spinner, MDL_VEH_RAPTOR_PROP);
         setattachment(spinner, instance, "engine_right");
-        spinner.movetype = MOVETYPE_NOCLIP;
+        set_movetype(spinner, MOVETYPE_NOCLIP);
         spinner.avelocity = '0 -90 0';
         instance.bomb1.gun2 = spinner;
 
@@ -724,7 +723,7 @@ METHOD(Raptor, vr_spawn, void(Raptor thisveh, entity instance))
     instance.frame               = 0;
     instance.vehicle_health = autocvar_g_vehicle_raptor_health;
     instance.vehicle_shield = autocvar_g_vehicle_raptor_shield;
-    instance.movetype     = MOVETYPE_TOSS;
+    set_movetype(instance, MOVETYPE_TOSS);
     instance.solid               = SOLID_SLIDEBOX;
     instance.vehicle_energy = 1;
 
index a9b9a86587d089dcae0172c85bda940b43399e72..24db99841be23d452a7f36e45caca5c2c4f03013 100644 (file)
@@ -67,7 +67,7 @@ METHOD(RaptorFlare, wr_think, void(entity thiswep, entity actor, .entity weapone
             _flare.effects = EF_LOWPRECISION | EF_FLAME;
             _flare.scale = 0.5;
             setorigin(_flare, actor.origin - '0 0 16');
-            _flare.movetype = MOVETYPE_TOSS;
+            set_movetype(_flare, MOVETYPE_TOSS);
             _flare.gravity = 0.15;
             _flare.velocity = 0.25 * actor.velocity + (v_forward + randomvec() * 0.25)* -500;
             setthink(_flare, raptor_flare_think);
@@ -91,7 +91,7 @@ void raptor_bomblet_boom(entity this)
                                     autocvar_g_vehicle_raptor_bomblet_edgedamage,
                                     autocvar_g_vehicle_raptor_bomblet_radius, NULL, NULL,
                                     autocvar_g_vehicle_raptor_bomblet_force, DEATH_VH_RAPT_BOMB.m_id, NULL);
-    remove(this);
+    delete(this);
 }
 
 void raptor_bomblet_touch(entity this, entity toucher)
@@ -128,7 +128,7 @@ void raptor_bomb_burst(entity this)
         bomblet = spawn();
         setorigin(bomblet, this.origin);
 
-        bomblet.movetype       = MOVETYPE_TOSS;
+        set_movetype(bomblet, MOVETYPE_TOSS);
         settouch(bomblet, raptor_bomblet_touch);
         setthink(bomblet, raptor_bomblet_boom);
         bomblet.nextthink   = time + 5;
@@ -140,7 +140,7 @@ void raptor_bomb_burst(entity this)
         CSQCProjectile(bomblet, true, PROJECTILE_RAPTORBOMBLET, true);
     }
 
-    remove(this);
+    delete(this);
 }
 
 void raptor_bomb_touch(entity this, entity toucher)
@@ -160,7 +160,8 @@ void raptor_bombdrop(entity this)
     org = gettaginfo(this, gettagindex(this, "bombmount_right"));
     setorigin(bomb_2, org);
 
-    bomb_1.movetype     = bomb_2.movetype   = MOVETYPE_BOUNCE;
+    set_movetype(bomb_1, MOVETYPE_BOUNCE);
+    set_movetype(bomb_2, MOVETYPE_BOUNCE);
     bomb_1.velocity     = bomb_2.velocity   = this.velocity;
     settouch(bomb_1, raptor_bomb_touch);
     settouch(bomb_2, raptor_bomb_touch);
@@ -187,31 +188,29 @@ void raptor_bombdrop(entity this)
 
 void raptor_flare_touch(entity this, entity toucher)
 {
-    remove(this);
+    delete(this);
 }
 
 void raptor_flare_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
 {
     this.health -= damage;
     if(this.health <= 0)
-        remove(this);
+        delete(this);
 }
 
 void raptor_flare_think(entity this)
 {
     this.nextthink = time + 0.1;
-    entity _missile = findchainentity(enemy, this.owner);
-    while(_missile)
+    FOREACH_ENTITY_ENT(enemy, this.owner,
     {
-        if(_missile.flags & FL_PROJECTILE)
-        if(vdist(this.origin - _missile.origin, <, autocvar_g_vehicle_raptor_flare_range))
+        if(it.flags & FL_PROJECTILE)
+        if(vdist(this.origin - it.origin, <, autocvar_g_vehicle_raptor_flare_range))
         if(random() > autocvar_g_vehicle_raptor_flare_chase)
-            _missile.enemy = this;
-        _missile = _missile.chain;
-    }
+            it.enemy = this;
+    });
 
     if(this.tur_impacttime < time)
-        remove(this);
+        delete(this);
 }
 
 #endif
@@ -224,14 +223,14 @@ void RaptorCBShellfragDraw(entity this)
         return;
 
     Movetype_Physics_MatchTicrate(this, autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
-    this.move_avelocity += randomvec() * 15;
+    this.avelocity += randomvec() * 15;
     this.renderflags = 0;
 
     if(this.cnt < time)
         this.alpha = bound(0, this.nextthink - time, 1);
 
     if(this.alpha < ALPHA_MIN_VISIBLE)
-        remove(this);
+        delete(this);
 }
 
 void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang)
@@ -240,16 +239,16 @@ void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang)
     setmodel(sfrag, MDL_VEH_RAPTOR_CB_FRAGMENT);
     setorigin(sfrag, _org);
 
-    sfrag.move_movetype = MOVETYPE_BOUNCE;
+    set_movetype(sfrag, MOVETYPE_BOUNCE);
     sfrag.gravity = 0.15;
     sfrag.solid = SOLID_CORPSE;
 
     sfrag.draw = RaptorCBShellfragDraw;
+    IL_PUSH(g_drawables, sfrag);
 
-    sfrag.move_origin = sfrag.origin = _org;
-    sfrag.move_velocity = _vel;
-    sfrag.move_avelocity = prandomvec() * vlen(sfrag.move_velocity);
-    sfrag.angles = sfrag.move_angles = _ang;
+    sfrag.velocity = _vel;
+    sfrag.avelocity = prandomvec() * vlen(sfrag.velocity);
+    sfrag.angles = _ang;
 
     sfrag.move_time = time;
     sfrag.damageforcescale = 4;
index 8015b3102729534d836ce32fc4d111e59f6ea8c1..80d26fc2f7f322756772e4f888330d9420406856 100644 (file)
@@ -349,7 +349,7 @@ void spiderbot_exit(entity this, int eject)
        setthink(this, vehicles_think);
        this.nextthink = time;
        this.frame = 5;
-       this.movetype = MOVETYPE_WALK;
+       set_movetype(this, MOVETYPE_WALK);
 
        if(!this.owner)
                return;
@@ -400,7 +400,7 @@ void spiderbot_headfade(entity this)
                        sound (this, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
                        Send_Effect(EFFECT_EXPLOSION_BIG, this.origin + '0 0 100', '0 0 0', 1);
                }
-               remove(this);
+               delete(this);
        }
 }
 
@@ -435,7 +435,7 @@ void spiderbot_blowup(entity this)
 
        vector org = gettaginfo(this, gettagindex(this, "tag_head"));
        setorigin(h, org);
-       h.movetype = MOVETYPE_BOUNCE;
+       set_movetype(h, MOVETYPE_BOUNCE);
        h.solid = SOLID_BBOX;
        h.velocity = v_up * (500 + random() * 500) + randomvec() * 128;
        h.modelflags = MF_ROCKET;
@@ -451,14 +451,14 @@ void spiderbot_blowup(entity this)
 
        org = gettaginfo(this.tur_head, gettagindex(this.tur_head, "tag_hardpoint01"));
        setorigin(g1, org);
-       g1.movetype = MOVETYPE_TOSS;
+       set_movetype(g1, MOVETYPE_TOSS);
        g1.solid = SOLID_CORPSE;
        g1.velocity = v_forward * 700 + (randomvec() * 32);
        g1.avelocity = randomvec() * 180;
 
        org = gettaginfo(this.tur_head, gettagindex(this.tur_head, "tag_hardpoint02"));
        setorigin(g2, org);
-       g2.movetype = MOVETYPE_TOSS;
+       set_movetype(g2, MOVETYPE_TOSS);
        g2.solid = SOLID_CORPSE;
        g2.velocity = v_forward * 700 + (randomvec() * 32);
        g2.avelocity = randomvec() * 180;
@@ -473,7 +473,7 @@ void spiderbot_blowup(entity this)
        RadiusDamage (this, this.enemy, 250, 15, 250, NULL, NULL, 250, DEATH_VH_SPID_DEATH.m_id, NULL);
 
        this.alpha = this.tur_head.alpha = this.gun1.alpha = this.gun2.alpha = -1;
-       this.movetype = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        this.deadflag = DEAD_DEAD;
        this.solid = SOLID_NOT;
        this.tur_head.effects &= ~EF_FLAME;
@@ -531,8 +531,8 @@ bool spiderbot_impulse(entity this, int _imp)
 
 spawnfunc(vehicle_spiderbot)
 {
-       if(!autocvar_g_vehicle_spiderbot) { remove(this); return; }
-       if(!vehicle_initialize(this, VEH_SPIDERBOT, false)) { remove(this); return; }
+       if(!autocvar_g_vehicle_spiderbot) { delete(this); return; }
+       if(!vehicle_initialize(this, VEH_SPIDERBOT, false)) { delete(this); return; }
 }
 
 METHOD(Spiderbot, vr_impact, void(Spiderbot thisveh, entity instance))
@@ -543,7 +543,7 @@ METHOD(Spiderbot, vr_impact, void(Spiderbot thisveh, entity instance))
 METHOD(Spiderbot, vr_enter, void(Spiderbot thisveh, entity instance))
 {
     instance.vehicle_weapon2mode = SBRM_GUIDE;
-    instance.movetype = MOVETYPE_WALK;
+    set_movetype(instance, MOVETYPE_WALK);
     CSQCVehicleSetup(instance.owner, 0);
     instance.owner.vehicle_health = (instance.vehicle_health / autocvar_g_vehicle_spiderbot_health) * 100;
     instance.owner.vehicle_shield = (instance.vehicle_shield / autocvar_g_vehicle_spiderbot_shield) * 100;
@@ -573,7 +573,7 @@ METHOD(Spiderbot, vr_death, void(Spiderbot thisveh, entity instance))
     instance.tur_head.effects  |= EF_FLAME;
     instance.colormod                  = instance.tur_head.colormod = '-1 -1 -1';
     instance.frame                             = 10;
-    instance.movetype                  = MOVETYPE_TOSS;
+    set_movetype(instance, MOVETYPE_TOSS);
 
     CSQCModel_UnlinkEntity(instance); // networking the death scene would be a nightmare
 }
@@ -594,7 +594,7 @@ METHOD(Spiderbot, vr_spawn, void(Spiderbot thisveh, entity instance))
 
     instance.frame = 5;
     instance.tur_head.frame = 1;
-    instance.movetype = MOVETYPE_WALK;
+    set_movetype(instance, MOVETYPE_WALK);
     instance.solid = SOLID_SLIDEBOX;
     instance.alpha = instance.tur_head.alpha = instance.gun1.alpha = instance.gun2.alpha = 1;
     instance.tur_head.angles = '0 0 0';
index 8876f89594cc80aab5d2f0fcda15691e502fbb83..dc1f6ba60a29e16190c54d930e285af683b314d0 100644 (file)
@@ -48,21 +48,17 @@ void spiderbot_rocket_guided(entity this)
 
 void spiderbot_guide_release(entity this)
 {
-    entity rkt;
-    rkt = findchainentity(realowner, this.owner);
-    if(!rkt)
-        return;
-
-    crosshair_trace(this.owner);
-    while(rkt)
+    FOREACH_ENTITY_ENT(realowner, this.owner,
     {
-        if(getthink(rkt) == spiderbot_rocket_guided)
+        if(i == 0) // something exists, let's trace!
+            crosshair_trace(this.owner);
+
+        if(getthink(it) == spiderbot_rocket_guided)
         {
-            rkt.pos1 = trace_endpos;
-            setthink(rkt, spiderbot_rocket_unguided);
+            it.pos1 = trace_endpos;
+            setthink(it, spiderbot_rocket_unguided);
         }
-        rkt = rkt.chain;
-    }
+    });
 }
 
 float spiberbot_calcartillery_flighttime;
@@ -232,7 +228,7 @@ void spiderbot_rocket_do(entity this)
             float h2 = 0.75 * vlen(rocket.pos1 - v);
 
             rocket.velocity  = spiberbot_calcartillery(v, rocket.pos1, ((h1 < h2) ? h1 : h2));
-            rocket.movetype  = MOVETYPE_TOSS;
+            set_movetype(rocket, MOVETYPE_TOSS);
             rocket.gravity   = 1;
             //setthink(rocket, spiderbot_rocket_artillery);
         break;
index 897e2caef2f5975e3627458dd0d6894d7da9a3d8..ea949da50cf6a048ab613f1dd8677a68f58149cf 100644 (file)
@@ -392,7 +392,7 @@ void CL_WeaponEntity_SetModel(entity this, string name, bool _anim)
        if (name == "")
        {
                this.model = "";
-               if (this.weaponchild) remove(this.weaponchild);
+               if (this.weaponchild) delete(this.weaponchild);
                this.weaponchild = NULL;
                this.movedir = '0 0 0';
                this.spawnorigin = '0 0 0';
@@ -436,7 +436,7 @@ void CL_WeaponEntity_SetModel(entity this, string name, bool _anim)
                }
                else
                {
-                       if (this.weaponchild) remove(this.weaponchild);
+                       if (this.weaponchild) delete(this.weaponchild);
                        this.weaponchild = NULL;
                }
 
index dd691a6921ca8ab2b9d619ee61df8731515189d5..fa9d64ab8d238666270e193eb967bd4230c19e0a 100644 (file)
@@ -299,6 +299,7 @@ REGISTRY_CHECK(Weapons)
 
 STATIC_INIT(register_weapons_done)
 {
+       string inaccessible = "";
     FOREACH(Weapons, true, {
         WepSet set = it.m_wepset = _WepSet_FromWeapon(it.m_id = i);
         WEPSET_ALL |= set;
@@ -309,8 +310,9 @@ STATIC_INIT(register_weapons_done)
         if (imp <= WEP_IMPULSE_END)
             localcmd(sprintf("alias weapon_%s \"impulse %d\"\n", it.netname, imp));
         else
-            LOG_TRACEF("Impulse limit exceeded, weapon will not be directly accessible: %s\n", it.netname);
+               inaccessible = strcat(inaccessible, "\n", it.netname);
     });
+    if (inaccessible) LOG_TRACEF("Impulse limit exceeded, weapon(s) will not be directly accessible: %s\n", inaccessible);
     #ifdef CSQC
     FOREACH(Weapons, true, it.wr_init(it));
     #endif
index 4de39db1772f31ab462467f55a0b76e9f3eeb3ec..8b844f13e08e39d8b0585ac94122733b3597e6ee 100644 (file)
@@ -191,6 +191,8 @@ const int WEP_FLAG_HIDDEN         =  0x40; // hides from menu
 const int WEP_FLAG_RELOADABLE     =  0x80; // can has reload
 const int WEP_FLAG_SUPERWEAPON    = 0x100; // powerup timer
 const int WEP_FLAG_MUTATORBLOCKED = 0x200; // hides from impulse 99 etc. (mutators are allowed to clear this flag)
+const int WEP_TYPE_MELEE_PRI      = 0x400; // primary attack is melee swing (for animation)
+const int WEP_TYPE_MELEE_SEC      = 0x800; // secondary attack is melee swing (for animation)
 
 // variables:
 string weaponorder_byid;
index 012b2c0f1417fe432814dea9f816f7a50e78f315..65b625b9a2f59119ba3c685c9120c9f16d3e73f1 100644 (file)
@@ -236,7 +236,7 @@ void W_Arc_Bolt_Explode(entity this, entity directhitentity)
        this.event_damage = func_null;
        RadiusDamage(this, this.realowner, WEP_CVAR(arc, bolt_damage), WEP_CVAR(arc, bolt_edgedamage), WEP_CVAR(arc, bolt_radius), NULL, NULL, WEP_CVAR(arc, bolt_force), this.projectiledeathtype, directhitentity);
 
-       remove(this);
+       delete(this);
 }
 
 void W_Arc_Bolt_Explode_use(entity this, entity actor, entity trigger)
@@ -295,7 +295,7 @@ void W_Arc_Attack_Bolt(Weapon thiswep, entity actor)
        setorigin(missile, w_shotorg);
        setsize(missile, '0 0 0', '0 0 0');
 
-       missile.movetype = MOVETYPE_FLY;
+       set_movetype(missile, MOVETYPE_FLY);
        W_SetupProjVelocity_PRE(missile, arc, bolt_);
 
        missile.angles = vectoangles(missile.velocity);
@@ -311,7 +311,7 @@ void W_Arc_Beam_Think(entity this)
 {
        if(this != this.owner.arc_beam)
        {
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -333,12 +333,10 @@ void W_Arc_Beam_Think(entity this)
                ||
                IS_DEAD(this.owner)
                ||
-               gameover
+               forbidWeaponUse(this.owner)
                ||
                (!PHYS_INPUT_BUTTON_ATCK(this.owner) && !burst )
                ||
-               STAT(FROZEN, this.owner)
-               ||
                this.owner.vehicle
                ||
                (WEP_CVAR(arc, overheat_max) > 0 && this.beam_heat >= WEP_CVAR(arc, overheat_max))
@@ -380,7 +378,7 @@ void W_Arc_Beam_Think(entity this)
                        // note: this doesn't force the switch
                        W_SwitchToOtherWeapon(own);
                }
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -685,7 +683,7 @@ void W_Arc_Beam(float burst, entity actor)
        beam.solid = SOLID_NOT;
        setthink(beam, W_Arc_Beam_Think);
        beam.owner = actor;
-       beam.movetype = MOVETYPE_NONE;
+       set_movetype(beam, MOVETYPE_NONE);
        beam.bot_dodge = true;
        beam.bot_dodgerating = WEP_CVAR(arc, beam_damage);
        beam.beam_bursting = burst;
@@ -1281,7 +1279,7 @@ void Draw_ArcBeam(entity this)
 
 void Remove_ArcBeam(entity this)
 {
-       remove(this.beam_muzzleentity);
+       delete(this.beam_muzzleentity);
        sound(this, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM);
 }
 
@@ -1298,6 +1296,7 @@ NET_HANDLE(ENT_CLIENT_ARC_BEAM, bool isnew)
 
                // set other main attributes of the beam
                this.draw = Draw_ArcBeam;
+               IL_PUSH(g_drawables, this);
                this.entremove = Remove_ArcBeam;
                this.move_time = time;
                loopsound(this, CH_SHOTS_SINGLE, SND(ARC_LOOP), VOL_BASE, ATTEN_NORM);
index 79a680e367eb27825d3d3a9befabbc99824c4edb..0c3765a13955fc6b1ce56e03b89f9345fed32da3 100644 (file)
@@ -75,12 +75,12 @@ void W_Blaster_Touch(entity this, entity toucher)
                toucher
        );
 
-       remove(this);
+       delete(this);
 }
 
 void W_Blaster_Think(entity this)
 {
-       this.movetype = MOVETYPE_FLY;
+       set_movetype(this, MOVETYPE_FLY);
        setthink(this, SUB_Remove);
        this.nextthink = time + this.blaster_lifetime;
        CSQCProjectile(this, true, PROJECTILE_BLASTER, true);
@@ -137,6 +137,7 @@ void W_Blaster_Attack(
 
        settouch(missile, W_Blaster_Touch);
        missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
        missile.missile_flags = MIF_SPLASH;
        missile.projectiledeathtype = atk_deathtype;
        setthink(missile, W_Blaster_Think);
index d1f2522abbcccecde8fe3263b8cd1857d06a2162..bb782643a67bb6ace6a5fd5196c93e2786cf8ac8 100644 (file)
@@ -114,7 +114,7 @@ void W_Crylink_Dequeue(entity e)
 void W_Crylink_Reset(entity this)
 {
        W_Crylink_Dequeue(this);
-       remove(this);
+       delete(this);
 }
 
 // force projectile to explode
@@ -138,7 +138,7 @@ void W_Crylink_LinkExplode(entity e, entity e2, entity directhitentity)
        W_Crylink_LinkExplode(e.queuenext, e2, directhitentity);
 
        e.classname = "spike_oktoremove";
-       remove(e);
+       delete(e);
 }
 
 // adjust towards center
@@ -268,7 +268,7 @@ void W_Crylink_LinkJoinEffect_Think(entity this)
                        }
                }
        }
-       remove(this);
+       delete(this);
 }
 
 float W_Crylink_Touch_WouldHitFriendly(entity projectile, float rad)
@@ -320,14 +320,14 @@ void W_Crylink_Touch(entity this, entity toucher)
                        this.realowner.crylink_lastgroup = NULL;
                W_Crylink_LinkExplode(this.queuenext, this, toucher);
                this.classname = "spike_oktoremove";
-               remove(this);
+               delete(this);
                return;
        }
        else if(finalhit)
        {
                // just unlink
                W_Crylink_Dequeue(this);
-               remove(this);
+               delete(this);
                return;
        }
        this.cnt = this.cnt - 1;
@@ -342,7 +342,7 @@ void W_Crylink_Touch(entity this, entity toucher)
 void W_Crylink_Fadethink(entity this)
 {
        W_Crylink_Dequeue(this);
-       remove(this);
+       delete(this);
 }
 
 void W_Crylink_Attack(Weapon thiswep, entity actor)
@@ -395,7 +395,7 @@ void W_Crylink_Attack(Weapon thiswep, entity actor)
 
                prevproj = proj;
 
-               proj.movetype = MOVETYPE_BOUNCEMISSILE;
+               set_movetype(proj, MOVETYPE_BOUNCEMISSILE);
                PROJECTILE_MAKETRIGGER(proj);
                proj.projectiledeathtype = WEP_CRYLINK.m_id;
                //proj.gravity = 0.001;
@@ -439,6 +439,7 @@ void W_Crylink_Attack(Weapon thiswep, entity actor)
                //proj.glow_size = 20;
 
                proj.flags = FL_PROJECTILE;
+               IL_PUSH(g_projectiles, proj);
                proj.missile_flags = MIF_SPLASH;
 
                CSQCProjectile(proj, true, (proj.cnt ? PROJECTILE_CRYLINK_BOUNCING : PROJECTILE_CRYLINK), true);
@@ -503,7 +504,7 @@ void W_Crylink_Attack2(Weapon thiswep, entity actor)
 
                prevproj = proj;
 
-               proj.movetype = MOVETYPE_BOUNCEMISSILE;
+               set_movetype(proj, MOVETYPE_BOUNCEMISSILE);
                PROJECTILE_MAKETRIGGER(proj);
                proj.projectiledeathtype = WEP_CRYLINK.m_id | HITTYPE_SECONDARY;
                //proj.gravity = 0.001;
@@ -554,6 +555,7 @@ void W_Crylink_Attack2(Weapon thiswep, entity actor)
                //proj.glow_size = 20;
 
                proj.flags = FL_PROJECTILE;
+               IL_PUSH(g_projectiles, proj);
         proj.missile_flags = MIF_SPLASH;
 
                CSQCProjectile(proj, true, (proj.cnt ? PROJECTILE_CRYLINK_BOUNCING : PROJECTILE_CRYLINK), true);
index 9d955f058dd3a59ecd9fdc0dd7a54548ea4b38ba..870ced3d9c1c713d0ea2f0b2e2882516b3f670d1 100644 (file)
@@ -120,7 +120,7 @@ void W_Devastator_Explode(entity this, entity directhitentity)
                        PS(this.realowner).m_switchweapon = w_getbestweapon(this.realowner);
                }
        }
-       remove(this);
+       delete(this);
 }
 
 void W_Devastator_Explode_think(entity this)
@@ -206,7 +206,7 @@ void W_Devastator_DoRemoteExplode(entity this, .entity weaponentity)
                        PS(this.realowner).m_switchweapon = w_getbestweapon(this.realowner);
                }
        }
-       remove(this);
+       delete(this);
 }
 
 void W_Devastator_RemoteExplode(entity this, .entity weaponentity)
@@ -376,7 +376,7 @@ void W_Devastator_Attack(Weapon thiswep, entity actor)
        missile.event_damage = W_Devastator_Damage;
        missile.damagedbycontents = true;
 
-       missile.movetype = MOVETYPE_FLY;
+       set_movetype(missile, MOVETYPE_FLY);
        PROJECTILE_MAKETRIGGER(missile);
        missile.projectiledeathtype = WEP_DEVASTATOR.m_id;
        setsize(missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
@@ -390,6 +390,7 @@ void W_Devastator_Attack(Weapon thiswep, entity actor)
        missile.nextthink = time;
        missile.cnt = time + WEP_CVAR(devastator, lifetime);
        missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
        missile.missile_flags = MIF_SPLASH;
 
        CSQCProjectile(missile, WEP_CVAR(devastator, guiderate) == 0 && WEP_CVAR(devastator, speedaccel) == 0, PROJECTILE_ROCKET, false); // because of fly sound
@@ -441,8 +442,7 @@ METHOD(Devastator, wr_aim, void(entity thiswep, entity actor))
     if(skill >= 2) // skill 0 and 1 bots won't detonate rockets!
     {
         // decide whether to detonate rockets
-        entity targetlist, targ;
-        float edgedamage, coredamage, edgeradius, recipricoledgeradius, d;
+        float edgedamage, coredamage, edgeradius, recipricoledgeradius;
         float selfdamage, teamdamage, enemydamage;
         edgedamage = WEP_CVAR(devastator, edgedamage);
         coredamage = WEP_CVAR(devastator, damage);
@@ -451,25 +451,23 @@ METHOD(Devastator, wr_aim, void(entity thiswep, entity actor))
         selfdamage = 0;
         teamdamage = 0;
         enemydamage = 0;
-        targetlist = findchainfloat(bot_attack, true);
         FOREACH_ENTITY_ENT(realowner, actor,
         {
             if(it.classname != "rocket") continue;
 
-            targ = targetlist;
-            while(targ)
+            entity rocket = it;
+            FOREACH_ENTITY_FLOAT(bot_attack, true,
             {
-                d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - it.origin);
-                d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
-                // count potential damage according to type of target
-                if(targ == actor)
-                    selfdamage = selfdamage + d;
-                else if(targ.team == actor.team && teamplay)
-                    teamdamage = teamdamage + d;
-                else if(bot_shouldattack(actor, targ))
-                    enemydamage = enemydamage + d;
-                targ = targ.chain;
-            }
+               float d = vlen(it.origin + (it.mins + it.maxs) * 0.5 - rocket.origin);
+               d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
+               // count potential damage according to type of target
+               if(it == actor)
+                       selfdamage = selfdamage + d;
+               else if(SAME_TEAM(it, actor))
+                       teamdamage = teamdamage + d;
+               else if(bot_shouldattack(actor, it))
+                       enemydamage = enemydamage + d;
+            });
         });
         float desirabledamage;
         desirabledamage = enemydamage;
@@ -478,36 +476,35 @@ METHOD(Devastator, wr_aim, void(entity thiswep, entity actor))
         if(teamplay && actor.team)
             desirabledamage = desirabledamage - teamdamage;
 
+        makevectors(actor.v_angle);
         FOREACH_ENTITY_ENT(realowner, actor,
         {
             if(it.classname != "rocket") continue;
 
-            makevectors(it.v_angle);
-            targ = targetlist;
             if(skill > 9) // normal players only do this for the target they are tracking
             {
-                targ = targetlist;
-                while(targ)
-                {
-                    if(
-                        (v_forward * normalize(it.origin - targ.origin)< 0.1)
-                        && desirabledamage > 0.1*coredamage
-                    ) PHYS_INPUT_BUTTON_ATCK2(actor) = true;
-                    targ = targ.chain;
-                }
-            }
-            else
-            {
-                float distance; distance= bound(300,vlen(actor.origin-actor.enemy.origin),30000);
+                   entity rocket = it;
+                   FOREACH_ENTITY_FLOAT(bot_attack, true,
+                   {
+                       if((v_forward * normalize(rocket.origin - it.origin) < 0.1)
+                           && desirabledamage > 0.1 * coredamage
+                           ) PHYS_INPUT_BUTTON_ATCK2(actor) = true;
+                   });
+               }
+               else
+               {
                 //As the distance gets larger, a correct detonation gets near imposible
                 //Bots are assumed to use the rocket spawnfunc_light to see if the rocket gets near a player
-                if(v_forward * normalize(it.origin - actor.enemy.origin)< 0.1)
-                    if(IS_PLAYER(actor.enemy))
-                        if(desirabledamage >= 0.1*coredamage)
-                            if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1))
-                                PHYS_INPUT_BUTTON_ATCK2(actor) = true;
-            // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n");
-            }
+                if((v_forward * normalize(it.origin - actor.enemy.origin) < 0.1)
+                       && IS_PLAYER(actor.enemy)
+                       && (desirabledamage >= 0.1 * coredamage)
+                       )
+                {
+                       float distance = bound(300, vlen(actor.origin - actor.enemy.origin), 30000);
+                       if(random() / distance * 300 > frametime * bound(0, (10 - skill) * 0.2, 1))
+                               PHYS_INPUT_BUTTON_ATCK2(actor) = true;
+                }
+               }
         });
         // if we would be doing at X percent of the core damage, detonate it
         // but don't fire a new shot at the same time!
index b9811abd87d37f7a37ac86ae98513f64360c6f98..5f8208a7ff6419ee9b82819f0df179030bee9afa 100644 (file)
@@ -50,6 +50,7 @@ CLASS(Electro, Weapon)
                P(class, prefix, speed_up, float, SEC) \
                P(class, prefix, speed_z, float, SEC) \
                P(class, prefix, spread, float, BOTH) \
+               P(class, prefix, stick, float, SEC) \
                P(class, prefix, switchdelay_drop, float, NONE) \
                P(class, prefix, switchdelay_raise, float, NONE) \
                P(class, prefix, touchexplode, float, SEC) \
@@ -141,7 +142,7 @@ void W_Electro_ExplodeCombo(entity this)
                NULL
        );
 
-       remove(this);
+       delete(this);
 }
 
 void W_Electro_Explode(entity this, entity directhitentity)
@@ -156,7 +157,7 @@ void W_Electro_Explode(entity this, entity directhitentity)
        this.event_damage = func_null;
        this.takedamage = DAMAGE_NO;
 
-       if(this.movetype == MOVETYPE_BOUNCE)
+       if(this.move_movetype == MOVETYPE_BOUNCE || this.classname == "electro_orb") // TODO: classname is more reliable anyway?
        {
                RadiusDamage(
                        this,
@@ -188,7 +189,7 @@ void W_Electro_Explode(entity this, entity directhitentity)
                );
        }
 
-       remove(this);
+       delete(this);
 }
 
 void W_Electro_Explode_use(entity this, entity actor, entity trigger)
@@ -202,8 +203,12 @@ void W_Electro_TouchExplode(entity this, entity toucher)
        W_Electro_Explode(this, toucher);
 }
 
+
+void sys_phys_update_single(entity this);
+
 void W_Electro_Bolt_Think(entity this)
 {
+       // sys_phys_update_single(this);
        if(time >= this.ltime)
        {
                this.use(this, NULL, NULL);
@@ -252,6 +257,7 @@ void W_Electro_Bolt_Think(entity this)
                        { this.nextthink = min(time + WEP_CVAR_PRI(electro, midaircombo_interval), this.ltime); }
        }
        else { this.nextthink = this.ltime; }
+       // this.nextthink = time;
 }
 
 void W_Electro_Attack_Bolt(Weapon thiswep, entity actor)
@@ -285,17 +291,58 @@ void W_Electro_Attack_Bolt(Weapon thiswep, entity actor)
        proj.projectiledeathtype = WEP_ELECTRO.m_id;
        setorigin(proj, w_shotorg);
 
-       proj.movetype = MOVETYPE_FLY;
+       // if (IS_CSQC)
+       set_movetype(proj, MOVETYPE_FLY);
        W_SetupProjVelocity_PRI(proj, electro);
        proj.angles = vectoangles(proj.velocity);
        settouch(proj, W_Electro_TouchExplode);
        setsize(proj, '0 0 -3', '0 0 -3');
        proj.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, proj);
        proj.missile_flags = MIF_SPLASH;
 
        CSQCProjectile(proj, true, PROJECTILE_ELECTRO_BEAM, true);
 
        MUTATOR_CALLHOOK(EditProjectile, actor, proj);
+       // proj.com_phys_pos = proj.origin;
+       // proj.com_phys_vel = proj.velocity;
+}
+
+void W_Electro_Orb_Stick(entity this, entity to)
+{
+       entity newproj = spawn();
+       newproj.classname = this.classname;
+
+       newproj.bot_dodge = this.bot_dodge;
+       newproj.bot_dodgerating = this.bot_dodgerating;
+
+       newproj.owner = this.owner;
+       newproj.realowner = this.realowner;
+       setsize(newproj, this.mins, this.maxs);
+       setorigin(newproj, this.origin);
+       setmodel(newproj, MDL_PROJECTILE_ELECTRO);
+       newproj.angles = vectoangles(-trace_plane_normal); // face against the surface
+
+       newproj.takedamage = this.takedamage;
+       newproj.damageforcescale = this.damageforcescale;
+       newproj.health = this.health;
+       newproj.event_damage = this.event_damage;
+       newproj.spawnshieldtime = this.spawnshieldtime;
+       newproj.damagedbycontents = true;
+
+       set_movetype(newproj, MOVETYPE_NONE); // lock the orb in place
+       newproj.projectiledeathtype = this.projectiledeathtype;
+
+       settouch(newproj, func_null);
+       setthink(newproj, getthink(this));
+       newproj.nextthink = this.nextthink;
+       newproj.use = this.use;
+       newproj.flags = this.flags;
+
+       delete(this);
+
+       if(to)
+               SetMovetypeFollow(this, to);
 }
 
 void W_Electro_Orb_Touch(entity this, entity toucher)
@@ -308,6 +355,9 @@ void W_Electro_Orb_Touch(entity this, entity toucher)
                //UpdateCSQCProjectile(this);
                spamsound(this, CH_SHOTS, SND(ELECTRO_BOUNCE), VOL_BASE, ATTEN_NORM);
                this.projectiledeathtype |= HITTYPE_BOUNCE;
+
+               if(WEP_CVAR_SEC(electro, stick))
+                       W_Electro_Orb_Stick(this, toucher);
        }
 }
 
@@ -359,8 +409,8 @@ void W_Electro_Attack_Orb(Weapon thiswep, entity actor)
 
        W_SetupShot_ProjectileSize(
                actor,
-               '0 0 -4',
-               '0 0 -4',
+               '-4 -4 -4',
+               '4 4 4',
                false,
                2,
                SND_ELECTRO_FIRE2,
@@ -385,15 +435,16 @@ void W_Electro_Attack_Orb(Weapon thiswep, entity actor)
 
        //proj.glow_size = 50;
        //proj.glow_color = 45;
-       proj.movetype = MOVETYPE_BOUNCE;
+       set_movetype(proj, MOVETYPE_BOUNCE);
        W_SetupProjVelocity_UP_SEC(proj, electro);
        settouch(proj, W_Electro_Orb_Touch);
-       setsize(proj, '0 0 -4', '0 0 -4');
+       setsize(proj, '-4 -4 -4', '4 4 4');
        proj.takedamage = DAMAGE_YES;
        proj.damageforcescale = WEP_CVAR_SEC(electro, damageforcescale);
        proj.health = WEP_CVAR_SEC(electro, health);
        proj.event_damage = W_Electro_Orb_Damage;
        proj.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, proj);
        proj.damagedbycontents = (WEP_CVAR_SEC(electro, damagedbycontents));
 
        proj.bouncefactor = WEP_CVAR_SEC(electro, bouncefactor);
index 37deb1452819a9238690130656b0c9dea9b7a989..a523354a021ee6f6e2e4d6cc80e28b16dd8c27a3 100644 (file)
@@ -109,7 +109,7 @@ void W_Fireball_Explode(entity this, entity directhitentity)
                }
        }
 
-       remove(this);
+       delete(this);
 }
 
 void W_Fireball_Explode_think(entity this)
@@ -218,12 +218,13 @@ void W_Fireball_Attack1(entity actor)
        proj.projectiledeathtype = WEP_FIREBALL.m_id;
        setorigin(proj, w_shotorg);
 
-       proj.movetype = MOVETYPE_FLY;
+       set_movetype(proj, MOVETYPE_FLY);
        W_SetupProjVelocity_PRI(proj, fireball);
        proj.angles = vectoangles(proj.velocity);
        settouch(proj, W_Fireball_TouchExplode);
        setsize(proj, '-16 -16 -16', '16 16 16');
        proj.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, proj);
     proj.missile_flags = MIF_SPLASH | MIF_PROXY;
 
        CSQCProjectile(proj, true, PROJECTILE_FIREBALL, true);
@@ -273,7 +274,7 @@ void W_Fireball_Firemine_Think(entity this)
 {
        if(time > this.pushltime)
        {
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -301,7 +302,7 @@ void W_Fireball_Firemine_Touch(entity this, entity toucher)
        if(toucher.takedamage == DAMAGE_AIM)
        if(Fire_AddDamage(toucher, this.realowner, WEP_CVAR_SEC(fireball, damage), WEP_CVAR_SEC(fireball, damagetime), this.projectiledeathtype) >= 0)
        {
-               remove(this);
+               delete(this);
                return;
        }
        this.projectiledeathtype |= HITTYPE_BOUNCE;
@@ -340,7 +341,7 @@ void W_Fireball_Attack2(entity actor)
        proj.owner = proj.realowner = actor;
        proj.bot_dodge = true;
        proj.bot_dodgerating = WEP_CVAR_SEC(fireball, damage);
-       proj.movetype = MOVETYPE_BOUNCE;
+       set_movetype(proj, MOVETYPE_BOUNCE);
        proj.projectiledeathtype = WEP_FIREBALL.m_id | HITTYPE_SECONDARY;
        settouch(proj, W_Fireball_Firemine_Touch);
        PROJECTILE_MAKETRIGGER(proj);
@@ -354,6 +355,7 @@ void W_Fireball_Attack2(entity actor)
 
        proj.angles = vectoangles(proj.velocity);
        proj.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, proj);
     proj.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_ARC;
 
        CSQCProjectile(proj, true, PROJECTILE_FIREMINE, true);
index 1a078dff0a4d0e9f56515fea34fe3f61ab7b39eb..7d45dc8b824d0b5d31145589abb69b7acfcbfed3 100644 (file)
@@ -68,7 +68,7 @@ void W_Hagar_Explode(entity this, entity directhitentity)
        this.event_damage = func_null;
        RadiusDamage(this, this.realowner, WEP_CVAR_PRI(hagar, damage), WEP_CVAR_PRI(hagar, edgedamage), WEP_CVAR_PRI(hagar, radius), NULL, NULL, WEP_CVAR_PRI(hagar, force), this.projectiledeathtype, directhitentity);
 
-       remove(this);
+       delete(this);
 }
 
 void W_Hagar_Explode_use(entity this, entity actor, entity trigger)
@@ -81,7 +81,7 @@ void W_Hagar_Explode2(entity this, entity directhitentity)
        this.event_damage = func_null;
        RadiusDamage(this, this.realowner, WEP_CVAR_SEC(hagar, damage), WEP_CVAR_SEC(hagar, edgedamage), WEP_CVAR_SEC(hagar, radius), NULL, NULL, WEP_CVAR_SEC(hagar, force), this.projectiledeathtype, directhitentity);
 
-       remove(this);
+       delete(this);
 }
 
 void W_Hagar_Explode2_use(entity this, entity actor, entity trigger)
@@ -164,11 +164,12 @@ void W_Hagar_Attack(Weapon thiswep, entity actor)
        setorigin(missile, w_shotorg);
        setsize(missile, '0 0 0', '0 0 0');
 
-       missile.movetype = MOVETYPE_FLY;
+       set_movetype(missile, MOVETYPE_FLY);
        W_SetupProjVelocity_PRI(missile, hagar);
 
        missile.angles = vectoangles(missile.velocity);
        missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
        missile.missile_flags = MIF_SPLASH;
 
        CSQCProjectile(missile, true, PROJECTILE_HAGAR, true);
@@ -207,11 +208,12 @@ void W_Hagar_Attack2(Weapon thiswep, entity actor)
        setorigin(missile, w_shotorg);
        setsize(missile, '0 0 0', '0 0 0');
 
-       missile.movetype = MOVETYPE_BOUNCEMISSILE;
+       set_movetype(missile, MOVETYPE_BOUNCEMISSILE);
        W_SetupProjVelocity_SEC(missile, hagar);
 
        missile.angles = vectoangles(missile.velocity);
        missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
        missile.missile_flags = MIF_SPLASH;
 
        CSQCProjectile(missile, true, PROJECTILE_HAGAR_BOUNCING, true);
@@ -264,7 +266,7 @@ void W_Hagar_Attack2_Load_Release(entity actor, .entity weaponentity)
                missile.projectiledeathtype = WEP_HAGAR.m_id | HITTYPE_SECONDARY;
                setorigin(missile, w_shotorg);
                setsize(missile, '0 0 0', '0 0 0');
-               missile.movetype = MOVETYPE_FLY;
+               set_movetype(missile, MOVETYPE_FLY);
                missile.missile_flags = MIF_SPLASH;
 
                // per-shot spread calculation: the more shots there are, the less spread is applied (based on the bias cvar)
@@ -288,6 +290,7 @@ void W_Hagar_Attack2_Load_Release(entity actor, .entity weaponentity)
 
                missile.angles = vectoangles(missile.velocity);
                missile.flags = FL_PROJECTILE;
+               IL_PUSH(g_projectiles, missile);
 
                CSQCProjectile(missile, true, PROJECTILE_HAGAR, true);
 
index d46972fa1c95066093482159349b2fc913aba0dd..64c87c8a0639eccdcc79249b710d3723350c2654 100644 (file)
@@ -66,7 +66,7 @@ void W_HLAC_Touch(entity this, entity toucher)
 
        RadiusDamage(this, this.realowner, WEP_CVAR_BOTH(hlac, isprimary, damage), WEP_CVAR_BOTH(hlac, isprimary, edgedamage), WEP_CVAR_BOTH(hlac, isprimary, radius), NULL, NULL, WEP_CVAR_BOTH(hlac, isprimary, force), this.projectiledeathtype, toucher);
 
-       remove(this);
+       delete(this);
 }
 
 void W_HLAC_Attack(Weapon thiswep, entity actor)
@@ -95,7 +95,7 @@ void W_HLAC_Attack(Weapon thiswep, entity actor)
 
     missile.bot_dodgerating = WEP_CVAR_PRI(hlac, damage);
 
-       missile.movetype = MOVETYPE_FLY;
+       set_movetype(missile, MOVETYPE_FLY);
        PROJECTILE_MAKETRIGGER(missile);
 
        setorigin(missile, w_shotorg);
@@ -110,6 +110,7 @@ void W_HLAC_Attack(Weapon thiswep, entity actor)
     missile.nextthink = time + WEP_CVAR_PRI(hlac, lifetime);
 
        missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
        missile.projectiledeathtype = WEP_HLAC.m_id;
 
        CSQCProjectile(missile, true, PROJECTILE_HLAC, true);
@@ -137,7 +138,7 @@ void W_HLAC_Attack2(entity actor)
 
     missile.bot_dodgerating = WEP_CVAR_SEC(hlac, damage);
 
-       missile.movetype = MOVETYPE_FLY;
+       set_movetype(missile, MOVETYPE_FLY);
        PROJECTILE_MAKETRIGGER(missile);
 
        setorigin(missile, w_shotorg);
@@ -152,6 +153,7 @@ void W_HLAC_Attack2(entity actor)
     missile.nextthink = time + WEP_CVAR_SEC(hlac, lifetime);
 
        missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
        missile.missile_flags = MIF_SPLASH;
        missile.projectiledeathtype = WEP_HLAC.m_id | HITTYPE_SECONDARY;
 
index f46e592e293b3f283e3d5140b34a3574a5afcc63..e9200e762656d2d01d948026f6fec7feb85e4bfb 100644 (file)
@@ -96,7 +96,7 @@ void W_Hook_ExplodeThink(entity this)
        if(dt < this.dmg_duration)
                this.nextthink = time + 0.05; // soon
        else
-               remove(this);
+               delete(this);
 }
 
 void W_Hook_Explode2(entity this)
@@ -115,7 +115,7 @@ void W_Hook_Explode2(entity this)
        this.dmg_duration = WEP_CVAR_SEC(hook, duration);
        this.teleport_time = time;
        this.dmg_last = 1;
-       this.movetype = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
 }
 
 void W_Hook_Explode2_use(entity this, entity actor, entity trigger)
@@ -152,7 +152,7 @@ void W_Hook_Attack2(Weapon thiswep, entity actor)
        gren.owner = gren.realowner = actor;
        gren.bot_dodge = true;
        gren.bot_dodgerating = WEP_CVAR_SEC(hook, damage);
-       gren.movetype = MOVETYPE_TOSS;
+       set_movetype(gren, MOVETYPE_TOSS);
        PROJECTILE_MAKETRIGGER(gren);
        gren.projectiledeathtype = WEP_HOOK.m_id | HITTYPE_SECONDARY;
        setorigin(gren, w_shotorg);
@@ -179,6 +179,7 @@ void W_Hook_Attack2(Weapon thiswep, entity actor)
 
        gren.angles = '0 0 0';
        gren.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, gren);
 
        CSQCProjectile(gren, true, PROJECTILE_HOOKBOMB, true);
 
@@ -541,6 +542,7 @@ NET_HANDLE(ENT_CLIENT_HOOK, bool bIsNew)
        if(bIsNew || !this.teleport_time)
        {
                this.draw = Draw_GrapplingHook;
+               IL_PUSH(g_drawables, this);
                this.entremove = Remove_GrapplingHook;
 
                switch(this.HookType)
index 331e2dd92925c8d768351e8cf572390cc6323706..59dfc10e20ecfbb9f31b856d47a058ea432ab27e 100644 (file)
@@ -130,7 +130,10 @@ void W_MachineGun_Attack(Weapon thiswep, int deathtype, entity actor, .entity we
 
        // casing code
        if(autocvar_g_casings >= 2)
+       {
+               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);
+       }
 
        if(actor.misc_bulletcounter == 1)
                W_DecreaseAmmo(thiswep, actor, WEP_CVAR(machinegun, first_ammo));
@@ -202,7 +205,10 @@ void W_MachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity
        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(machinegun, first_refire) * W_WeaponRateFactor(actor);
@@ -226,7 +232,10 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, .entity weaponentit
        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);
+       }
 
        actor.misc_bulletcounter = actor.misc_bulletcounter + 1;
        if(actor.misc_bulletcounter == 0)
index 08b3634f41306cad37e10cf2cf67a0b3c2692c28..e5ba64f2464068102c2b5f568087c739eca3836c 100644 (file)
@@ -70,6 +70,7 @@ void W_MineLayer_Stick(entity this, entity to)
        // in order for mines to face properly when sticking to the ground, they must be a server side entity rather than a csqc projectile
 
        entity newmine = spawn();
+       IL_PUSH(g_mines, newmine);
        newmine.classname = this.classname;
 
        newmine.bot_dodge = this.bot_dodge;
@@ -91,7 +92,7 @@ void W_MineLayer_Stick(entity this, entity to)
        newmine.spawnshieldtime = this.spawnshieldtime;
        newmine.damagedbycontents = true;
 
-       newmine.movetype = MOVETYPE_NONE; // lock the mine in place
+       set_movetype(newmine, MOVETYPE_NONE); // lock the mine in place
        newmine.projectiledeathtype = this.projectiledeathtype;
 
        newmine.mine_time = this.mine_time;
@@ -101,8 +102,9 @@ void W_MineLayer_Stick(entity this, entity to)
        newmine.nextthink = time;
        newmine.cnt = this.cnt;
        newmine.flags = this.flags;
+       IL_PUSH(g_projectiles, newmine);
 
-       remove(this);
+       delete(this);
 
        if(to)
                SetMovetypeFollow(newmine, to);
@@ -135,7 +137,7 @@ void W_MineLayer_Explode(entity this, entity directhitentity)
                }
        }
        this.realowner.minelayer_mines -= 1;
-       remove(this);
+       delete(this);
 }
 
 void W_MineLayer_Explode_think(entity this)
@@ -148,7 +150,7 @@ void W_MineLayer_DoRemoteExplode(entity this)
        this.event_damage = func_null;
        this.takedamage = DAMAGE_NO;
 
-       if(this.movetype == MOVETYPE_NONE || this.movetype == MOVETYPE_FOLLOW)
+       if(this.move_movetype == MOVETYPE_NONE || this.move_movetype == MOVETYPE_FOLLOW)
                this.velocity = this.mine_orientation; // particle fx and decals need .velocity
 
        RadiusDamage(this, this.realowner, WEP_CVAR(minelayer, remote_damage), WEP_CVAR(minelayer, remote_edgedamage), WEP_CVAR(minelayer, remote_radius), NULL, NULL, WEP_CVAR(minelayer, remote_force), this.projectiledeathtype | HITTYPE_BOUNCE, NULL);
@@ -166,7 +168,7 @@ void W_MineLayer_DoRemoteExplode(entity this)
                }
        }
        this.realowner.minelayer_mines -= 1;
-       remove(this);
+       delete(this);
 }
 
 void W_MineLayer_RemoteExplode(entity this)
@@ -203,9 +205,10 @@ void W_MineLayer_ProximityExplode(entity this)
 int W_MineLayer_Count(entity e)
 {
        int minecount = 0;
-       entity mine;
-       for(mine = NULL; (mine = find(mine, classname, "mine")); ) if(mine.realowner == e)
+       IL_EACH(g_mines, it.realowner == e,
+       {
                minecount += 1;
+       });
 
        return minecount;
 }
@@ -216,12 +219,12 @@ void W_MineLayer_Think(entity this)
 
        this.nextthink = time;
 
-       if(this.movetype == MOVETYPE_FOLLOW)
+       if(this.move_movetype == MOVETYPE_FOLLOW)
        {
                if(LostMovetypeFollow(this))
                {
                        UnsetMovetypeFollow(this);
-                       this.movetype = MOVETYPE_NONE;
+                       set_movetype(this, MOVETYPE_NONE);
                }
        }
 
@@ -274,7 +277,7 @@ void W_MineLayer_Think(entity this)
 
 void W_MineLayer_Touch(entity this, entity toucher)
 {
-       if(this.movetype == MOVETYPE_NONE || this.movetype == MOVETYPE_FOLLOW)
+       if(this.move_movetype == MOVETYPE_NONE || this.move_movetype == MOVETYPE_FOLLOW)
                return; // we're already a stuck mine, why do we get called? TODO does this even happen?
 
        if(WarpZone_Projectile_Touch(this, toucher))
@@ -335,6 +338,7 @@ void W_MineLayer_Attack(Weapon thiswep, entity actor)
        Send_Effect(EFFECT_ROCKET_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
        mine = WarpZone_RefSys_SpawnSameRefSys(actor);
+       IL_PUSH(g_mines, mine);
        mine.owner = mine.realowner = actor;
        if(WEP_CVAR(minelayer, detonatedelay) >= 0)
                mine.spawnshieldtime = time + WEP_CVAR(minelayer, detonatedelay);
@@ -350,7 +354,7 @@ void W_MineLayer_Attack(Weapon thiswep, entity actor)
        mine.event_damage = W_MineLayer_Damage;
        mine.damagedbycontents = true;
 
-       mine.movetype = MOVETYPE_TOSS;
+       set_movetype(mine, MOVETYPE_TOSS);
        PROJECTILE_MAKETRIGGER(mine);
        mine.projectiledeathtype = WEP_MINE_LAYER.m_id;
        setsize(mine, '-4 -4 -4', '4 4 4'); // give it some size so it can be shot
@@ -364,6 +368,7 @@ void W_MineLayer_Attack(Weapon thiswep, entity actor)
        mine.nextthink = time;
        mine.cnt = (WEP_CVAR(minelayer, lifetime) - WEP_CVAR(minelayer, lifetime_countdown));
        mine.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, mine);
        mine.missile_flags = MIF_SPLASH | MIF_ARC | MIF_PROXY;
 
        if(mine.cnt > 0) { mine.cnt += time; }
@@ -384,24 +389,23 @@ void W_MineLayer_Attack(Weapon thiswep, entity actor)
        actor.minelayer_mines = W_MineLayer_Count(actor);
 }
 
-float W_MineLayer_PlacedMines(entity this, float detonate)
+bool W_MineLayer_PlacedMines(entity this, bool detonate)
 {
-       entity mine;
-       float minfound = 0;
+       bool minfound = false;
 
-       for(mine = NULL; (mine = find(mine, classname, "mine")); ) if(mine.realowner == this)
+       IL_EACH(g_mines, it.realowner == this,
        {
                if(detonate)
                {
-                       if(!mine.minelayer_detonate)
+                       if(!it.minelayer_detonate)
                        {
-                               mine.minelayer_detonate = true;
-                               minfound = 1;
+                               it.minelayer_detonate = true;
+                               minfound = true;
                        }
                }
                else
-                       minfound = 1;
-       }
+                       minfound = true;
+       });
        return minfound;
 }
 
@@ -415,8 +419,7 @@ METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor))
     if(skill >= 2) // skill 0 and 1 bots won't detonate mines!
     {
         // decide whether to detonate mines
-        entity targetlist, targ;
-        float edgedamage, coredamage, edgeradius, recipricoledgeradius, d;
+        float edgedamage, coredamage, edgeradius, recipricoledgeradius;
         float selfdamage, teamdamage, enemydamage;
         edgedamage = WEP_CVAR(minelayer, edgedamage);
         coredamage = WEP_CVAR(minelayer, damage);
@@ -425,31 +428,24 @@ METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor))
         selfdamage = 0;
         teamdamage = 0;
         enemydamage = 0;
-        targetlist = findchainfloat(bot_attack, true);
-        entity mine = find(NULL, classname, "mine");
-        while(mine)
+
+        IL_EACH(g_mines, it.realowner == actor,
         {
-            if(mine.realowner != actor)
-            {
-                mine = find(mine, classname, "mine");
-                continue;
-            }
-            targ = targetlist;
-            while(targ)
-            {
-                d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - mine.origin);
-                d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
+               entity mine = it;
+               FOREACH_ENTITY_FLOAT(bot_attack, true,
+               {
+                       float d = vlen(it.origin + (it.mins + it.maxs) * 0.5 - mine.origin);
+                       d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
                 // count potential damage according to type of target
-                if(targ == actor)
+                if(it == actor)
                     selfdamage = selfdamage + d;
-                else if(targ.team == actor.team && teamplay)
+                else if(SAME_TEAM(it, actor))
                     teamdamage = teamdamage + d;
-                else if(bot_shouldattack(actor, targ))
+                else if(bot_shouldattack(actor, it))
                     enemydamage = enemydamage + d;
-                targ = targ.chain;
-            }
-            mine = find(mine, classname, "mine");
-        }
+               });
+        });
+
         float desirabledamage;
         desirabledamage = enemydamage;
         if(time > actor.invincible_finished && time > actor.spawnshieldtime)
@@ -457,41 +453,35 @@ METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor))
         if(teamplay && actor.team)
             desirabledamage = desirabledamage - teamdamage;
 
-        mine = find(NULL, classname, "mine");
-        while(mine)
+        makevectors(actor.v_angle);
+        IL_EACH(g_mines, it.realowner == actor,
         {
-            if(mine.realowner != actor)
-            {
-                mine = find(mine, classname, "mine");
-                continue;
-            }
-            makevectors(mine.v_angle);
-            targ = targetlist;
             if(skill > 9) // normal players only do this for the target they are tracking
             {
-                targ = targetlist;
-                while(targ)
-                {
-                    if(
-                        (v_forward * normalize(mine.origin - targ.origin)< 0.1)
-                        && desirabledamage > 0.1*coredamage
-                    ) PHYS_INPUT_BUTTON_ATCK2(actor) = true;
-                    targ = targ.chain;
-                }
-            }else{
-                float distance; distance= bound(300,vlen(actor.origin-actor.enemy.origin),30000);
+                   entity mine = it;
+                   FOREACH_ENTITY_FLOAT(bot_attack, true,
+                   {
+                       if((v_forward * normalize(mine.origin - it.origin) < 0.1)
+                           && desirabledamage > 0.1 * coredamage
+                           ) PHYS_INPUT_BUTTON_ATCK2(actor) = true;
+                   });
+               }
+               else
+               {
                 //As the distance gets larger, a correct detonation gets near imposible
                 //Bots are assumed to use the mine spawnfunc_light to see if the mine gets near a player
-                if(v_forward * normalize(mine.origin - actor.enemy.origin)< 0.1)
-                    if(IS_PLAYER(actor.enemy))
-                        if(desirabledamage >= 0.1*coredamage)
-                            if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1))
-                                PHYS_INPUT_BUTTON_ATCK2(actor) = true;
-            // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n");
-            }
-
-            mine = find(mine, classname, "mine");
-        }
+                if((v_forward * normalize(it.origin - actor.enemy.origin) < 0.1)
+                       && IS_PLAYER(actor.enemy)
+                       && (desirabledamage >= 0.1 * coredamage)
+                       )
+                {
+                       float distance = bound(300, vlen(actor.origin - actor.enemy.origin), 30000);
+                       if(random() / distance * 300 > frametime * bound(0, (10 - skill) * 0.2, 1))
+                               PHYS_INPUT_BUTTON_ATCK2(actor) = true;
+                }
+               }
+        });
+
         // if we would be doing at X percent of the core damage, detonate it
         // but don't fire a new shot at the same time!
         if(desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events
index 8cbe75e74b060a35721d93b453fb1af9ae3390f3..c2e0cfc70d61d14111cf73527038dd4b83b14eb4 100644 (file)
@@ -76,12 +76,12 @@ void W_Mortar_Grenade_Explode(entity this, entity directhitentity)
        this.event_damage = func_null;
        this.takedamage = DAMAGE_NO;
 
-       if(this.movetype == MOVETYPE_NONE)
+       if(this.move_movetype == MOVETYPE_NONE)
                this.velocity = this.oldvelocity;
 
        RadiusDamage(this, this.realowner, WEP_CVAR_PRI(mortar, damage), WEP_CVAR_PRI(mortar, edgedamage), WEP_CVAR_PRI(mortar, radius), NULL, NULL, WEP_CVAR_PRI(mortar, force), this.projectiledeathtype, directhitentity);
 
-       remove(this);
+       delete(this);
 }
 
 void W_Mortar_Grenade_Explode_use(entity this, entity actor, entity trigger)
@@ -101,12 +101,12 @@ void W_Mortar_Grenade_Explode2(entity this, entity directhitentity)
        this.event_damage = func_null;
        this.takedamage = DAMAGE_NO;
 
-       if(this.movetype == MOVETYPE_NONE)
+       if(this.move_movetype == MOVETYPE_NONE)
                this.velocity = this.oldvelocity;
 
        RadiusDamage(this, this.realowner, WEP_CVAR_SEC(mortar, damage), WEP_CVAR_SEC(mortar, edgedamage), WEP_CVAR_SEC(mortar, radius), NULL, NULL, WEP_CVAR_SEC(mortar, force), this.projectiledeathtype, directhitentity);
 
-       remove(this);
+       delete(this);
 }
 
 void W_Mortar_Grenade_Explode2_use(entity this, entity actor, entity trigger)
@@ -155,14 +155,14 @@ void W_Mortar_Grenade_Touch1(entity this, entity toucher)
                this.projectiledeathtype |= HITTYPE_BOUNCE;
                this.gl_bouncecnt += 1;
        }
-       else if(WEP_CVAR_PRI(mortar, type) == 2 && (!toucher || (toucher.takedamage != DAMAGE_AIM && toucher.movetype == MOVETYPE_NONE))) // stick
+       else if(WEP_CVAR_PRI(mortar, type) == 2 && (!toucher || (toucher.takedamage != DAMAGE_AIM && toucher.move_movetype == MOVETYPE_NONE))) // stick
        {
                spamsound(this, CH_SHOTS, SND(GRENADE_STICK), VOL_BASE, ATTN_NORM);
 
                // let it stick whereever it is
                this.oldvelocity = this.velocity;
                this.velocity = '0 0 0';
-               this.movetype = MOVETYPE_NONE; // also disables gravity
+               set_movetype(this, MOVETYPE_NONE); // also disables gravity
                this.gravity = 0; // nope, it does NOT! maybe a bug in CSQC code? TODO
                UpdateCSQCProjectile(this);
 
@@ -191,14 +191,14 @@ void W_Mortar_Grenade_Touch2(entity this, entity toucher)
                        this.nextthink = time + WEP_CVAR_SEC(mortar, lifetime_bounce);
 
        }
-       else if(WEP_CVAR_SEC(mortar, type) == 2 && (!toucher || (toucher.takedamage != DAMAGE_AIM && toucher.movetype == MOVETYPE_NONE))) // stick
+       else if(WEP_CVAR_SEC(mortar, type) == 2 && (!toucher || (toucher.takedamage != DAMAGE_AIM && toucher.move_movetype == MOVETYPE_NONE))) // stick
        {
                spamsound(this, CH_SHOTS, SND(GRENADE_STICK), VOL_BASE, ATTN_NORM);
 
                // let it stick whereever it is
                this.oldvelocity = this.velocity;
                this.velocity = '0 0 0';
-               this.movetype = MOVETYPE_NONE; // also disables gravity
+               set_movetype(this, MOVETYPE_NONE); // also disables gravity
                this.gravity = 0; // nope, it does NOT! maybe a bug in CSQC code? TODO
                UpdateCSQCProjectile(this);
 
@@ -224,7 +224,7 @@ void W_Mortar_Attack(Weapon thiswep, entity actor)
        gren.owner = gren.realowner = actor;
        gren.bot_dodge = true;
        gren.bot_dodgerating = WEP_CVAR_PRI(mortar, damage);
-       gren.movetype = MOVETYPE_BOUNCE;
+       set_movetype(gren, MOVETYPE_BOUNCE);
        gren.bouncefactor = WEP_CVAR(mortar, bouncefactor);
        gren.bouncestop = WEP_CVAR(mortar, bouncestop);
        PROJECTILE_MAKETRIGGER(gren);
@@ -248,6 +248,7 @@ void W_Mortar_Attack(Weapon thiswep, entity actor)
 
        gren.angles = vectoangles(gren.velocity);
        gren.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, gren);
 
        if(WEP_CVAR_PRI(mortar, type) == 0 || WEP_CVAR_PRI(mortar, type) == 2)
                CSQCProjectile(gren, true, PROJECTILE_GRENADE, true);
@@ -272,7 +273,7 @@ void W_Mortar_Attack2(Weapon thiswep, entity actor)
        gren.owner = gren.realowner = actor;
        gren.bot_dodge = true;
        gren.bot_dodgerating = WEP_CVAR_SEC(mortar, damage);
-       gren.movetype = MOVETYPE_BOUNCE;
+       set_movetype(gren, MOVETYPE_BOUNCE);
        gren.bouncefactor = WEP_CVAR(mortar, bouncefactor);
        gren.bouncestop = WEP_CVAR(mortar, bouncestop);
        PROJECTILE_MAKETRIGGER(gren);
@@ -295,6 +296,7 @@ void W_Mortar_Attack2(Weapon thiswep, entity actor)
 
        gren.angles = vectoangles(gren.velocity);
        gren.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, gren);
 
        if(WEP_CVAR_SEC(mortar, type) == 0 || WEP_CVAR_SEC(mortar, type) == 2)
                CSQCProjectile(gren, true, PROJECTILE_GRENADE, true);
index dbcad2c1e6d8e177666ebfb0b40e9141ba2f13a9..401e4e2059d41d553ccaf3b17fe4e5f6e2977f6a 100644 (file)
@@ -62,7 +62,7 @@ void W_Porto_Success(entity this)
        }
 
        this.realowner.porto_current = NULL;
-       remove(this);
+       delete(this);
 }
 
 string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector velo);
@@ -98,7 +98,7 @@ void W_Porto_Fail(entity this, float failhard)
                        }
                }
        }
-       remove(this);
+       delete(this);
 }
 
 void W_Porto_Remove(entity p)
@@ -113,7 +113,7 @@ void W_Porto_Think(entity this)
 {
        trace_plane_normal = '0 0 0';
        if(this.realowner.playerid != this.playerid)
-               remove(this);
+               delete(this);
        else
                W_Porto_Fail(this, 0);
 }
@@ -143,7 +143,7 @@ void W_Porto_Touch(entity this, entity toucher)
        if(this.realowner.playerid != this.playerid)
        {
                sound(this, CH_SHOTS, SND_PORTO_UNSUPPORTED, VOL_BASE, ATTEN_NORM);
-               remove(this);
+               delete(this);
        }
        else if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP)
        {
@@ -257,7 +257,7 @@ void W_Porto_Attack(entity actor, float type)
        gren.playerid = actor.playerid;
        gren.bot_dodge = true;
        gren.bot_dodgerating = 200;
-       gren.movetype = MOVETYPE_BOUNCEMISSILE;
+       set_movetype(gren, MOVETYPE_BOUNCEMISSILE);
        PROJECTILE_MAKETRIGGER(gren);
        gren.effects = EF_RED;
        gren.scale = 4;
@@ -275,6 +275,7 @@ void W_Porto_Attack(entity actor, float type)
 
        gren.angles = vectoangles(gren.velocity);
        gren.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, gren);
 
        gren.portal_id = time;
        actor.porto_current = gren;
index 13e44531029ae8b1c47d7adb2146a8e238653a67..c46b8f2b2cc8cd859add380552083e8839a7c879 100644 (file)
@@ -76,7 +76,10 @@ void W_Rifle_FireBullet(Weapon thiswep, float pSpread, float pDamage, float pFor
                fireBullet(actor, w_shotorg, w_shotdir, pSpread, pSolidPenetration, pDamage, pForce, deathtype, (pTracer ? EF_RED : EF_BLUE));
 
        if(autocvar_g_casings >= 2)
+    {
+        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);
+    }
 }
 
 void W_Rifle_Attack(entity actor)
index 524c6791f922b912bae8e0e788baa32ffdb927fa..42487b5a3cb423082c5cdfe4c8e3bdc9dbafb256 100644 (file)
@@ -99,7 +99,7 @@ void W_Seeker_Missile_Explode(entity this, entity directhitentity)
        this.event_damage = func_null;
        RadiusDamage(this, this.realowner, WEP_CVAR(seeker, missile_damage), WEP_CVAR(seeker, missile_edgedamage), WEP_CVAR(seeker, missile_radius), NULL, NULL, WEP_CVAR(seeker, missile_force), this.projectiledeathtype, directhitentity);
 
-       remove(this);
+       delete(this);
 }
 
 void W_Seeker_Missile_Explode_think(entity this)
@@ -244,9 +244,9 @@ void W_Seeker_Missile_Animate(entity this)
                this.nextthink       = time;// + cvar("g_balance_seeker_missile_activate_delay"); // cant dealy with csqc projectiles
 
                if(autocvar_g_balance_seeker_missile_proxy)
-                       this.movetype    = MOVETYPE_BOUNCEMISSILE;
+                       this.move_movetype    = MOVETYPE_BOUNCEMISSILE;
                else
-                       this.movetype    = MOVETYPE_FLYMISSILE;
+                       this.move_movetype    = MOVETYPE_FLYMISSILE;
        }
 
        UpdateCSQCProjectile(this);
@@ -293,8 +293,9 @@ void W_Seeker_Fire_Missile(Weapon thiswep, entity actor, vector f_diff, entity m
 
        setorigin(missile, w_shotorg);
        setsize(missile, '-4 -4 -4', '4 4 4');
-       missile.movetype    = MOVETYPE_FLYMISSILE;
-       missile.flags       = FL_PROJECTILE;
+       set_movetype(missile, MOVETYPE_FLYMISSILE);
+       missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
        missile.missile_flags = MIF_SPLASH | MIF_GUIDED_TAG;
 
        W_SetupProjVelocity_UP_PRE(missile, seeker, missile_);
@@ -315,7 +316,7 @@ void W_Seeker_Flac_Explode(entity this, entity directhitentity)
 
        RadiusDamage(this, this.realowner, WEP_CVAR(seeker, flac_damage), WEP_CVAR(seeker, flac_edgedamage), WEP_CVAR(seeker, flac_radius), NULL, NULL, WEP_CVAR(seeker, flac_force), this.projectiledeathtype, directhitentity);
 
-       remove(this);
+       delete(this);
 }
 
 void W_Seeker_Flac_Touch(entity this, entity toucher)
@@ -367,10 +368,11 @@ void W_Seeker_Fire_Flac(Weapon thiswep, entity actor)
        setthink(missile, adaptor_think2use_hittype_splash);
        missile.nextthink               = time + WEP_CVAR(seeker, flac_lifetime) + WEP_CVAR(seeker, flac_lifetime_rand);
        missile.solid                   = SOLID_BBOX;
-       missile.movetype                = MOVETYPE_FLY;
+       set_movetype(missile, MOVETYPE_FLY);
        missile.projectiledeathtype = WEP_SEEKER.m_id;
        missile.projectiledeathtype = WEP_SEEKER.m_id | HITTYPE_SECONDARY;
-       missile.flags                           = FL_PROJECTILE;
+       missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
        missile.missile_flags       = MIF_SPLASH;
 
        // csqc projectiles
@@ -431,7 +433,7 @@ void W_Seeker_Vollycontroller_Think(entity this) // TODO: Merge this with W_Seek
        Weapon thiswep = WEP_SEEKER;
        if((!(this.realowner.items & IT_UNLIMITED_AMMO) && this.realowner.(thiswep.ammo_field) < WEP_CVAR(seeker, missile_ammo)) || (this.cnt <= -1) || (IS_DEAD(this.realowner)) || (PS(this.realowner).m_switchweapon != WEP_SEEKER))
        {
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -472,7 +474,7 @@ void W_Seeker_Tracker_Think(entity this)
                if(this)
                {
                        WaypointSprite_Kill(this.tag_target.wps_tag_tracker);
-                       remove(this);
+                       delete(this);
                }
                return;
        }
@@ -490,7 +492,7 @@ void W_Seeker_Tag_Explode(entity this)
        //    return;
        Damage_DamageInfo(this.origin, 0, 0, 0, this.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE, 0, this);
 
-       remove(this);
+       delete(this);
 }
 
 void W_Seeker_Tag_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
@@ -560,7 +562,7 @@ void W_Seeker_Tag_Touch(entity this, entity toucher)
                }
        }
 
-       remove(this);
+       delete(this);
        return;
 }
 
@@ -578,7 +580,7 @@ void W_Seeker_Fire_Tag(Weapon thiswep, entity actor)
        settouch(missile, W_Seeker_Tag_Touch);
        setthink(missile, SUB_Remove);
        missile.nextthink       = time + WEP_CVAR(seeker, tag_lifetime);
-       missile.movetype        = MOVETYPE_FLY;
+       set_movetype(missile, MOVETYPE_FLY);
        missile.solid           = SOLID_BBOX;
 
        missile.takedamage       = DAMAGE_YES;
@@ -589,10 +591,11 @@ void W_Seeker_Fire_Tag(Weapon thiswep, entity actor)
        setorigin(missile, w_shotorg);
        setsize(missile, '-2 -2 -2', '2 2 2');
 
-       missile.flags       = FL_PROJECTILE;
+       missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
        //missile.missile_flags = MIF_..?;
 
-       missile.movetype    = MOVETYPE_FLY;
+       set_movetype(missile, MOVETYPE_FLY);
        W_SetupProjVelocity_PRE(missile, seeker, tag_);
        missile.angles = vectoangles(missile.velocity);
 
index 786671c31fd5f4d1c871fde31046e81ba0d85645..f143bd1cc2e0fe7703d7d3ea1364ae36e40c4d50 100644 (file)
@@ -2,7 +2,7 @@
 CLASS(Shockwave, Weapon)
 /* ammotype  */ //ATTRIB(Shockwave, ammo_field, .int, ammo_none)
 /* impulse   */ ATTRIB(Shockwave, impulse, int, 2)
-/* flags     */ ATTRIB(Shockwave, spawnflags, int, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN | WEP_FLAG_CANCLIMB | WEP_FLAG_MUTATORBLOCKED);
+/* flags     */ ATTRIB(Shockwave, spawnflags, int, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN | WEP_FLAG_CANCLIMB | WEP_TYPE_MELEE_SEC);
 /* rating    */ ATTRIB(Shockwave, bot_pickupbasevalue, float, BOT_PICKUP_RATING_LOW);
 /* color     */ ATTRIB(Shockwave, wpcolor, vector, '0.5 0.25 0');
 /* modelname */ ATTRIB(Shockwave, mdl, string, "shotgun");
@@ -11,7 +11,7 @@ CLASS(Shockwave, Weapon)
 #endif
 /* crosshair */ ATTRIB(Shockwave, w_crosshair, string, "gfx/crosshairshotgun");
 /* crosshair */ ATTRIB(Shockwave, w_crosshair_size, float, 0.7);
-/* wepimg    */ ATTRIB(Shockwave, model2, string, "weaponshotgun");
+/* wepimg    */ ATTRIB(Shockwave, model2, string, "weaponshockwave");
 /* refname   */ ATTRIB(Shockwave, netname, string, "shockwave");
 /* wepname   */ ATTRIB(Shockwave, m_name, string, _("Shockwave"));
 
@@ -122,7 +122,7 @@ void W_Shockwave_Melee_Think(entity this)
        // check to see if we can still continue, otherwise give up now
        if(IS_DEAD(this.realowner) && WEP_CVAR(shockwave, melee_no_doubleslap))
        {
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -214,7 +214,7 @@ void W_Shockwave_Melee_Think(entity this)
                        }
                        else
                        {
-                               remove(this);
+                               delete(this);
                                return;
                        }
                }
@@ -223,7 +223,7 @@ void W_Shockwave_Melee_Think(entity this)
        if(time >= this.cnt + meleetime)
        {
                // melee is finished
-               remove(this);
+               delete(this);
                return;
        }
        else
@@ -366,7 +366,7 @@ void W_Shockwave_Attack(entity actor)
        float i, queue = 0;
 
        // set up the shot direction
-       W_SetupShot(actor, false, 3, SND_LASERGUN_FIRE, CH_WEAPON_B, WEP_CVAR(shockwave, blast_damage));
+       W_SetupShot(actor, true, 3, SND_LASERGUN_FIRE, CH_WEAPON_B, WEP_CVAR(shockwave, blast_damage));
        vector attack_endpos = (w_shotorg + (w_shotdir * WEP_CVAR(shockwave, blast_distance)));
        WarpZone_TraceLine(w_shotorg, attack_endpos, MOVE_NOMONSTERS, actor);
        vector attack_hitpos = trace_endpos;
@@ -397,6 +397,22 @@ void W_Shockwave_Attack(entity actor)
                false
        );
 
+       float lag = ANTILAG_LATENCY(actor);
+       if(lag < 0.001)
+               lag = 0;
+       if (!IS_REAL_CLIENT(actor))
+               lag = 0;
+       if(autocvar_g_antilag == 0 || actor.cvar_cl_noantilag)
+               lag = 0; // only do hitscan, but no antilag
+       if(lag)
+       {
+               FOREACH_CLIENT(IS_PLAYER(it) && it != actor, antilag_takeback(it, CS(it), time - lag));
+               IL_EACH(g_monsters, it != actor,
+               {
+                       antilag_takeback(it, it, time - lag);
+               });
+       }
+
        while(head)
        {
                if(head.takedamage)
@@ -570,7 +586,7 @@ void W_Shockwave_Attack(entity actor)
                        vector nearest_on_line = (w_shotorg + a * w_shotdir);
                        vector nearest_to_attacker = WarpZoneLib_NearestPointOnBox(center + head.mins, center + head.maxs, nearest_on_line);
 
-                       if((vlen(head.WarpZone_findradius_dist) <= WEP_CVAR(shockwave, blast_distance))
+                       if((vdist(head.WarpZone_findradius_dist, <=, WEP_CVAR(shockwave, blast_distance)))
                                && (W_Shockwave_Attack_IsVisible(actor, head, nearest_on_line, w_shotorg, attack_endpos)))
                        {
                                // calculate importance of distance and accuracy for this attack
@@ -651,11 +667,8 @@ void W_Shockwave_Attack(entity actor)
                        final_force
                );
 
-               if(accuracy_isgooddamage(actor.realowner, head))
-               {
-                       LOG_INFO("wtf\n");
-                       accuracy_add(actor.realowner, WEP_SHOCKWAVE.m_id, 0, final_damage);
-               }
+               if(accuracy_isgooddamage(actor, head))
+                       accuracy_add(actor, WEP_SHOCKWAVE.m_id, 0, final_damage);
 
                #ifdef DEBUG_SHOCKWAVE
                LOG_INFO(sprintf(
@@ -670,6 +683,15 @@ void W_Shockwave_Attack(entity actor)
                shockwave_hit_force[i-1] = '0 0 0';
                shockwave_hit_damage[i-1] = 0;
        }
+
+       if(lag)
+       {
+               FOREACH_CLIENT(IS_PLAYER(it) && it != actor, antilag_restore(it, CS(it)));
+               IL_EACH(g_monsters, it != actor,
+               {
+                       antilag_restore(it, it);
+               });
+       }
 }
 
 METHOD(Shockwave, wr_aim, void(entity thiswep, entity actor))
@@ -735,7 +757,7 @@ void Draw_Shockwave(entity this)
 {
        // fading/removal control
        float a = bound(0, (SW_MAXALPHA - ((time - this.sw_time) / SW_FADETIME)), SW_MAXALPHA);
-       if(a < ALPHA_MIN_VISIBLE) { remove(this); }
+       if(a < ALPHA_MIN_VISIBLE) { delete(this); }
 
        // WEAPONTODO: save this only once when creating the entity
        vector sw_color = entcs_GetColor(this.sv_entnum - 1); // GetTeamRGB(entcs_GetTeam(this.sv_entnum));
@@ -840,6 +862,7 @@ void Net_ReadShockwaveParticle()
        entity shockwave;
        shockwave = spawn();
        shockwave.draw = Draw_Shockwave;
+       IL_PUSH(g_drawables, shockwave);
 
        shockwave.sw_shotorg_x = ReadCoord(); shockwave.sw_shotorg_y = ReadCoord(); shockwave.sw_shotorg_z = ReadCoord();
        shockwave.sw_shotdir_x = ReadCoord(); shockwave.sw_shotdir_y = ReadCoord(); shockwave.sw_shotdir_z = ReadCoord();
index 34d2e462c724008eda9063150624d9547b3248dc..b03c6fb4da31ae397691e2bf66981dd6383975e7 100644 (file)
@@ -2,7 +2,7 @@
 CLASS(Shotgun, Weapon)
 /* ammotype  */ ATTRIB(Shotgun, ammo_field, .int, ammo_shells)
 /* impulse   */ ATTRIB(Shotgun, impulse, int, 2)
-/* flags     */ ATTRIB(Shotgun, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN);
+/* flags     */ ATTRIB(Shotgun, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_TYPE_MELEE_SEC);
 /* rating    */ ATTRIB(Shotgun, bot_pickupbasevalue, float, BOT_PICKUP_RATING_LOW);
 /* color     */ ATTRIB(Shotgun, wpcolor, vector, '0.5 0.25 0');
 /* modelname */ ATTRIB(Shotgun, mdl, string, "shotgun");
@@ -60,24 +60,24 @@ spawnfunc(weapon_shotgun) { weapon_defaultspawnfunc(this, WEP_SHOTGUN); }
 
 void W_Shotgun_Attack(Weapon thiswep, entity actor, float isprimary)
 {
-       float   sc;
-       entity flash;
-
        W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(shotgun, ammo));
 
        W_SetupShot(actor, true, 5, SND_SHOTGUN_FIRE, ((isprimary) ? CH_WEAPON_A : CH_WEAPON_SINGLE), WEP_CVAR_PRI(shotgun, damage) * WEP_CVAR_PRI(shotgun, bullets));
-       for(sc = 0;sc < WEP_CVAR_PRI(shotgun, bullets);sc = sc + 1)
+       for(int sc = 0;sc < WEP_CVAR_PRI(shotgun, bullets);sc = sc + 1)
                fireBullet(actor, w_shotorg, w_shotdir, WEP_CVAR_PRI(shotgun, spread), WEP_CVAR_PRI(shotgun, solidpenetration), WEP_CVAR_PRI(shotgun, damage), WEP_CVAR_PRI(shotgun, force), WEP_SHOTGUN.m_id, 0);
 
        Send_Effect(EFFECT_SHOTGUN_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, WEP_CVAR_PRI(shotgun, ammo));
 
        // casing code
        if(autocvar_g_casings >= 1)
-               for(sc = 0;sc < WEP_CVAR_PRI(shotgun, ammo);sc = sc + 1)
+       {
+               makevectors(actor.v_angle); // for some reason, this is lost
+               //for(int sc = 0;sc < WEP_CVAR_PRI(shotgun, ammo);sc = sc + 1)
                        SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 30) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 1, actor);
+       }
 
        // muzzle flash for 1st person view
-       flash = spawn();
+       entity flash = spawn();
        setmodel(flash, MDL_SHOTGUN_MUZZLEFLASH); // precision set below
        setthink(flash, SUB_Remove);
        flash.nextthink = time + 0.06;
@@ -110,7 +110,7 @@ void W_Shotgun_Melee_Think(entity this)
        // check to see if we can still continue, otherwise give up now
        if(IS_DEAD(this.realowner) && WEP_CVAR_SEC(shotgun, melee_no_doubleslap))
        {
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -163,7 +163,7 @@ void W_Shotgun_Melee_Think(entity this)
                        }
                        else
                        {
-                               remove(this);
+                               delete(this);
                                return;
                        }
                }
@@ -172,7 +172,7 @@ void W_Shotgun_Melee_Think(entity this)
        if(time >= this.cnt + meleetime)
        {
                // melee is finished
-               remove(this);
+               delete(this);
                return;
        }
        else
index c0e0ac89ba89814e3fd8fab83b8e0f8e30a00a41..6d8182aab8cc7a357dcefe997ef7e22ffa233f57 100644 (file)
@@ -179,7 +179,7 @@ void W_Tuba_NoteOff(entity this)
                        }
                }
        }
-       remove(this);
+       delete(this);
 }
 
 int W_Tuba_GetNote(entity pl, int hittype)
@@ -563,9 +563,9 @@ void Ent_TubaNote_Think(entity this)
                sound(this, CH_TUBA_SINGLE, SND_Null, 0, 0);
                if (this.enemy) {
                        sound(this.enemy, CH_TUBA_SINGLE, SND_Null, 0, 0);
-                       remove(this.enemy);
+                       delete(this.enemy);
                }
-               remove(this);
+               delete(this);
        } else {
                tubasound(this, 0);
        }
index 8a2fbdac3c30205abe3fed8ae1e0101d311dad62..488b5af2785a654d7e76c1a83fc847dae7ce43fe 100644 (file)
@@ -140,6 +140,7 @@ NET_HANDLE(TE_CSQC_VAPORBEAMPARTICLE, bool isNew)
        setthink(this, SUB_Remove);
        this.nextthink = time + bound(0, autocvar_cl_vaporizerbeam_lifetime, 10);
        this.draw = VaporizerBeam_Draw;
+       if (isNew) IL_PUSH(g_drawables, this);
        this.drawmask = MASK_NORMAL;
 
        this.vorg1_x = ReadCoord(); this.vorg1_y = ReadCoord(); this.vorg1_z = ReadCoord();
@@ -157,7 +158,7 @@ NET_HANDLE(TE_CSQC_VAPORBEAMPARTICLE, bool isNew)
                WarpZone_TrailParticles(NULL, particleeffectnum(((this.cnt) ? EFFECT_VAPORIZER_HIT(this.team) : EFFECT_VAPORIZER(this.team))), this.vorg1, this.vorg2);
                this.draw = func_null;
                this.drawmask = MASK_NORMAL;
-               remove(this);
+               delete(this);
        }
 
        return true;
@@ -176,7 +177,7 @@ void W_RocketMinsta_Explosion(entity actor, vector loc)
        dmgent.owner = dmgent.realowner = actor;
        setorigin(dmgent, loc);
        RadiusDamage (dmgent, actor, autocvar_g_rm_damage, autocvar_g_rm_edgedamage, autocvar_g_rm_radius, NULL, NULL, autocvar_g_rm_force, WEP_DEVASTATOR.m_id | HITTYPE_SPLASH, other);
-       remove(dmgent);
+       delete(dmgent);
 }
 
 void W_Vaporizer_Attack(Weapon thiswep, entity actor)
@@ -225,7 +226,7 @@ void W_RocketMinsta_Laser_Explode (entity this)
        this.event_damage = func_null;
        this.takedamage = DAMAGE_NO;
        RadiusDamage (this, this.realowner, this.rm_damage, this.rm_edmg, autocvar_g_rm_laser_radius, NULL, NULL, this.rm_force, this.projectiledeathtype, other);
-       remove(this);
+       delete(this);
 }
 
 void W_RocketMinsta_Laser_Explode_use(entity this, entity actor, entity trigger)
@@ -238,7 +239,7 @@ void W_RocketMinsta_Laser_Touch(entity this, entity toucher)
        PROJECTILE_TOUCH(this, toucher);
        //W_RocketMinsta_Laser_Explode ();
        RadiusDamage(this, this.realowner, this.rm_damage, this.rm_edmg, autocvar_g_rm_laser_radius, NULL, NULL, this.rm_force, this.projectiledeathtype, toucher);
-       remove(this);
+       delete(this);
 }
 
 void W_RocketMinsta_Attack2(entity actor)
@@ -277,7 +278,7 @@ void W_RocketMinsta_Attack2(entity actor)
 
         //W_SetupProjectileVelocity(proj, autocvar_g_rm_laser_speed, spread * (rndspread ? random() : 1) * autocvar_g_rm_laser_speed);
 
-        proj.movetype = MOVETYPE_BOUNCEMISSILE;
+        set_movetype(proj, MOVETYPE_BOUNCEMISSILE);
         //W_SETUPPROJECTILEVELOCITY(proj, g_balance_minstanex_laser);
                proj.velocity = (w_shotdir + (((counter + 0.5) / total) * 2 - 1) * v_right * (spread * (rndspread ? random() : 1))) * cvar("g_rm_laser_speed");
                proj.velocity_z = proj.velocity_z + cvar("g_rm_laser_zspread") * (random() - 0.5);
@@ -286,6 +287,7 @@ void W_RocketMinsta_Attack2(entity actor)
         settouch(proj, W_RocketMinsta_Laser_Touch);
         setsize(proj, '0 0 -3', '0 0 -3');
         proj.flags = FL_PROJECTILE;
+        IL_PUSH(g_projectiles, proj);
         proj.missile_flags = MIF_SPLASH;
 
         CSQCProjectile(proj, true, PROJECTILE_ROCKETMINSTA_LASER, true);
@@ -329,13 +331,14 @@ void W_RocketMinsta_Attack3 (entity actor)
 
         //W_SetupProjectileVelocity(proj, autocvar_g_rm_laser_speed, spread * (rndspread ? random() : 1) * autocvar_g_rm_laser_speed);
 
-        proj.movetype = MOVETYPE_BOUNCEMISSILE;
+        set_movetype(proj, MOVETYPE_BOUNCEMISSILE);
                proj.velocity = w_shotdir * autocvar_g_rm_laser_speed;
                proj.velocity = W_CalculateProjectileVelocity(actor, actor.velocity, proj.velocity, true);
         proj.angles = vectoangles(proj.velocity);
         settouch(proj, W_RocketMinsta_Laser_Touch);
         setsize(proj, '0 0 -3', '0 0 -3');
         proj.flags = FL_PROJECTILE;
+        IL_PUSH(g_projectiles, proj);
         proj.missile_flags = MIF_SPLASH;
 
         CSQCProjectile(proj, true, PROJECTILE_ROCKETMINSTA_LASER, true);
index 240eec0c1cf5d7fd1f8a79e170eb407917347e06..01fa43aaf28d2669bdc0132b2ecc5df5ad503c80 100644 (file)
@@ -55,6 +55,21 @@ float sound_starttime;
 
 # SVQC
 
+Main loop:
+* SV_Physics()
+    * StartFrame()
+    * if (force_retouch)
+        * foreach entity:
+            * .touch()
+    * foreach client:
+        * PlayerPreThink()
+        * .think()
+        * PlayerPostThink()
+    * foreach nonclient:
+        * .think()
+    * EndFrame()
+
+
 ```
 
 .entity clientcamera;
index c0e6d3ba728e738b5cc7f431e2025501df0278e4..939a86adb359c502e8ddc767da306077ec6256f7 100644 (file)
@@ -40,6 +40,8 @@ int(string s1, string s2, int len) _strncasecmp = #230;
 int() _buf_create = #440;
 #define buf_create _buf_create
 
+bool(entity ent) wasfreed = #353;
+
 #pragma noref 0
 
 #endif
index db8752d2bb8075d2f9611c3c776830c6d682540d..9419dceea18aafb7f8e75f1063b0ab8a3d79c523 100644 (file)
@@ -6,6 +6,7 @@
 #undef error
 #undef movetogoal
 #undef objerror
+#undef remove
 #undef walkmove
 
 #ifdef MENUQC
index b24d0120a49e56a0bee597379b3522e454013949..801b8731bc89bf08bdcf8d5ed52c445763986c3e 100644 (file)
@@ -6,4 +6,5 @@
 #define error builtin_error
 #define movetogoal builtin_movetogoal
 #define objerror builtin_objerror
+#define remove builtin_remove
 #define walkmove builtin_walkmove
index 9fd6ad6948ac5e7b2501d338ea2b0f338743759c..d49094f7b48c68019752dd871f46ee360bd7478e 100644 (file)
@@ -44,5 +44,4 @@
 ### listening
 
     entity listener = new_pure(someListener);
-    listener.evt_$event = void(entity this) { code; };
-    subscribe(listener, $event);
+    subscribe(listener, $event, void(entity this) { code; });
index 32db1f3d3e6cb1f1b0a4f7672dfc1a058d522f07..726f693e9e8149e36ce0af9c29c6d81942c40382 100644 (file)
@@ -1,58 +1,4 @@
-/** Components always interpolate from the previous state */
-#define COMPONENT(com) \
-       void com_##com##_interpolate(entity it, float a); \
-       .bool com_##com
-
-#define FOREACH_COMPONENT(com, body) FOREACH_ENTITY_FLOAT(com_##com, true, body)
-
-
-#define EVENT(T, args) .bool evt_##T##_listener; .void args evt_##T
-
-#define emit(T, ...) \
-       MACRO_BEGIN \
-       FOREACH_ENTITY_FLOAT_ORDERED(evt_##T##_listener, true, it.evt_##T(__VA_ARGS__)); \
-       MACRO_END
-
-#define subscribe(listener, T) \
-       MACRO_BEGIN \
-       listener.evt_##T##_listener = true; \
-       MACRO_END
-
-
-/**
- * framelimit 0 is no limit, interpolation does not apply
- * framerate below minfps will result in less than 100% speed
- */
-#define SYSTEM(sys, frameLimit, minfps) \
-       void sys_##sys##_update(entity this, float dt); \
-       float autocvar_xon_sys_##sys##_dt = ((frameLimit) ? (1 / (frameLimit)) : 0); \
-       float autocvar_xon_sys_##sys##_minfps = (1 / (1 / (minfps)))
-
-#define SYSTEM_UPDATE(sys) \
-       MACRO_BEGIN \
-       static float t = 0; \
-       float dt = autocvar_xon_sys_##sys##_dt; \
-       float minfps = autocvar_xon_sys_##sys##_minfps; \
-       static float accumulator = 0; \
-       float a = 0; \
-       if (dt) { \
-               accumulator += min(frametime, 1 / (minfps)); \
-       } else { \
-               accumulator += frametime; \
-               dt = accumulator; \
-               a = 1; \
-       } \
-       while (accumulator >= dt) \
-       { \
-               time = t; \
-               FOREACH_COMPONENT(sys, sys_##sys##_update(it, dt)); \
-               t += dt; \
-               accumulator -= dt; \
-       } \
-       if (!a) a = accumulator / dt; \
-       FOREACH_COMPONENT(sys, com_##sys##_interpolate(it, a)); \
-       MACRO_END
-
+#include "_lib.qh"
 
 #include "_mod.inc"
 #include "components/_mod.inc"
diff --git a/qcsrc/ecs/_lib.qh b/qcsrc/ecs/_lib.qh
new file mode 100644 (file)
index 0000000..a617c73
--- /dev/null
@@ -0,0 +1,57 @@
+#pragma once
+
+/** Components always interpolate from the previous state */
+#define COMPONENT(com) \
+       void com_##com##_interpolate(entity it, float a); \
+       .bool com_##com
+
+#define FOREACH_COMPONENT(com, body) FOREACH_ENTITY_FLOAT(com_##com, true, body)
+
+
+#define EVENT(T, args) .bool evt_##T##_listener; .void args evt_##T
+
+#define emit(T, ...) \
+       MACRO_BEGIN \
+       FOREACH_ENTITY_FLOAT_ORDERED(evt_##T##_listener, true, it.evt_##T(__VA_ARGS__)); \
+       MACRO_END
+
+#define subscribe(listener, T, fn) \
+       MACRO_BEGIN \
+       listener.evt_##T = (fn); \
+       listener.evt_##T##_listener = true; \
+       MACRO_END
+
+
+/**
+ * framelimit 0 is no limit, interpolation does not apply
+ * framerate below minfps will result in less than 100% speed
+ */
+#define SYSTEM(sys, frameLimit, minfps) \
+       void sys_##sys##_update(entity this, float dt); \
+       float autocvar_xon_sys_##sys##_dt = ((frameLimit) ? (1 / (frameLimit)) : 0); \
+       float autocvar_xon_sys_##sys##_minfps = (1 / (1 / (minfps)))
+
+#define SYSTEM_UPDATE(sys) \
+       MACRO_BEGIN \
+       static float t = 0; \
+       float dt = autocvar_xon_sys_##sys##_dt; \
+       float minfps = autocvar_xon_sys_##sys##_minfps; \
+       static float accumulator = 0; \
+       float a = 0; \
+       if (dt) { \
+               accumulator += min(frametime, 1 / (minfps)); \
+       } else { \
+               accumulator += frametime; \
+               dt = accumulator; \
+               a = 1; \
+       } \
+       while (accumulator >= dt) \
+       { \
+               time = t; \
+               FOREACH_COMPONENT(sys, sys_##sys##_update(it, dt)); \
+               t += dt; \
+               accumulator -= dt; \
+       } \
+       if (!a) a = accumulator / dt; \
+       FOREACH_COMPONENT(sys, com_##sys##_interpolate(it, a)); \
+       MACRO_END
index 37944ca5c3f8d026ce1ae1b5a7c9da7188ec5b08..bc1c66ace4cb1746ed0b723bcfa1d7dcb4b6374a 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 COMPONENT(in);
-.vector com_in_move;
+.vector com_in_move, com_in_move_prev;
 .vector com_in_angles;
 .bool   com_in_jump;
+.bool   com_in_crouch;
index 502657e4bcbeb52db0fa319c1c41161a21f13480..f150a296c299e8d46980c1ba2d4fb278665947d4 100644 (file)
@@ -4,4 +4,23 @@ COMPONENT(phys);
 .vector com_phys_pos, com_phys_pos_prev;
 .vector com_phys_ang, com_phys_ang_prev;
 .vector com_phys_vel;
+.float com_phys_vel_max;
+.float com_phys_vel_max_air;
+.float com_phys_vel_max_air_strafe;
 .vector com_phys_acc;
+.float com_phys_acc_rate;
+.float com_phys_acc_rate_air;
+.float com_phys_acc_rate_air_strafe;
+.float com_phys_acc_rate_air_stop;
+.float com_phys_friction;
+
+.vector com_phys_gravity;
+.float com_phys_gravity_factor;
+// TODO: remove
+.bool com_phys_ground;
+.bool com_phys_air;
+.bool com_phys_ladder;
+.bool com_phys_vel_2d;
+.bool com_phys_water;
+.bool com_phys_friction_air;
+.bool move_qcphysics;
index 98fb4815c1ce28cc699a429537ea75c2643b4487..c139d72b51ed4738fb396b3407fd335324cd921a 100644 (file)
@@ -1 +1,2 @@
 // generated file; do not modify
+#include <ecs/events/physics.qc>
index 98fb4815c1ce28cc699a429537ea75c2643b4487..1e8c791ce9b403aafc843acd2e95b6aebff0e082 100644 (file)
@@ -1 +1,2 @@
 // generated file; do not modify
+#include <ecs/events/physics.qh>
diff --git a/qcsrc/ecs/events/physics.qc b/qcsrc/ecs/events/physics.qc
new file mode 100644 (file)
index 0000000..909f45c
--- /dev/null
@@ -0,0 +1 @@
+#include "physics.qh"
diff --git a/qcsrc/ecs/events/physics.qh b/qcsrc/ecs/events/physics.qh
new file mode 100644 (file)
index 0000000..df32c55
--- /dev/null
@@ -0,0 +1,3 @@
+#pragma once
+
+EVENT(phys_land, (entity this));
index f79d7f065134aaff00519783a734cb1bba4ea8b7..a5ada6cfbed8684281f77a42c6ee4b24c0c161bd 100644 (file)
@@ -1,2 +1,9 @@
 // generated file; do not modify
+#include <ecs/systems/input.qc>
 #include <ecs/systems/physics.qc>
+#ifdef CSQC
+    #include <ecs/systems/cl_physics.qc>
+#endif
+#ifdef SVQC
+    #include <ecs/systems/sv_physics.qc>
+#endif
index e71e0591c747dfe996fa2295a73d1b363ac395dc..869aefd5571e4907ba47f65867eb415a276f6767 100644 (file)
@@ -1,2 +1,3 @@
 // generated file; do not modify
+#include <ecs/systems/input.qh>
 #include <ecs/systems/physics.qh>
diff --git a/qcsrc/ecs/systems/cl_physics.qc b/qcsrc/ecs/systems/cl_physics.qc
new file mode 100644 (file)
index 0000000..206c80d
--- /dev/null
@@ -0,0 +1,30 @@
+#include "physics.qh"
+
+void sys_phys_fix(entity this, float dt)
+{
+       this.team = myteam + 1; // is this correct?
+       PHYS_WATERJUMP_TIME(this) -= dt;
+       this.oldmovement = this.movement;
+       this.movement = PHYS_INPUT_MOVEVALUES(this);
+       this.items = STAT(ITEMS, this);
+       this.spectatorspeed = STAT(SPECTATORSPEED, this);
+       if (!(PHYS_INPUT_BUTTON_JUMP(this))) // !jump
+               UNSET_JUMP_HELD(this);           // canjump = true
+       PM_ClientMovement_UpdateStatus(this);
+}
+
+bool sys_phys_override(entity this)
+{
+       // no vehicle prediction
+       return hud != HUD_NORMAL;
+}
+
+void sys_phys_monitor(entity this) {}
+
+void sys_phys_ai(entity this) {}
+
+void sys_phys_pregame_hold(entity this) {}
+
+void sys_phys_spectator_control(entity this) {}
+
+void sys_phys_fixspeed(entity this, float maxspeed_mod) {}
diff --git a/qcsrc/ecs/systems/input.qc b/qcsrc/ecs/systems/input.qc
new file mode 100644 (file)
index 0000000..eac3625
--- /dev/null
@@ -0,0 +1,7 @@
+#include "input.qh"
+
+void sys_in_update(entity this, float dt)
+{
+       this.com_in_jump = PHYS_INPUT_BUTTON_JUMP(this);
+       this.com_in_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
+}
diff --git a/qcsrc/ecs/systems/input.qh b/qcsrc/ecs/systems/input.qh
new file mode 100644 (file)
index 0000000..fc3f11a
--- /dev/null
@@ -0,0 +1,3 @@
+#pragma once
+
+SYSTEM(in, 30, 10);
index 8348b87851cc82f8e3bf6999d54bd01a6246116b..f5052b376f89f4072ca33ef968b3e4bba3d66f56 100644 (file)
@@ -1,6 +1,491 @@
 #include "physics.qh"
+#include "input.qh"
+
+.int disableclientprediction;
+
+void sys_phys_simulate(entity this, float dt);
+void sys_phys_simulate_simple(entity this, float dt);
 
 void sys_phys_update(entity this, float dt)
 {
-       PM_Main(this);
+       if (!IS_CLIENT(this)) {
+               sys_phys_simulate_simple(this, dt);
+               return;
+       }
+       sys_in_update(this, dt);
+
+       sys_phys_fix(this, dt);
+       if (sys_phys_override(this)) { return; } sys_phys_monitor(this);
+
+       this.buttons_old = PHYS_INPUT_BUTTON_MASK(this);
+       this.movement_old = this.movement;
+       this.v_angle_old = this.v_angle;
+
+       sys_phys_ai(this);
+
+       sys_phys_pregame_hold(this);
+
+       if (IS_SVQC) {
+               if (this.move_movetype == MOVETYPE_NONE) { return; }
+               // when we get here, disableclientprediction cannot be 2
+               this.disableclientprediction = (this.move_qcphysics) ? -1 : 0;
+       }
+
+       viewloc_PlayerPhysics(this);
+
+       PM_check_frozen(this);
+
+       PM_check_blocked(this);
+
+       float maxspeed_mod = (!this.in_swamp) ? 1 : this.swamp_slowdown;  // cvar("g_balance_swamp_moverate");
+
+// conveyors: first fix velocity
+       if (this.conveyor.state) { this.velocity -= this.conveyor.movedir; }
+       MUTATOR_CALLHOOK(PlayerPhysics, this);
+
+       if (!IS_PLAYER(this)) {
+               sys_phys_spectator_control(this);
+               maxspeed_mod = this.spectatorspeed;
+       }
+       sys_phys_fixspeed(this, maxspeed_mod);
+
+       if (IS_DEAD(this)) {
+               // handle water here
+               vector midpoint = ((this.absmin + this.absmax) * 0.5);
+               if (pointcontents(midpoint) == CONTENT_WATER) {
+                       this.velocity = this.velocity * 0.5;
+
+                       // do we want this?
+                       // if(pointcontents(midpoint + '0 0 2') == CONTENT_WATER)
+                       // { this.velocity_z = 70; }
+               }
+               goto end;
+       }
+
+       if (IS_SVQC && !PHYS_FIXANGLE(this)) { this.angles = '0 1 0' * this.v_angle.y; }
+       if (IS_PLAYER(this)) {
+               if (IS_ONGROUND(this)) {
+                       PM_check_hitground(this);
+                       PM_Footsteps(this);
+               } else if (IsFlying(this)) {
+                       this.wasFlying = true;
+               }
+               CheckPlayerJump(this);
+       }
+
+       if (this.flags & FL_WATERJUMP) {
+               this.velocity_x = this.movedir.x;
+               this.velocity_y = this.movedir.y;
+               if (this.waterlevel == WATERLEVEL_NONE
+                   || time > PHYS_TELEPORT_TIME(this)
+                   || PHYS_WATERJUMP_TIME(this) <= 0
+                  ) {
+                       this.flags &= ~FL_WATERJUMP;
+                       PHYS_TELEPORT_TIME(this) = 0;
+                       PHYS_WATERJUMP_TIME(this) = 0;
+               }
+       } else if (MUTATOR_CALLHOOK(PM_Physics, this, maxspeed_mod)) {
+               // handled
+       } else if (this.move_movetype == MOVETYPE_NOCLIP
+           || this.move_movetype == MOVETYPE_FLY
+           || this.move_movetype == MOVETYPE_FLY_WORLDONLY
+           || MUTATOR_CALLHOOK(IsFlying, this)) {
+               this.com_phys_friction = PHYS_FRICTION(this);
+               this.com_phys_vel_max = PHYS_MAXSPEED(this) * maxspeed_mod;
+               this.com_phys_acc_rate = PHYS_ACCELERATE(this) * maxspeed_mod;
+               this.com_phys_friction_air = true;
+               sys_phys_simulate(this, dt);
+               this.com_phys_friction_air = false;
+       } else if (this.waterlevel >= WATERLEVEL_SWIMMING) {
+               this.com_phys_vel_max = PHYS_MAXSPEED(this) * maxspeed_mod;
+               this.com_phys_acc_rate = PHYS_ACCELERATE(this) * maxspeed_mod;
+               this.com_phys_water = true;
+               sys_phys_simulate(this, dt);
+               this.com_phys_water = false;
+       } else if (time < this.ladder_time) {
+               this.com_phys_friction = PHYS_FRICTION(this);
+               this.com_phys_vel_max = PHYS_MAXSPEED(this) * maxspeed_mod;
+               this.com_phys_acc_rate = PHYS_ACCELERATE(this) * maxspeed_mod;
+               this.com_phys_gravity = '0 0 -1' * PHYS_GRAVITY(this) * dt;
+               if (PHYS_ENTGRAVITY(this)) { this.com_phys_gravity *= PHYS_ENTGRAVITY(this); }
+               this.com_phys_ladder = true;
+               this.com_phys_friction_air = true;
+               sys_phys_simulate(this, dt);
+               this.com_phys_friction_air = false;
+               this.com_phys_ladder = false;
+               this.com_phys_gravity = '0 0 0';
+       } else if (ITEMS_STAT(this) & IT_USING_JETPACK) {
+               PM_jetpack(this, maxspeed_mod);
+       } else if (IS_ONGROUND(this)) {
+               if (!WAS_ONGROUND(this)) {
+                       emit(phys_land, this);
+                       if (this.lastground < time - 0.3) {
+                               this.velocity *= (1 - PHYS_FRICTION_ONLAND(this));
+                       }
+               }
+               this.com_phys_vel_max = PHYS_MAXSPEED(this) * maxspeed_mod;
+               this.com_phys_gravity = '0 0 -1' * PHYS_GRAVITY(this) * dt;
+               if (PHYS_ENTGRAVITY(this)) { this.com_phys_gravity *= PHYS_ENTGRAVITY(this); }
+               this.com_phys_ground = true;
+               this.com_phys_vel_2d = true;
+               sys_phys_simulate(this, dt);
+               this.com_phys_vel_2d = false;
+               this.com_phys_ground = false;
+               this.com_phys_gravity = '0 0 0';
+       } else {
+               this.com_phys_acc_rate_air = PHYS_AIRACCELERATE(this) * min(maxspeed_mod, 1);
+               this.com_phys_acc_rate_air_stop = PHYS_AIRSTOPACCELERATE(this) * maxspeed_mod;
+               this.com_phys_acc_rate_air_strafe = PHYS_AIRSTRAFEACCELERATE(this) * maxspeed_mod;
+               this.com_phys_vel_max_air_strafe = PHYS_MAXAIRSTRAFESPEED(this) * maxspeed_mod;
+               this.com_phys_vel_max_air = PHYS_MAXAIRSPEED(this) * maxspeed_mod;
+               this.com_phys_vel_max = PHYS_MAXAIRSPEED(this) * min(maxspeed_mod, 1);
+               this.com_phys_air = true;
+               this.com_phys_vel_2d = true;
+               sys_phys_simulate(this, dt);
+               this.com_phys_vel_2d = false;
+               this.com_phys_air = false;
+       }
+
+       LABEL(end)
+       if (IS_ONGROUND(this)) { this.lastground = time; }
+// conveyors: then break velocity again
+       if (this.conveyor.state) { this.velocity += this.conveyor.movedir; }
+       this.lastflags = this.flags;
+
+       this.lastclassname = this.classname;
+}
+
+/** for players */
+void sys_phys_simulate(entity this, float dt)
+{
+       const vector g = -this.com_phys_gravity;
+       const bool jump = this.com_in_jump;
+
+       if (!this.com_phys_ground && !this.com_phys_air) {
+               // noclipping
+               // flying
+               // on a spawnfunc_func_ladder
+               // swimming in spawnfunc_func_water
+               // swimming
+               UNSET_ONGROUND(this);
+
+               if (this.com_phys_friction_air) {
+                       this.velocity_z += g.z / 2;
+                       this.velocity = this.velocity * (1 - dt * this.com_phys_friction);
+                       this.velocity_z += g.z / 2;
+               }
+       }
+
+       if (this.com_phys_water) {
+               // water jump only in certain situations
+               // this mimics quakeworld code
+               if (jump && this.waterlevel == WATERLEVEL_SWIMMING && this.velocity_z >= -180 && !this.viewloc) {
+                       vector yawangles = '0 1 0' * this.v_angle.y;
+                       makevectors(yawangles);
+                       vector forward = v_forward;
+                       vector spot = this.origin + 24 * forward;
+                       spot_z += 8;
+                       traceline(spot, spot, MOVE_NOMONSTERS, this);
+                       if (trace_startsolid) {
+                               spot_z += 24;
+                               traceline(spot, spot, MOVE_NOMONSTERS, this);
+                               if (!trace_startsolid) {
+                                       this.velocity = forward * 50;
+                                       this.velocity_z = 310;
+                                       UNSET_ONGROUND(this);
+                                       SET_JUMP_HELD(this);
+                               }
+                       }
+               }
+       }
+       makevectors(vmul(this.v_angle, (this.com_phys_vel_2d ? '0 1 0' : '1 1 1')));
+       // wishvel = v_forward * this.movement.x + v_right * this.movement.y + v_up * this.movement.z;
+       vector wishvel = v_forward * this.movement.x
+           + v_right * this.movement.y
+           + '0 0 1' * this.movement.z * (this.com_phys_vel_2d ? 0 : 1);
+       if (this.com_phys_water) {
+               if (PHYS_INPUT_BUTTON_CROUCH(this)) {
+                       wishvel.z = -PHYS_MAXSPEED(this);
+               }
+               if (this.viewloc) {
+                       wishvel.z = -160;    // drift anyway
+               } else if (wishvel == '0 0 0') {
+                       wishvel = '0 0 -60'; // drift towards bottom
+               }
+       }
+       if (this.com_phys_ladder) {
+               if (this.viewloc) {
+                       wishvel.z = this.oldmovement.x;
+               }
+               if (this.ladder_entity.classname == "func_water") {
+                       float f = vlen(wishvel);
+                       if (f > this.ladder_entity.speed) {
+                               wishvel *= (this.ladder_entity.speed / f);
+                       }
+
+                       this.watertype = this.ladder_entity.skin;
+                       f = this.ladder_entity.origin_z + this.ladder_entity.maxs_z;
+                       if ((this.origin_z + this.view_ofs_z) < f) {
+                               this.waterlevel = WATERLEVEL_SUBMERGED;
+                       } else if ((this.origin_z + (this.mins_z + this.maxs_z) * 0.5) < f) {
+                               this.waterlevel = WATERLEVEL_SWIMMING;
+                       } else if ((this.origin_z + this.mins_z + 1) < f) {
+                               this.waterlevel = WATERLEVEL_WETFEET;
+                       } else {
+                               this.waterlevel = WATERLEVEL_NONE;
+                               this.watertype = CONTENT_EMPTY;
+                       }
+               }
+       }
+       // acceleration
+       const vector wishdir = normalize(wishvel);
+       float wishspeed = min(vlen(wishvel), this.com_phys_vel_max);
+
+       if (this.com_phys_air) {
+               if ((IS_SVQC && time >= PHYS_TELEPORT_TIME(this))
+                   ||  (IS_CSQC && PHYS_WATERJUMP_TIME(this) <= 0)) {
+                       // apply air speed limit
+                       float airaccelqw = PHYS_AIRACCEL_QW(this);
+                       float wishspeed0 = wishspeed;
+                       const float maxairspd = this.com_phys_vel_max;
+                       wishspeed = min(wishspeed, maxairspd);
+                       if (IS_DUCKED(this)) {
+                               wishspeed *= 0.5;
+                       }
+                       float airaccel = this.com_phys_acc_rate_air;
+
+                       float accelerating = (this.velocity * wishdir > 0);
+                       float wishspeed2 = wishspeed;
+
+                       // CPM: air control
+                       if (PHYS_AIRSTOPACCELERATE(this)) {
+                               vector curdir = normalize(vec2(this.velocity));
+                               airaccel += (this.com_phys_acc_rate_air_stop - airaccel) * max(0, -(curdir * wishdir));
+                       }
+                       // note that for straight forward jumping:
+                       // step = accel * PHYS_INPUT_TIMELENGTH * wishspeed0;
+                       // accel  = bound(0, wishspeed - vel_xy_current, step) * accelqw + step * (1 - accelqw);
+                       // -->
+                       // dv/dt = accel * maxspeed (when slow)
+                       // dv/dt = accel * maxspeed * (1 - accelqw) (when fast)
+                       // log dv/dt = logaccel + logmaxspeed (when slow)
+                       // log dv/dt = logaccel + logmaxspeed + log(1 - accelqw) (when fast)
+                       float strafity = IsMoveInDirection(this.movement, -90) + IsMoveInDirection(this.movement, +90);  // if one is nonzero, other is always zero
+                       if (PHYS_MAXAIRSTRAFESPEED(this)) {
+                               wishspeed =
+                                   min(wishspeed,
+                                       GeomLerp(this.com_phys_vel_max_air, strafity, this.com_phys_vel_max_air_strafe));
+                       }
+                       if (PHYS_AIRSTRAFEACCELERATE(this)) {
+                               airaccel = GeomLerp(airaccel, strafity, this.com_phys_acc_rate_air_strafe);
+                       }
+                       if (PHYS_AIRSTRAFEACCEL_QW(this)) {
+                               airaccelqw =
+                                   (((strafity > 0.5 ? PHYS_AIRSTRAFEACCEL_QW(this) : PHYS_AIRACCEL_QW(this)) >= 0) ? +1 : -1)
+                                   *
+                                   (1 - GeomLerp(1 - fabs(PHYS_AIRACCEL_QW(this)), strafity, 1 - fabs(PHYS_AIRSTRAFEACCEL_QW(this))));
+                       }
+                       // !CPM
+
+                       if (PHYS_WARSOWBUNNY_TURNACCEL(this) && accelerating && this.movement.y == 0 && this.movement.x != 0) {
+                               PM_AirAccelerate(this, wishdir, wishspeed2);
+                       } else {
+                               float sidefric = maxairspd ? (PHYS_AIRACCEL_SIDEWAYS_FRICTION(this) / maxairspd) : 0;
+                               PM_Accelerate(this, wishdir, wishspeed, wishspeed0, airaccel, airaccelqw,
+                                       PHYS_AIRACCEL_QW_STRETCHFACTOR(this), sidefric, PHYS_AIRSPEEDLIMIT_NONQW(this));
+                       }
+
+                       if (PHYS_AIRCONTROL(this)) {
+                               CPM_PM_Aircontrol(this, wishdir, wishspeed2);
+                       }
+               }
+       } else {
+               if (this.com_phys_ground && IS_DUCKED(this)) { wishspeed *= 0.5; }
+               if (this.com_phys_water) {
+                       wishspeed *= 0.7;
+
+                       //      if (PHYS_WATERJUMP_TIME(this) <= 0) // TODO: use
+                       {
+                               // water friction
+                               float f = 1 - dt * PHYS_FRICTION(this);
+                               f = min(max(0, f), 1);
+                               this.velocity *= f;
+
+                               f = wishspeed - this.velocity * wishdir;
+                               if (f > 0) {
+                                       float accelspeed = min(PHYS_ACCELERATE(this) * dt * wishspeed, f);
+                                       this.velocity += accelspeed * wishdir;
+                               }
+
+                               // holding jump button swims upward slowly
+                               if (jump && !this.viewloc) {
+                                       // was:
+                                       // lava: 50
+                                       // slime: 80
+                                       // water: 100
+                                       // idea: double those
+                                       this.velocity_z = 200;
+                                       if (this.waterlevel >= WATERLEVEL_SUBMERGED) {
+                                               this.velocity_z = PHYS_MAXSPEED(this) * 0.7;
+                                       }
+                               }
+                       }
+                       if (this.viewloc) {
+                               const float addspeed = wishspeed - this.velocity * wishdir;
+                               if (addspeed > 0) {
+                                       const float accelspeed = min(PHYS_ACCELERATE(this) * dt * wishspeed, addspeed);
+                                       this.velocity += accelspeed * wishdir;
+                               }
+                       } else {
+                               // water acceleration
+                               PM_Accelerate(this, wishdir, wishspeed, wishspeed, this.com_phys_acc_rate, 1, 0, 0, 0);
+                       }
+                       return;
+               }
+               if (this.com_phys_ground) {
+                       // apply edge friction
+                       const float f2 = vlen2(vec2(this.velocity));
+                       if (f2 > 0) {
+                               trace_dphitq3surfaceflags = 0;
+                               tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
+                               // TODO: apply edge friction
+                               // apply ground friction
+                               const int realfriction = (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK)
+                                   ? PHYS_FRICTION_SLICK(this)
+                                       : PHYS_FRICTION(this);
+
+                               float f = sqrt(f2);
+                               f = 1 - dt * realfriction
+                                   * ((f < PHYS_STOPSPEED(this)) ? (PHYS_STOPSPEED(this) / f) : 1);
+                               f = max(0, f);
+                               this.velocity *= f;
+                               /*
+                                  Mathematical analysis time!
+
+                                  Our goal is to invert this mess.
+
+                                  For the two cases we get:
+                                   v = v0 * (1 - dt * (PHYS_STOPSPEED(this) / v0) * PHYS_FRICTION(this))
+                                     = v0 - dt * PHYS_STOPSPEED(this) * PHYS_FRICTION(this)
+                                   v0 = v + dt * PHYS_STOPSPEED(this) * PHYS_FRICTION(this)
+                                  and
+                                   v = v0 * (1 - dt * PHYS_FRICTION(this))
+                                   v0 = v / (1 - dt * PHYS_FRICTION(this))
+
+                                  These cases would be chosen ONLY if:
+                                   v0 < PHYS_STOPSPEED(this)
+                                   v + dt * PHYS_STOPSPEED(this) * PHYS_FRICTION(this) < PHYS_STOPSPEED(this)
+                                   v < PHYS_STOPSPEED(this) * (1 - dt * PHYS_FRICTION(this))
+                                  and, respectively:
+                                   v0 >= PHYS_STOPSPEED(this)
+                                   v / (1 - dt * PHYS_FRICTION(this)) >= PHYS_STOPSPEED(this)
+                                   v >= PHYS_STOPSPEED(this) * (1 - dt * PHYS_FRICTION(this))
+                                */
+                       }
+                       const float addspeed = wishspeed - this.velocity * wishdir;
+                       if (addspeed > 0) {
+                               const float accelspeed = min(PHYS_ACCELERATE(this) * dt * wishspeed, addspeed);
+                               this.velocity += accelspeed * wishdir;
+                       }
+                       return;
+               }
+
+               if (IS_CSQC ? PHYS_WATERJUMP_TIME(this) <= 0 : time >= PHYS_TELEPORT_TIME(this)) {
+                       PM_Accelerate(this, wishdir, wishspeed, wishspeed, this.com_phys_acc_rate, 1, 0, 0, 0);
+               }
+       }
+}
+
+.entity groundentity;
+/** for other entities */
+void sys_phys_simulate_simple(entity this, float dt)
+{
+       vector mn = this.mins;
+       vector mx = this.maxs;
+
+       vector g = '0 0 0';
+       if (this.com_phys_gravity_factor && !g) g = '0 0 -1' * PHYS_GRAVITY(NULL);
+
+       vector acc = this.com_phys_acc;
+       vector vel = this.com_phys_vel;
+       vector pos = this.com_phys_pos;
+
+       // SV_Physics_Toss
+
+       vel += g * dt;
+
+       this.angles += dt * this.avelocity;
+       float movetime = dt;
+       for (int i = 0; i < MAX_CLIP_PLANES && movetime > 0; i++) {
+               vector push = vel * movetime;
+               vector p0 = pos;
+               vector p1 = p0 + push;
+               // SV_PushEntity
+               tracebox(p0, mn, mx, p1, MOVE_NORMAL, this);
+               if (!trace_startsolid) {
+                       bool hit = trace_fraction < 1;
+                       pos = trace_endpos;
+                       entity ent = trace_ent;
+                       // SV_LinkEdict_TouchAreaGrid
+                       if (this.solid != SOLID_NOT) {
+                               FOREACH_ENTITY_RADIUS_ORDERED(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin), true, {
+                                       if (it.solid != SOLID_TRIGGER || it == this) continue;
+                                       if (gettouch(it) && boxesoverlap(it.absmin, it.absmax, this.absmin, this.absmax)) {
+                                           // SV_LinkEdict_TouchAreaGrid_Call
+                                           trace_allsolid = false;
+                                           trace_startsolid = false;
+                                           trace_fraction = 1;
+                                           trace_inwater = false;
+                                           trace_inopen = true;
+                                           trace_endpos = it.origin;
+                                           trace_plane_normal = '0 0 1';
+                                           trace_plane_dist = 0;
+                                           trace_ent = this;
+                                           trace_dpstartcontents = 0;
+                                           trace_dphitcontents = 0;
+                                           trace_dphitq3surfaceflags = 0;
+                                           trace_dphittexturename = string_null;
+                                           gettouch(it)(this, it);
+                                           vel = this.velocity;
+                                       }
+                               });
+                       }
+                       if (hit && this.solid >= SOLID_TRIGGER && (!IS_ONGROUND(this) || this.groundentity != ent)) {
+                               // SV_Impact (ent, trace);
+                               tracebox(p0, mn, mx, p1, MOVE_NORMAL, this);
+                               void(entity, entity) touched = gettouch(this);
+                               if (touched && this.solid != SOLID_NOT) {
+                                       touched(ent, this);
+                               }
+                               void(entity, entity) touched2 = gettouch(ent);
+                               if (this && ent && touched2 && ent.solid != SOLID_NOT) {
+                                       trace_endpos = ent.origin;
+                                       trace_plane_normal *= -1;
+                                       trace_plane_dist *= -1;
+                                       trace_ent = this;
+                                       trace_dpstartcontents = 0;
+                                       trace_dphitcontents = 0;
+                                       trace_dphitq3surfaceflags = 0;
+                                       trace_dphittexturename = string_null;
+                                       touched2(this, ent);
+                               }
+                       }
+               }
+               // end SV_PushEntity
+               if (wasfreed(this)) { return; }
+               tracebox(p0, mn, mx, p1, MOVE_NORMAL, this);
+               if (trace_fraction == 1) { break; }
+               movetime *= 1 - min(1, trace_fraction);
+               ClipVelocity(vel, trace_plane_normal, vel, 1);
+       }
+
+       this.com_phys_acc = acc;
+       this.com_phys_vel = vel;
+       this.com_phys_pos = pos;
+       setorigin(this, this.com_phys_pos);
+}
+
+void sys_phys_update_single(entity this)
+{
+       sys_phys_simulate_simple(this, frametime);
 }
index 38d4e55e55e94da8a31ba67c1ff3f832a286932c..16c996adee6ccf97ae82f3400a0fd71eeb14fb7f 100644 (file)
@@ -1,3 +1,11 @@
 #pragma once
 
 SYSTEM(phys, 30, 10);
+
+void sys_phys_fix(entity this, float dt);
+bool sys_phys_override(entity this);
+void sys_phys_monitor(entity this);
+void sys_phys_pregame_hold(entity this);
+void sys_phys_ai(entity this);
+void sys_phys_spectator_control(entity this);
+void sys_phys_fixspeed(entity this, float maxspeed_mod);
diff --git a/qcsrc/ecs/systems/sv_physics.qc b/qcsrc/ecs/systems/sv_physics.qc
new file mode 100644 (file)
index 0000000..fe053a2
--- /dev/null
@@ -0,0 +1,117 @@
+#include "physics.qh"
+
+void sys_phys_fix(entity this, float dt)
+{
+       WarpZone_PlayerPhysics_FixVAngle(this);
+       Physics_UpdateStats(this, PHYS_HIGHSPEED(this));
+}
+
+bool sys_phys_override(entity this)
+{
+       int buttons = PHYS_INPUT_BUTTON_MASK(this);
+       if (PM_check_specialcommand(this, buttons)) { return true; }
+       if (this.PlayerPhysplug && this.PlayerPhysplug(this)) { return true; }
+       return false;
+}
+
+void sys_phys_monitor(entity this)
+{
+       int buttons = PHYS_INPUT_BUTTON_MASK(this);
+       anticheat_physics(this);
+       if (sv_maxidle > 0) {
+               if (buttons != this.buttons_old
+                   || this.movement != this.movement_old
+                   || this.v_angle != this.v_angle_old) { this.parm_idlesince = time; }
+       }
+       PM_check_nickspam(this);
+       PM_check_punch(this);
+}
+
+void sys_phys_ai(entity this)
+{
+       if (!IS_BOT_CLIENT(this)) { return; }
+       if (playerdemo_read(this)) { return; }
+       bot_think(this);
+}
+
+void sys_phys_pregame_hold(entity this)
+{
+       if (!IS_PLAYER(this)) { return; }
+       const bool allowed_to_move = (time >= game_starttime);
+       if (!allowed_to_move) {
+               this.velocity = '0 0 0';
+               set_movetype(this, MOVETYPE_NONE);
+               this.disableclientprediction = 2;
+       } else if (this.disableclientprediction == 2) {
+               if (this.move_movetype == MOVETYPE_NONE) { set_movetype(this, MOVETYPE_WALK); }
+               this.disableclientprediction = 0;
+       }
+}
+
+void sys_phys_spectator_control(entity this)
+{
+       float maxspeed_mod = autocvar_sv_spectator_speed_multiplier;
+       if (!this.spectatorspeed) { this.spectatorspeed = maxspeed_mod; }
+       if ((this.impulse >= 1 && this.impulse <= 19)
+           || (this.impulse >= 200 && this.impulse <= 209)
+           || (this.impulse >= 220 && this.impulse <= 229)
+          ) {
+               if (this.lastclassname != STR_PLAYER) {
+                       if (this.impulse == 10
+                           || this.impulse == 15
+                           || this.impulse == 18
+                           || (this.impulse >= 200 && this.impulse <= 209)
+                          ) { this.spectatorspeed = bound(1, this.spectatorspeed + 0.5, 5); } else if (this.impulse == 11) {
+                               this.spectatorspeed = maxspeed_mod;
+                       } else if (this.impulse == 12
+                           || this.impulse == 16
+                           || this.impulse == 19
+                           || (this.impulse >= 220 && this.impulse <= 229)
+                                 ) {
+                               this.spectatorspeed = bound(1, this.spectatorspeed - 0.5, 5);
+                       } else if (this.impulse >= 1 && this.impulse <= 9) {
+                               this.spectatorspeed = 1 + 0.5 * (this.impulse - 1);
+                       }
+               }  // otherwise just clear
+               this.impulse = 0;
+       }
+}
+
+void sys_phys_fixspeed(entity this, float maxspeed_mod)
+{
+       float spd = max(PHYS_MAXSPEED(this), PHYS_MAXAIRSPEED(this)) * maxspeed_mod;
+       if (this.speed != spd) {
+               this.speed = spd;
+               string temps = ftos(spd);
+               stuffcmd(this, strcat("cl_forwardspeed ", temps, "\n"));
+               stuffcmd(this, strcat("cl_backspeed ", temps, "\n"));
+               stuffcmd(this, strcat("cl_sidespeed ", temps, "\n"));
+               stuffcmd(this, strcat("cl_upspeed ", temps, "\n"));
+       }
+
+       if (this.jumpspeedcap_min != autocvar_sv_jumpspeedcap_min) {
+               this.jumpspeedcap_min = autocvar_sv_jumpspeedcap_min;
+               stuffcmd(this, sprintf("\ncl_jumpspeedcap_min \"%s\"\n", autocvar_sv_jumpspeedcap_min));
+       }
+       if (this.jumpspeedcap_max != autocvar_sv_jumpspeedcap_max) {
+               this.jumpspeedcap_max = autocvar_sv_jumpspeedcap_max;
+               stuffcmd(this, sprintf("\ncl_jumpspeedcap_max \"%s\"\n", autocvar_sv_jumpspeedcap_max));
+       }
+}
+
+void sys_phys_land(entity this)
+{
+       if (autocvar_speedmeter) {
+               LOG_TRACEF("landing velocity: %v (abs: %f)", this.velocity, vlen(this.velocity));
+       }
+       if (this.jumppadcount > 1) {
+               LOG_TRACEF("%dx jumppad combo", this.jumppadcount);
+       }
+       this.jumppadcount = 0;
+}
+
+STATIC_INIT(sys_phys)
+{
+       entity listener = new_pure(sys_phys);
+       subscribe(listener, phys_land, sys_phys_land);
+}
index 61755fe94322e1d360390792823fcb0d9ed77d6e..f52c9a3c735437ef6195f8c1499baceba51842af 100644 (file)
@@ -2,6 +2,18 @@
        #define COMPAT_NO_MOD_IS_XONOTIC
 #endif
 
+#ifdef CSQC
+#define IS_CSQC 1
+#else
+#define IS_CSQC 0
+#endif
+
+#ifdef SVQC
+#define IS_SVQC 1
+#else
+#define IS_SVQC 0
+#endif
+
 #include "compiler.qh"
 
 #ifndef QCC_SUPPORT_INT
@@ -77,6 +89,7 @@ void    isnt_bool(float this) { print(ftos(this)); }
 #include "file.qh"
 #include "functional.qh"
 #include "i18n.qh"
+#include "intrusivelist.qh"
 #include "iter.qh"
 #include "json.qc"
 #include "lazy.qh"
@@ -111,6 +124,22 @@ void    isnt_bool(float this) { print(ftos(this)); }
 
 #include "matrix/_mod.inc"
 
+#ifndef SVQC
+#define objerror_safe(e)
+#else
+void make_safe_for_remove(entity this);
+    #define objerror_safe(e) make_safe_for_remove(e)
+#endif
+
+#define objerror(this, msg) MACRO_BEGIN { \
+       LOG_WARNING("======OBJECT ERROR======"); \
+       entity _e = (this); \
+       eprint(_e); \
+       objerror_safe(_e); \
+       delete(_e); \
+       LOG_WARNINGF("%s OBJECT ERROR in %s:\n%s\nTip: read above for entity information", PROGNAME, __FUNC__, msg); \
+} MACRO_END
+
 #ifdef MENUQC
        void _m_init();
        void m_init() { if (_m_init) _m_init(); }
@@ -236,3 +265,8 @@ void    isnt_bool(float this) { print(ftos(this)); }
        #define CSQC_Ent_Remove _CSQC_Ent_Remove
 #endif
 #undef ENGINE_EVENT
+
+#ifndef MENUQC
+       #include <ecs/_lib.qh>
+       #include <ecs/components/_mod.qh>
+#endif
index c0809ecdf88d242e03fbd329dd648e636ee881a1..18305177bf8a266261e1be9ad143dfde695fcace 100644 (file)
@@ -20,7 +20,7 @@ USING(ArrayList, entity);
        MACRO_BEGIN \
        { \
                buf_del(this.al_buf); \
-               remove(this); \
+               delete(this); \
                this = NULL; \
        } MACRO_END
 
index d12ae42501494941e2dd9d679cbe8a13b8d12f64..e430a648d168a41d38a976745880113c6f3258f1 100644 (file)
@@ -9,57 +9,57 @@
 #define count_years_decs(time, decs) sprintf(CTX(_("CI_DEC^%s years")), ftos_decimals(time, decs))
 #define count_years(time) \
        count_fill(time, \
-       CTX(_("CI_ZER^%d years")), /* zeroth */ \
-       CTX(_("CI_FIR^%d year")),  /* first */ \
-       CTX(_("CI_SEC^%d years")), /* year */ \
-       CTX(_("CI_THI^%d years")), /* third */ \
-       CTX(_("CI_MUL^%d years"))) /* multi */
+       _("CI_ZER^%d years"), /* zeroth */ \
+       _("CI_FIR^%d year"),  /* first */ \
+       _("CI_SEC^%d years"), /* year */ \
+       _("CI_THI^%d years"), /* third */ \
+       _("CI_MUL^%d years")) /* multi */
 
 #define count_weeks_decs(time, decs) sprintf(CTX(_("CI_DEC^%s weeks")), ftos_decimals(time, decs))
 #define count_weeks(time) \
        count_fill(time, \
-       CTX(_("CI_ZER^%d weeks")), /* zeroth */ \
-       CTX(_("CI_FIR^%d week")),  /* first */ \
-       CTX(_("CI_SEC^%d weeks")), /* week */ \
-       CTX(_("CI_THI^%d weeks")), /* third */ \
-       CTX(_("CI_MUL^%d weeks"))) /* multi */
+       _("CI_ZER^%d weeks"), /* zeroth */ \
+       _("CI_FIR^%d week"),  /* first */ \
+       _("CI_SEC^%d weeks"), /* week */ \
+       _("CI_THI^%d weeks"), /* third */ \
+       _("CI_MUL^%d weeks")) /* multi */
 
 #define count_days_decs(time, decs) sprintf(CTX(_("CI_DEC^%s days")), ftos_decimals(time, decs))
 #define count_days(time) \
        count_fill(time, \
-       CTX(_("CI_ZER^%d days")), /* zeroth */ \
-       CTX(_("CI_FIR^%d day")),  /* first */ \
-       CTX(_("CI_SEC^%d days")), /* day */ \
-       CTX(_("CI_THI^%d days")), /* third */ \
-       CTX(_("CI_MUL^%d days"))) /* multi */
+       _("CI_ZER^%d days"), /* zeroth */ \
+       _("CI_FIR^%d day"),  /* first */ \
+       _("CI_SEC^%d days"), /* day */ \
+       _("CI_THI^%d days"), /* third */ \
+       _("CI_MUL^%d days")) /* multi */
 
 #define count_hours_decs(time, decs) sprintf(CTX(_("CI_DEC^%s hours")), ftos_decimals(time, decs))
 #define count_hours(time) \
        count_fill(time, \
-       CTX(_("CI_ZER^%d hours")), /* zeroth */ \
-       CTX(_("CI_FIR^%d hour")),  /* first */ \
-       CTX(_("CI_SEC^%d hours")), /* hour */ \
-       CTX(_("CI_THI^%d hours")), /* third */ \
-       CTX(_("CI_MUL^%d hours"))) /* multi */
+       _("CI_ZER^%d hours"), /* zeroth */ \
+       _("CI_FIR^%d hour"),  /* first */ \
+       _("CI_SEC^%d hours"), /* hour */ \
+       _("CI_THI^%d hours"), /* third */ \
+       _("CI_MUL^%d hours")) /* multi */
 
 
 #define count_minutes_decs(time, decs) sprintf(CTX(_("CI_DEC^%s minutes")), ftos_decimals(time, decs))
 #define count_minutes(time) \
        count_fill(time, \
-       CTX(_("CI_ZER^%d minutes")), /* zeroth */ \
-       CTX(_("CI_FIR^%d minute")),  /* first */ \
-       CTX(_("CI_SEC^%d minutes")), /* minute */ \
-       CTX(_("CI_THI^%d minutes")), /* third */ \
-       CTX(_("CI_MUL^%d minutes"))) /* multi */
+       _("CI_ZER^%d minutes"), /* zeroth */ \
+       _("CI_FIR^%d minute"),  /* first */ \
+       _("CI_SEC^%d minutes"), /* minute */ \
+       _("CI_THI^%d minutes"), /* third */ \
+       _("CI_MUL^%d minutes")) /* multi */
 
 #define count_seconds_decs(time, decs) sprintf(CTX(_("CI_DEC^%s seconds")), ftos_decimals(time, decs))
 #define count_seconds(time) \
        count_fill(time, \
-       CTX(_("CI_ZER^%d seconds")), /* zeroth */ \
-       CTX(_("CI_FIR^%d second")),  /* first */ \
-       CTX(_("CI_SEC^%d seconds")), /* second */ \
-       CTX(_("CI_THI^%d seconds")), /* third */ \
-       CTX(_("CI_MUL^%d seconds"))) /* multi */
+       _("CI_ZER^%d seconds"), /* zeroth */ \
+       _("CI_FIR^%d second"),  /* first */ \
+       _("CI_SEC^%d seconds"), /* second */ \
+       _("CI_THI^%d seconds"), /* third */ \
+       _("CI_MUL^%d seconds")) /* multi */
 
 string count_ordinal(int interval)
 {
@@ -102,16 +102,16 @@ string count_fill(float interval, string zeroth, string first, string second, st
 
        switch (floor(interval))
        {
-               case 0: return sprintf(zeroth, interval);
+               case 0: return sprintf(CTX(zeroth), interval);
                case 1:
                {
                        if (interval == 1)  // EXACTLY value of 1
-                               return sprintf(first, interval);
-                       else return sprintf(multi, interval);
+                               return sprintf(CTX(first), interval);
+                       else return sprintf(CTX(multi), interval);
                }
-               case 2: return sprintf(second, interval);
-               case 3: return sprintf(third, interval);
-               default: return sprintf(multi, interval);
+               case 2: return sprintf(CTX(second), interval);
+               case 3: return sprintf(CTX(third), interval);
+               default: return sprintf(CTX(multi), interval);
        }
        return "";
 }
index 1a8ba710ae182c7984b5cec0924b2eb99216aaf8..4bea5e36a7399098aa3defabd15185a688524806 100644 (file)
@@ -106,7 +106,7 @@ void CSQCPlayer_Unpredict(entity this)
 
 void CSQCPlayer_SetMinsMaxs(entity this)
 {
-       if ((this.flags & FL_DUCKED) || !this.isplayermodel)
+       if (IS_DUCKED(this) || !this.isplayermodel)
        {
                this.mins = STAT(PL_CROUCH_MIN, NULL);
                this.maxs = STAT(PL_CROUCH_MAX, NULL);
@@ -130,72 +130,31 @@ void CSQCPlayer_SavePrediction(entity this)
 }
 
 void CSQC_ClientMovement_PlayerMove_Frame(entity this);
-void _Movetype_Physics_ClientFrame(entity this, float movedt);
-
-void Movetype_Physics_Spam(entity this)  // optimized
-{
-       _Movetype_Physics_ClientFrame(this, PHYS_INPUT_TIMELENGTH);
-       if(wasfreed(this))
-               return;
-
-       this.avelocity = this.move_avelocity;
-       this.velocity = this.move_velocity;
-       this.angles = this.move_angles;
-       this.flags = BITSET(this.flags, FL_ONGROUND, boolean(this.move_flags & FL_ONGROUND));
-       this.flags = BITSET(this.flags, FL_WATERJUMP, boolean(this.move_flags & FL_WATERJUMP));
-       this.waterlevel = this.move_waterlevel;
-       this.watertype = this.move_watertype;
-       setorigin(this, this.move_origin);
-}
-
-void CSQCPlayer_CheckWater(entity this)
-{
-       this.move_origin = this.origin;
-       this.move_waterlevel = this.waterlevel;
-       this.move_watertype = this.watertype;
-       _Movetype_CheckWater(this);
-       this.waterlevel = this.move_waterlevel;
-       this.watertype = this.move_watertype;
-}
 
 void CSQCPlayer_Physics(entity this)
 {
-       if(autocvar_cl_movement)
-       {
-               if(autocvar_cl_movement == 1)
-                       CSQCPlayer_CheckWater(this); // we apparently need to check water *before* physics so it can use this for water jump
+       if(!autocvar_cl_movement) { return; }
 
-               vector oldv_angle = this.v_angle;
-               vector oldangles = this.angles; // we need to save these, as they're abused by other code
-               this.v_angle = PHYS_INPUT_ANGLES(this);
-               this.angles = PHYS_WORLD_ANGLES(this);
+       _Movetype_CheckWater(this); // we apparently need to check water *before* physics so it can use this for water jump
 
-               CSQC_ClientMovement_PlayerMove_Frame(this);
+       vector oldv_angle = this.v_angle;
+       vector oldangles = this.angles; // we need to save these, as they're abused by other code
+       this.v_angle = PHYS_INPUT_ANGLES(this);
+       this.angles = PHYS_WORLD_ANGLES(this);
 
-               if(autocvar_cl_movement == 1)
-               {
-                       this.move_origin = this.origin;
-                       this.move_angles = this.angles;
-                       //this.move_movetype = MOVETYPE_WALK; // temp
-                       this.move_velocity = this.velocity;
-                       this.move_avelocity = this.avelocity;
-                       this.move_flags = BITSET(this.move_flags, FL_ONGROUND, IS_ONGROUND(this));
-                       this.move_flags = BITSET(this.move_flags, FL_WATERJUMP, boolean(this.flags & FL_WATERJUMP));
-                       this.move_waterlevel = this.waterlevel;
-                       this.move_watertype = this.watertype;
-                       Movetype_Physics_Spam(this);
-               }
+       CSQC_ClientMovement_PlayerMove_Frame(this);
 
-               view_angles = this.v_angle;
-               input_angles = this.angles;
-               this.v_angle = oldv_angle;
-               this.angles = oldangles;
+       Movetype_Physics_NoMatchTicrate(this, PHYS_INPUT_TIMELENGTH, true);
 
-               this.pmove_flags =
-                               ((this.flags & FL_DUCKED) ? PMF_DUCKED : 0) |
-                               (!(this.flags & FL_JUMPRELEASED) ? PMF_JUMP_HELD : 0) |
-                               ((IS_ONGROUND(this)) ? PMF_ONGROUND : 0);
-       }
+       view_angles = this.v_angle;
+       input_angles = this.angles;
+       this.v_angle = oldv_angle;
+       this.angles = oldangles;
+
+       this.pmove_flags =
+                       ((IS_DUCKED(this)) ? PMF_DUCKED : 0) |
+                       ((IS_JUMP_HELD(this)) ? PMF_JUMP_HELD : 0) |
+                       ((IS_ONGROUND(this)) ? PMF_ONGROUND : 0);
 }
 
 void CSQCPlayer_PredictTo(entity this, float endframe, bool apply_error)
@@ -231,6 +190,15 @@ void CSQCPlayer_PredictTo(entity this, float endframe, bool apply_error)
                do
                {
                        if (!getinputstate(csqcplayer_moveframe)) break;
+                       /*if (input_timelength > 0.0005)
+                       {
+                               if (input_timelength > 0.05)
+                               {
+                                       input_timelength /= 2;
+                                       CSQCPlayer_Physics(this);
+                               }
+                               CSQCPlayer_Physics(this);
+                       }*/
                        CSQCPlayer_Physics(this);
                        CSQCPlayer_SetMinsMaxs(this);
                        ++csqcplayer_moveframe;
index 1c97199c8e29684225649a78f116a9abca857778..513875aa9889f05067373a4a13ea70ae417ba311 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef LIB_CSQCMODEL_CL_PLAYER_H
 #define LIB_CSQCMODEL_CL_PLAYER_H
 
-int autocvar_cl_movement = 1;
+bool autocvar_cl_movement = true;
 
 entity csqcplayer;
 float csqcplayer_status;
index 3e7e020c67a5fea2ea7368fb3444a30f9fbebea2..c20c53440785ceb09f8b236f6bfeef606794b6b2 100644 (file)
@@ -12,7 +12,7 @@
        /** Remove entity */
        void SUB_Remove(entity this)
        {
-               remove(this);
+               delete(this);
        }
 
        void defer_think(entity this)
diff --git a/qcsrc/lib/intrusivelist.qh b/qcsrc/lib/intrusivelist.qh
new file mode 100644 (file)
index 0000000..10de3e9
--- /dev/null
@@ -0,0 +1,245 @@
+#pragma once
+
+#include "iter.qh"
+
+const int IL_MAX = 128;
+
+void IL_INIT(entity this);
+void IL_DTOR(entity this);
+void IL_ENDFRAME();
+
+/**
+ * limitations:
+ *   NULL cannot be present
+ *   elements can only be present once
+ *   a maximum of `IL_MAX` lists can exist at one time
+ *   freed entities must be removed from the list
+ */
+CLASS(IntrusiveList, Object)
+       ATTRIB(IntrusiveList, il_head, entity, NULL);
+       ATTRIB(IntrusiveList, il_tail, entity, NULL);
+       ATTRIB(IntrusiveList, il_nextfld, .entity, nil);
+       ATTRIB(IntrusiveList, il_prevfld, .entity, nil);
+       INIT(IntrusiveList) { IL_INIT(this); }
+       DESTRUCTOR(IntrusiveList) { IL_DTOR(this); }
+ENDCLASS(IntrusiveList)
+
+// bitflags
+.vector il_lists;
+// bitflags
+.vector il_listmask;
+
+#define IL_NEW() NEW(IntrusiveList)
+
+#define IL_EMPTY(this) (this.il_head == NULL)
+
+#define IL_FIRST(this) (this.il_head)
+#define IL_LAST(this) (this.il_tail)
+#define IL_PEEK(this) (this.il_tail)
+
+bool IL_CONTAINS(IntrusiveList this, entity it)
+{
+       assert(this, return false);
+       return it.(this.il_nextfld) || this.il_head == it || this.il_tail == it;
+}
+
+/**
+ * Push to tail
+ */
+entity IL_PUSH(IntrusiveList this, entity it)
+{
+       assert(this, return NULL);
+       assert(it, return NULL);
+       .entity il_next = this.il_nextfld;
+       .entity il_prev = this.il_prevfld;
+       assert(!IL_CONTAINS(this, it), return NULL);
+
+       entity tail = it.(il_prev) = this.il_tail;
+       tail ? (tail.(il_next) = it) : this.il_head = it;
+       this.il_tail = it;
+       it.il_lists |= this.il_listmask;
+       return it;
+}
+
+/**
+ * Push to head
+ */
+entity IL_UNSHIFT(IntrusiveList this, entity it)
+{
+       assert(this, return NULL);
+       assert(it, return NULL);
+       .entity il_next = this.il_nextfld;
+       .entity il_prev = this.il_prevfld;
+       assert(!IL_CONTAINS(this, it), return NULL);
+
+       entity head = it.(il_next) = this.il_head;
+       head ? (head.(il_prev) = it) : this.il_tail = it;
+       this.il_head = it;
+       it.il_lists |= this.il_listmask;
+       return it;
+}
+
+/**
+ * Pop from tail
+ */
+entity IL_POP(IntrusiveList this)
+{
+       assert(this, return NULL);
+       .entity il_next = this.il_nextfld;
+       .entity il_prev = this.il_prevfld;
+
+       if (!this.il_tail) return NULL;
+       entity it = this.il_tail;
+       entity prev = it.(il_prev);
+       if (prev) (this.il_tail = prev).(il_next) = NULL;
+       else this.il_head = this.il_tail = NULL;
+       return it;
+}
+
+/**
+ * Pop from head
+ */
+entity IL_SHIFT(IntrusiveList this)
+{
+       assert(this, return NULL);
+       .entity il_next = this.il_nextfld;
+       .entity il_prev = this.il_prevfld;
+
+       if (!this.il_head) return NULL;
+       entity it = this.il_head;
+       entity next = it.(il_next);
+       if (next) (this.il_head = next).(il_prev) = NULL;
+       else this.il_head = this.il_tail = NULL;
+       return it;
+}
+
+/**
+ * Remove any element, anywhere in the list
+ */
+void IL_REMOVE(IntrusiveList this, entity it)
+{
+       assert(this, return);
+       .entity il_next = this.il_nextfld;
+       .entity il_prev = this.il_prevfld;
+       entity next = it.(il_next);
+       entity prev = it.(il_prev);
+       entity ohead = this.il_head;
+       entity otail = this.il_tail;
+       next ? next.(il_prev) = prev : this.il_tail = prev;
+       prev ? prev.(il_next) = next : this.il_head = next;
+       LOG_DEBUGF("remove %i (%i :: %i), head: %i -> %i, tail: %i -> %i\n", it, it.(il_prev), it.(il_next), ohead, this.il_head, otail, this.il_tail);
+       it.(il_next) = it.(il_prev) = NULL;
+}
+
+/**
+ * Remove all elements
+ */
+#define IL_CLEAR(this) \
+       MACRO_BEGIN \
+       { \
+               IntrusiveList __il = this; \
+               assert(__il); \
+               .entity il_prev = __il.il_prevfld; \
+               IL_EACH(__il, true, it.(il_next) = it.(il_prev) = NULL); \
+               __il.il_head = __il.il_tail = NULL; \
+       } MACRO_END
+
+/**
+ * Delete the list
+ */
+#define IL_DELETE(this, dtor) \
+       MACRO_BEGIN \
+       { \
+               delete(this); \
+               this = NULL; \
+       } MACRO_END
+
+#define IL_EACH(this, cond, body) \
+       MACRO_BEGIN \
+       { \
+               IntrusiveList _il = this; \
+               assert(_il); \
+               .entity il_next = _il.il_nextfld; \
+               noref int i = 0; \
+               for (entity _next, _it = _il.il_head; _it; (_it = _next, ++i)) \
+               { \
+                       const noref entity it = _it; \
+                       _next = it.(il_next); \
+                       if (cond) { LAMBDA(body) } \
+               } \
+       } MACRO_END
+
+.int il_id;
+IntrusiveList il_links[IL_MAX];
+.entity il_links_flds[IL_MAX * 2];
+int il_links_ptr;
+
+#define IL_FLOOR(n) ((n) | 0)
+#define IL_CEIL(n)  IL_FLOOR((n) + 0.5)
+
+#define IL_LISTS_PER_BIT IL_CEIL(IL_MAX / (3 * 24))
+
+void IL_INIT(IntrusiveList this)
+{
+       .entity nextfld, prevfld;
+       for (int i = il_links_ptr; i < il_links_ptr + IL_MAX; ++i) {
+               int idx = i;
+               if (idx >= IL_MAX) idx -= IL_MAX;
+               int id = idx;
+               idx *= 2;
+               if (!il_links[idx]) {
+                       il_links[idx] = this;
+                       nextfld = il_links_flds[idx + 0];
+                       prevfld = il_links_flds[idx + 1];
+                       this.il_id = id;
+                       int bit = IL_FLOOR(id / IL_LISTS_PER_BIT);
+                       if (bit < (1 * 24)) this.il_listmask = '1 0 0' * (1 << (bit - (0 * 24)));
+                       else if (bit < (2 * 24)) this.il_listmask = '0 1 0' * (1 << (bit - (1 * 24)));
+                       else if (bit < (3 * 24)) this.il_listmask = '0 0 1' * (1 << (bit - (2 * 24)));
+                       else assert(false);
+                       il_links_ptr = id + 1;
+                       if (il_links_ptr >= IL_MAX) il_links_ptr -= IL_MAX;
+                       this.il_nextfld = nextfld;
+                       this.il_prevfld = prevfld;
+                       return;
+               }
+       }
+       LOG_WARNINGF("IntrusiveList overflow");
+}
+
+void IL_DTOR(IntrusiveList this)
+{
+       IL_CLEAR(this);
+       il_links[this.il_id] = NULL;
+}
+
+void IL_ENDFRAME()
+{
+#if 0
+       // incompatible with CSQC, remove() clears entities
+       for (int i = 0; i < IL_MAX; ++i) {
+               IntrusiveList list = il_links[i];
+               if (list) {
+                       .entity nextfld = list.il_nextfld;
+                       for (entity next, it = list.il_head; it; it = next) {
+                               next = it.(nextfld);
+                               if (wasfreed(it)) {
+                                       IL_REMOVE(list, it);
+                               }
+                       }
+               }
+       }
+#endif
+}
+
+void ONREMOVE(entity this)
+{
+       if (this.il_lists) {
+               for (int i = 0; i < IL_MAX; ++i) {
+                       IntrusiveList list = il_links[i];
+                       if (this.il_lists & list.il_listmask && IL_CONTAINS(list, this)) {
+                               IL_REMOVE(list, this);
+                       }
+               }
+       }
+}
index c21d02121347d34b79042a31809ccd421693ab3f..7183e90feab6bad7a26ce4ba98f8e01886ea8bca 100644 (file)
        MACRO_BEGIN \
        { \
                int _i = 0; \
-               for (entity _it = list##_first; _it; (_it = _it.next, ++_i)) \
+               for (entity _it = list##_first, _next = NULL; _it; (_it = _next, ++_i)) \
                { \
                        const noref int i = _i; \
                        ITER_CONST noref entity it = _it; \
+                       _next = _it.next; \
                        if (cond) { LAMBDA(body) } \
                } \
        } MACRO_END
             if (cond) LAMBDA(body) \
         } \
     } MACRO_END
+#define MUTEX_LOCK(this) MACRO_BEGIN \
+       if (this) LOG_SEVEREF("Loop mutex held by %s", this); \
+       this = __FUNC__; \
+MACRO_END
+#define MUTEX_UNLOCK(this) MACRO_BEGIN \
+       this = string_null; \
+MACRO_END
 #define _FOREACH_ENTITY_FIND_UNORDERED(id, T, fld, match, cond, body) \
        MACRO_BEGIN { \
-               if (_FOREACH_ENTITY_FIND_##T##_##id##mutex) LOG_SEVEREF("Loop mutex held by %s", _FOREACH_ENTITY_FIND_##T##_##id##mutex); \
-               _FOREACH_ENTITY_FIND_##T##_##id##mutex = __FUNC__; \
+               MUTEX_LOCK(_FOREACH_ENTITY_FIND_##T##_##id##mutex); \
                entity _foundchain_first = _findchain##T##_tofield(fld, match, _FOREACH_ENTITY_FIND_##T##_next##id); \
                FOREACH_LIST(_foundchain, _FOREACH_ENTITY_FIND_##T##_next##id, cond, body); \
-               _FOREACH_ENTITY_FIND_##T##_##id##mutex = string_null; \
+               MUTEX_UNLOCK(_FOREACH_ENTITY_FIND_##T##_##id##mutex); \
        } MACRO_END
 
 #define FOREACH_ENTITY(cond, body) ORDERED(FOREACH_ENTITY)(cond, body)
 
 #ifndef MENUQC
 entity(vector org, float rad, .entity tofield) _findchainradius_tofield = #22;
-#define FOREACH_ENTITY_RADIUS(org, dist, cond, body) FOREACH_ENTITY_RADIUS_UNORDERED(org, dist, cond, body)
+#define FOREACH_ENTITY_RADIUS(org, dist, cond, body) ORDERED(FOREACH_ENTITY_RADIUS)(org, dist, cond, body)
 .entity _FOREACH_ENTITY_FIND_radius_next; noref string _FOREACH_ENTITY_FIND_radius_mutex;
 #define FOREACH_ENTITY_RADIUS_UNORDERED(org, dist, cond, body) _FOREACH_ENTITY_FIND_UNORDERED(, radius, org, dist, cond, body)
+.entity _FOREACH_ENTITY_FIND_radius_nexttmp; noref string _FOREACH_ENTITY_FIND_radius_tmpmutex;
+#define FOREACH_ENTITY_RADIUS_ORDERED(org, dist, cond, body) \
+MACRO_BEGIN \
+       entity _rev_first = NULL; \
+       _FOREACH_ENTITY_FIND_UNORDERED(tmp, radius, org, dist, cond, (it._FOREACH_ENTITY_FIND_radius_nexttmp = _rev_first, _rev_first = it)); \
+       MUTEX_LOCK(_FOREACH_ENTITY_FIND_radius_tmpmutex); \
+       FOREACH_LIST(_rev, _FOREACH_ENTITY_FIND_radius_nexttmp, true, body); \
+       MUTEX_UNLOCK(_FOREACH_ENTITY_FIND_radius_tmpmutex); \
+MACRO_END
 #endif
 
 #define FOREACH_ENTITY_FLOAT(fld, match, body) ORDERED(FOREACH_ENTITY_FLOAT)(fld, match, body)
index 6afc862ed0a6306b97e2ad5ca02702b3a79a4817..c518de14132fd84890b66342d41d4a75c41c10f9 100644 (file)
@@ -40,7 +40,7 @@ entity LL_POP(LinkedList this)
        LinkedListNode prev = n.ll_prev;
        if (prev) (this.ll_tail = prev).ll_next = NULL;
        else this.ll_head = this.ll_tail = NULL;
-       remove(n);
+       delete(n);
        return e;
 }
 
@@ -57,7 +57,7 @@ entity LL_POP(LinkedList this)
                        entity it = LL_POP(_ll); \
                        if (!it) continue; \
                        dtor \
-                       remove(it); \
+                       delete(it); \
                } \
        } MACRO_END
 
@@ -68,7 +68,7 @@ entity LL_POP(LinkedList this)
        MACRO_BEGIN \
        { \
                LL_CLEAR_2(this, dtor); \
-               remove(this); \
+               delete(this); \
                this = NULL; \
        } MACRO_END
 
index 370d96be5629f2fdc3e6a26b767799a7c1c2c7b4..a8874adbd4630d69a03458346404391ac23bd2a6 100644 (file)
@@ -82,13 +82,7 @@ string(string...) strcat0n = #115;
        } MACRO_END
 
 // TODO: this sucks, lets find a better way to do backtraces?
-#ifdef SVQC
-       void builtin_remove(entity);
-       #define _backtrace() builtin_remove(NULL)
-#else
-       void remove(entity);
-       #define _backtrace() remove(NULL)
-#endif
+#define _backtrace() builtin_remove(NULL)
 
 noref int autocvar_developer;
 noref bool autocvar_prvm_backtraceforwarnings;
index 23ec02e823242d3d58d74959d21695ece58ac6fc..db51bbffa19e663386737cb059fe40bc4ede81e9 100644 (file)
@@ -22,7 +22,7 @@ void MX_Nick_(entity fh, entity pass, int status)
             fh.url_verb = "PUT";
             fh.url_content_type = "application/json";
             url_fputs(fh, sprintf("{\"displayname\": \"%s\"}", pass.message));
-            remove(pass);
+            delete(pass);
             url_fclose(fh);
             break;
         }
@@ -175,7 +175,7 @@ void MX_Typing_(entity fh, entity pass, int status)
             fh.url_verb = "PUT";
             fh.url_content_type = "application/json";
             url_fputs(fh, sprintf("{\"typing\": %s, \"timeout\": 30000}", pass.message));
-            remove(pass);
+            delete(pass);
             url_fclose(fh);
             break;
         }
@@ -204,7 +204,7 @@ void MX_Say_(entity fh, entity pass, int status)
             fh.url_verb = "PUT";
             fh.url_content_type = "application/json";
             url_fputs(fh, sprintf("{\"msgtype\": \"m.text\", \"body\": \"%s\"}", pass.message));
-            strunzone(pass.message); remove(pass);
+            strunzone(pass.message); delete(pass);
             url_fclose(fh);
             break;
         }
index 0ce157848e2ad6d1a411664016eb1644d99db88f..7cb9bb8967959214bde61b14b7788358b2446b07 100644 (file)
@@ -176,7 +176,7 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); }
                } MACRO_END
        #define Net_Reject() \
                MACRO_BEGIN { \
-                       if (this)     remove(this); \
+                       if (this)     delete(this); \
                } MACRO_END
 
        string g_buf;
index 3708552d5968c5d5bcfb1c976bd56cae9779fa63..e3206dcf3ee799b584e85bf71457fbe44d20ee3e 100644 (file)
@@ -71,10 +71,17 @@ entity __spawn(string _classname, string _sourceLoc, bool pure)
 #define new_pure(class) _new(class, true)
 #define spawn() __spawn("entity", __FILE__ ":" STR(__LINE__), false)
 
+[[accumulate]] void ONREMOVE(entity this) {}
+
+#ifndef SVQC
+       #define delete_fn builtin_remove
+#endif
+
 #define delete(this) MACRO_BEGIN { \
     entity _this = (this); \
     void(entity) _dtor = _this.dtor; \
-    if (_dtor) _dtor(_this); else remove(_this); \
+    ONREMOVE(this); \
+    if (_dtor) _dtor(_this); else delete_fn(_this); \
     /* this = NULL; */  \
 } MACRO_END
 
@@ -271,7 +278,7 @@ STATIC_INIT(RegisterClasses)
 #define spawn_1(this)
 #define _vtbl NULL
 CLASS(Object, );
-    DESTRUCTOR(Object) { remove(this); }
+    DESTRUCTOR(Object) { builtin_remove(this); }
     #define remove(this) delete(this)
        METHOD(Object, describe, string(Object this))
        {
index 7ce923c537d8242ff77cd73f336ab438d173f57b..5f2f5851688d490ef5b973db1442ccc4ebd40c12 100644 (file)
@@ -71,10 +71,13 @@ REGISTRY(Registries, BITS(8))
        REGISTER_INIT(id) {} \
        void Register_##id() \
        { \
-               if (registry##_COUNT >= registry##_MAX) LOG_FATALF("Registry capacity exceeded (%d)", registry##_MAX); \
-               entity this = id = inst; \
-               this.registered_id = #id; \
-               REGISTRY_PUSH(registry, fld, this); \
+               entity this = id; \
+               if (this == NULL) { \
+                       if (registry##_COUNT >= registry##_MAX) LOG_FATALF("Registry capacity exceeded (%d)", registry##_MAX); \
+                       this = id = inst; \
+                       this.registered_id = #id; \
+                       REGISTRY_PUSH(registry, fld, this); \
+               } \
                Register_##id##_init(this); \
        } \
        ACCUMULATE_FUNCTION(_Register##registry, Register_##id) \
@@ -180,5 +183,9 @@ void Registry_send(string id, string hash);
        CLASS(id##Registry, Object) \
                ATTRIB(id##Registry, m_name, string, str) \
                ATTRIB(id##Registry, REGISTRY_NEXT, entity, id##_first) \
+               METHOD(id##Registry, m_reload, void()); \
        ENDCLASS(id##Registry) \
-       REGISTER(Registries, REGISTRY, id, m_id, NEW(id##Registry));
+       REGISTER(Registries, REGISTRY, id, m_id, NEW(id##Registry)); \
+       METHOD(id##Registry, m_reload, void()) { \
+               Register##id(); \
+       }
index 5d42bdccd74c2c76927b7c8cf07734037d69d8b3..bc545b0d0f53721c338fe7b9d6af93b6a5e8bc6b 100644 (file)
@@ -102,12 +102,6 @@ SELFWRAP(SendEntity, bool, (entity to, int sendflags), (entity this, entity to,
 #endif
 #define error(...) (__self = (NULL), builtin_error(__VA_ARGS__))
 #define movetogoal(e, ...) (__self = (e), builtin_movetogoal(__VA_ARGS__))
-#ifndef SVQC
-    #define objerror(e, ...) (__self = (e), builtin_objerror(__VA_ARGS__))
-#else
-    void make_safe_for_remove(entity this);
-    #define objerror(e, ...) (__self = (e), make_safe_for_remove(__self), builtin_objerror(__VA_ARGS__))
-#endif
 #define walkmove(e, ...) (__self = (e), builtin_walkmove(__VA_ARGS__))
 
 #ifndef MENUQC
index 0463979c1a3fb855c3245360ffcb3be7f4387a6a..7acf965a85b113b514298b8303bf81de4eee931f 100644 (file)
@@ -144,6 +144,7 @@ noref bool require_spawnfunc_prefix;
                FIELD_SCALAR(fld, monster_moveflags) \
                FIELD_SCALAR(fld, monster_name) \
                FIELD_SCALAR(fld, movetype) \
+               FIELD_SCALAR(fld, move_movetype) \
                FIELD_SCALAR(fld, netname) \
                FIELD_SCALAR(fld, nextthink) \
                FIELD_SCALAR(fld, noalign) \
index bd8b792967a5cfbba7365455c12aa6044b19b2a4..8aaacdec428e366123d197810684927ed97cf030 100644 (file)
@@ -27,7 +27,7 @@ USING(vectori, vector);
        #define _STAT(id) g_stat_##id
        #define REGISTER_STAT_2(id, T) \
                T _STAT(id); \
-               T CAT(_STAT(id), _prev); \
+               /* T CAT(_STAT(id), _prev); */ \
                REGISTER(Stats, STAT_##id, m_id, new_pure(stat)) \
                { \
                        if (#T == "vector" || #T == "vectori") { \
@@ -38,8 +38,8 @@ USING(vectori, vector);
                [[accumulate]] void stats_get() \
                { \
                        T it = getstat_##T(STAT_##id.m_id); \
-                       if (it != CAT(_STAT(id), _prev)) \
-                               CAT(_STAT(id), _prev) = _STAT(id) = it; \
+                       /* if (it != CAT(_STAT(id), _prev)) \
+                               CAT(_STAT(id), _prev) = */ _STAT(id) = it; \
                }
        #define REGISTER_STAT_3(x, T, expr) REGISTER_STAT_2(x, T)
 #elif defined(SVQC)
index c4c700a72d6b8341e9e561af642d638853c78e9d..8c8bcd16bc0d70ed0160dc4fd10ce35ab6ef4ed1 100644 (file)
@@ -55,7 +55,7 @@ float url_URI_Get_Callback(int id, float status, string data)
                        LOG_INFO("url_URI_Get_Callback: out of memory in buf_create\n");
                        e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
                        strunzone(e.url_url);
-                       remove(e);
+                       delete(e);
                        return 1;
                }
                e.url_rbufpos = 0;
@@ -64,7 +64,7 @@ float url_URI_Get_Callback(int id, float status, string data)
                        LOG_INFO("url_URI_Get_Callback: out of memory in buf_create\n");
                        e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
                        strunzone(e.url_url);
-                       remove(e);
+                       delete(e);
                        return 1;
                }
                for (i = 0; i < n; ++i)
@@ -77,7 +77,7 @@ float url_URI_Get_Callback(int id, float status, string data)
                // an ERROR
                e.url_ready(e, e.url_ready_pass, -fabs(status));
                strunzone(e.url_url);
-               remove(e);
+               delete(e);
                return 1;
        }
 }
@@ -107,7 +107,7 @@ void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
                                        LOG_INFO("url_single_fopen: out of memory in buf_create\n");
                                        rdy(e, pass, URL_READY_ERROR);
                                        strunzone(e.url_url);
-                                       remove(e);
+                                       delete(e);
                                        return;
                                }
                                e.url_wbufpos = 0;
@@ -229,7 +229,7 @@ void url_fclose(entity e)
                                        e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
                                        buf_del(e.url_wbuf);
                                        strunzone(e.url_url);
-                                       remove(e);
+                                       delete(e);
                                        return;
                                }
                        }
@@ -241,7 +241,7 @@ void url_fclose(entity e)
                                e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
                                buf_del(e.url_wbuf);
                                strunzone(e.url_url);
-                               remove(e);
+                               delete(e);
                                return;
                        }
 
@@ -262,20 +262,20 @@ void url_fclose(entity e)
                        e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED);
                        buf_del(e.url_rbuf);
                        strunzone(e.url_url);
-                       remove(e);
+                       delete(e);
                }
        }
        else if (e.url_fh == URL_FH_STDOUT)
        {
                e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED);  // closing creates no reading handle
-               remove(e);
+               delete(e);
        }
        else
        {
                // file
                fclose(e.url_fh);
                e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED);  // closing creates no reading handle
-               remove(e);
+               delete(e);
        }
 }
 
@@ -336,7 +336,7 @@ void url_multi_ready(entity fh, entity me, float status)
                        LOG_INFO("uri_multi_ready: got HTTP error 422, data is in unusable format - not continuing\n");
                        me.url_ready(fh, me.url_ready_pass, status);
                        strunzone(me.url_url);
-                       remove(me);
+                       delete(me);
                        return;
                }
                me.url_attempt += 1;
@@ -345,7 +345,7 @@ void url_multi_ready(entity fh, entity me, float status)
                {
                        me.url_ready(fh, me.url_ready_pass, status);
                        strunzone(me.url_url);
-                       remove(me);
+                       delete(me);
                        return;
                }
                url_single_fopen(argv(me.url_attempt), me.url_mode, url_multi_ready, me);
index adb6d6a95b272fdfc59f6c650e318411ad3738c3..10e8ed8c437f98983b55945e0e938bf9f5d73e0f 100644 (file)
@@ -34,6 +34,13 @@ vector cross(vector a, vector b)
 }
 #endif
 
+noref vector _vmul_a, _vmul_b;
+#define vmul(a, b) \
+    (_vmul_a = (a), _vmul_b = (b), \
+         '1 0 0' * (_vmul_a.x * _vmul_b.x) \
+       + '0 1 0' * (_vmul_a.y * _vmul_b.y) \
+       + '0 0 1' * (_vmul_a.z * _vmul_b.z))
+
 const vector eX = '1 0 0';
 const vector eY = '0 1 0';
 const vector eZ = '0 0 1';
@@ -124,6 +131,17 @@ vector vec_reflect(vector vel, vector norm, float bounce)
        return vel - (1 + bounce) * (vel * norm) * norm;
 }
 
+vector vec_epsilon(vector this, float eps)
+{
+       if (this.x > -eps && this.x < eps) this.x = 0;
+       if (this.y > -eps && this.y < eps) this.y = 0;
+       if (this.z > -eps && this.z < eps) this.z = 0;
+       return this;
+}
+
+#define ClipVelocity(in, normal, out, overbounce) \
+       (out = vec_epsilon(vec_reflect(in, normal, (overbounce) - 1), 0.1))
+
 #ifndef MENUQC
        vector get_corner_position(entity box, int corner)
        {
index fd0925db93f65720648b644818e06deb4bb82750..bd0397f897330d876cdede80e284e1a2062ed0cf 100644 (file)
@@ -89,7 +89,7 @@ NET_HANDLE(ENT_CLIENT_WARPZONE, bool isnew)
        // engine currently wants this
        setpredraw(this, WarpZone_Fade_PreDraw);
 
-       //this.move_touch = WarpZone_Touch;
+       //settouch(this, WarpZone_Touch);
        return true;
 }
 
index 5acacc7734d47953601c3fd385fa35b2f86497e4..0946414d57b0c8b2c8fe1868eed2aa39857c8b96 100644 (file)
@@ -671,7 +671,7 @@ void WarpZone_RefSys_GC(entity this)
        // garbage collect unused reference systems
        this.nextthink = time + 1;
        if(this.owner.WarpZone_refsys != this)
-               remove(this);
+               delete(this);
 }
 void WarpZone_RefSys_CheckCreate(entity me)
 {
@@ -688,7 +688,7 @@ void WarpZone_RefSys_Clear(entity me)
 {
        if(me.WarpZone_refsys)
        {
-               remove(me.WarpZone_refsys);
+               delete(me.WarpZone_refsys);
                me.WarpZone_refsys = NULL;
        }
 }
index 6dd0ea3c7f357ad960a801de459c13812c1d1b17..f1bd0e524e5bbd3c6cebaa2784c0c226579fa765 100644 (file)
 .float warpzone_teleport_finishtime;
 .entity warpzone_teleport_zone;
 
-#ifdef SVQC
-       #define WarpZone_StoreProjectileData(e_) MACRO_BEGIN { \
-               entity e = e_; \
-               e.warpzone_oldorigin = e.origin; \
-               e.warpzone_oldvelocity = e.velocity; \
-               e.warpzone_oldangles = e.angles; \
-               } MACRO_END
-#elif defined(CSQC)
-       #define WarpZone_StoreProjectileData(e_) MACRO_BEGIN { \
-               entity e = e_; \
-               e.warpzone_oldorigin = e.move_origin; \
-               e.warpzone_oldvelocity = e.move_velocity; \
-               e.warpzone_oldangles = e.move_angles; \
-               } MACRO_END
-#endif
+#define WarpZone_StoreProjectileData(e_) MACRO_BEGIN { \
+       entity e = e_; \
+       e.warpzone_oldorigin = e.origin; \
+       e.warpzone_oldvelocity = e.velocity; \
+       e.warpzone_oldangles = e.angles; \
+       } MACRO_END
 
 void WarpZone_TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity)
 {
-#ifdef SVQC
        setorigin(player, to); // NOTE: this also aborts the move, when this is called by touch
+#ifdef SVQC
        player.oldorigin = to; // for DP's unsticking
-       player.angles = to_angles;
        player.fixangle = true;
-       player.velocity = to_velocity;
-#elif defined(CSQC)
-       player.move_origin = to;
-       player.move_angles = to_angles;
-       player.move_velocity = to_velocity;
 #endif
+       player.angles = to_angles;
+       player.velocity = to_velocity;
 
        BITXOR_ASSIGN(player.effects, EF_TELEPORT_BIT);
 
        if(IS_PLAYER(player))
-#ifdef SVQC
                BITCLR_ASSIGN(player.flags, FL_ONGROUND);
-#elif defined(CSQC)
-               BITCLR_ASSIGN(player.move_flags, FL_ONGROUND);
-#endif
 
        WarpZone_PostTeleportPlayer_Callback(player);
 }
@@ -85,15 +68,9 @@ float WarpZone_Teleport(entity wz, entity player, float f0, float f1)
 {
        vector o0, a0, v0, o1, a1, v1, o10;
 
-#ifdef SVQC
        o0 = player.origin + player.view_ofs;
        v0 = player.velocity;
        a0 = player.angles;
-#elif defined(CSQC)
-       o0 = player.move_origin + player.view_ofs;
-       v0 = player.move_velocity;
-       a0 = player.move_angles;
-#endif
 
        o10 = o1 = WarpZone_TransformOrigin(wz, o0);
        v1 = WarpZone_TransformVelocity(wz, v0);
@@ -198,21 +175,17 @@ void WarpZone_Touch(entity this, entity toucher)
                return;
 
        // FIXME needs a better check to know what is safe to teleport and what not
-#ifdef SVQC
-       if(toucher.movetype == MOVETYPE_NONE || toucher.movetype == MOVETYPE_FOLLOW || toucher.tag_entity)
-#elif defined(CSQC)
-       if(toucher.move_movetype == MOVETYPE_NONE || toucher.move_movetype == MOVETYPE_FOLLOW || toucher.tag_networkentity)
+       if((toucher.move_movetype == MOVETYPE_NONE && toucher.move_movetype == MOVETYPE_NONE) || toucher.move_movetype == MOVETYPE_FOLLOW || toucher.move_movetype == MOVETYPE_FOLLOW || toucher.tag_entity
+#ifdef CSQC
+       || tag_networkentity
 #endif
+       )
                return;
 
        if(WarpZoneLib_ExactTrigger_Touch(this, toucher))
                return;
 
-#ifdef SVQC
        if(WarpZone_PlaneDist(this, toucher.origin + toucher.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet)
-#elif defined(CSQC)
-       if(WarpZone_PlaneDist(this, toucher.move_origin + toucher.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet)
-#endif
                return;
 
        float f;
@@ -229,11 +202,7 @@ void WarpZone_Touch(entity this, entity toucher)
        float d;
        d = 24 + max(vlen(toucher.mins), vlen(toucher.maxs));
        if(IS_NOT_A_CLIENT(toucher))
-       #ifdef SVQC
                f = -d / bound(frametime * d * 1, frametime * vlen(toucher.velocity), d);
-       #elif defined(CSQC)
-               f = -d / bound(frametime * d * 1, frametime * vlen(toucher.move_velocity), d);
-       #endif
        else
                f = -1;
        if(WarpZone_Teleport(this, toucher, f, 0))
@@ -365,17 +334,8 @@ float WarpZone_CheckProjectileImpact(entity player)
 {
        vector o0, v0;
 
-       .vector orgvec, velvec;
-#ifdef SVQC
-       orgvec = origin;
-       velvec = velocity;
-#elif defined(CSQC)
-       orgvec = move_origin;
-       velvec = move_velocity;
-#endif
-
-       o0 = player.orgvec + player.view_ofs;
-       v0 = player.velvec;
+       o0 = player.origin + player.view_ofs;
+       v0 = player.velocity;
 
        // if we teleported shortly before, abort
        if(time <= player.warpzone_teleport_finishtime + 0.1)
@@ -393,19 +353,15 @@ float WarpZone_CheckProjectileImpact(entity player)
        LOG_INFO("impactfilter found something - and it even gets handled correctly - please tell divVerent that this code apparently gets triggered again\n");
 #endif
        LOG_INFO("Entity type: ", player.classname, "\n");
-       LOG_INFO("Origin: ", vtos(player.orgvec), "\n");
-       LOG_INFO("Velocity: ", vtos(player.velvec), "\n");
+       LOG_INFO("Origin: ", vtos(player.origin), "\n");
+       LOG_INFO("Velocity: ", vtos(player.velocity), "\n");
 
 #ifdef WARPZONELIB_REMOVEHACK
        return 0;
 #else
        // retry previous move
-#ifdef SVQC
        setorigin(player, player.warpzone_oldorigin);
-#elif defined(CSQC)
-       player.move_origin = player.warpzone_oldorigin;
-#endif
-       player.velvec = player.warpzone_oldvelocity;
+       player.velocity = player.warpzone_oldvelocity;
        if(WarpZone_Teleport(wz, player, 0, 1))
        {
                string save1, save2;
@@ -425,7 +381,7 @@ float WarpZone_CheckProjectileImpact(entity player)
        else
        {
                setorigin(player, o0 - player.view_ofs);
-               player.velvec = v0;
+               player.velocity = v0;
        }
 
        return +1;
@@ -847,7 +803,7 @@ void WarpZone_StartFrame()
                WarpZone_PostInitialize_Callback();
        }
 
-       FOREACH_ENTITY(!is_pure(it),
+       FOREACH_ENTITY_FLOAT(pure_data, false,
        {
                if(warpzone_warpzones_exist)
                        WarpZone_StoreProjectileData(it);
@@ -879,9 +835,10 @@ void WarpZone_StartFrame()
 .float warpzone_reconnecting;
 bool visible_to_some_client(entity ent)
 {
-       FOREACH_ENTITY(!IS_NOT_A_CLIENT(it), LAMBDA(
-               if (IS_PLAYER(it) && IS_REAL_CLIENT(it) && checkpvs(it.origin + it.view_ofs, ent)) return true;
-       ));
+       FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && checkpvs(it.origin + it.view_ofs, ent),
+       {
+               return true;
+       });
        return false;
 }
 void trigger_warpzone_reconnect_use(entity this, entity actor, entity trigger)
index 73f09c0e07e871c65c738e887547ec95e8e46d31..d5533647f51e7727cb19b886e9fd3eea6887bb8c 100644 (file)
@@ -43,7 +43,7 @@ void WarpZoneLib_ExactTrigger_Init(entity this)
                setsize(this, this.mins * this.scale, this.maxs * this.scale);
        else
                setsize(this, this.mins, this.maxs);
-       this.movetype = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        this.solid = SOLID_TRIGGER;
        this.model = "";
 }
index 5e39191dd658c71d38dd363393483854ba7cb3e4..3009ab4eaf8b00f47fd4efdf362b3c0ba42b67b0 100644 (file)
@@ -37,7 +37,7 @@
 
                if (n) n.prevSibling = p;
                else this.lastChild = p;
-               remove(other);
+               delete(other);
        }
 
        METHOD(AnimHost, removeAllAnim, void(entity this))
index 9b617ab8a16eaa421a050b3732bb7890801af3b6..f32b85298ed7e23a8a70c04f46aa8d1fedad6dde 100644 (file)
@@ -849,6 +849,7 @@ void m_draw(float width, float height)
        postMenuDraw();
 
        frametime = 0;
+       IL_ENDFRAME();
 }
 
 void m_display()
index f387f429b651f62895b974dc3550aa58b295bf8a..a34d0d80a1cb12a9e713efb213d147b5f272226d 100644 (file)
@@ -14,6 +14,13 @@ entity makeXonoticServerListTab()
        me.configureDialog(me);
        return me;
 }
+
+void XonoticServerListTab_refresh(entity this, entity slist)
+{
+    bool clear = false;
+    slist.refreshServerList(slist, clear ? REFRESHSERVERLIST_RESET : REFRESHSERVERLIST_ASK);
+}
+
 void XonoticServerListTab_fill(entity me)
 {
        entity e, slist;
@@ -21,13 +28,13 @@ void XonoticServerListTab_fill(entity me)
        slist  = makeXonoticServerList();
 
        me.gotoRC(me, 0.5, 0);
-               me.TD(me, 1, 0.6, e = makeXonoticTextLabel(1, _("Filter:")));
-               me.TD(me, 1, 2.8, e = makeXonoticInputBox(0, string_null));
+               me.TD(me, 1, 0.5, e = makeXonoticTextLabel(1, _("Filter:")));
+               me.TD(me, 1, 2, e = makeXonoticInputBox(0, string_null));
                        e.onChange = ServerList_Filter_Change;
                        e.onChangeEntity = slist;
                        slist.controlledTextbox = e;
 
-       me.gotoRC(me, 0.5, 3.6);
+       me.gotoRC(me, 0.5, 2.6);
                me.TD(me, 1, 0.9, e = makeXonoticCheckBox(0, "menu_slist_categories", ZCTX(_("SRVS^Categories"))));
                        e.onClickEntity = slist;
                        e.onClick = ServerList_Categories_Click;
@@ -43,6 +50,9 @@ void XonoticServerListTab_fill(entity me)
                        e.onClick = ServerList_ShowFull_Click;
                me.TD(me, 1, 0.6, e = makeXonoticCheckBox_T(0, "net_slist_pause", _("Pause"),
                        _("Pause updating the server list to prevent servers from \"jumping around\"")));
+               me.TD(me, 1, 1, e = makeXonoticButton_T(_("Refresh"), '0 0 0', _("Reload the server list")));
+                       e.onClick = XonoticServerListTab_refresh;
+                       e.onClickEntity = slist;
 
        me.gotoRC(me, 2, 0);
                me.TD(me, 1, 1, slist.sortButton1 = makeXonoticButton(string_null, '0 0 0'));
index 9ee031dc783e6196dca7df6592ba6ab5f63fb6ea..193f8336838acb793ed261da5566bd9cb2bddf8c 100644 (file)
@@ -59,6 +59,15 @@ void XonoticGametypeList_saveCvars(entity me)
                owner.gameTypeChangeNotify(owner);
        }
 }
+void XonoticGametypeList_draw(entity me)
+{
+       if(me.nItems != GameType_GetCount())
+       {
+               me.nItems = GameType_GetCount();
+               me.setSelected(me, 0);
+       }
+       SUPER(XonoticGametypeList).draw(me);
+}
 void XonoticGametypeList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
        string s1, s2;
index 95eceaa09b350abaa6c337986d5e37c41dd1631c..9e17c5c85523e5008d275f80687688951cf19448 100644 (file)
@@ -4,6 +4,7 @@
 CLASS(XonoticGametypeList, XonoticListBox)
        METHOD(XonoticGametypeList, configureXonoticGametypeList, void(entity));
        ATTRIB(XonoticGametypeList, rowsPerItem, float, 2)
+       METHOD(XonoticGametypeList, draw, void(entity));
        METHOD(XonoticGametypeList, drawListBoxItem, void(entity, int, vector, bool, bool));
        METHOD(XonoticGametypeList, resizeNotify, void(entity, vector, vector, vector, vector));
        METHOD(XonoticGametypeList, setSelected, void(entity, float));
index ca2db83573d02a468f7077cb5474f331979fc00d..27e488164be5065733501571283131907c86a012 100644 (file)
@@ -41,10 +41,10 @@ void Xonotic_KeyBinds_Read()
        KEYBIND_DEF("+fire2"                                , _("secondary fire"));
        KEYBIND_DEF(""                                      , "");
        KEYBIND_DEF(""                                      , _("Weapon switching"));
-       KEYBIND_DEF("weapprev"                              , _("previous"));
-       KEYBIND_DEF("weapnext"                              , _("next"));
-       KEYBIND_DEF("weaplast"                              , _("previously used"));
-       KEYBIND_DEF("weapbest"                              , _("best"));
+       KEYBIND_DEF("weapprev"                              , CTX(_("WEAPON^previous")));
+       KEYBIND_DEF("weapnext"                              , CTX(_("WEAPON^next")));
+       KEYBIND_DEF("weaplast"                              , CTX(_("WEAPON^previously used")));
+       KEYBIND_DEF("weapbest"                              , CTX(_("WEAPON^best")));
        KEYBIND_DEF("reload"                                , _("reload"));
 
        int i;
index a32f8b5832cf01e9ecccc534be2d794d6672118f..ed3083a1203fd94c69943efb17341c80c45127d1 100644 (file)
@@ -43,7 +43,7 @@ const string STR_OBSERVER = "observer";
 
 #define FOREACH_CLIENT(cond, body) FOREACH_CLIENTSLOT(IS_CLIENT(it) && (cond), body)
 
-// NOTE: FOR_EACH_MONSTER deprecated! Use the following instead: FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, { code; });
+// NOTE: FOR_EACH_MONSTER deprecated! Use the following instead: IL_EACH(g_monsters, true, { code; });
 
 #include <common/effects/all.qh>
 #include <common/models/all.qh>
index fc50ee1aee479b918ba3b6b7e1f6ead144353669..188cc713137adff0ff81112ecc795719b4abe612 100644 (file)
@@ -357,7 +357,7 @@ float autocvar_sv_gameplayfix_q2airaccelerate;
 int autocvar_sv_gentle;
 #define autocvar_sv_gravity cvar("sv_gravity")
 string autocvar_sv_intermission_cdtrack;
-float autocvar_sv_itemstime;
+int autocvar_sv_itemstime;
 string autocvar_sv_jumpspeedcap_max;
 float autocvar_sv_jumpspeedcap_max_disable_on_ramps;
 string autocvar_sv_jumpspeedcap_min;
index b2fca55e8671a76f7e31acfe71a666adb8ab9447..b867b5f6d13776dca6e9659054647240424558e8 100644 (file)
@@ -43,7 +43,7 @@ float findtrajectorywithleading(vector org, vector m1, vector m2, entity targ, f
        if (!tracetossfaketarget)
                tracetossfaketarget = new(tracetossfaketarget);
        tracetossfaketarget.solid = savesolid;
-       tracetossfaketarget.movetype = targ.movetype;
+       set_movetype(tracetossfaketarget, targ.move_movetype);
        _setmodel(tracetossfaketarget, targ.model); // no low precision
        tracetossfaketarget.model = targ.model;
        tracetossfaketarget.modelindex = targ.modelindex;
@@ -63,7 +63,7 @@ float findtrajectorywithleading(vector org, vector m1, vector m2, entity targ, f
 
                        // make it disappear
                        tracetossfaketarget.solid = SOLID_NOT;
-                       tracetossfaketarget.movetype = MOVETYPE_NONE;
+                       set_movetype(tracetossfaketarget, MOVETYPE_NONE);
                        tracetossfaketarget.model = "";
                        tracetossfaketarget.modelindex = 0;
                        // relink to remove it from physics considerations
@@ -78,7 +78,7 @@ float findtrajectorywithleading(vector org, vector m1, vector m2, entity targ, f
 
        // make it disappear
        tracetossfaketarget.solid = SOLID_NOT;
-       tracetossfaketarget.movetype = MOVETYPE_NONE;
+       set_movetype(tracetossfaketarget, MOVETYPE_NONE);
        tracetossfaketarget.model = "";
        tracetossfaketarget.modelindex = 0;
        // relink to remove it from physics considerations
index 8707a03bd4d9b7d0070f6a71b6503f2ed9aef5cc..58feef6599c78e923c0d0fd0b31f715ee0518369 100644 (file)
@@ -346,31 +346,28 @@ void bot_endgame()
 
 void bot_relinkplayerlist()
 {
-       entity e;
-       entity prevbot;
        player_count = 0;
        currentbots = 0;
-       player_list = e = findchainflags(flags, FL_CLIENT);
        bot_list = NULL;
-       prevbot = NULL;
-       while (e)
+
+       entity prevbot = NULL;
+       FOREACH_CLIENT(true,
        {
-               player_count = player_count + 1;
-               e.nextplayer = e.chain;
-               if (IS_BOT_CLIENT(e))
+               ++player_count;
+
+               if(IS_BOT_CLIENT(it))
                {
-                       if (prevbot)
-                               prevbot.nextbot = e;
+                       if(prevbot)
+                               prevbot.nextbot = it;
                        else
                        {
-                               bot_list = e;
+                               bot_list = it;
                                bot_list.nextbot = NULL;
                        }
-                       prevbot = e;
-                       currentbots = currentbots + 1;
+                       prevbot = it;
+                       ++currentbots;
                }
-               e = e.chain;
-       }
+       });
        LOG_TRACE(strcat("relink: ", ftos(currentbots), " bots seen.\n"));
        bot_strategytoken = bot_list;
        bot_strategytoken_taken = true;
@@ -394,7 +391,7 @@ void bot_clientdisconnect(entity this)
        this.playermodel_freeme = string_null;
        this.playerskin_freeme = string_null;
        if(this.bot_cmd_current)
-               remove(this.bot_cmd_current);
+               delete(this.bot_cmd_current);
        if(bot_waypoint_queue_owner==this)
                bot_waypoint_queue_owner = NULL;
 }
@@ -427,70 +424,84 @@ void bot_clientconnect(entity this)
 
 void bot_removefromlargestteam()
 {
-       float besttime, bestcount, thiscount;
-       entity best, head;
        CheckAllowedTeams(NULL);
        GetTeamCounts(NULL);
-       head = findchainfloat(isbot, true);
-       if (!head)
-               return;
-       best = head;
-       besttime = head.createdtime;
-       bestcount = 0;
-       while (head)
+
+       entity best = NULL;
+       float besttime = 0;
+       int bestcount = 0;
+
+       int bcount = 0;
+       FOREACH_ENTITY_FLOAT(isbot, true,
        {
-               if(head.team == NUM_TEAM_1)
-                       thiscount = c1;
-               else if(head.team == NUM_TEAM_2)
-                       thiscount = c2;
-               else if(head.team == NUM_TEAM_3)
-                       thiscount = c3;
-               else if(head.team == NUM_TEAM_4)
-                       thiscount = c4;
-               else
-                       thiscount = 0;
-               if (thiscount > bestcount)
+               ++bcount;
+
+               if(!best)
+               {
+                       best = it;
+                       besttime = it.createdtime;
+               }
+
+               int thiscount = 0;
+
+               switch(it.team)
+               {
+                       case NUM_TEAM_1: thiscount = c1; break;
+                       case NUM_TEAM_2: thiscount = c2; break;
+                       case NUM_TEAM_3: thiscount = c3; break;
+                       case NUM_TEAM_4: thiscount = c4; break;
+               }
+
+               if(thiscount > bestcount)
                {
                        bestcount = thiscount;
-                       besttime = head.createdtime;
-                       best = head;
+                       besttime = it.createdtime;
+                       best = it;
                }
-               else if (thiscount == bestcount && besttime < head.createdtime)
+               else if(thiscount == bestcount && besttime < it.createdtime)
                {
-                       besttime = head.createdtime;
-                       best = head;
+                       besttime = it.createdtime;
+                       best = it;
                }
-               head = head.chain;
-       }
+       });
+       if(!bcount)
+               return; // no bots to remove
        currentbots = currentbots - 1;
        dropclient(best);
 }
 
 void bot_removenewest()
 {
-       float besttime;
-       entity best, head;
-
        if(teamplay)
        {
                bot_removefromlargestteam();
                return;
        }
 
-       head = findchainfloat(isbot, true);
-       if (!head)
-               return;
-       best = head;
-       besttime = head.createdtime;
-       while (head)
+       float besttime = 0;
+       entity best = NULL;
+       int bcount = 0;
+
+       FOREACH_ENTITY_FLOAT(isbot, true,
        {
-               if (besttime < head.createdtime)
+               ++bcount;
+
+               if(!best)
                {
-                       besttime = head.createdtime;
-                       best = head;
+                       best = it;
+                       besttime = it.createdtime;
                }
-               head = head.chain;
-       }
+
+               if(besttime < it.createdtime)
+               {
+                       besttime = it.createdtime;
+                       best = it;
+               }
+       });
+
+       if(!bcount)
+               return; // no bots to remove
+
        currentbots = currentbots - 1;
        dropclient(best);
 }
@@ -573,7 +584,7 @@ float bot_fixcount()
        // But don't remove bots immediately on level change, as the real players
        // usually haven't rejoined yet
        bots_would_leave = false;
-       if (teamplay && autocvar_bot_vs_human && (c3==-1 && c4==-1))
+       if (teamplay && autocvar_bot_vs_human && AvailableTeams() == 2)
                bots = min(ceil(fabs(autocvar_bot_vs_human) * activerealplayers), maxclients - realplayers);
        else if ((realplayers || autocvar_bot_join_empty || (currentbots > 0 && time < 5)))
        {
@@ -659,9 +670,11 @@ void bot_serverframe()
                else
                {
                        // TODO: Make this check cleaner
-                       entity wp = findchain(classname, "waypoint");
-                       if(time - wp.nextthink > 10)
+                       IL_EACH(g_waypoints, time - it.nextthink > 10,
+                       {
                                waypoint_save_links();
+                               break;
+                       });
                }
        }
        else
index a28c94b7f729a8744241489008dc324caae6f51d..e9dd92668995f895482c59dd310fcb4138f1d09d 100644 (file)
@@ -52,9 +52,7 @@ float bot_weapons_mid[Weapons_MAX];
 float bot_weapons_close[Weapons_MAX];
 
 entity bot_list;
-entity player_list;
 .entity nextbot;
-.entity nextplayer;
 .string cleanname;
 .string netname_freeme;
 .string playermodel_freeme;
index c3603e9ff1bdc7390bde112b1e67d876d4fd0921..ceb9b296e7a6a9fd5dc963b2c11437bdda75b987 100644 (file)
@@ -41,41 +41,30 @@ void havocbot_ai(entity this)
                // TODO: tracewalk() should take care of this job (better path finding under water)
                // if we don't have a goal and we're under water look for a waypoint near the "shore" and push it
                if(IS_DEAD(this))
-               if(this.goalcurrent==NULL)
-               if(this.waterlevel==WATERLEVEL_SWIMMING || (this.aistatus & AI_STATUS_OUT_WATER))
+               if(!this.goalcurrent)
+               if(this.waterlevel == WATERLEVEL_SWIMMING || (this.aistatus & AI_STATUS_OUT_WATER))
                {
                        // Look for the closest waypoint out of water
-                       entity newgoal, head;
-                       float bestdistance, distance;
-
-                       newgoal = NULL;
-                       bestdistance = 10000;
-                       for (head = findchain(classname, "waypoint"); head; head = head.chain)
+                       entity newgoal = NULL;
+                       IL_EACH(g_waypoints, vdist(it.origin - this.origin, <=, 10000),
                        {
-                               distance = vlen(head.origin - this.origin);
-                               if(distance>10000)
-                                       continue;
-
-                               if(head.origin.z < this.origin.z)
+                               if(it.origin.z < this.origin.z)
                                        continue;
 
-                               if(head.origin.z - this.origin.z - this.view_ofs.z > 100)
+                               if(it.origin.z - this.origin.z - this.view_ofs.z > 100)
                                        continue;
 
-                               if (pointcontents(head.origin + head.maxs + '0 0 1') != CONTENT_EMPTY)
+                               if (pointcontents(it.origin + it.maxs + '0 0 1') != CONTENT_EMPTY)
                                        continue;
 
-                               traceline(this.origin + this.view_ofs , head.origin, true, head);
+                               traceline(this.origin + this.view_ofs, ((it.absmin + it.absmax) * 0.5), true, this);
 
-                               if(trace_fraction<1)
+                               if(trace_fraction < 1)
                                        continue;
 
-                               if(distance<bestdistance)
-                               {
-                                       newgoal = head;
-                                       bestdistance = distance;
-                               }
-                       }
+                               if(!newgoal || vlen2(it.origin - this.origin) < vlen2(newgoal.origin - this.origin))
+                                       newgoal = it;
+                       });
 
                        if(newgoal)
                        {
@@ -496,27 +485,17 @@ void havocbot_movetogoal(entity this)
                {
                        if(fabs(this.velocity.z)<50)
                        {
-                               entity head, newgoal = NULL;
-                               float distance, bestdistance = 0;
-
-                               for (head = findchain(classname, "waypoint"); head; head = head.chain)
+                               entity newgoal = NULL;
+                               IL_EACH(g_waypoints, vdist(it.origin - this.origin, <=, 1000),
                                {
+                                       traceline(this.origin + this.view_ofs, ((it.absmin + it.absmax) * 0.5), true, this);
 
-                                       distance = vlen(head.origin - this.origin);
-                                       if(distance>1000)
+                                       if(trace_fraction < 1)
                                                continue;
 
-                                       traceline(this.origin + this.view_ofs , ( ( head.absmin + head.absmax ) * 0.5 ), true, NULL);
-
-                                       if(trace_fraction<1)
-                                               continue;
-
-                                       if(distance>bestdistance)
-                                       {
-                                               newgoal = head;
-                                               bestdistance = distance;
-                                       }
-                               }
+                                       if(!newgoal || vlen2(it.origin - this.origin) > vlen2(newgoal.origin - this.origin))
+                                               newgoal = it;
+                               });
 
                                if(newgoal)
                                {
@@ -1169,7 +1148,7 @@ float havocbot_moveto(entity this, vector pos)
                                {
                                        LOG_TRACE("Warning: can't walk to the personal waypoint located at ", vtos(this.havocbot_personal_waypoint.origin),"\n");
                                        this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_LINKING;
-                                       remove(this.havocbot_personal_waypoint);
+                                       delete(this.havocbot_personal_waypoint);
                                        return CMD_STATUS_ERROR;
                                }
                                else
@@ -1192,7 +1171,7 @@ float havocbot_moveto(entity this, vector pos)
                {
                        // Step 5: Waypoint reached
                        LOG_TRACE(this.netname, "'s personal waypoint reached\n");
-                       remove(this.havocbot_personal_waypoint);
+                       delete(this.havocbot_personal_waypoint);
                        this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_REACHED;
                        return CMD_STATUS_FINISHED;
                }
index 034e29fabf4a254307abefa73d737131fa545093..9ea6a3d904e6da3347805a3a05ea61827bf9fb6c 100644 (file)
 
 void havocbot_goalrating_items(entity this, float ratingscale, vector org, float sradius)
 {
-       entity head;
-       float rating, d, discard, distance, friend_distance, enemy_distance;
+       float rating, d, discard, friend_distance, enemy_distance;
        vector o;
        ratingscale = ratingscale * 0.0001; // items are rated around 10000 already
-       head = findchainfloat(bot_pickup, true);
 
-       while (head)
+       FOREACH_ENTITY_FLOAT(bot_pickup, true,
        {
-               o = (head.absmin + head.absmax) * 0.5;
-               distance = vlen(o - org);
+               o = (it.absmin + it.absmax) * 0.5;
                friend_distance = 10000; enemy_distance = 10000;
                rating = 0;
 
-               if(!head.solid || distance > sradius || (head == this.ignoregoal && time < this.ignoregoaltime) )
-               {
-                       head = head.chain;
+               if(!it.solid || vdist(o - org, >, sradius) || (it == this.ignoregoal && time < this.ignoregoaltime) )
                        continue;
-               }
 
                // Check if the item can be picked up safely
-               if(head.classname == "droppedweapon")
+               if(it.classname == "droppedweapon")
                {
                        traceline(o, o + '0 0 -1500', true, NULL);
 
                        d = pointcontents(trace_endpos + '0 0 1');
                        if(d & CONTENT_WATER || d & CONTENT_SLIME || d & CONTENT_LAVA)
-                       {
-                               head = head.chain;
                                continue;
-                       }
-                       if(tracebox_hits_trigger_hurt(head.origin, head.mins, head.maxs, trace_endpos))
-                       {
-                               head = head.chain;
+                       if(tracebox_hits_trigger_hurt(it.origin, it.mins, it.maxs, trace_endpos))
                                continue;
-                       }
                }
                else
                {
                        // Ignore items under water
-                       traceline(head.origin + head.maxs, head.origin + head.maxs, MOVE_NORMAL, head);
+                       traceline(it.origin + it.maxs, it.origin + it.maxs, MOVE_NORMAL, it);
                        if(trace_dpstartcontents & DPCONTENTS_LIQUIDSMASK)
-                       {
-                               head = head.chain;
                                continue;
-                       }
                }
 
                if(teamplay)
                {
                        discard = false;
 
-                       FOREACH_CLIENT(IS_PLAYER(it) && it != this && !IS_DEAD(it), LAMBDA(
+                       entity picker = it;
+                       FOREACH_CLIENT(IS_PLAYER(it) && it != this && !IS_DEAD(it),
+                       {
                                d = vlen(it.origin - o); // distance between player and item
 
                                if ( it.team == this.team )
@@ -79,29 +66,29 @@ void havocbot_goalrating_items(entity this, float ratingscale, vector org, float
 
                                        discard = true;
 
-                                       if( head.health && it.health > this.health )
+                                       if( picker.health && it.health > this.health )
                                                continue;
 
-                                       if( head.armorvalue && it.armorvalue > this.armorvalue)
+                                       if( picker.armorvalue && it.armorvalue > this.armorvalue)
                                                continue;
 
-                                       if( head.weapons )
-                                       if( head.weapons & ~it.weapons )
+                                       if( picker.weapons )
+                                       if( picker.weapons & ~it.weapons )
                                                continue;
 
-                                       if (head.ammo_shells && it.ammo_shells > this.ammo_shells)
+                                       if (picker.ammo_shells && it.ammo_shells > this.ammo_shells)
                                                continue;
 
-                                       if (head.ammo_nails && it.ammo_nails > this.ammo_nails)
+                                       if (picker.ammo_nails && it.ammo_nails > this.ammo_nails)
                                                continue;
 
-                                       if (head.ammo_rockets && it.ammo_rockets > this.ammo_rockets)
+                                       if (picker.ammo_rockets && it.ammo_rockets > this.ammo_rockets)
                                                continue;
 
-                                       if (head.ammo_cells && it.ammo_cells > this.ammo_cells)
+                                       if (picker.ammo_cells && it.ammo_cells > this.ammo_cells)
                                                continue;
 
-                                       if (head.ammo_plasma && it.ammo_plasma > this.ammo_plasma)
+                                       if (picker.ammo_plasma && it.ammo_plasma > this.ammo_plasma)
                                                continue;
 
                                        discard = false;
@@ -113,40 +100,33 @@ void havocbot_goalrating_items(entity this, float ratingscale, vector org, float
                                        if( d < enemy_distance )
                                                enemy_distance = d;
                                }
-                       ));
+                       });
 
                        // Rate the item only if no one needs it, or if an enemy is closer to it
-                       if ( (enemy_distance < friend_distance && distance < enemy_distance) ||
+                       if ( (enemy_distance < friend_distance && vdist(o - org, <, enemy_distance)) ||
                                (friend_distance > autocvar_bot_ai_friends_aware_pickup_radius ) || !discard )
-                               rating = head.bot_pickupevalfunc(this, head);
+                               rating = it.bot_pickupevalfunc(this, it);
 
                }
                else
-                       rating = head.bot_pickupevalfunc(this, head);
+                       rating = it.bot_pickupevalfunc(this, it);
 
                if(rating > 0)
-                       navigation_routerating(this, head, rating * ratingscale, 2000);
-               head = head.chain;
-       }
+                       navigation_routerating(this, it, rating * ratingscale, 2000);
+       });
 }
 
 void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius)
 {
-       entity head;
-       head = findchain(classname, "dom_controlpoint");
-       while (head)
+       FOREACH_ENTITY_CLASS("dom_controlpoint", vdist((((it.absmin + it.absmax) * 0.5) - org), <, sradius),
        {
-               if(vdist((((head.absmin + head.absmax) * 0.5) - org), <, sradius))
-               {
-                       if(head.cnt > -1) // this is just being fought for
-                               navigation_routerating(this, head, ratingscale, 5000);
-                       else if(head.goalentity.cnt == 0) // unclaimed point
-                               navigation_routerating(this, head, ratingscale * 0.5, 5000);
-                       else if(head.goalentity.team != this.team) // other team's point
-                               navigation_routerating(this, head, ratingscale * 0.2, 5000);
-               }
-               head = head.chain;
-       }
+               if(it.cnt > -1) // this is just being fought
+                       navigation_routerating(this, it, ratingscale, 5000);
+               else if(it.goalentity.cnt == 0) // unclaimed
+                       navigation_routerating(this, it, ratingscale * 0.5, 5000);
+               else if(it.goalentity.team != this.team) // other team's point
+                       navigation_routerating(this, it, ratingscale * 0.2, 5000);
+       });
 }
 
 void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org, float sradius)
index 8deefdb39716c527be0bc1e36512cccfb07471cf..c9418e2e31e072f054c84e9b4cb5f450873bb979 100644 (file)
@@ -373,25 +373,17 @@ float navigation_waypoint_will_link(vector v, vector org, entity ent, float walk
 // find the spawnfunc_waypoint near a dynamic goal such as a dropped weapon
 entity navigation_findnearestwaypoint_withdist_except(entity ent, float walkfromwp, float bestdist, entity except)
 {
-       entity waylist, w, best;
-       vector v, org, pm1, pm2;
-
-       pm1 = ent.origin + ent.mins;
-       pm2 = ent.origin + ent.maxs;
-       waylist = findchain(classname, "waypoint");
+       vector pm1 = ent.origin + ent.mins;
+       vector pm2 = ent.origin + ent.maxs;
 
        // do two scans, because box test is cheaper
-       w = waylist;
-       while (w)
+       IL_EACH(g_waypoints, it != ent && it != except,
        {
-               // if object is touching spawnfunc_waypoint
-               if(w != ent && w != except)
-                       if (boxesoverlap(pm1, pm2, w.absmin, w.absmax))
-                               return w;
-               w = w.chain;
-       }
+               if(boxesoverlap(pm1, pm2, it.absmin, it.absmax))
+                       return it;
+       });
 
-       org = ent.origin + 0.5 * (ent.mins + ent.maxs);
+       vector org = ent.origin + 0.5 * (ent.mins + ent.maxs);
        org.z = ent.origin.z + ent.mins.z - STAT(PL_MIN, NULL).z; // player height
        // TODO possibly make other code have the same support for bboxes
        if(ent.tag_entity)
@@ -399,34 +391,28 @@ entity navigation_findnearestwaypoint_withdist_except(entity ent, float walkfrom
        if (navigation_testtracewalk)
                te_plasmaburn(org);
 
-       best = NULL;
+       entity best = NULL;
+       vector v;
 
        // box check failed, try walk
-       w = waylist;
-       while (w)
+       IL_EACH(g_waypoints, it != ent,
        {
-               // if object can walk from spawnfunc_waypoint
-               if(w != ent)
+               if(it.wpisbox)
                {
-                       if (w.wpisbox)
-                       {
-                               vector wm1, wm2;
-                               wm1 = w.origin + w.mins;
-                               wm2 = w.origin + w.maxs;
-                               v.x = bound(wm1_x, org.x, wm2_x);
-                               v.y = bound(wm1_y, org.y, wm2_y);
-                               v.z = bound(wm1_z, org.z, wm2_z);
-                       }
-                       else
-                               v = w.origin;
-                       if(navigation_waypoint_will_link(v, org, ent, walkfromwp, bestdist))
-                       {
-                               bestdist = vlen(v - org);
-                               best = w;
-                       }
+                       vector wm1 = it.origin + it.mins;
+                       vector wm2 = it.origin + it.maxs;
+                       v.x = bound(wm1_x, org.x, wm2_x);
+                       v.y = bound(wm1_y, org.y, wm2_y);
+                       v.z = bound(wm1_z, org.z, wm2_z);
                }
-               w = w.chain;
-       }
+               else
+                       v = it.origin;
+               if(navigation_waypoint_will_link(v, org, ent, walkfromwp, bestdist))
+               {
+                       bestdist = vlen(v - org);
+                       best = it;
+               }
+       });
        return best;
 }
 entity navigation_findnearestwaypoint(entity ent, float walkfromwp)
@@ -442,46 +428,39 @@ entity navigation_findnearestwaypoint(entity ent, float walkfromwp)
 }
 
 // finds the waypoints near the bot initiating a navigation query
-float navigation_markroutes_nearestwaypoints(entity this, entity waylist, float maxdist)
+float navigation_markroutes_nearestwaypoints(entity this, float maxdist)
 {
-       entity head;
-       vector v, m1, m2, diff;
-       float c;
+       vector v, m1, m2;
 //     navigation_testtracewalk = true;
-       c = 0;
-       head = waylist;
-       while (head)
+       int c = 0;
+       IL_EACH(g_waypoints, !it.wpconsidered,
        {
-               if (!head.wpconsidered)
+               if (it.wpisbox)
                {
-                       if (head.wpisbox)
+                       m1 = it.origin + it.mins;
+                       m2 = it.origin + it.maxs;
+                       v = this.origin;
+                       v.x = bound(m1_x, v.x, m2_x);
+                       v.y = bound(m1_y, v.y, m2_y);
+                       v.z = bound(m1_z, v.z, m2_z);
+               }
+               else
+                       v = it.origin;
+               vector diff = v - this.origin;
+               diff.z = max(0, diff.z);
+               if(vdist(diff, <, maxdist))
+               {
+                       it.wpconsidered = true;
+                       if (tracewalk(this, this.origin, this.mins, this.maxs, v, bot_navigation_movemode))
                        {
-                               m1 = head.origin + head.mins;
-                               m2 = head.origin + head.maxs;
-                               v = this.origin;
-                               v.x = bound(m1_x, v.x, m2_x);
-                               v.y = bound(m1_y, v.y, m2_y);
-                               v.z = bound(m1_z, v.z, m2_z);
-                       }
-                       else
-                               v = head.origin;
-                       diff = v - this.origin;
-                       diff.z = max(0, diff.z);
-                       if(vdist(diff, <, maxdist))
-                       {
-                               head.wpconsidered = true;
-                               if (tracewalk(this, this.origin, this.mins, this.maxs, v, bot_navigation_movemode))
-                               {
-                                       head.wpnearestpoint = v;
-                                       head.wpcost = vlen(v - this.origin) + head.dmg;
-                                       head.wpfire = 1;
-                                       head.enemy = NULL;
-                                       c = c + 1;
-                               }
+                               it.wpnearestpoint = v;
+                               it.wpcost = vlen(v - this.origin) + it.dmg;
+                               it.wpfire = 1;
+                               it.enemy = NULL;
+                               c = c + 1;
                        }
                }
-               head = head.chain;
-       }
+       });
        //navigation_testtracewalk = false;
        return c;
 }
@@ -515,19 +494,17 @@ void navigation_markroutes_checkwaypoint(entity w, entity wp, float cost2, vecto
 // queries the entire spawnfunc_waypoint network for pathes leading away from the bot
 void navigation_markroutes(entity this, entity fixed_source_waypoint)
 {
-       entity w, wp, waylist;
-       float searching, cost, cost2;
+       float cost, cost2;
        vector p;
-       w = waylist = findchain(classname, "waypoint");
-       while (w)
+
+       IL_EACH(g_waypoints, true,
        {
-               w.wpconsidered = false;
-               w.wpnearestpoint = '0 0 0';
-               w.wpcost = 10000000;
-               w.wpfire = 0;
-               w.enemy = NULL;
-               w = w.chain;
-       }
+               it.wpconsidered = false;
+               it.wpnearestpoint = '0 0 0';
+               it.wpcost = 10000000;
+               it.wpfire = 0;
+               it.enemy = NULL;
+       });
 
        if(fixed_source_waypoint)
        {
@@ -541,7 +518,7 @@ void navigation_markroutes(entity this, entity fixed_source_waypoint)
        {
                // try a short range search for the nearest waypoints, and expand the search repeatedly if none are found
                // as this search is expensive we will use lower values if the bot is on the air
-               float i, increment, maxdistance;
+               float increment, maxdistance;
                if(IS_ONGROUND(this))
                {
                        increment = 750;
@@ -553,77 +530,70 @@ void navigation_markroutes(entity this, entity fixed_source_waypoint)
                        maxdistance = 1500;
                }
 
-               for(i=increment;!navigation_markroutes_nearestwaypoints(this, waylist, i)&&i<maxdistance;i+=increment);
+               for(int j = increment; !navigation_markroutes_nearestwaypoints(this, j) && j < maxdistance; j += increment);
        }
 
-       searching = true;
+       bool searching = true;
        while (searching)
        {
                searching = false;
-               w = waylist;
-               while (w)
+               IL_EACH(g_waypoints, it.wpfire,
                {
-                       if (w.wpfire)
-                       {
-                               searching = true;
-                               w.wpfire = 0;
-                               cost = w.wpcost;
-                               p = w.wpnearestpoint;
-                               wp = w.wp00;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp00mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp01;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp01mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp02;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp02mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp03;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp03mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp04;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp04mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp05;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp05mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp06;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp06mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp07;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp07mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp08;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp08mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp09;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp09mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp10;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp10mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp11;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp11mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp12;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp12mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp13;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp13mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp14;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp14mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp15;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp15mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp16;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp16mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp17;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp17mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp18;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp18mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp19;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp19mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp20;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp20mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp21;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp21mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp22;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp22mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp23;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp23mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp24;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp24mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp25;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp25mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp26;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp26mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp27;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp27mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp28;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp28mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp29;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp29mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp30;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp30mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               wp = w.wp31;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + w.wp31mincost) navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
-                       }
-                       w = w.chain;
-               }
+                       searching = true;
+                       it.wpfire = 0;
+                       cost = it.wpcost;
+                       p = it.wpnearestpoint;
+                       entity wp;
+                       wp = it.wp00;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp00mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp01;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp01mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp02;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp02mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp03;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp03mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp04;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp04mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp05;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp05mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp06;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp06mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp07;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp07mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp08;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp08mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp09;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp09mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp10;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp10mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp11;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp11mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp12;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp12mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp13;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp13mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp14;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp14mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp15;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp15mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp16;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp16mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp17;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp17mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp18;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp18mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp19;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp19mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp20;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp20mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp21;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp21mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp22;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp22mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp23;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp23mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp24;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp24mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp25;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp25mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp26;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp26mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp27;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp27mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp28;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp28mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp29;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp29mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp30;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp30mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       wp = it.wp31;if (wp){cost2 = cost + wp.dmg;if (wp.wpcost > cost2 + it.wp31mincost) navigation_markroutes_checkwaypoint(it, wp, cost2, p);
+                       }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+               });
        }
 }
 
 // queries the entire spawnfunc_waypoint network for pathes leading to the bot
 void navigation_markroutes_inverted(entity fixed_source_waypoint)
 {
-       entity w, wp, waylist;
-       float searching, cost, cost2;
+       float cost, cost2;
        vector p;
-       w = waylist = findchain(classname, "waypoint");
-       while (w)
+       IL_EACH(g_waypoints, true,
        {
-               w.wpconsidered = false;
-               w.wpnearestpoint = '0 0 0';
-               w.wpcost = 10000000;
-               w.wpfire = 0;
-               w.enemy = NULL;
-               w = w.chain;
-       }
+               it.wpconsidered = false;
+               it.wpnearestpoint = '0 0 0';
+               it.wpcost = 10000000;
+               it.wpfire = 0;
+               it.enemy = NULL;
+       });
 
        if(fixed_source_waypoint)
        {
@@ -638,36 +608,32 @@ void navigation_markroutes_inverted(entity fixed_source_waypoint)
                error("need to start with a waypoint\n");
        }
 
-       searching = true;
+       bool searching = true;
        while (searching)
        {
                searching = false;
-               w = waylist;
-               while (w)
+               IL_EACH(g_waypoints, it.wpfire,
                {
-                       if (w.wpfire)
+                       searching = true;
+                       it.wpfire = 0;
+                       cost = it.wpcost; // cost to walk from it to home
+                       p = it.wpnearestpoint;
+                       entity wp = it;
+                       IL_EACH(g_waypoints, true,
                        {
-                               searching = true;
-                               w.wpfire = 0;
-                               cost = w.wpcost; // cost to walk from w to home
-                               p = w.wpnearestpoint;
-                               for(wp = waylist; wp; wp = wp.chain)
-                               {
-                                       if(w != wp.wp00) if(w != wp.wp01) if(w != wp.wp02) if(w != wp.wp03)
-                                       if(w != wp.wp04) if(w != wp.wp05) if(w != wp.wp06) if(w != wp.wp07)
-                                       if(w != wp.wp08) if(w != wp.wp09) if(w != wp.wp10) if(w != wp.wp11)
-                                       if(w != wp.wp12) if(w != wp.wp13) if(w != wp.wp14) if(w != wp.wp15)
-                                       if(w != wp.wp16) if(w != wp.wp17) if(w != wp.wp18) if(w != wp.wp19)
-                                       if(w != wp.wp20) if(w != wp.wp21) if(w != wp.wp22) if(w != wp.wp23)
-                                       if(w != wp.wp24) if(w != wp.wp25) if(w != wp.wp26) if(w != wp.wp27)
-                                       if(w != wp.wp28) if(w != wp.wp29) if(w != wp.wp30) if(w != wp.wp31)
-                                               continue;
-                                       cost2 = cost + wp.dmg;
-                                       navigation_markroutes_checkwaypoint(w, wp, cost2, p);
-                               }
-                       }
-                       w = w.chain;
-               }
+                               if(wp != it.wp00) if(wp != it.wp01) if(wp != it.wp02) if(wp != it.wp03)
+                               if(wp != it.wp04) if(wp != it.wp05) if(wp != it.wp06) if(wp != it.wp07)
+                               if(wp != it.wp08) if(wp != it.wp09) if(wp != it.wp10) if(wp != it.wp11)
+                               if(wp != it.wp12) if(wp != it.wp13) if(wp != it.wp14) if(wp != it.wp15)
+                               if(wp != it.wp16) if(wp != it.wp17) if(wp != it.wp18) if(wp != it.wp19)
+                               if(wp != it.wp20) if(wp != it.wp21) if(wp != it.wp22) if(wp != it.wp23)
+                               if(wp != it.wp24) if(wp != it.wp25) if(wp != it.wp26) if(wp != it.wp27)
+                               if(wp != it.wp28) if(wp != it.wp29) if(wp != it.wp30) if(wp != it.wp31)
+                                       continue;
+                               cost2 = cost + it.dmg;
+                               navigation_markroutes_checkwaypoint(wp, it, cost2, p);
+                       });
+               });
        }
 }
 
@@ -1024,40 +990,34 @@ void navigation_goalrating_end(entity this)
 
 void botframe_updatedangerousobjects(float maxupdate)
 {
-       entity head, bot_dodgelist;
        vector m1, m2, v, o;
        float c, d, danger;
        c = 0;
-       bot_dodgelist = findchainfloat(bot_dodge, true);
-       botframe_dangerwaypoint = find(botframe_dangerwaypoint, classname, "waypoint");
-       while (botframe_dangerwaypoint != NULL)
+       IL_EACH(g_waypoints, true,
        {
                danger = 0;
-               m1 = botframe_dangerwaypoint.mins;
-               m2 = botframe_dangerwaypoint.maxs;
-               head = bot_dodgelist;
-               while (head)
+               m1 = it.mins;
+               m2 = it.maxs;
+               FOREACH_ENTITY_FLOAT(bot_dodge, true,
                {
-                       v = head.origin;
+                       v = it.origin;
                        v.x = bound(m1_x, v.x, m2_x);
                        v.y = bound(m1_y, v.y, m2_y);
                        v.z = bound(m1_z, v.z, m2_z);
-                       o = (head.absmin + head.absmax) * 0.5;
-                       d = head.bot_dodgerating - vlen(o - v);
+                       o = (it.absmin + it.absmax) * 0.5;
+                       d = it.bot_dodgerating - vlen(o - v);
                        if (d > 0)
                        {
                                traceline(o, v, true, NULL);
                                if (trace_fraction == 1)
                                        danger = danger + d;
                        }
-                       head = head.chain;
-               }
-               botframe_dangerwaypoint.dmg = danger;
+               });
+               it.dmg = danger;
                c = c + 1;
                if (c >= maxupdate)
                        break;
-               botframe_dangerwaypoint = find(botframe_dangerwaypoint, classname, "waypoint");
-       }
+       });
 }
 
 void navigation_unstuck(entity this)
@@ -1118,27 +1078,18 @@ void navigation_unstuck(entity this)
                // build a new queue
                LOG_DEBUG(strcat(this.netname, " stuck, scanning reachable waypoints within ", ftos(search_radius)," qu\n"));
 
-               entity head, first;
-
-               first = NULL;
-               head = findradius(this.origin, search_radius);
+               entity first = NULL;
 
-               while(head)
+               FOREACH_ENTITY_RADIUS(this.origin, search_radius, it.classname == "waypoint" && !(it.wpflags & WAYPOINTFLAG_GENERATED),
                {
-                       if(head.classname=="waypoint")
-               //      if(!(head.wpflags & WAYPOINTFLAG_GENERATED))
-                       {
-                               if(bot_waypoint_queue_goal)
-                                       bot_waypoint_queue_goal.bot_waypoint_queue_nextgoal = head;
-                               else
-                                       first = head;
-
-                               bot_waypoint_queue_goal = head;
-                               bot_waypoint_queue_goal.bot_waypoint_queue_nextgoal = NULL;
-                       }
+                       if(bot_waypoint_queue_goal)
+                               bot_waypoint_queue_goal.bot_waypoint_queue_nextgoal = it;
+                       else
+                               first = it;
 
-                       head = head.chain;
-               }
+                       bot_waypoint_queue_goal = it;
+                       bot_waypoint_queue_goal.bot_waypoint_queue_nextgoal = NULL;
+               });
 
                if (first)
                        bot_waypoint_queue_goal = first;
index 7fef6afef3a3f7a549f15f3753416ab5d5866a83..ad01776652b4de67098af9f77e5057d8df13e196 100644 (file)
@@ -10,7 +10,6 @@ float navigation_testtracewalk;
 vector jumpstepheightvec;
 vector stepheightvec;
 
-entity botframe_dangerwaypoint;
 entity navigation_bestgoal;
 
 // stack of current goals (the last one of which may be an item or other
@@ -57,7 +56,7 @@ void debuggoalstack(entity this);
 
 float tracewalk(entity e, vector start, vector m1, vector m2, vector end, float movemode);
 
-float navigation_markroutes_nearestwaypoints(entity this, entity waylist, float maxdist);
+float navigation_markroutes_nearestwaypoints(entity this, float maxdist);
 float navigation_routetogoal(entity this, entity e, vector startposition);
 
 void navigation_clearroute(entity this);
index 01a1117c9f018332b598f4b39cb6bec4a13220c2..291b22f5fa25433274a8c0b3184f3bda92fb487a 100644 (file)
@@ -252,7 +252,7 @@ entity find_bot_by_number(float number)
        if(!number)
                return NULL;
 
-       bot = findchainflags(flags, FL_CLIENT);
+       bot = findchainflags(flags, FL_CLIENT); // TODO: doesn't findchainflags loop backwards through entities?
        while (bot)
        {
                if(IS_BOT_CLIENT(bot))
index 58bb0b46ba5d5419bf40767b212f93cdda63b22d..89078f5c88d885a277eba061d617005cfb1f79ba 100644 (file)
@@ -19,16 +19,14 @@ entity waypoint_spawn(vector m1, vector m2, float f)
 {
        if(!(f & WAYPOINTFLAG_PERSONAL))
        {
-               for(entity wp = findchain(classname, "waypoint"); wp; wp = wp.chain)
+               IL_EACH(g_waypoints, boxesoverlap(m1, m2, it.absmin, it.absmax),
                {
-                       // if a matching spawnfunc_waypoint already exists, don't add a duplicate
-                       if(boxesoverlap(m1, m2, wp.absmin, wp.absmax))
-                               return wp;
-               }
+                       return it;
+               });
        }
-               
 
        entity w = new(waypoint);
+       IL_PUSH(g_waypoints, w);
        w.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
        w.wpflags = f;
        w.solid = SOLID_TRIGGER;
@@ -45,7 +43,7 @@ entity waypoint_spawn(vector m1, vector m2, float f)
                        if(!(f & WAYPOINTFLAG_GENERATED))
                        {
                                LOG_TRACE("Killed a waypoint that was stuck in solid at ", vtos(w.origin), "\n");
-                               remove(w);
+                               delete(w);
                                return NULL;
                        }
                        else
@@ -173,7 +171,7 @@ void waypoint_think(entity this)
        //dprint("waypoint_think wpisbox = ", ftos(this.wpisbox), "\n");
        sm1 = this.origin + this.mins;
        sm2 = this.origin + this.maxs;
-       FOREACH_ENTITY_CLASS("waypoint", true,
+       IL_EACH(g_waypoints, true,
        {
                if (boxesoverlap(this.absmin, this.absmax, it.absmin, it.absmax))
                {
@@ -295,6 +293,8 @@ void waypoint_schedulerelink(entity wp)
 // spawnfunc_waypoint map entity
 spawnfunc(waypoint)
 {
+       IL_PUSH(g_waypoints, this);
+
        setorigin(this, this.origin);
        // schedule a relink after other waypoints have had a chance to spawn
        waypoint_clearlinks(this);
@@ -338,34 +338,27 @@ void waypoint_remove(entity e)
        waypoint_schedulerelink(e.wp30);
        waypoint_schedulerelink(e.wp31);
        // and now remove the spawnfunc_waypoint
-       remove(e);
+       delete(e);
 }
 
 // empties the map of waypoints
 void waypoint_removeall()
 {
-       entity head, next;
-       head = findchain(classname, "waypoint");
-       while (head)
+       IL_EACH(g_waypoints, true,
        {
-               next = head.chain;
-               remove(head);
-               head = next;
-       }
+               delete(it);
+       });
 }
 
 // tell all waypoints to relink
 // (is this useful at all?)
 void waypoint_schedulerelinkall()
 {
-       entity head;
        relink_total = relink_walkculled = relink_pvsculled = relink_lengthculled = 0;
-       head = findchain(classname, "waypoint");
-       while (head)
+       IL_EACH(g_waypoints, true,
        {
-               waypoint_schedulerelink(head);
-               head = head.chain;
-       }
+               waypoint_schedulerelink(it);
+       });
 }
 
 // Load waypoint links from file
@@ -588,87 +581,71 @@ entity waypoint_get_link(entity w, float i)
 // Save all waypoint links to a file
 void waypoint_save_links()
 {
-       string filename, s;
-       float file, c, i;
-       entity w, link;
-       filename = strcat("maps/", mapname);
-       filename = strcat(filename, ".waypoints.cache");
-       file = fopen(filename, FILE_WRITE);
+       string filename = sprintf("maps/%s.waypoints.cache", mapname);
+       int file = fopen(filename, FILE_WRITE);
        if (file < 0)
        {
-               LOG_INFO("waypoint links save to ");
-               LOG_INFO(filename);
-               LOG_INFO(" failed\n");
+               LOG_INFOF("waypoint link save to %s failed\n", filename);
+               return;
        }
-       c = 0;
-       w = findchain(classname, "waypoint");
-       while (w)
+
+       int c = 0;
+       IL_EACH(g_waypoints, true,
        {
-               for(i=0;i<32;++i)
+               for(int j = 0; j < 32; ++j)
                {
-                       // :S
-                       link = waypoint_get_link(w, i);
-                       if(link==NULL)
-                               continue;
-
-                       s = strcat(vtos(w.origin), "*", vtos(link.origin), "\n");
-                       fputs(file, s);
-                       ++c;
+                       entity link = waypoint_get_link(it, j);
+                       if(link)
+                       {
+                               string s = strcat(vtos(it.origin), "*", vtos(link.origin), "\n");
+                               fputs(file, s);
+                               ++c;
+                       }
                }
-               w = w.chain;
-       }
+       });
        fclose(file);
        botframe_cachedwaypointlinks = true;
 
-       LOG_INFO("saved ");
-       LOG_INFO(ftos(c));
-       LOG_INFO(" waypoints links to maps/");
-       LOG_INFO(mapname);
-       LOG_INFO(".waypoints.cache\n");
+       LOG_INFOF("saved %d waypoint links to maps/%s.waypoints.cache\n", c, mapname);
 }
 
 // save waypoints to gamedir/data/maps/mapname.waypoints
 void waypoint_saveall()
 {
-       string filename, s;
-       float file, c;
-       entity w;
-       filename = strcat("maps/", mapname);
-       filename = strcat(filename, ".waypoints");
-       file = fopen(filename, FILE_WRITE);
-       if (file >= 0)
+       string filename = sprintf("maps/%s.waypoints", mapname);
+       int file = fopen(filename, FILE_WRITE);
+       if (file < 0)
        {
-               c = 0;
-               w = findchain(classname, "waypoint");
-               while (w)
-               {
-                       if (!(w.wpflags & WAYPOINTFLAG_GENERATED))
-                       {
-                               s = strcat(vtos(w.origin + w.mins), "\n");
-                               s = strcat(s, vtos(w.origin + w.maxs));
-                               s = strcat(s, "\n");
-                               s = strcat(s, ftos(w.wpflags));
-                               s = strcat(s, "\n");
-                               fputs(file, s);
-                               c = c + 1;
-                       }
-                       w = w.chain;
-               }
-               fclose(file);
-               bprint("saved ");
-               bprint(ftos(c));
-               bprint(" waypoints to maps/");
-               bprint(mapname);
-               bprint(".waypoints\n");
+               waypoint_save_links(); // save anyway?
+               botframe_loadedforcedlinks = false;
+
+               LOG_INFOF("waypoint links: save to %s failed\n", filename);
+               return;
        }
-       else
+
+       int c = 0;
+       IL_EACH(g_waypoints, true,
        {
-               bprint("waypoint save to ");
-               bprint(filename);
-               bprint(" failed\n");
-       }
+               if(it.wpflags & WAYPOINTFLAG_GENERATED)
+                       continue;
+
+               for(int j = 0; j < 32; ++j)
+               {
+                       string s;
+                       s = strcat(vtos(it.origin + it.mins), "\n");
+                       s = strcat(s, vtos(it.origin + it.maxs));
+                       s = strcat(s, "\n");
+                       s = strcat(s, ftos(it.wpflags));
+                       s = strcat(s, "\n");
+                       fputs(file, s);
+                       ++c;
+               }
+       });
+       fclose(file);
        waypoint_save_links();
        botframe_loadedforcedlinks = false;
+
+       LOG_INFOF("saved %d waypoints to maps/%s.waypoints\n", c, mapname);
 }
 
 // load waypoints from file
@@ -723,33 +700,30 @@ vector waypoint_fixorigin(vector position)
 
 void waypoint_spawnforitem_force(entity e, vector org)
 {
-       entity w;
-
        // Fix the waypoint altitude if necessary
        org = waypoint_fixorigin(org);
 
        // don't spawn an item spawnfunc_waypoint if it already exists
-       w = findchain(classname, "waypoint");
-       while (w)
+       IL_EACH(g_waypoints, true,
        {
-               if (w.wpisbox)
+               if(it.wpisbox)
                {
-                       if (boxesoverlap(org, org, w.absmin, w.absmax))
+                       if(boxesoverlap(org, org, it.absmin, it.absmax))
                        {
-                               e.nearestwaypoint = w;
+                               e.nearestwaypoint = it;
                                return;
                        }
                }
                else
                {
-                       if (vlen(w.origin - org) < 16)
+                       if(vdist(it.origin - org, <, 16))
                        {
-                               e.nearestwaypoint = w;
+                               e.nearestwaypoint = it;
                                return;
                        }
                }
-               w = w.chain;
-       }
+       });
+
        e.nearestwaypoint = waypoint_spawn(org, org, WAYPOINTFLAG_GENERATED | WAYPOINTFLAG_ITEM);
 }
 
@@ -810,19 +784,20 @@ entity waypoint_spawnpersonal(entity this, vector position)
 
 void botframe_showwaypointlinks()
 {
-       entity head, w;
        if (time < botframe_waypointeditorlightningtime)
                return;
        botframe_waypointeditorlightningtime = time + 0.5;
-       FOREACH_CLIENT(IS_PLAYER(it) && !it.isbot, LAMBDA(
+       FOREACH_CLIENT(IS_PLAYER(it) && !it.isbot,
+       {
                if(IS_ONGROUND(it) || it.waterlevel > WATERLEVEL_NONE)
                {
                        //navigation_testtracewalk = true;
-                       head = navigation_findnearestwaypoint(it, false);
+                       entity head = navigation_findnearestwaypoint(it, false);
                //      print("currently selected WP is ", etos(head), "\n");
                        //navigation_testtracewalk = false;
                        if (head)
                        {
+                               entity w;
                                w = head     ;if (w) te_lightning2(NULL, w.origin, it.origin);
                                w = head.wp00;if (w) te_lightning2(NULL, w.origin, head.origin);
                                w = head.wp01;if (w) te_lightning2(NULL, w.origin, head.origin);
@@ -858,7 +833,7 @@ void botframe_showwaypointlinks()
                                w = head.wp31;if (w) te_lightning2(NULL, w.origin, head.origin);
                        }
                }
-       ));
+       });
 }
 
 float botframe_autowaypoints_fixdown(vector v)
@@ -871,17 +846,11 @@ float botframe_autowaypoints_fixdown(vector v)
 
 float botframe_autowaypoints_createwp(vector v, entity p, .entity fld, float f)
 {
-       entity w;
-
-       w = find(NULL, classname, "waypoint");
-       while (w)
+       IL_EACH(g_waypoints, boxesoverlap(v - '32 32 32', v + '32 32 32', it.absmin, it.absmax),
        {
                // if a matching spawnfunc_waypoint already exists, don't add a duplicate
-               if (boxesoverlap(v - '32 32 32', v + '32 32 32', w.absmin, w.absmax))
-               //if (boxesoverlap(v - '4 4 4', v + '4 4 4', w.absmin, w.absmax))
-                       return 0;
-               w = find(w, classname, "waypoint");
-       }
+               return 0;
+       });
 
        waypoint_schedulerelink(p.(fld) = waypoint_spawn(v, v, f));
        return 1;
@@ -924,25 +893,18 @@ float botframe_autowaypoints_fix_from(entity p, float walkfromwp, entity wp, .en
                        maxdist = 2100;
                }
 
-               float bestdist;
-               bestdist = maxdist;
-               w = find(NULL, classname, "waypoint");
-               while (w)
+               float bestdist = maxdist;
+               IL_EACH(g_waypoints, it != wp && !(it.wpflags & WAYPOINTFLAG_NORELINK),
                {
-                       if(w != wp && !(w.wpflags & WAYPOINTFLAG_NORELINK))
+                       float d = vlen(wp.origin - it.origin) + vlen(it.origin - porg);
+                       if(d < bestdist)
+                       if(navigation_waypoint_will_link(wp.origin, it.origin, p, walkfromwp, 1050))
+                       if(navigation_waypoint_will_link(it.origin, porg, p, walkfromwp, 1050))
                        {
-                               float d;
-                               d = vlen(wp.origin - w.origin) + vlen(w.origin - porg);
-                               if(d < bestdist)
-                                       if(navigation_waypoint_will_link(wp.origin, w.origin, p, walkfromwp, 1050))
-                                               if(navigation_waypoint_will_link(w.origin, porg, p, walkfromwp, 1050))
-                                               {
-                                                       bestdist = d;
-                                                       p.(fld) = w;
-                                               }
+                               bestdist = d;
+                               p.(fld) = it;
                        }
-                       w = find(w, classname, "waypoint");
-               }
+               });
                if(bestdist < maxdist)
                {
                        LOG_INFO("update chain to new nearest WP ", etos(p.(fld)), "\n");
@@ -1048,84 +1010,80 @@ void botframe_autowaypoints_fix(entity p, float walkfromwp, .entity fld)
 
 void botframe_deleteuselesswaypoints()
 {
-       entity w, w1, w2;
-       float i, j, k;
-       for (w = NULL; (w = findfloat(w, bot_pickup, true)); )
+       FOREACH_ENTITY_FLOAT(bot_pickup, true,
        {
                // NOTE: this protects waypoints if they're the ONLY nearest
                // waypoint. That's the intention.
-               navigation_findnearestwaypoint(w, false);  // Walk TO item.
-               navigation_findnearestwaypoint(w, true);  // Walk FROM item.
-       }
-       for (w = NULL; (w = find(w, classname, "waypoint")); )
+               navigation_findnearestwaypoint(it, false);  // Walk TO item.
+               navigation_findnearestwaypoint(it, true);  // Walk FROM item.
+       });
+       IL_EACH(g_waypoints, true,
        {
-               w.wpflags |= WAYPOINTFLAG_DEAD_END;
-               w.wpflags &= ~WAYPOINTFLAG_USEFUL;
+               it.wpflags |= WAYPOINTFLAG_DEAD_END;
+               it.wpflags &= ~WAYPOINTFLAG_USEFUL;
                // WP is useful if:
-               if (w.wpflags & WAYPOINTFLAG_ITEM)
-                       w.wpflags |= WAYPOINTFLAG_USEFUL;
-               if (w.wpflags & WAYPOINTFLAG_TELEPORT)
-                       w.wpflags |= WAYPOINTFLAG_USEFUL;
-               if (w.wpflags & WAYPOINTFLAG_PROTECTED)
-                       w.wpflags |= WAYPOINTFLAG_USEFUL;
+               if (it.wpflags & WAYPOINTFLAG_ITEM)
+                       it.wpflags |= WAYPOINTFLAG_USEFUL;
+               if (it.wpflags & WAYPOINTFLAG_TELEPORT)
+                       it.wpflags |= WAYPOINTFLAG_USEFUL;
+               if (it.wpflags & WAYPOINTFLAG_PROTECTED)
+                       it.wpflags |= WAYPOINTFLAG_USEFUL;
                // b) WP is closest WP for an item/spawnpoint/other entity
                //    This has been done above by protecting these WPs.
-       }
+       });
        // c) There are w1, w, w2 so that w1 -> w, w -> w2 and not w1 -> w2.
-       for (w1 = NULL; (w1 = find(w1, classname, "waypoint")); )
+       IL_EACH(g_waypoints, !(it.wpflags & WAYPOINTFLAG_PERSONAL),
        {
-               if (w1.wpflags & WAYPOINTFLAG_PERSONAL)
-                       continue;
-               for (i = 0; i < 32; ++i)
+               for (int m = 0; m < 32; ++m)
                {
-                       w = waypoint_get_link(w1, i);
+                       entity w = waypoint_get_link(it, m);
                        if (!w)
                                break;
                        if (w.wpflags & WAYPOINTFLAG_PERSONAL)
                                continue;
                        if (w.wpflags & WAYPOINTFLAG_USEFUL)
                                continue;
-                       for (j = 0; j < 32; ++j)
+                       for (int j = 0; j < 32; ++j)
                        {
-                               w2 = waypoint_get_link(w, j);
+                               entity w2 = waypoint_get_link(w, j);
                                if (!w2)
                                        break;
-                               if (w1 == w2)
+                               if (it == w2)
                                        continue;
                                if (w2.wpflags & WAYPOINTFLAG_PERSONAL)
                                        continue;
-                               // If we got here, w1 != w2 exist with w1 -> w
+                               // If we got here, it != w2 exist with it -> w
                                // and w -> w2. That means the waypoint is not
                                // a dead end.
                                w.wpflags &= ~WAYPOINTFLAG_DEAD_END;
-                               for (k = 0; k < 32; ++k)
+                               for (int k = 0; k < 32; ++k)
                                {
-                                       if (waypoint_get_link(w1, k) == w2)
+                                       if (waypoint_get_link(it, k) == w2)
                                                continue;
                                        // IF WE GET HERE, w is proven useful
-                                       // to get from w1 to w2!
+                                       // to get from it to w2!
                                        w.wpflags |= WAYPOINTFLAG_USEFUL;
                                        goto next;
                                }
                        }
 LABEL(next)
                }
-       }
+       });
        // d) The waypoint is a dead end. Dead end waypoints must be kept as
        //     they are needed to complete routes while autowaypointing.
 
-       for (w = NULL; (w = find(w, classname, "waypoint")); )
+       IL_EACH(g_waypoints, !(it.wpflags & (WAYPOINTFLAG_USEFUL | WAYPOINTFLAG_DEAD_END)),
        {
-               if (!(w.wpflags & (WAYPOINTFLAG_USEFUL | WAYPOINTFLAG_DEAD_END)))
-               {
-                       LOG_INFOF("Removed a waypoint at %v. Try again for more!\n", w.origin);
-                       te_explosion(w.origin);
-                       waypoint_remove(w);
-                       break;
-               }
-       }
-       for (w = NULL; (w = find(w, classname, "waypoint")); )
-               w.wpflags &= ~(WAYPOINTFLAG_USEFUL | WAYPOINTFLAG_DEAD_END); // temp flag
+               LOG_INFOF("Removed a waypoint at %v. Try again for more!\n", it.origin);
+               te_explosion(it.origin);
+               waypoint_remove(it);
+               break;
+       });
+
+       IL_EACH(g_waypoints, true,
+       {
+               it.wpflags &= ~(WAYPOINTFLAG_USEFUL | WAYPOINTFLAG_DEAD_END); // temp flag
+       });
 }
 
 void botframe_autowaypoints()
index 5dcd0ad9359d353687409b097c3654a1f30cd65e..163337e036ce7a22ceeab2d4b5aca3b72f192fa7 100644 (file)
@@ -73,21 +73,25 @@ void CampaignPreInit()
 {
        float baseskill;
        string title;
-       if(autocvar_sv_cheats)
-       {
-               CampaignBailout("JOLLY CHEATS AHAHAHAHAHAHAH))");
-               return;
-       }
        campaign_level = autocvar__campaign_index;
        campaign_name = strzone(autocvar__campaign_name);
        campaign_index_var = strzone(strcat("g_campaign", campaign_name, "_index"));
        CampaignFile_Load(campaign_level, 2);
+
        if(campaign_entries < 1)
        {
                CampaignBailout("unknown map");
                return;
        }
 
+       if(autocvar_sv_cheats)
+       {
+               MapInfo_SwitchGameType(MapInfo_Type_FromString(campaign_gametype[0]));
+               CampaignFile_Unload();
+               CampaignBailout("JOLLY CHEATS AHAHAHAHAHAHAH))");
+               return;
+       }
+
        baseskill = autocvar_g_campaign_skill;
        baseskill = baseskill + campaign_botskill[0];
        if(baseskill < 0)
index a7cbeae2856f37e6ffd7913524810e58c94e76f1..40ca3da2759d96efa8d08b3d988c6e08bb67d54d 100644 (file)
@@ -232,7 +232,7 @@ float CheatImpulse(entity this, int imp)
                        break;
                case CHIMPULSE_TELEPORT.impulse:
                        IS_CHEAT(this, imp, 0, 0);
-                       if(this.movetype == MOVETYPE_NOCLIP)
+                       if(this.move_movetype == MOVETYPE_NOCLIP)
                        {
                                e = find(NULL, classname, "info_autoscreenshot");
                                if(e)
@@ -240,7 +240,7 @@ float CheatImpulse(entity this, int imp)
                                        sprint(this, "Emergency teleport used info_autoscreenshot location\n");
                                        setorigin(this, e.origin);
                                        this.angles = e.angles;
-                                       remove(e);
+                                       delete(e);
                                        // should we? this.angles_x = -this.angles_x;
                                        this.fixangle = true;
                                        this.velocity = '0 0 0';
@@ -274,7 +274,7 @@ float CheatImpulse(entity this, int imp)
                        e2 = spawn();
                        setorigin(e2, e.origin);
                        RadiusDamage(e2, this, 1000, 0, 128, NULL, NULL, 500, DEATH_CHEAT.m_id, e);
-                       remove(e2);
+                       delete(e2);
 
                        LOG_INFO("404 Sportsmanship not found.\n");
                        DID_CHEAT();
@@ -364,7 +364,7 @@ float CheatCommand(entity this, int argc)
                                                tracebox(e.origin, e.mins, e.maxs, e.origin, MOVE_NORMAL, e);
                                                if(trace_startsolid)
                                                {
-                                                       remove(e);
+                                                       delete(e);
                                                        sprint(this, "cannot make stuff there (no space)\n");
                                                }
                                                else
@@ -480,13 +480,13 @@ float CheatCommand(entity this, int argc)
                                RandomSelection_Add(e, 0, string_null, 1, 1 / vlen(e.origin + (e.mins + e.maxs) * 0.5 - trace_endpos));
                        if(RandomSelection_chosen_ent)
                        {
-                               remove(RandomSelection_chosen_ent.killindicator.killindicator);
-                               remove(RandomSelection_chosen_ent.killindicator);
+                               delete(RandomSelection_chosen_ent.killindicator.killindicator);
+                               delete(RandomSelection_chosen_ent.killindicator);
                                if(RandomSelection_chosen_ent.aiment)
-                                       remove(RandomSelection_chosen_ent.aiment);
+                                       delete(RandomSelection_chosen_ent.aiment);
                                if(RandomSelection_chosen_ent.enemy)
-                                       remove(RandomSelection_chosen_ent.enemy);
-                               remove(RandomSelection_chosen_ent);
+                                       delete(RandomSelection_chosen_ent.enemy);
+                               delete(RandomSelection_chosen_ent);
                        }
                        DID_CHEAT();
                        break;
@@ -604,15 +604,15 @@ float CheatCommand(entity this, int argc)
                case "drag_clear":
                        IS_CHEAT(this, 0, argc, 0);
                        for(entity e = NULL; (e = find(e, classname, "dragbox_box")); )
-                               remove(e);
+                               delete(e);
                        for(entity e = NULL; (e = find(e, classname, "dragbox_corner_1")); )
-                               remove(e);
+                               delete(e);
                        for(entity e = NULL; (e = find(e, classname, "dragbox_corner_2")); )
-                               remove(e);
+                               delete(e);
                        for(entity e = NULL; (e = find(e, classname, "dragpoint")); )
-                               remove(e);
+                               delete(e);
                        for(entity e = NULL; (e = find(e, classname, "drag_digit")); )
-                               remove(e);
+                               delete(e);
                        DID_CHEAT();
                        break;
                case "god":
@@ -639,29 +639,29 @@ float CheatCommand(entity this, int argc)
                        break;
                case "noclip":
                        IS_CHEAT(this, 0, argc, 0);
-                       if(this.movetype != MOVETYPE_NOCLIP)
+                       if(this.move_movetype != MOVETYPE_NOCLIP)
                        {
-                               this.movetype = MOVETYPE_NOCLIP;
+                               set_movetype(this, MOVETYPE_NOCLIP);
                                sprint(this, "noclip ON\n");
                                DID_CHEAT();
                        }
                        else
                        {
-                               this.movetype = MOVETYPE_WALK;
+                               set_movetype(this, MOVETYPE_WALK);
                                sprint(this, "noclip OFF\n");
                        }
                        break;
                case "fly":
                        IS_CHEAT(this, 0, argc, 0);
-                       if(this.movetype != MOVETYPE_FLY)
+                       if(this.move_movetype != MOVETYPE_FLY)
                        {
-                               this.movetype = MOVETYPE_FLY;
+                               set_movetype(this, MOVETYPE_FLY);
                                sprint(this, "flymode ON\n");
                                DID_CHEAT();
                        }
                        else
                        {
-                               this.movetype = MOVETYPE_WALK;
+                               set_movetype(this, MOVETYPE_WALK);
                                sprint(this, "flymode OFF\n");
                        }
                        break;
@@ -675,7 +675,7 @@ float CheatCommand(entity this, int argc)
                        entity e = spawn();
                        e.target = argv(1);
                        SUB_UseTargets(e, this, NULL);
-                       remove(e);
+                       delete(e);
                        DID_CHEAT();
                        break;
                case "killtarget":
@@ -683,7 +683,7 @@ float CheatCommand(entity this, int argc)
                        entity e2 = spawn();
                        e2.killtarget = argv(1);
                        SUB_UseTargets(e2, this, NULL);
-                       remove(e2);
+                       delete(e2);
                        DID_CHEAT();
                        break;
                case "teleporttotarget":
@@ -695,7 +695,7 @@ float CheatCommand(entity this, int argc)
                        if(!wasfreed(ent))
                        {
                                Simple_TeleportPlayer(ent, this);
-                               remove(ent);
+                               delete(ent);
                                DID_CHEAT();
                        }
                        break;
@@ -868,9 +868,9 @@ void Drag_Begin(entity dragger, entity draggee, vector touchpoint)
 {
        float tagscale;
 
-       draggee.dragmovetype = draggee.movetype;
+       draggee.dragmovetype = draggee.move_movetype;
        draggee.draggravity = draggee.gravity;
-       draggee.movetype = MOVETYPE_WALK;
+       set_movetype(draggee, MOVETYPE_WALK);
        draggee.gravity = 0.00001;
        UNSET_ONGROUND(draggee);
        draggee.draggedby = dragger;
@@ -895,10 +895,10 @@ void Drag_Finish(entity dragger)
        if(dragger)
                dragger.dragentity = NULL;
        draggee.draggedby = NULL;
-       draggee.movetype = draggee.dragmovetype;
+       set_movetype(draggee, draggee.dragmovetype);
        draggee.gravity = draggee.draggravity;
 
-       switch(draggee.movetype)
+       switch(draggee.move_movetype)
        {
                case MOVETYPE_TOSS:
                case MOVETYPE_WALK:
index e3669c73191b01f5a38b8971a29d70a1d9639267..8de814507c39e53e16436826f921b30db1bea6b3 100644 (file)
@@ -145,7 +145,7 @@ void ClientData_Attach(entity this)
 
 void ClientData_Detach(entity this)
 {
-       remove(this.clientdata);
+       delete(this.clientdata);
        this.clientdata = NULL;
 }
 
@@ -303,7 +303,7 @@ void PutObserverInServer(entity this)
        this.health = FRAGS_SPECTATOR;
        this.takedamage = DAMAGE_NO;
        this.solid = SOLID_NOT;
-       this.movetype = MOVETYPE_FLY_WORLDONLY; // user preference is controlled by playerprethink
+       set_movetype(this, MOVETYPE_FLY_WORLDONLY); // user preference is controlled by playerprethink
        this.flags = FL_CLIENT | FL_NOTARGET;
        this.armorvalue = 666;
        this.effects = 0;
@@ -515,7 +515,7 @@ void PutClientInServer(entity this)
                this.iscreature = true;
                this.teleportable = TELEPORT_NORMAL;
                this.damagedbycontents = true;
-               this.movetype = MOVETYPE_WALK;
+               set_movetype(this, MOVETYPE_WALK);
                this.solid = SOLID_SLIDEBOX;
                this.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID;
                if (autocvar_g_playerclip_collisions)
@@ -673,7 +673,7 @@ void PutClientInServer(entity this)
                if (autocvar_spawn_debug)
                {
                        sprint(this, strcat("spawnpoint origin:  ", vtos(spot.origin), "\n"));
-                       remove(spot); // usefull for checking if there are spawnpoints, that let drop through the floor
+                       delete(spot); // usefull for checking if there are spawnpoints, that let drop through the floor
                }
 
                PS(this).m_switchweapon = w_getbestweapon(this);
@@ -831,7 +831,7 @@ void ClientKill_Now(entity this)
        }
 
        if(this.killindicator && !wasfreed(this.killindicator))
-               remove(this.killindicator);
+               delete(this.killindicator);
 
        this.killindicator = NULL;
 
@@ -848,14 +848,14 @@ void KillIndicator_Think(entity this)
        if (gameover)
        {
                this.owner.killindicator = NULL;
-               remove(this);
+               delete(this);
                return;
        }
 
        if (this.owner.alpha < 0 && !this.owner.vehicle)
        {
                this.owner.killindicator = NULL;
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -1181,7 +1181,7 @@ void ClientConnect(entity this)
        if (!sv_foginterval && world.fog != "")
                stuffcmd(this, strcat("\nfog ", world.fog, "\nr_fog_exp2 0\nr_drawfog 1\n"));
 
-       if (autocvar_sv_teamnagger && !(autocvar_bot_vs_human && (c3==-1 && c4==-1)))
+       if (autocvar_sv_teamnagger && !(autocvar_bot_vs_human && AvailableTeams() == 2))
                if (!g_ca && !g_cts && !g_race) // teamnagger is currently bad for ca, race & cts
                        send_CSQC_teamnagger();
 
@@ -1237,8 +1237,8 @@ void ClientDisconnect(entity this)
 
        this.flags &= ~FL_CLIENT;
 
-       if (this.chatbubbleentity) remove(this.chatbubbleentity);
-       if (this.killindicator) remove(this.killindicator);
+       if (this.chatbubbleentity) delete(this.chatbubbleentity);
+       if (this.killindicator) delete(this.killindicator);
 
        WaypointSprite_PlayerGone(this);
 
@@ -1247,7 +1247,7 @@ void ClientDisconnect(entity this)
        if (this.netname_previous) strunzone(this.netname_previous);
        if (this.clientstatus) strunzone(this.clientstatus);
        if (this.weaponorder_byimpulse) strunzone(this.weaponorder_byimpulse);
-       if (this.personal) remove(this.personal);
+       if (this.personal) delete(this.personal);
 
        this.playerid = 0;
        ReadyCount();
@@ -1261,7 +1261,7 @@ void ChatBubbleThink(entity this)
        {
                if(this.owner) // but why can that ever be NULL?
                        this.owner.chatbubbleentity = NULL;
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -1325,7 +1325,7 @@ void respawn(entity this)
        {
                this.solid = SOLID_NOT;
                this.takedamage = DAMAGE_NO;
-               this.movetype = MOVETYPE_FLY;
+               set_movetype(this, MOVETYPE_FLY);
                this.velocity = '0 0 1' * autocvar_g_respawn_ghosts_speed;
                this.avelocity = randomvec() * autocvar_g_respawn_ghosts_speed * 3 - randomvec() * autocvar_g_respawn_ghosts_speed * 3;
                this.effects |= CSQCMODEL_EF_RESPAWNGHOST;
@@ -1651,7 +1651,7 @@ void SpectateCopy(entity this, entity spectatee)
        this.angles = spectatee.v_angle;
        STAT(FROZEN, this) = STAT(FROZEN, spectatee);
        this.revive_progress = spectatee.revive_progress;
-       if(!PHYS_INPUT_BUTTON_USE(this))
+       if(!PHYS_INPUT_BUTTON_USE(this) && STAT(CAMERA_SPECTATOR, this) != 2)
                this.fixangle = true;
        setorigin(this, spectatee.origin);
        setsize(this, spectatee.mins, spectatee.maxs);
@@ -1713,7 +1713,7 @@ bool SpectateSet(entity this)
        msg_entity = this;
        WriteByte(MSG_ONE, SVC_SETVIEW);
        WriteEntity(MSG_ONE, this.enemy);
-       this.movetype = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        accuracy_resend(this);
 
        if(!SpectateUpdate(this))
@@ -1968,7 +1968,6 @@ void ObserverThink(entity this)
                MinigameImpulse(this, this.impulse);
                this.impulse = 0;
        }
-       float prefered_movetype;
        if (this.flags & FL_JUMPRELEASED) {
                if (PHYS_INPUT_BUTTON_JUMP(this) && !this.version_mismatch) {
                        this.flags &= ~FL_JUMPRELEASED;
@@ -1979,9 +1978,8 @@ void ObserverThink(entity this)
                                TRANSMUTE(Spectator, this);
                        }
                } else {
-                       prefered_movetype = ((!PHYS_INPUT_BUTTON_USE(this) ? this.cvar_cl_clippedspectating : !this.cvar_cl_clippedspectating) ? MOVETYPE_FLY_WORLDONLY : MOVETYPE_NOCLIP);
-                       if (this.movetype != prefered_movetype)
-                               this.movetype = prefered_movetype;
+                       int preferred_movetype = ((!PHYS_INPUT_BUTTON_USE(this) ? this.cvar_cl_clippedspectating : !this.cvar_cl_clippedspectating) ? MOVETYPE_FLY_WORLDONLY : MOVETYPE_NOCLIP);
+                       set_movetype(this, preferred_movetype);
                }
        } else {
                if (!(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_JUMP(this))) {
@@ -2002,6 +2000,13 @@ void SpectatorThink(entity this)
        {
                if(MinigameImpulse(this, this.impulse))
                        this.impulse = 0;
+
+               if (this.impulse == IMP_weapon_drop.impulse)
+               {
+                       STAT(CAMERA_SPECTATOR, this) = (STAT(CAMERA_SPECTATOR, this) + 1) % 3;
+                       this.impulse = 0;
+                       return;
+               }
        }
        if (this.flags & FL_JUMPRELEASED) {
                if (PHYS_INPUT_BUTTON_JUMP(this) && !this.version_mismatch) {
@@ -2324,12 +2329,15 @@ void PlayerPreThink (entity this)
         .entity weaponentity = weaponentities[0]; // TODO: unhardcode
                if (this.hook.state) {
                        do_crouch = false;
+               } else if (this.waterlevel >= WATERLEVEL_SWIMMING) {
+                       do_crouch = false;
                } else if (this.vehicle) {
                        do_crouch = false;
                } else if (STAT(FROZEN, this)) {
                        do_crouch = false;
-        } else if ((PS(this).m_weapon == WEP_SHOTGUN || PS(this).m_weapon == WEP_SHOCKWAVE) && this.(weaponentity).wframe == WFRAME_FIRE2 && time < this.(weaponentity).weapon_nextthink) {
-                   // WEAPONTODO: predict
+        } else if ((PS(this).m_weapon.spawnflags & WEP_TYPE_MELEE_PRI) && this.(weaponentity).wframe == WFRAME_FIRE1 && time < this.(weaponentity).weapon_nextthink) {
+                       do_crouch = false;
+        } else if ((PS(this).m_weapon.spawnflags & WEP_TYPE_MELEE_SEC) && this.(weaponentity).wframe == WFRAME_FIRE2 && time < this.(weaponentity).weapon_nextthink) {
                        do_crouch = false;
         }
 
@@ -2461,6 +2469,30 @@ void DrownPlayer(entity this)
        }
 }
 
+void Player_Physics(entity this)
+{
+       set_movetype(this, ((this.move_qcphysics) ? MOVETYPE_NONE : this.move_movetype));
+
+       if(!this.move_qcphysics)
+               return;
+
+       int mt = this.move_movetype;
+
+       if(mt == MOVETYPE_PUSH || mt == MOVETYPE_FAKEPUSH || mt == MOVETYPE_PHYSICS)
+       {
+               this.move_qcphysics = false;
+               set_movetype(this, mt);
+               return;
+       }
+
+       if(!frametime && !this.pm_frametime)
+               return;
+
+       Movetype_Physics_NoMatchTicrate(this, this.pm_frametime, true);
+
+       this.pm_frametime = 0;
+}
+
 /*
 =============
 PlayerPostThink
@@ -2471,6 +2503,8 @@ Called every frame for each client after the physics are run
 .float idlekick_lasttimeleft;
 void PlayerPostThink (entity this)
 {
+       Player_Physics(this);
+
        if (sv_maxidle > 0)
        if (frametime) // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero).
        if (IS_REAL_CLIENT(this))
index 517ee3796100c028220a10e0842d64d9f675e7ce..a2aeb88a9b20dc8239ea1bbb1d7533f4be7e64be 100644 (file)
@@ -463,7 +463,7 @@ IMPULSE(waypoint_clear_personal)
        WaypointSprite_ClearPersonal(this);
        if (this.personal)
        {
-               remove(this.personal);
+               delete(this.personal);
                this.personal = NULL;
        }
        sprint(this, "personal waypoint cleared\n");
@@ -474,7 +474,7 @@ IMPULSE(waypoint_clear)
        WaypointSprite_ClearOwned(this);
        if (this.personal)
        {
-               remove(this.personal);
+               delete(this.personal);
                this.personal = NULL;
        }
        sprint(this, "all waypoints cleared\n");
@@ -512,96 +512,93 @@ IMPULSE(navwaypoint_save)
 IMPULSE(navwaypoint_unreachable)
 {
        if (!autocvar_g_waypointeditor) return;
-       for (entity e = findchain(classname, "waypoint"); e; e = e.chain)
+       IL_EACH(g_waypoints, true,
        {
-               e.colormod = '0.5 0.5 0.5';
-               e.effects &= ~(EF_NODEPTHTEST | EF_RED | EF_BLUE);
-       }
+               it.colormod = '0.5 0.5 0.5';
+               it.effects &= ~(EF_NODEPTHTEST | EF_RED | EF_BLUE);
+       });
        entity e2 = navigation_findnearestwaypoint(this, false);
        navigation_markroutes(this, e2);
 
-       int i, m;
+       int j, m;
 
-       i = 0;
+       j = 0;
        m = 0;
-       for (entity e = findchain(classname, "waypoint"); e; e = e.chain)
+       IL_EACH(g_waypoints, it.wpcost >= 10000000,
        {
-               if (e.wpcost < 10000000) continue;
-               LOG_INFO("unreachable: ", etos(e), " ", vtos(e.origin), "\n");
-               e.colormod_z = 8;
-               e.effects |= EF_NODEPTHTEST | EF_BLUE;
-               ++i;
+               LOG_INFO("unreachable: ", etos(it), " ", vtos(it.origin), "\n");
+               it.colormod_z = 8;
+               it.effects |= EF_NODEPTHTEST | EF_BLUE;
+               ++j;
                ++m;
-       }
-       if (i) LOG_INFOF("%d waypoints cannot be reached from here in any way (marked with blue light)\n", i);
+       });
+       if (j) LOG_INFOF("%d waypoints cannot be reached from here in any way (marked with blue light)\n", j);
        navigation_markroutes_inverted(e2);
 
-       i = 0;
-       for (entity e = findchain(classname, "waypoint"); e; e = e.chain)
+       j = 0;
+       IL_EACH(g_waypoints, it.wpcost >= 10000000,
        {
-               if (e.wpcost < 10000000) continue;
-               LOG_INFO("cannot reach me: ", etos(e), " ", vtos(e.origin), "\n");
-               e.colormod_x = 8;
-               if (!(e.effects & EF_NODEPTHTEST))  // not already reported before
+               LOG_INFO("cannot reach me: ", etos(it), " ", vtos(it.origin), "\n");
+               it.colormod_x = 8;
+               if (!(it.effects & EF_NODEPTHTEST))  // not already reported before
                        ++m;
-               e.effects |= EF_NODEPTHTEST | EF_RED;
-               ++i;
-       }
-       if (i) LOG_INFOF("%d waypoints cannot walk to here in any way (marked with red light)\n", i);
+               it.effects |= EF_NODEPTHTEST | EF_RED;
+               ++j;
+       });
+       if (j) LOG_INFOF("%d waypoints cannot walk to here in any way (marked with red light)\n", j);
        if (m) LOG_INFOF("%d waypoints have been marked total\n", m);
 
-       i = 0;
-       for (entity e = findchain(classname, "info_player_deathmatch"); e; e = e.chain)
+       j = 0;
+       FOREACH_ENTITY_CLASS("info_player_deathmatch", true,
        {
-               vector org = e.origin;
-               tracebox(e.origin, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), e.origin - '0 0 512', MOVE_NOMONSTERS, NULL);
-               setorigin(e, trace_endpos);
-               if (navigation_findnearestwaypoint(e, false))
+               vector org = it.origin;
+               tracebox(it.origin, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin - '0 0 512', MOVE_NOMONSTERS, NULL);
+               setorigin(it, trace_endpos);
+               if (navigation_findnearestwaypoint(it, false))
                {
-                       setorigin(e, org);
-                       e.effects &= ~EF_NODEPTHTEST;
-                       e.model = "";
+                       setorigin(it, org);
+                       it.effects &= ~EF_NODEPTHTEST;
+                       it.model = "";
                }
                else
                {
-                       setorigin(e, org);
-                       LOG_INFO("spawn without waypoint: ", etos(e), " ", vtos(e.origin), "\n");
-                       e.effects |= EF_NODEPTHTEST;
-                       _setmodel(e, this.model);
-                       e.frame = this.frame;
-                       e.skin = this.skin;
-                       e.colormod = '8 0.5 8';
-                       setsize(e, '0 0 0', '0 0 0');
-                       ++i;
+                       setorigin(it, org);
+                       LOG_INFO("spawn without waypoint: ", etos(it), " ", vtos(it.origin), "\n");
+                       it.effects |= EF_NODEPTHTEST;
+                       _setmodel(it, this.model);
+                       it.frame = this.frame;
+                       it.skin = this.skin;
+                       it.colormod = '8 0.5 8';
+                       setsize(it, '0 0 0', '0 0 0');
+                       ++j;
                }
-       }
-       if (i) LOG_INFOF("%d spawnpoints have no nearest waypoint (marked by player model)\n", i);
+       });
+       if (j) LOG_INFOF("%d spawnpoints have no nearest waypoint (marked by player model)\n", j);
 
-       i = 0;
-       entity start = findchainflags(flags, FL_ITEM);
-       for (entity e = start; e; e = e.chain)
+       j = 0;
+       FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
        {
-               e.effects &= ~(EF_NODEPTHTEST | EF_RED | EF_BLUE);
-               e.colormod = '0.5 0.5 0.5';
-       }
-       for (entity e = start; e; e = e.chain)
+               it.effects &= ~(EF_NODEPTHTEST | EF_RED | EF_BLUE);
+               it.colormod = '0.5 0.5 0.5';
+       });
+       FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
        {
-               if (navigation_findnearestwaypoint(e, false)) continue;
-               LOG_INFO("item without waypoint: ", etos(e), " ", vtos(e.origin), "\n");
-               e.effects |= EF_NODEPTHTEST | EF_RED;
-               e.colormod_x = 8;
-               ++i;
-       }
-       if (i) LOG_INFOF("%d items have no nearest waypoint and cannot be walked away from (marked with red light)\n", i);
+               if (navigation_findnearestwaypoint(it, false)) continue;
+               LOG_INFO("item without waypoint: ", etos(it), " ", vtos(it.origin), "\n");
+               it.effects |= EF_NODEPTHTEST | EF_RED;
+               it.colormod_x = 8;
+               ++j;
+       });
+       if (j) LOG_INFOF("%d items have no nearest waypoint and cannot be walked away from (marked with red light)\n", j);
 
-       i = 0;
-       for (entity e = start; e; e = e.chain)
+       j = 0;
+       FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
        {
-               if (navigation_findnearestwaypoint(e, true)) continue;
-               LOG_INFO("item without waypoint: ", etos(e), " ", vtos(e.origin), "\n");
-               e.effects |= EF_NODEPTHTEST | EF_BLUE;
-               e.colormod_z = 8;
-               ++i;
-       }
-       if (i) LOG_INFOF("%d items have no nearest waypoint and cannot be walked to (marked with blue light)\n", i);
+               if (navigation_findnearestwaypoint(it, true)) continue;
+               LOG_INFO("item without waypoint: ", etos(it), " ", vtos(it.origin), "\n");
+               it.effects |= EF_NODEPTHTEST | EF_BLUE;
+               it.colormod_z = 8;
+               ++j;
+       });
+       if (j) LOG_INFOF("%d items have no nearest waypoint and cannot be walked to (marked with blue light)\n", j);
 }
index 50ceba31014316ea5cff9e7c0ee528c3d30f681c..29a55cbd85dd796dbf615d39fe19b64d5eb2538d 100644 (file)
@@ -91,7 +91,8 @@ void CopyBody(entity this, float keepvelocity)
        clone.modelindex = this.modelindex;
        clone.skin = this.skin;
        clone.species = this.species;
-       clone.movetype = this.movetype;
+       clone.move_qcphysics = false; // don't run gamecode logic on clones, too many
+       set_movetype(clone, this.move_movetype);
        clone.solid = this.solid;
        clone.ballistics_density = this.ballistics_density;
        clone.takedamage = this.takedamage;
@@ -151,7 +152,7 @@ void player_anim(entity this)
        int animbits = deadbits;
        if(STAT(FROZEN, this))
                animbits |= ANIMSTATE_FROZEN;
-       if(this.movetype == MOVETYPE_FOLLOW)
+       if(this.move_movetype == MOVETYPE_FOLLOW)
                animbits |= ANIMSTATE_FOLLOW;
        if(this.crouch)
                animbits |= ANIMSTATE_DUCK;
@@ -531,7 +532,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                // get rid of kill indicator
                if(this.killindicator)
                {
-                       remove(this.killindicator);
+                       delete(this.killindicator);
                        this.killindicator = NULL;
                        if(this.killindicator_teamchange)
                                defer_ClientKill_Now_TeamChange = true;
@@ -594,7 +595,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                // view from the floor
                this.view_ofs = '0 0 -8';
                // toss the corpse
-               this.movetype = MOVETYPE_TOSS;
+               set_movetype(this, MOVETYPE_TOSS);
                // shootable corpse
                this.solid = SOLID_CORPSE;
                this.ballistics_density = autocvar_g_ballistics_density_corpse;
index 3c97737e541d559ab13723d0091a6d361986adcd..d980a0f4cf2d42334e070e5d0d12e6b7bc11b8e9 100644 (file)
@@ -189,7 +189,7 @@ void timeout_handler_reset(entity this)
        timeout_time = 0;
        timeout_leadtime = 0;
 
-       remove(this);
+       delete(this);
 }
 
 void timeout_handler_think(entity this)
@@ -364,10 +364,10 @@ void CommonCommand_editmob(int request, entity caller, int argc)
 
                                        if (arg_lower == "list") { print_to(caller, monsterlist_reply); return; }
 
-                                       FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, LAMBDA(
-                                               if(it.realowner == caller)
-                                                       ++tmp_moncount;
-                                       ));
+                                       IL_EACH(g_monsters, it.realowner == caller,
+                                       {
+                                               ++tmp_moncount;
+                                       });
 
                                        if (!autocvar_g_monsters) { print_to(caller, "Monsters are disabled"); return; }
                                        if (autocvar_g_monsters_max <= 0 || autocvar_g_monsters_max_perplayer <= 0) { print_to(caller, "Monster spawning is disabled"); return; }
@@ -436,10 +436,12 @@ void CommonCommand_editmob(int request, entity caller, int argc)
 
                                        int tmp_remcount = 0;
 
-                                       FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, LAMBDA(
+                                       IL_EACH(g_monsters, true,
+                                       {
                                                Monster_Remove(it);
                                                ++tmp_remcount;
-                                       ));
+                                       });
+                                       IL_CLEAR(g_monsters);
 
                                        monsters_total = monsters_killed = totalspawned = 0;
 
index b12977823eadf5f2466a6a5ee3d5e59fc3fcc756..998de24cbc74550167873424458ba863f6d4d3f8 100644 (file)
@@ -207,7 +207,7 @@ void RadarMap_Next()
                localcmd(strcat("defer 1 \"sv_cmd radarmap --flags ", ftos(radarmapper.count), strcat(" --res ", ftos(radarmapper.size.x), " ", ftos(radarmapper.size.y), " --sharpen ", ftos(radarmapper.ltime), " --qual ", ftos(radarmapper.size.z)), "\"\n"));
                GotoNextMap(0);
        }
-       remove(radarmapper);
+       delete(radarmapper);
        radarmapper = NULL;
 }
 void RadarMap_Think(entity this)
@@ -253,7 +253,7 @@ void RadarMap_Think(entity this)
                if (this.cnt < 0)
                {
                        LOG_INFO("Error writing ", this.netname, "\n");
-                       remove(this);
+                       delete(this);
                        radarmapper = NULL;
                        return;
                }
@@ -439,7 +439,7 @@ float RadarMap_Make(float argc)
 
                                default:
                                        i = argc;
-                                       remove(radarmapper);
+                                       delete(radarmapper);
                                        radarmapper = NULL;
                                        break;
                        }
index 895318affc8261a3e3da6f16e7be025e7443a506..f263f5e61c4223837af1dd7f5a675c9a20c14534 100644 (file)
@@ -45,7 +45,7 @@ void make_mapinfo_Think(entity this)
        {
                LOG_INFO("Done rebuiling mapinfos.\n");
                MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
-               remove(this);
+               delete(this);
        }
        else
        {
@@ -830,7 +830,7 @@ void GameCommand_gettaginfo(float request, float argc)
                                        LOG_INFO("bone not found\n");
                                }
 
-                               remove(tmp_entity);
+                               delete(tmp_entity);
                                return;
                        }
                }
@@ -889,7 +889,7 @@ void GameCommand_animbench(float request, float argc)
                                LOG_INFO("model ", tmp_entity.model, " frame ", ftos(f1), " animtime ", ftos(n / t1), "/s\n");
                                LOG_INFO("model ", tmp_entity.model, " frame ", ftos(f2), " animtime ", ftos(n / t2), "/s\n");
 
-                               remove(tmp_entity);
+                               delete(tmp_entity);
                                return;
                        }
                }
index 0aa48c2fe705884650d4c3a258c4dbe20cbc677b..72bedd982ca79797397b9d811b8362752a9b2b95 100644 (file)
@@ -344,7 +344,7 @@ void reset_map(bool dorespawn)
                        continue;
                }
                if (it.team_saved) it.team = it.team_saved;
-               if (it.flags & FL_PROJECTILE) remove(it);  // remove any projectiles left
+               if (it.flags & FL_PROJECTILE) delete(it);  // remove any projectiles left
        });
 
        // Waypoints and assault start come LAST
@@ -392,7 +392,7 @@ void ReadyRestart_think(entity this)
        restart_mapalreadyrestarted = true;
        reset_map(true);
        Score_ClearAll();
-       remove(this);
+       delete(this);
 }
 
 // Forces a restart of the game without actually reloading the map // this is a mess...
index df791a62627fa7986966e1e3d15b94334bef1a07..109f3ad0219ccd83349b077186df1500a4580cd2 100644 (file)
@@ -443,3 +443,21 @@ const int MIF_GUIDED_CONFUSABLE = MIF_GUIDED_HEAT | MIF_GUIDED_AI;
 
 .bool init_for_player_needed;
 .void(entity this, entity player) init_for_player;
+
+IntrusiveList g_monsters;
+STATIC_INIT(g_monsters) { g_monsters = IL_NEW(); }
+
+IntrusiveList g_waypoints;
+STATIC_INIT(g_waypoints) { g_waypoints = IL_NEW(); }
+
+IntrusiveList g_vehicles;
+STATIC_INIT(g_vehicles) { g_vehicles = IL_NEW(); }
+
+IntrusiveList g_turrets;
+STATIC_INIT(g_turrets) { g_turrets = IL_NEW(); }
+
+IntrusiveList g_mines;
+STATIC_INIT(g_mines) { g_mines = IL_NEW(); }
+
+IntrusiveList g_projectiles;
+STATIC_INIT(g_projectiles) { g_projectiles = IL_NEW(); }
index 4fbccc7b02c160b736b09cf82718ea338acdd1b7..ef1e78802efbe4ca679530fb5cbda2198d4e4fb5 100644 (file)
@@ -503,7 +503,7 @@ void Ice_Think(entity this)
 {
        if(!STAT(FROZEN, this.owner) || this.owner.iceblock != this)
        {
-               remove(this);
+               delete(this);
                return;
        }
        setorigin(this, this.owner.origin - '0 0 16');
@@ -569,7 +569,7 @@ void Unfreeze (entity targ)
 
        // remove the ice block
        if(targ.iceblock)
-               remove(targ.iceblock);
+               delete(targ.iceblock);
        targ.iceblock = NULL;
 }
 
@@ -837,7 +837,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
        if (!IS_PLAYER(targ) || time >= targ.spawnshieldtime || targ == attacker)
        {
                vector farce = damage_explosion_calcpush(targ.damageforcescale * force, targ.velocity, autocvar_g_balance_damagepush_speedfactor);
-               if(targ.movetype == MOVETYPE_PHYSICS)
+               if(targ.move_movetype == MOVETYPE_PHYSICS)
                {
                        entity farcent = new(farce);
                        farcent.enemy = targ;
@@ -852,10 +852,8 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
                else
                {
                        targ.velocity = targ.velocity + farce;
-                       targ.move_velocity = targ.velocity;
                }
                UNSET_ONGROUND(targ);
-               targ.move_flags &= ~FL_ONGROUND;
                UpdateCSQCProjectile(targ);
        }
        // apply damage
@@ -1253,14 +1251,14 @@ void fireburner_think(entity this)
        // for players, this is done in the regular loop
        if(wasfreed(this.owner))
        {
-               remove(this);
+               delete(this);
                return;
        }
        Fire_ApplyEffect(this.owner);
        if(!Fire_IsBurning(this.owner))
        {
                this.owner.fire_burner = NULL;
-               remove(this);
+               delete(this);
                return;
        }
        Fire_ApplyDamage(this.owner);
index fd3cd08ecfe70d9864117218e9ad2e6dddec0c26..1b2662d6e4ede1927712d46266b2afc2f9533771 100644 (file)
@@ -74,10 +74,10 @@ void RemoveGrapplingHook(entity pl)
 {
        if(pl.hook == NULL)
                return;
-       remove(pl.hook);
+       delete(pl.hook);
        pl.hook = NULL;
-       if(pl.movetype == MOVETYPE_FLY)
-               pl.movetype = MOVETYPE_WALK;
+       if(pl.move_movetype == MOVETYPE_FLY)
+               set_movetype(pl, MOVETYPE_WALK);
 
        //pl.disableclientprediction = false;
 }
@@ -87,7 +87,7 @@ void GrapplingHookReset(entity this)
        if(this.realowner.hook == this)
                RemoveGrapplingHook(this.owner);
        else // in any case:
-               remove(this);
+               delete(this);
 }
 
 void GrapplingHookThink(entity this);
@@ -101,7 +101,7 @@ void GrapplingHook_Stop(entity this)
        this.nextthink = time;
        settouch(this, func_null);
        this.velocity = '0 0 0';
-       this.movetype = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        this.hook_length = -1;
 }
 
@@ -220,8 +220,8 @@ void GrapplingHookThink(entity this)
                                this.hook_length = newlength;
                        }
 
-                       if(pull_entity.movetype == MOVETYPE_FLY)
-                               pull_entity.movetype = MOVETYPE_WALK;
+                       if(pull_entity.move_movetype == MOVETYPE_FLY)
+                               set_movetype(pull_entity, MOVETYPE_WALK);
 
                        if(this.realowner.hook_state & HOOK_RELEASING)
                        {
@@ -238,7 +238,7 @@ void GrapplingHookThink(entity this)
                                dv = ((v - v0) * dir) * dir;
                                if(tarzan >= 2)
                                {
-                                       if(this.aiment.movetype == MOVETYPE_WALK || this.aiment.classname == "nade")
+                                       if(this.aiment.move_movetype == MOVETYPE_WALK || this.aiment.classname == "nade")
                                        {
                                                entity aim_ent = ((IS_VEHICLE(this.aiment) && this.aiment.owner) ? this.aiment.owner : this.aiment);
                                                v = v - dv * 0.5;
@@ -280,7 +280,7 @@ void GrapplingHookThink(entity this)
                        if(spd < 50)
                                spd = 0;
                        this.realowner.velocity = dir*spd;
-                       this.realowner.movetype = MOVETYPE_FLY;
+                       set_movetype(this.realowner, MOVETYPE_FLY);
 
                        UNSET_ONGROUND(this.realowner);
                }
@@ -303,14 +303,14 @@ void GrapplingHookThink(entity this)
 
 void GrapplingHookTouch(entity this, entity toucher)
 {
-       if(toucher.movetype == MOVETYPE_FOLLOW)
+       if(toucher.move_movetype == MOVETYPE_FOLLOW)
                return;
        PROJECTILE_TOUCH(this, toucher);
 
        GrapplingHook_Stop(this);
 
        if(toucher)
-               if(toucher.movetype != MOVETYPE_NONE)
+               if(toucher.move_movetype != MOVETYPE_NONE)
                {
                        SetMovetypeFollow(this, toucher);
                        WarpZone_RefSys_BeginAddingIncrementally(this, this.aiment);
@@ -370,8 +370,9 @@ void FireGrapplingHook(entity actor)
        missile.reset = GrapplingHookReset;
        missile.classname = "grapplinghook";
        missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
 
-       missile.movetype = ((autocvar_g_balance_grapplehook_gravity) ? MOVETYPE_TOSS : MOVETYPE_FLY);
+       set_movetype(missile, ((autocvar_g_balance_grapplehook_gravity) ? MOVETYPE_TOSS : MOVETYPE_FLY));
        PROJECTILE_MAKETRIGGER(missile);
 
        //setmodel (missile, MDL_HOOK); // precision set below
index 41366f5ea2a5f1c9a84d9e386774740a774f261e..425716d2da7cb92dc3001d2383947b7a4eab86dd 100644 (file)
@@ -37,7 +37,7 @@ flags:
 void dynlight_think(entity this)
 {
        if(!this.owner)
-               remove(this);
+               delete(this);
 
        this.nextthink = time + 0.1;
 }
@@ -48,7 +48,7 @@ void dynlight_find_aiment(entity this)
                objerror (this, "dynlight: no target to follow");
 
        targ = find(NULL, targetname, this.target);
-       this.movetype = MOVETYPE_FOLLOW;
+       set_movetype(this, MOVETYPE_FOLLOW);
        this.aiment = targ;
        this.owner = targ;
        this.punchangle = targ.angles;
@@ -123,7 +123,7 @@ spawnfunc(dynlight)
        if (this.target)
 //     if (!(this.spawnflags & DFOLLOW))
        {
-               this.movetype = MOVETYPE_NOCLIP;
+               set_movetype(this, MOVETYPE_NOCLIP);
                if (!this.speed)
                        this.speed = 100;
                InitializeEntity(this, dynlight_find_path, INITPRIO_FINDTARGET);
index 38e72c7329977c77e6d022c33908f5cc1742c5fd..348f307270d84b52c2ab9a6486318a948a81fdaa 100644 (file)
@@ -165,7 +165,7 @@ bool g_clientmodel_genericsendentity(entity this, entity to, int sf)
 
 
 #define G_MODEL_INIT(ent,sol) \
-       if(ent.geomtype) if(autocvar_physics_ode && checkextension("DP_PHYSICS_ODE")) ent.movetype = MOVETYPE_PHYSICS; \
+       if(ent.geomtype) if(autocvar_physics_ode && checkextension("DP_PHYSICS_ODE")) set_movetype(ent, MOVETYPE_PHYSICS); \
        if(!ent.scale) ent.scale = ent.modelscale; \
        SetBrushEntityModel(ent); \
        ent.use = g_model_setcolormaptoactivator; \
@@ -173,7 +173,7 @@ bool g_clientmodel_genericsendentity(entity this, entity to, int sf)
        if(!ent.solid) ent.solid = (sol); else if(ent.solid < 0) ent.solid = SOLID_NOT;
 
 #define G_CLIENTMODEL_INIT(ent,sol) \
-       if(ent.geomtype) if(autocvar_physics_ode && checkextension("DP_PHYSICS_ODE")) ent.movetype = MOVETYPE_PHYSICS; \
+       if(ent.geomtype) if(autocvar_physics_ode && checkextension("DP_PHYSICS_ODE")) set_movetype(ent, MOVETYPE_PHYSICS); \
        if(!ent.scale) ent.scale = ent.modelscale; \
        SetBrushEntityModel(ent); \
        ent.use = g_clientmodel_use; \
index dba509b28b8d3e276aba89cac2346d196d1891b9..c16b3d495445e3de72b7a08639d74818accab3a3 100644 (file)
@@ -8,7 +8,7 @@
 
 spawnfunc(info_null)
 {
-       remove(this);
+       delete(this);
        // if anything breaks, tell the mapper to fix his map! info_null is meant to remove itself immediately.
 }
 
@@ -51,9 +51,9 @@ void tracebox_antilag_force_wz (entity source, vector v1, vector mi, vector ma,
        {
                // take players back into the past
                FOREACH_CLIENT(IS_PLAYER(it) && it != forent, antilag_takeback(it, CS(it), time - lag));
-               FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, {
-                       if(it != forent)
-                               antilag_takeback(it, it, time - lag);
+               IL_EACH(g_monsters, it != forent,
+               {
+                       antilag_takeback(it, it, time - lag);
                });
        }
 
@@ -67,9 +67,9 @@ void tracebox_antilag_force_wz (entity source, vector v1, vector mi, vector ma,
        if (lag)
        {
                FOREACH_CLIENT(IS_PLAYER(it) && it != forent, antilag_restore(it, CS(it)));
-               FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, {
-                       if (it != forent)
-                               antilag_restore(it, it);
+               IL_EACH(g_monsters, it != forent,
+               {
+                       antilag_restore(it, it);
                });
        }
 
@@ -281,7 +281,7 @@ void LODmodel_attach(entity this)
                if(e)
                {
                        this.lodmodel1 = e.model;
-                       remove(e);
+                       delete(e);
                }
        }
        if(this.lodtarget2 != "")
@@ -290,7 +290,7 @@ void LODmodel_attach(entity this)
                if(e)
                {
                        this.lodmodel2 = e.model;
-                       remove(e);
+                       delete(e);
                }
        }
 
@@ -417,7 +417,7 @@ void InitTrigger(entity this)
        SetMovedir(this);
        this.solid = SOLID_TRIGGER;
        SetBrushEntityModel(this);
-       this.movetype = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        this.modelindex = 0;
        this.model = "";
 }
@@ -429,7 +429,7 @@ void InitSolidBSPTrigger(entity this)
        SetMovedir(this);
        this.solid = SOLID_BSP;
        SetBrushEntityModel(this);
-       this.movetype = MOVETYPE_NONE; // why was this PUSH? -div0
+       set_movetype(this, MOVETYPE_NONE); // why was this PUSH? -div0
 //     this.modelindex = 0;
        this.model = "";
 }
@@ -440,7 +440,7 @@ bool InitMovingBrushTrigger(entity this)
 // to mean no restrictions, so use a yaw of 360 instead.
        this.solid = SOLID_BSP;
        SetBrushEntityModel(this);
-       this.movetype = MOVETYPE_PUSH;
+       set_movetype(this, MOVETYPE_PUSH);
        if(this.modelindex == 0)
        {
                objerror(this, "InitMovingBrushTrigger: no brushes found!");
index f2eb1d1186eb59f793c503e97f2333f23a5a5589..ed35a5b0d8bb8ab0871ec1a0c1e59d798c1a5f9c 100644 (file)
@@ -540,7 +540,7 @@ spawnfunc(__init_dedicated_server)
        cvar_string = cvar_string_normal;
        cvar_set = cvar_set_normal;
 
-       remove = remove_unsafely;
+       delete_fn = remove_unsafely;
 
        entity e = spawn();
        setthink(e, GotoFirstMap);
@@ -657,7 +657,7 @@ spawnfunc(worldspawn)
                error("world already spawned - you may have EXACTLY ONE worldspawn!");
        world_already_spawned = true;
 
-       remove = remove_safely; // during spawning, watch what you remove!
+       delete_fn = remove_safely; // during spawning, watch what you remove!
 
        cvar_changes_init(); // do this very early now so it REALLY matches the server config
 
@@ -923,7 +923,7 @@ spawnfunc(worldspawn)
 spawnfunc(light)
 {
        //makestatic (this); // Who the f___ did that?
-       remove(this);
+       delete(this);
 }
 
 string GetGametype()
@@ -1488,7 +1488,7 @@ void FixIntermissionClient(entity e)
                e.health = -2342;
                // first intermission phase; voting phase has positive health (used to decide whether to send SVC_FINALE or not)
                e.solid = SOLID_NOT;
-               e.movetype = MOVETYPE_NONE;
+               set_movetype(e, MOVETYPE_NONE);
                e.takedamage = DAMAGE_NO;
                for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
                {
@@ -1984,11 +1984,54 @@ string GotoMap(string m)
                return "Map switch will happen after scoreboard.";
 }
 
+bool autocvar_sv_freezenonclients;
+bool autocvar_sv_gameplayfix_delayprojectiles;
+void Physics_Frame()
+{
+       if(autocvar_sv_freezenonclients)
+               return;
+
+       FOREACH_ENTITY_FLOAT(pure_data, false,
+       {
+               if(IS_CLIENT(it) || it.classname == "" || it.move_movetype == MOVETYPE_PUSH || it.move_movetype == MOVETYPE_FAKEPUSH || it.move_movetype == MOVETYPE_PHYSICS)
+                       continue;
+
+               int mt = it.move_movetype;
+
+               if(mt == MOVETYPE_PUSH || mt == MOVETYPE_FAKEPUSH || mt == MOVETYPE_PHYSICS)
+               {
+                       it.move_qcphysics = false;
+                       set_movetype(it, mt);
+                       continue;
+               }
+
+               set_movetype(it, ((it.move_qcphysics) ? MOVETYPE_NONE : it.move_movetype));
+
+               if(it.move_movetype == MOVETYPE_NONE)
+                       continue;
+
+               if(it.move_qcphysics)
+                       Movetype_Physics_NoMatchTicrate(it, PHYS_INPUT_TIMELENGTH, false);
+       });
+
+       if(autocvar_sv_gameplayfix_delayprojectiles >= 0)
+               return;
+
+       FOREACH_ENTITY_FLOAT(move_qcphysics, true,
+       {
+               if(IS_CLIENT(it) || is_pure(it) || it.classname == "" || it.move_movetype == MOVETYPE_NONE)
+                       continue;
+               Movetype_Physics_NoMatchTicrate(it, PHYS_INPUT_TIMELENGTH, false);
+       });
+}
 
+void systems_update();
 void EndFrame()
 {
        anticheat_endframe();
 
+       Physics_Frame();
+
        FOREACH_CLIENT(IS_REAL_CLIENT(it), {
                entity e = IS_SPEC(it) ? it.enemy : it;
                if (e.typehitsound) {
@@ -2009,13 +2052,16 @@ void EndFrame()
                it.damage_dealt = 0;
                antilag_record(it, CS(it), altime);
        });
-       FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, {
+       IL_EACH(g_monsters, true,
+       {
                antilag_record(it, it, altime);
        });
        FOREACH_CLIENT(PS(it), {
                PlayerState s = PS(it);
                s.ps_push(s, it);
        });
+       systems_update();
+       IL_ENDFRAME();
 }
 
 
index 8cc37597938b17bbba95d75f972935366c2ed9d0..78f7497acc6ede1ed3e2006d820996d2b1ad7101 100644 (file)
@@ -243,7 +243,7 @@ void OnlineBanList_Think(entity this)
        return;
 
 LABEL(killme)
-       remove(this);
+       delete(this);
 }
 
 const float BAN_MAX = 256;
index cf2b25acff05fb776137775c59ac07f67ce19d63..05172241c3e320630e3e4fc02321de3ab370c86f 100644 (file)
@@ -99,9 +99,9 @@ void spawn_item_key(entity this)
                this.noalign = 1;
 
        if (this.noalign)
-               this.movetype = MOVETYPE_NONE;
+               set_movetype(this, MOVETYPE_NONE);
        else
-               this.movetype = MOVETYPE_TOSS;
+               set_movetype(this, MOVETYPE_TOSS);
 
        precache_sound(this.noise);
 
@@ -160,7 +160,7 @@ spawnfunc(item_key)
        // reject this entity if more than one key was set!
        if (this.itemkeys>0 && (this.itemkeys & (this.itemkeys-1)) != 0) {
                objerror(this, "item_key.itemkeys must contain only 1 bit set specifying the key it represents!");
-               remove(this);
+               delete(this);
                return;
        }
 
@@ -202,7 +202,7 @@ spawnfunc(item_key)
 
                if (this.netname == "") {
                        objerror(this, "item_key doesn't have a default name for this key and a custom one was not specified!");
-                       remove(this);
+                       delete(this);
                        return;
                }
                break;
@@ -217,7 +217,7 @@ spawnfunc(item_key)
                _model = "models/keys/key.md3"; // FIXME: replace it by a keycard model!
        } else if (this.model == "") {
                objerror(this, "item_key doesn't have a default model for this key and a custom one was not specified!");
-               remove(this);
+               delete(this);
                return;
        }
 
index 2c206cf1a78112959ba04c9efefd4c966223235f..deb2b29616263beab55f7b0ab3c305f057b237e3 100644 (file)
@@ -33,20 +33,25 @@ void crosshair_trace(entity pl)
 {
        traceline_antilag(pl, pl.cursor_trace_start, pl.cursor_trace_start + normalize(pl.cursor_trace_endpos - pl.cursor_trace_start) * MAX_SHOT_DISTANCE, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
 }
+.bool ctrace_solidchanged;
 void crosshair_trace_plusvisibletriggers(entity pl)
 {
-       entity first;
-       entity e;
-       first = findchainfloat(solid, SOLID_TRIGGER);
-
-       for (e = first; e; e = e.chain)
-               if (e.model != "")
-                       e.solid = SOLID_BSP;
+       FOREACH_ENTITY_FLOAT(solid, SOLID_TRIGGER,
+       {
+               if(it.model != "")
+               {
+                       it.solid = SOLID_BSP;
+                       it.ctrace_solidchanged = true;
+               }
+       });
 
        crosshair_trace(pl);
 
-       for (e = first; e; e = e.chain)
-               e.solid = SOLID_TRIGGER;
+       FOREACH_ENTITY_FLOAT(ctrace_solidchanged, true,
+       {
+               it.solid = SOLID_TRIGGER;
+               it.ctrace_solidchanged = false;
+       });
 }
 void WarpZone_crosshair_trace(entity pl)
 {
@@ -881,7 +886,7 @@ void InitializeEntitiesRun()
 {
     entity startoflist = initialize_entity_first;
     initialize_entity_first = NULL;
-    remove = remove_except_protected;
+    delete_fn = remove_except_protected;
     for (entity e = startoflist; e; e = e.initialize_entity_next)
     {
                e.remove_except_protected_forbidden = 1;
@@ -912,7 +917,7 @@ void InitializeEntitiesRun()
         }
         e = next;
     }
-    remove = remove_unsafely;
+    delete_fn = remove_unsafely;
 }
 
 .float(entity) isEliminated;
@@ -1031,8 +1036,7 @@ bool SUB_NoImpactCheck(entity this, entity toucher)
        // these stop the projectile from moving, so...
        if(trace_dphitcontents == 0)
        {
-               //dprint("A hit happened with zero hit contents... DEBUG THIS, this should never happen for projectiles! Projectile will self-destruct.\n");
-               LOG_TRACEF("A hit from a projectile happened with no hit contents! DEBUG THIS, this should never happen for projectiles! Projectile will self-destruct. (edict: %d, classname: %s, origin: %s)\n", etof(this), this.classname, vtos(this.origin));
+               LOG_TRACEF("A hit from a projectile happened with no hit contents! DEBUG THIS, this should never happen for projectiles! Projectile will self-destruct. (edict: %i, classname: %s, origin: %v)", this, this.classname, this.origin);
                checkclient(this);
        }
     if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
@@ -1073,10 +1077,10 @@ bool WarpZone_Projectile_Touch_ImpactFilter_Callback(entity this, entity toucher
                else if(this.classname == "spike")
                {
                        W_Crylink_Dequeue(this);
-                       remove(this);
+                       delete(this);
                }
                else
-                       remove(this);
+                       delete(this);
                return true;
        }
        if(trace_ent && trace_ent.solid > SOLID_TRIGGER)
@@ -1319,7 +1323,7 @@ void detach_sameorigin(entity e)
 
 void follow_sameorigin(entity e, entity to)
 {
-    e.movetype = MOVETYPE_FOLLOW; // make the hole follow
+    set_movetype(e, MOVETYPE_FOLLOW); // make the hole follow
     e.aiment = to; // make the hole follow bmodel
     e.punchangle = to.angles; // the original angles of bmodel
     e.view_ofs = e.origin - to.origin; // relative origin
@@ -1328,7 +1332,7 @@ void follow_sameorigin(entity e, entity to)
 
 void unfollow_sameorigin(entity e)
 {
-    e.movetype = MOVETYPE_NONE;
+    set_movetype(e, MOVETYPE_NONE);
 }
 
 entity gettaginfo_relative_ent;
@@ -1350,7 +1354,7 @@ vector gettaginfo_relative(entity e, float tag)
 void SetMovetypeFollow(entity ent, entity e)
 {
        // FIXME this may not be warpzone aware
-       ent.movetype = MOVETYPE_FOLLOW; // make the hole follow
+       set_movetype(ent, MOVETYPE_FOLLOW); // make the hole follow
        ent.solid = SOLID_NOT; // MOVETYPE_FOLLOW is always non-solid - this means this cannot be teleported by warpzones any more! Instead, we must notice when our owner gets teleported.
        ent.aiment = e; // make the hole follow bmodel
        ent.punchangle = e.angles; // the original angles of bmodel
@@ -1361,14 +1365,14 @@ void SetMovetypeFollow(entity ent, entity e)
 }
 void UnsetMovetypeFollow(entity ent)
 {
-       ent.movetype = MOVETYPE_FLY;
+       set_movetype(ent, MOVETYPE_FLY);
        PROJECTILE_MAKETRIGGER(ent);
        ent.aiment = NULL;
 }
 float LostMovetypeFollow(entity ent)
 {
 /*
-       if(ent.movetype != MOVETYPE_FOLLOW)
+       if(ent.move_movetype != MOVETYPE_FOLLOW)
                if(ent.aiment)
                        error("???");
 */
index 20b3b54c04bb5f4d106064c2cb6db090024ea674..cace20ccf46fa9c1cfa2360a5056df842a01a79e 100644 (file)
@@ -259,10 +259,11 @@ void assault_new_round(entity this)
        // Eject players from vehicles
     FOREACH_CLIENT(IS_PLAYER(it) && it.vehicle, vehicles_exit(it.vehicle, VHEF_RELEASE));
 
-    FOREACH_ENTITY_FLAGS(vehicle_flags, VHF_ISVEHICLE, LAMBDA(
+    IL_EACH(g_vehicles, true,
+    {
         vehicles_clearreturn(it);
         vehicles_spawn(it);
-    ));
+    });
 
        // up round counter
        this.winning = this.winning + 1;
@@ -273,10 +274,14 @@ void assault_new_round(entity this)
        else
                assault_attacker_team = NUM_TEAM_1;
 
-       FOREACH_ENTITY(IS_NOT_A_CLIENT(it), LAMBDA(
+       FOREACH_ENTITY_FLOAT(pure_data, false,
+       {
+               if(IS_CLIENT(it))
+                       continue;
+
                if (it.team_saved == NUM_TEAM_1) it.team_saved = NUM_TEAM_2;
                else if (it.team_saved == NUM_TEAM_2) it.team_saved = NUM_TEAM_1;
-       ));
+       });
 
        // reset the level with a countdown
        cvar_set("timelimit", ftos(ceil(time - game_starttime) / 60));
@@ -328,7 +333,7 @@ int WinningCondition_Assault()
 // spawnfuncs
 spawnfunc(info_player_attacker)
 {
-       if (!g_assault) { remove(this); return; }
+       if (!g_assault) { delete(this); return; }
 
        this.team = NUM_TEAM_1; // red, gets swapped every round
        spawnfunc_info_player_deathmatch(this);
@@ -336,7 +341,7 @@ spawnfunc(info_player_attacker)
 
 spawnfunc(info_player_defender)
 {
-       if (!g_assault) { remove(this); return; }
+       if (!g_assault) { delete(this); return; }
 
        this.team = NUM_TEAM_2; // blue, gets swapped every round
        spawnfunc_info_player_deathmatch(this);
@@ -344,7 +349,7 @@ spawnfunc(info_player_defender)
 
 spawnfunc(target_objective)
 {
-       if (!g_assault) { remove(this); return; }
+       if (!g_assault) { delete(this); return; }
 
        this.classname = "target_objective";
        this.use = assault_objective_use;
@@ -355,7 +360,7 @@ spawnfunc(target_objective)
 
 spawnfunc(target_objective_decrease)
 {
-       if (!g_assault) { remove(this); return; }
+       if (!g_assault) { delete(this); return; }
 
        this.classname = "target_objective_decrease";
 
@@ -374,7 +379,7 @@ spawnfunc(target_objective_decrease)
 spawnfunc(func_breakable);
 spawnfunc(func_assault_destructible)
 {
-       if (!g_assault) { remove(this); return; }
+       if (!g_assault) { delete(this); return; }
 
        this.spawnflags = 3;
        this.classname = "func_assault_destructible";
@@ -389,7 +394,7 @@ spawnfunc(func_assault_destructible)
 
 spawnfunc(func_assault_wall)
 {
-       if (!g_assault) { remove(this); return; }
+       if (!g_assault) { delete(this); return; }
 
        this.classname = "func_assault_wall";
        this.mdl = this.model;
@@ -402,7 +407,7 @@ spawnfunc(func_assault_wall)
 
 spawnfunc(target_assault_roundend)
 {
-       if (!g_assault) { remove(this); return; }
+       if (!g_assault) { delete(this); return; }
 
        this.winning = 0; // round not yet won by attackers
        this.classname = "target_assault_roundend";
@@ -413,7 +418,7 @@ spawnfunc(target_assault_roundend)
 
 spawnfunc(target_assault_roundstart)
 {
-       if (!g_assault) { remove(this); return; }
+       if (!g_assault) { delete(this); return; }
 
        assault_attacker_team = NUM_TEAM_1;
        this.classname = "target_assault_roundstart";
@@ -425,68 +430,48 @@ spawnfunc(target_assault_roundstart)
 // legacy bot code
 void havocbot_goalrating_ast_targets(entity this, float ratingscale)
 {
-       entity ad, best, wp;
-       float radius, bestvalue;
-       bool found;
-       vector p;
-
-       ad = findchain(classname, "func_assault_destructible");
-
-       for (; ad; ad = ad.chain)
+       FOREACH_ENTITY_CLASS("func_assault_destructible", it.bot_attack,
        {
-               if (ad.target == "")
-                       continue;
-
-               if (!ad.bot_attack)
+               if (it.target == "")
                        continue;
 
-               found = false;
-               FOREACH_ENTITY_STRING(targetname, ad.target,
+               bool found = false;
+               FOREACH_ENTITY_STRING(targetname, it.target,
                {
-                       if(it.classname == "target_objective_decrease")
+                       if(it.classname != "target_objective_decrease")
+                               continue;
+
+                       if(it.enemy.health > 0 && it.enemy.health < ASSAULT_VALUE_INACTIVE)
                        {
-                               if(it.enemy.health > 0 && it.enemy.health < ASSAULT_VALUE_INACTIVE)
-                               {
-                               //      dprint(etos(ad),"\n");
-                                       found = true;
-                                       break;
-                               }
+                               found = true;
+                               break;
                        }
                });
 
                if(!found)
-               {
-               ///     dprint("target not found\n");
                        continue;
-               }
-               /// dprint("target #", etos(ad), " found\n");
 
-
-               p = 0.5 * (ad.absmin + ad.absmax);
-       //      dprint(vtos(ad.origin), " ", vtos(ad.absmin), " ", vtos(ad.absmax),"\n");
-       //      te_knightspike(p);
-       //      te_lightning2(NULL, '0 0 0', p);
+               vector p = 0.5 * (it.absmin + it.absmax);
 
                // Find and rate waypoints around it
                found = false;
-               best = NULL;
-               bestvalue = 99999999999;
-               for(radius=0; radius<1500 && !found; radius+=500)
+               entity best = NULL;
+               float bestvalue = 99999999999;
+               entity des = it;
+               for(float radius = 0; radius < 1500 && !found; radius += 500)
                {
-                       for(wp=findradius(p, radius); wp; wp=wp.chain)
+                       FOREACH_ENTITY_RADIUS(p, radius, it.classname == "waypoint" && !(it.wpflags & WAYPOINTFLAG_GENERATED),
                        {
-                               if(!(wp.wpflags & WAYPOINTFLAG_GENERATED))
-                               if(wp.classname=="waypoint")
-                               if(checkpvs(wp.origin, ad))
+                               if(checkpvs(it.origin, des))
                                {
                                        found = true;
-                                       if(wp.cnt<bestvalue)
+                                       if(it.cnt < bestvalue)
                                        {
-                                               best = wp;
-                                               bestvalue = wp.cnt;
+                                               best = it;
+                                               bestvalue = it.cnt;
                                        }
                                }
-                       }
+                       });
                }
 
                if(best)
@@ -500,14 +485,14 @@ void havocbot_goalrating_ast_targets(entity this, float ratingscale)
 
                        this.havocbot_attack_time = 0;
 
-                       if(checkpvs(this.view_ofs,ad))
+                       if(checkpvs(this.view_ofs,it))
                        if(checkpvs(this.view_ofs,best))
                        {
                        //      dprint("increasing attack time for this target\n");
                                this.havocbot_attack_time = time + 2;
                        }
                }
-       }
+       });
 }
 
 void havocbot_role_ast_offense(entity this)
@@ -683,7 +668,11 @@ MUTATOR_HOOKFUNCTION(as, OnEntityPreSpawn)
 // scoreboard setup
 void assault_ScoreRules()
 {
-       ScoreRules_basics(2, SFL_SORT_PRIO_SECONDARY, SFL_SORT_PRIO_SECONDARY, true);
+       int teams = 0;
+       teams |= BIT(0);
+       teams |= BIT(1); // always red vs blue
+
+       ScoreRules_basics(teams, SFL_SORT_PRIO_SECONDARY, SFL_SORT_PRIO_SECONDARY, true);
        ScoreInfo_SetLabel_TeamScore(  ST_ASSAULT_OBJECTIVES,    "objectives",      SFL_SORT_PRIO_PRIMARY);
        ScoreInfo_SetLabel_PlayerScore(SP_ASSAULT_OBJECTIVES,    "objectives",      SFL_SORT_PRIO_PRIMARY);
        ScoreRules_basics_end();
index 6e302a177909ba45f86578aeaea202bc1267bef4..209c8b85673b09a587379821121c72fe69daf7ca 100644 (file)
@@ -36,7 +36,15 @@ REGISTER_MUTATOR(ca, false)
                if (ca_teams < 2) ca_teams = autocvar_g_ca_teams;
                ca_teams = bound(2, ca_teams, 4);
 
-        ScoreRules_basics(ca_teams, SFL_SORT_PRIO_PRIMARY, 0, true);
+               int teams = 0;
+               if(ca_teams >= 1) teams |= BIT(0);
+               if(ca_teams >= 2) teams |= BIT(1);
+               if(ca_teams >= 3) teams |= BIT(2);
+               if(ca_teams >= 4) teams |= BIT(3);
+
+               ca_teams = teams; // now set it?
+
+        ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, true);
         ScoreInfo_SetLabel_TeamScore(ST_CA_ROUNDS, "rounds", SFL_SORT_PRIO_PRIMARY);
         ScoreRules_basics_end();
 
@@ -117,7 +125,7 @@ float CA_GetWinnerTeam()
 void nades_Clear(entity player);
 
 #define CA_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0))
-#define CA_ALIVE_TEAMS_OK() (CA_ALIVE_TEAMS() == ca_teams)
+#define CA_ALIVE_TEAMS_OK() (CA_ALIVE_TEAMS() == NumTeams(ca_teams))
 float CA_CheckWinner()
 {
        if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
@@ -179,9 +187,15 @@ bool CA_CheckTeams()
                prev_missing_teams_mask = -1;
                return false;
        }
-       int missing_teams_mask = (!redalive) + (!bluealive) * 2;
-       if(ca_teams >= 3) missing_teams_mask += (!yellowalive) * 4;
-       if(ca_teams >= 4) missing_teams_mask += (!pinkalive) * 8;
+       int missing_teams_mask = 0;
+       if(ca_teams & BIT(0))
+               missing_teams_mask += (!redalive) * 1;
+       if(ca_teams & BIT(1))
+               missing_teams_mask += (!bluealive) * 2;
+       if(ca_teams & BIT(2))
+               missing_teams_mask += (!yellowalive) * 4;
+       if(ca_teams & BIT(3))
+               missing_teams_mask += (!pinkalive) * 8;
        if(prev_missing_teams_mask != missing_teams_mask)
        {
                Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
index b3a06416cd1abd330b1f96ef8339d5d9f5894e00..5274072cf1ff85e9f9e1a885a9430199db30f267 100644 (file)
@@ -334,7 +334,7 @@ void ctf_CaptureShield_Spawn(entity flag)
        settouch(shield, ctf_CaptureShield_Touch);
        setcefc(shield, ctf_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 = 0.5;
@@ -355,7 +355,7 @@ void ctf_Handle_Drop(entity flag, entity player, int droptype)
        player = (player ? player : flag.pass_sender);
 
        // main
-       flag.movetype = MOVETYPE_TOSS;
+       set_movetype(flag, MOVETYPE_TOSS);
        flag.takedamage = DAMAGE_YES;
        flag.angles = '0 0 0';
        flag.health = flag.max_flag_health;
@@ -414,7 +414,7 @@ void ctf_Handle_Retrieve(entity flag, entity player)
                setattachment(flag, player, "");
                setorigin(flag, FLAG_CARRY_OFFSET);
        }
-       flag.movetype = MOVETYPE_NONE;
+       set_movetype(flag, MOVETYPE_NONE);
        flag.takedamage = DAMAGE_NO;
        flag.solid = SOLID_NOT;
        flag.angles = '0 0 0';
@@ -480,7 +480,7 @@ void ctf_Handle_Throw(entity player, entity receiver, int droptype)
                        ctf_CalculatePassVelocity(flag, targ_origin, player.origin, false);
 
                        // main
-                       flag.movetype = MOVETYPE_FLY;
+                       set_movetype(flag, MOVETYPE_FLY);
                        flag.takedamage = DAMAGE_NO;
                        flag.pass_sender = player;
                        flag.pass_target = receiver;
@@ -668,7 +668,7 @@ void ctf_Handle_Pickup(entity flag, entity player, int pickuptype)
        }
 
        // flag setup
-       flag.movetype = MOVETYPE_NONE;
+       set_movetype(flag, MOVETYPE_NONE);
        flag.takedamage = DAMAGE_NO;
        flag.solid = SOLID_NOT;
        flag.angles = '0 0 0';
@@ -937,9 +937,9 @@ void ctf_FlagThink(entity this)
                                        if(pointcontents(midpoint + FLAG_FLOAT_OFFSET) == CONTENT_WATER)
                                                { this.velocity_z = autocvar_g_ctf_flag_dropped_floatinwater; }
                                        else
-                                               { this.movetype = MOVETYPE_FLY; }
+                                               { set_movetype(this, MOVETYPE_FLY); }
                                }
-                               else if(this.movetype == MOVETYPE_FLY) { this.movetype = MOVETYPE_TOSS; }
+                               else if(this.move_movetype == MOVETYPE_FLY) { set_movetype(this, MOVETYPE_TOSS); }
                        }
                        if(autocvar_g_ctf_flag_return_dropped)
                        {
@@ -1157,7 +1157,7 @@ void ctf_RespawnFlag(entity flag)
        setattachment(flag, NULL, "");
        setorigin(flag, flag.ctf_spawnorigin);
 
-       flag.movetype = ((flag.noalign) ? MOVETYPE_NONE : MOVETYPE_TOSS);
+       set_movetype(flag, ((flag.noalign) ? MOVETYPE_NONE : MOVETYPE_TOSS));
        flag.takedamage = DAMAGE_NO;
        flag.health = flag.max_flag_health;
        flag.solid = SOLID_TRIGGER;
@@ -1318,13 +1318,13 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e
        {
                flag.dropped_origin = flag.origin;
                flag.noalign = true;
-               flag.movetype = MOVETYPE_NONE;
+               set_movetype(flag, MOVETYPE_NONE);
        }
        else // drop to floor, automatically find a platform and set that as spawn origin
        {
                flag.noalign = false;
                droptofloor(flag);
-               flag.movetype = MOVETYPE_TOSS;
+               set_movetype(flag, MOVETYPE_NONE);
        }
 
        InitializeEntity(flag, ctf_DelayedFlagSetup, INITPRIO_SETLOCATION);
@@ -1528,23 +1528,19 @@ void havocbot_goalrating_ctf_droppedflags(entity this, float ratingscale, vector
 
 void havocbot_goalrating_ctf_carrieritems(entity this, float ratingscale, vector org, float sradius)
 {
-       entity head;
-       float t;
-       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)
-               if (vdist(head.origin - org, <, sradius))
+               if (it.solid)
+               if (it.health || it.armorvalue)
+               if (vdist(it.origin - org, <, sradius))
                {
                        // get the value of the item
-                       t = head.bot_pickupevalfunc(this, head) * 0.0001;
+                       float t = it.bot_pickupevalfunc(this, it) * 0.0001;
                        if (t > 0)
-                               navigation_routerating(this, head, t * ratingscale, 500);
+                               navigation_routerating(this, it, t * ratingscale, 500);
                }
-               head = head.chain;
-       }
+       });
 }
 
 void havocbot_ctf_reset_role(entity this)
@@ -2334,7 +2330,7 @@ MUTATOR_HOOKFUNCTION(ctf, MatchEnd)
                        case FLAG_PASSING:
                        {
                                // lock the flag, game is over
-                               flag.movetype = MOVETYPE_NONE;
+                               set_movetype(flag, MOVETYPE_NONE);
                                flag.takedamage = DAMAGE_NO;
                                flag.solid = SOLID_NOT;
                                flag.nextthink = false; // stop thinking
@@ -2422,10 +2418,10 @@ MUTATOR_HOOKFUNCTION(ctf, SV_ParseClientCommand)
                {
                        switch(argv(1))
                        {
-                               case "red": _team = NUM_TEAM_1; break;
-                               case "blue": _team = NUM_TEAM_2; break;
-                               case "yellow": if(ctf_teams >= 3) _team = NUM_TEAM_3; break;
-                               case "pink": if(ctf_teams >= 4) _team = NUM_TEAM_4; break;
+                               case "red":    if(ctf_teams & BIT(0)) _team = NUM_TEAM_1; break;
+                               case "blue":   if(ctf_teams & BIT(1)) _team = NUM_TEAM_2; break;
+                               case "yellow": if(ctf_teams & BIT(2)) _team = NUM_TEAM_3; break;
+                               case "pink":   if(ctf_teams & BIT(3)) _team = NUM_TEAM_4; break;
                        }
                }
 
@@ -2471,7 +2467,7 @@ Keys:
 "noise5" sound played when flag touches the ground... */
 spawnfunc(item_flag_team1)
 {
-       if(!g_ctf) { remove(this); return; }
+       if(!g_ctf) { delete(this); return; }
 
        ctf_FlagSetup(NUM_TEAM_1, this);
 }
@@ -2489,7 +2485,7 @@ Keys:
 "noise5" sound played when flag touches the ground... */
 spawnfunc(item_flag_team2)
 {
-       if(!g_ctf) { remove(this); return; }
+       if(!g_ctf) { delete(this); return; }
 
        ctf_FlagSetup(NUM_TEAM_2, this);
 }
@@ -2507,7 +2503,7 @@ Keys:
 "noise5" sound played when flag touches the ground... */
 spawnfunc(item_flag_team3)
 {
-       if(!g_ctf) { remove(this); return; }
+       if(!g_ctf) { delete(this); return; }
 
        ctf_FlagSetup(NUM_TEAM_3, this);
 }
@@ -2525,7 +2521,7 @@ Keys:
 "noise5" sound played when flag touches the ground... */
 spawnfunc(item_flag_team4)
 {
-       if(!g_ctf) { remove(this); return; }
+       if(!g_ctf) { delete(this); return; }
 
        ctf_FlagSetup(NUM_TEAM_4, this);
 }
@@ -2543,8 +2539,8 @@ Keys:
 "noise5" sound played when flag touches the ground... */
 spawnfunc(item_flag_neutral)
 {
-       if(!g_ctf) { remove(this); return; }
-       if(!cvar("g_ctf_oneflag")) { remove(this); return; }
+       if(!g_ctf) { delete(this); return; }
+       if(!cvar("g_ctf_oneflag")) { delete(this); return; }
 
        ctf_FlagSetup(0, this);
 }
@@ -2557,7 +2553,7 @@ Keys:
 "cnt" Scoreboard color of the team (for example 4 is red and 13 is blue)... */
 spawnfunc(ctf_team)
 {
-       if(!g_ctf) { remove(this); return; }
+       if(!g_ctf) { delete(this); return; }
 
        this.classname = "ctf_team";
        this.team = this.cnt + 1;
@@ -2608,27 +2604,44 @@ void ctf_SpawnTeam (string teamname, int teamcolor)
 
 void ctf_DelayedInit(entity this) // Do this check with a delay so we can wait for teams to be set up.
 {
-       ctf_teams = 2;
+       ctf_teams = 0;
 
        entity tmp_entity;
        for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
        {
-               if(tmp_entity.team == NUM_TEAM_3) { ctf_teams = max(3, ctf_teams); }
-               if(tmp_entity.team == NUM_TEAM_4) { ctf_teams = max(4, ctf_teams); }
+               //if(tmp_entity.team == NUM_TEAM_3) { ctf_teams = max(3, ctf_teams); }
+               //if(tmp_entity.team == NUM_TEAM_4) { ctf_teams = max(4, ctf_teams); }
+
+               switch(tmp_entity.team)
+               {
+                       case NUM_TEAM_1: BITSET_ASSIGN(ctf_teams, BIT(0)); break;
+                       case NUM_TEAM_2: BITSET_ASSIGN(ctf_teams, BIT(1)); break;
+                       case NUM_TEAM_3: BITSET_ASSIGN(ctf_teams, BIT(2)); break;
+                       case NUM_TEAM_4: BITSET_ASSIGN(ctf_teams, BIT(3)); break;
+               }
                if(tmp_entity.team == 0) { ctf_oneflag = true; }
        }
 
-       ctf_teams = bound(2, ctf_teams, 4);
+       if(NumTeams(ctf_teams) < 2) // somehow, there's not enough flags!
+       {
+               ctf_teams = 0; // so set the default red and blue teams
+               BITSET_ASSIGN(ctf_teams, BIT(0));
+               BITSET_ASSIGN(ctf_teams, BIT(1));
+       }
+
+       //ctf_teams = bound(2, ctf_teams, 4);
 
        // if no teams are found, spawn defaults
        if(find(NULL, classname, "ctf_team") == NULL)
        {
                LOG_TRACE("No \"ctf_team\" entities found on this map, creating them anyway.\n");
-               ctf_SpawnTeam("Red", NUM_TEAM_1);
-               ctf_SpawnTeam("Blue", NUM_TEAM_2);
-               if(ctf_teams >= 3)
+               if(ctf_teams & BIT(0))
+                       ctf_SpawnTeam("Red", NUM_TEAM_1);
+               if(ctf_teams & BIT(1))
+                       ctf_SpawnTeam("Blue", NUM_TEAM_2);
+               if(ctf_teams & BIT(2))
                        ctf_SpawnTeam("Yellow", NUM_TEAM_3);
-               if(ctf_teams >= 4)
+               if(ctf_teams & BIT(3))
                        ctf_SpawnTeam("Pink", NUM_TEAM_4);
        }
 
index bfddc30b01bbbc7439a2fb76ab793e0662db4e41..187b4aa951c46c8239bc86e5ffe8f89121ced3d0 100644 (file)
@@ -127,7 +127,7 @@ MUTATOR_HOOKFUNCTION(cts, PlayerPhysics)
                if(player.race_penalty)
                {
                        player.velocity = '0 0 0';
-                       player.movetype = MOVETYPE_NONE;
+                       set_movetype(player, MOVETYPE_NONE);
                        player.disableclientprediction = 2;
                }
        }
@@ -406,7 +406,7 @@ MUTATOR_HOOKFUNCTION(cts, ClientKill)
 
        if(player.killindicator && player.killindicator.health == 1) // player.killindicator.health == 1 means that the kill indicator was spawned by CTS_ClientKill
        {
-               remove(player.killindicator);
+               delete(player.killindicator);
                player.killindicator = NULL;
 
                ClientKill_Now(player); // allow instant kill in this case
index 7acddd32dfe1e75533eb7b8a6ad8ca30d6f45252..7d36e3a622d12ae1c285e0190d8a374904155d88 100644 (file)
@@ -535,7 +535,7 @@ spawnfunc(dom_controlpoint)
 {
        if(!g_domination)
        {
-               remove(this);
+               delete(this);
                return;
        }
        setthink(this, dom_controlpoint_setup);
@@ -580,7 +580,7 @@ spawnfunc(dom_team)
 {
        if(!g_domination || autocvar_g_domination_teams_override >= 2)
        {
-               remove(this);
+               delete(this);
                return;
        }
        precache_model(this.model);
@@ -600,7 +600,7 @@ spawnfunc(dom_team)
 }
 
 // scoreboard setup
-void ScoreRules_dom(float teams)
+void ScoreRules_dom(int teams)
 {
        if(domination_roundbased)
        {
@@ -684,7 +684,14 @@ void dom_DelayedInit(entity this) // Do this check with a delay so we can wait f
        }
 
        CheckAllowedTeams(NULL);
-       domination_teams = ((c4>=0) ? 4 : (c3>=0) ? 3 : 2);
+       //domination_teams = ((c4>=0) ? 4 : (c3>=0) ? 3 : 2);
+
+       int teams = 0;
+       if(c1 >= 0) teams |= BIT(0);
+       if(c2 >= 0) teams |= BIT(1);
+       if(c3 >= 0) teams |= BIT(2);
+       if(c4 >= 0) teams |= BIT(3);
+       domination_teams = teams;
 
        domination_roundbased = autocvar_g_domination_roundbased;
 
index 4f8f0fde7bf99406ec137d8df295edacc73c94ee..93547989097eb43aad853fa417268146eb14d1e9 100644 (file)
@@ -62,7 +62,7 @@ int autocvar_g_freezetag_teams_override;
 float autocvar_g_freezetag_warmup;
 
 const float SP_FREEZETAG_REVIVALS = 4;
-void freezetag_ScoreRules(float teams)
+void freezetag_ScoreRules(int teams)
 {
        ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, true); // SFL_SORT_PRIO_PRIMARY
        ScoreInfo_SetLabel_PlayerScore(SP_FREEZETAG_REVIVALS, "revivals", 0);
@@ -91,7 +91,7 @@ void freezetag_count_alive_players()
        eliminatedPlayers.SendFlags |= 1;
 }
 #define FREEZETAG_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0))
-#define FREEZETAG_ALIVE_TEAMS_OK() (FREEZETAG_ALIVE_TEAMS() == freezetag_teams)
+#define FREEZETAG_ALIVE_TEAMS_OK() (FREEZETAG_ALIVE_TEAMS() == NumTeams(freezetag_teams))
 
 float freezetag_CheckTeams()
 {
@@ -110,9 +110,15 @@ float freezetag_CheckTeams()
                prev_missing_teams_mask = -1;
                return 0;
        }
-       float missing_teams_mask = (!redalive) + (!bluealive) * 2;
-       if(freezetag_teams >= 3) missing_teams_mask += (!yellowalive) * 4;
-       if(freezetag_teams >= 4) missing_teams_mask += (!pinkalive) * 8;
+       int missing_teams_mask = 0;
+       if(freezetag_teams & BIT(0))
+               missing_teams_mask += (!redalive) * 1;
+       if(freezetag_teams & BIT(1))
+               missing_teams_mask += (!bluealive) * 2;
+       if(freezetag_teams & BIT(2))
+               missing_teams_mask += (!yellowalive) * 4;
+       if(freezetag_teams & BIT(3))
+               missing_teams_mask += (!pinkalive) * 8;
        if(prev_missing_teams_mask != missing_teams_mask)
        {
                Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
@@ -617,6 +623,14 @@ void freezetag_Initialize()
        if(freezetag_teams < 2)
                freezetag_teams = autocvar_g_freezetag_teams;
        freezetag_teams = bound(2, freezetag_teams, 4);
+
+       int teams = 0;
+       if(freezetag_teams >= 1) teams |= BIT(0);
+       if(freezetag_teams >= 2) teams |= BIT(1);
+       if(freezetag_teams >= 3) teams |= BIT(2);
+       if(freezetag_teams >= 4) teams |= BIT(3);
+
+       freezetag_teams = teams; // now set it?
        freezetag_ScoreRules(freezetag_teams);
 
        round_handler_Spawn(freezetag_CheckTeams, freezetag_CheckWinner, func_null);
index 9d31506e6dfe77134f2dcf8fb225fa1e2a53f475..28d369d5b9c77f4fa691f990683dcf2c2b70ee37 100644 (file)
@@ -77,7 +77,7 @@ float autocvar_g_invasion_spawn_delay;
 
 spawnfunc(invasion_spawnpoint)
 {
-       if(!g_invasion) { remove(this); return; }
+       if(!g_invasion) { delete(this); return; }
 
        this.classname = "invasion_spawnpoint";
 
@@ -193,7 +193,11 @@ float Invasion_CheckWinner()
 {
        if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
        {
-               FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, LAMBDA(Monster_Remove(it)));
+               IL_EACH(g_monsters, true,
+               {
+                       Monster_Remove(it);
+               });
+               IL_CLEAR(g_monsters);
 
                Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_ROUND_OVER);
                Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ROUND_OVER);
@@ -203,23 +207,21 @@ float Invasion_CheckWinner()
 
        float total_alive_monsters = 0, supermonster_count = 0, red_alive = 0, blue_alive = 0, yellow_alive = 0, pink_alive = 0;
 
-       FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, LAMBDA(
-               if(it.health > 0)
-               {
-                       if((get_monsterinfo(it.monsterid)).spawnflags & MON_FLAG_SUPERMONSTER)
-                               ++supermonster_count;
-                       ++total_alive_monsters;
+       IL_EACH(g_monsters, it.health > 0,
+       {
+               if((get_monsterinfo(it.monsterid)).spawnflags & MON_FLAG_SUPERMONSTER)
+                       ++supermonster_count;
+               ++total_alive_monsters;
 
-                       if(teamplay)
-                       switch(it.team)
-                       {
-                               case NUM_TEAM_1: ++red_alive; break;
-                               case NUM_TEAM_2: ++blue_alive; break;
-                               case NUM_TEAM_3: ++yellow_alive; break;
-                               case NUM_TEAM_4: ++pink_alive; break;
-                       }
+               if(teamplay)
+               switch(it.team)
+               {
+                       case NUM_TEAM_1: ++red_alive; break;
+                       case NUM_TEAM_2: ++blue_alive; break;
+                       case NUM_TEAM_3: ++yellow_alive; break;
+                       case NUM_TEAM_4: ++pink_alive; break;
                }
-       ));
+       });
 
        if((total_alive_monsters + inv_numkilled) < inv_maxspawned && inv_maxcurrent < inv_maxspawned)
        {
@@ -272,7 +274,11 @@ float Invasion_CheckWinner()
                ));
        }
 
-       FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, LAMBDA(Monster_Remove(it)));
+       IL_EACH(g_monsters, true,
+       {
+               Monster_Remove(it);
+       });
+       IL_CLEAR(g_monsters);
 
        if(teamplay)
        {
@@ -479,7 +485,7 @@ MUTATOR_HOOKFUNCTION(inv, AllowMobButcher)
        return true;
 }
 
-void invasion_ScoreRules(float inv_teams)
+void invasion_ScoreRules(int inv_teams)
 {
        if(inv_teams) { CheckAllowedTeams(NULL); }
        ScoreRules_basics(inv_teams, 0, 0, false);
@@ -491,7 +497,16 @@ void invasion_ScoreRules(float inv_teams)
 void invasion_DelayedInit(entity this) // Do this check with a delay so we can wait for teams to be set up.
 {
        if(autocvar_g_invasion_teams)
+       {
                invasion_teams = bound(2, autocvar_g_invasion_teams, 4);
+               int teams = 0;
+               if(invasion_teams >= 1) teams |= BIT(0);
+               if(invasion_teams >= 2) teams |= BIT(1);
+               if(invasion_teams >= 3) teams |= BIT(2);
+               if(invasion_teams >= 4) teams |= BIT(3);
+
+               invasion_teams = teams; // now set it?
+       }
        else
                invasion_teams = 0;
 
index 00cdf0d6872f54e0e17fb633f4ece9d9d4ee8820..1ce62672d8b6e5d9eaf6c5ffb0d608dcced47edf 100644 (file)
@@ -96,7 +96,7 @@ void ka_RespawnBall(entity this) // runs whenever the ball needs to be relocated
        }
 
        makevectors(this.angles);
-       this.movetype = MOVETYPE_BOUNCE;
+       set_movetype(this, MOVETYPE_BOUNCE);
        this.velocity = '0 0 200';
        this.angles = '0 0 0';
        this.effects = autocvar_g_keepawayball_effects;
@@ -152,7 +152,7 @@ void ka_TouchEvent(entity this, entity toucher) // runs any time that the ball c
 
        // make the ball invisible/unable to do anything/set up time scoring
        this.velocity = '0 0 0';
-       this.movetype = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        this.effects |= EF_NODRAW;
        settouch(this, func_null);
        setthink(this, ka_TimeScoring);
@@ -191,7 +191,7 @@ void ka_DropEvent(entity plyr) // runs any time that a player is supposed to los
 
        // reset the ball
        setattachment(ball, NULL, "");
-       ball.movetype = MOVETYPE_BOUNCE;
+       set_movetype(ball, MOVETYPE_BOUNCE);
        ball.wait = time + 1;
        settouch(ball, ka_TouchEvent);
        setthink(ball, ka_RespawnBall);
@@ -490,7 +490,7 @@ void ka_SpawnBall() // loads various values for the ball, runs only once at star
        e.damageforcescale = autocvar_g_keepawayball_damageforcescale;
        e.takedamage = DAMAGE_YES;
        e.solid = SOLID_TRIGGER;
-       e.movetype = MOVETYPE_BOUNCE;
+       set_movetype(e, MOVETYPE_BOUNCE);
        e.glow_color = autocvar_g_keepawayball_trail_color;
        e.glow_trail = true;
        e.flags = FL_ITEM;
index 9ac66b5f577db2bb247ea5c6802a966e143b4f33..64b0397aa957dacc47c49fc261c915e7d4060786 100644 (file)
@@ -144,7 +144,7 @@ const float SP_KH_DESTROYS = 6;
 const float SP_KH_PICKUPS = 7;
 const float SP_KH_KCKILLS = 8;
 const float SP_KH_LOSSES = 9;
-void kh_ScoreRules(float teams)
+void kh_ScoreRules(int teams)
 {
        ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, true);
        ScoreInfo_SetLabel_TeamScore(  ST_KH_CAPS,      "caps",      SFL_SORT_PRIO_SECONDARY);
@@ -307,7 +307,7 @@ void kh_Key_Attach(entity key)  // runs when a player picks up a key and several
 #endif
        key.flags = 0;
        key.solid = SOLID_NOT;
-       key.movetype = MOVETYPE_NONE;
+       set_movetype(key, MOVETYPE_NONE);
        key.team = key.owner.team;
        key.nextthink = time;
        key.damageforcescale = 0;
@@ -346,7 +346,7 @@ void kh_Key_Detach(entity key) // runs every time a key is dropped or lost. Runs
 #endif
        key.flags = FL_ITEM;
        key.solid = SOLID_TRIGGER;
-       key.movetype = MOVETYPE_TOSS;
+       set_movetype(key, MOVETYPE_TOSS);
        key.pain_finished = time + autocvar_g_balance_keyhunt_delay_return;
        key.damageforcescale = autocvar_g_balance_keyhunt_damageforcescale;
        key.takedamage = DAMAGE_YES;
@@ -558,7 +558,7 @@ void kh_Key_Remove(entity key)  // runs after when all the keys have been collec
                }
        }
 
-       remove(key);
+       delete(key);
 
        kh_update_state();
 }
@@ -959,9 +959,15 @@ void kh_WaitForPlayers()  // delay start of the round until enough players are p
                }
                else
                {
-                       float missing_teams_mask = boolean(p1) + boolean(p2) * 2;
-                       if(kh_teams >= 3) missing_teams_mask += boolean(p3) * 4;
-                       if(kh_teams >= 4) missing_teams_mask += boolean(p4) * 8;
+                       int missing_teams_mask = 0;
+                       if(kh_teams & BIT(0))
+                               missing_teams_mask += boolean(p1) * 1;
+                       if(kh_teams & BIT(1))
+                               missing_teams_mask += boolean(p2) * 2;
+                       if(kh_teams & BIT(2))
+                               missing_teams_mask += boolean(p3) * 4;
+                       if(kh_teams & BIT(3))
+                               missing_teams_mask += boolean(p4) * 8;
                        if(prev_missing_teams_mask != missing_teams_mask)
                        {
                                Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
@@ -1056,6 +1062,14 @@ void kh_Initialize()  // sets up th KH environment
                kh_teams = autocvar_g_keyhunt_teams;
        kh_teams = bound(2, kh_teams, 4);
 
+       int teams = 0;
+       if(kh_teams >= 1) teams |= BIT(0);
+       if(kh_teams >= 2) teams |= BIT(1);
+       if(kh_teams >= 3) teams |= BIT(2);
+       if(kh_teams >= 4) teams |= BIT(3);
+
+       kh_teams = teams; // now set it?
+
        // make a KH entity for controlling the game
        kh_controller = spawn();
        setthink(kh_controller, kh_Controller_Think);
@@ -1085,7 +1099,7 @@ void kh_finalize()
 {
        // to be called before intermission
        kh_FinishRound();
-       remove(kh_controller);
+       delete(kh_controller);
        kh_controller = NULL;
 }
 
index 132eba1620515b6e8c7d9478029deeac3d38cca5..63fbd15a272476c1184fd26786daf3ce478b5d9c 100644 (file)
@@ -159,7 +159,7 @@ MUTATOR_HOOKFUNCTION(rc, PlayerPhysics)
                if(player.race_penalty)
                {
                        player.velocity = '0 0 0';
-                       player.movetype = MOVETYPE_NONE;
+                       set_movetype(player, MOVETYPE_NONE);
                        player.disableclientprediction = 2;
                }
        }
@@ -463,6 +463,14 @@ void rc_SetLimits()
        {
                ActivateTeamplay();
                race_teams = bound(2, autocvar_g_race_teams, 4);
+               int teams = 0;
+               if(race_teams >= 1) teams |= BIT(0);
+               if(race_teams >= 2) teams |= BIT(1);
+               if(race_teams >= 3) teams |= BIT(2);
+               if(race_teams >= 4) teams |= BIT(3);
+
+               race_teams = teams; // now set it?
+
                have_team_spawns = -1; // request team spawns
        }
        else
index 0d516b262623c6f5489d665977ed68c34b7f312a..3bc522ded3b5c568d1cd458659b4a7f2e024ee20 100644 (file)
@@ -51,19 +51,19 @@ Keys:
 "cnt" Scoreboard color of the team (for example 4 is red and 13 is blue)... */
 spawnfunc(tdm_team)
 {
-       if(!g_tdm || !this.cnt) { remove(this); return; }
+       if(!g_tdm || !this.cnt) { delete(this); return; }
 
        this.classname = "tdm_team";
        this.team = this.cnt + 1;
 }
 
 // code from here on is just to support maps that don't have team entities
-void tdm_SpawnTeam (string teamname, float teamcolor)
+void tdm_SpawnTeam (string teamname, int teamcolor)
 {
        entity this = new_pure(tdm_team);
        this.netname = teamname;
-       this.cnt = teamcolor;
-       this.team = this.cnt + 1;
+       this.cnt = teamcolor - 1;
+       this.team = teamcolor;
        this.spawnfunc_checked = true;
        //spawnfunc_tdm_team(this);
 }
@@ -75,14 +75,25 @@ void tdm_DelayedInit(entity this)
        {
                LOG_TRACE("No \"tdm_team\" entities found on this map, creating them anyway.\n");
 
-               int numteams = min(4, autocvar_g_tdm_teams_override);
+               int numteams = autocvar_g_tdm_teams_override;
 
                if(numteams < 2) { numteams = autocvar_g_tdm_teams; }
                numteams = bound(2, numteams, 4);
 
-               float i;
-               for(i = 1; i <= numteams; ++i)
-                       tdm_SpawnTeam(Team_ColorName(Team_NumberToTeam(i)), Team_NumberToTeam(i) - 1);
+               int teams = 0;
+               if(numteams >= 1) teams |= BIT(0);
+               if(numteams >= 2) teams |= BIT(1);
+               if(numteams >= 3) teams |= BIT(2);
+               if(numteams >= 4) teams |= BIT(3);
+
+               if(teams & BIT(0))
+                       tdm_SpawnTeam("Red", NUM_TEAM_1);
+               if(teams & BIT(1))
+                       tdm_SpawnTeam("Blue", NUM_TEAM_2);
+               if(teams & BIT(2))
+                       tdm_SpawnTeam("Yellow", NUM_TEAM_3);
+               if(teams & BIT(3))
+                       tdm_SpawnTeam("Pink", NUM_TEAM_4);
        }
 }
 
index b6e1350789c3904bcd1e7f97a0bee5db9d82c70b..b07d86384cea58417eca4f60159440662401d4fd 100644 (file)
@@ -6,15 +6,11 @@
 
 void pathlib_deletepath(entity start)
 {
-    entity e;
-
-    e = findchainentity(owner, start);
-    while(e)
+    FOREACH_ENTITY_ENT(owner, start,
     {
-        setthink(e, SUB_Remove);
-        e.nextthink = time;
-        e = e.chain;
-    }
+        setthink(it, SUB_Remove);
+        it.nextthink = time;
+    });
 }
 
 //#define PATHLIB_NODEEXPIRE 0.05
@@ -218,9 +214,6 @@ float pathlib_makenode_adaptive(entity parent,vector start, vector to, vector go
 
 entity pathlib_getbestopen()
 {
-    entity node;
-    entity bestnode;
-
     if(best_open_node)
     {
         ++pathlib_bestcash_hits;
@@ -229,19 +222,14 @@ entity pathlib_getbestopen()
         return best_open_node;
     }
 
-    node = findchainentity(owner,openlist);
-    if(!node)
-        return NULL;
-
-    bestnode = node;
-    while(node)
+    entity bestnode = NULL;
+    FOREACH_ENTITY_ENT(owner, openlist,
     {
-        ++pathlib_bestopen_seached;
-        if(node.pathlib_node_f < bestnode.pathlib_node_f)
-            bestnode = node;
+        ++pathlib_bestopen_searched;
 
-        node = node.chain;
-    }
+        if(!bestnode || it.pathlib_node_f < bestnode.pathlib_node_f)
+            bestnode = it;
+    });
 
     return bestnode;
 }
@@ -300,10 +288,10 @@ void pathlib_cleanup()
     }
 
     if(openlist)
-        remove(openlist);
+        delete(openlist);
 
     if(closedlist)
-        remove(closedlist);
+        delete(closedlist);
 
     openlist       = NULL;
     closedlist     = NULL;
@@ -432,7 +420,7 @@ entity pathlib_astar(entity this, vector from,vector to)
     pathlib_made_cnt         = 0;
     pathlib_merge_cnt        = 0;
     pathlib_searched_cnt     = 0;
-    pathlib_bestopen_seached = 0;
+    pathlib_bestopen_searched = 0;
     pathlib_bestcash_hits    = 0;
     pathlib_bestcash_saved   = 0;
 
@@ -561,7 +549,7 @@ entity pathlib_astar(entity this, vector from,vector to)
             LOG_TRACE("Nodes -          merged: ", ftos(pathlib_merge_cnt),"\n");
             LOG_TRACE("Nodes -          closed: ", ftos(pathlib_closed_cnt),"\n");
             LOG_TRACE("Nodes -        searched: ", ftos(pathlib_searched_cnt),"\n");
-            LOG_TRACE("Nodes bestopen searched: ", ftos(pathlib_bestopen_seached),"\n");
+            LOG_TRACE("Nodes bestopen searched: ", ftos(pathlib_bestopen_searched),"\n");
             LOG_TRACE("Nodes bestcash -   hits: ", ftos(pathlib_bestcash_hits),"\n");
             LOG_TRACE("Nodes bestcash -   save: ", ftos(pathlib_bestcash_saved),"\n");
             LOG_TRACE("AStar done.\n");
index 3059021d1238536b9d6b86b627bfbbd623bd6e5e..fea57426e6462cfbbc860262f203da2368c9690c 100644 (file)
@@ -77,7 +77,7 @@ void a_think(entity this)
 {
     te_lightning1(this,this.origin, this.pos1);
     if(this.cnt < time)
-        remove(this);
+        delete(this);
     else
         this.nextthink = time + 0.2;
 }
index 35dcce5b25030cad21e169218900308c5c1f6f55..a2aaf55635d119e08959f93ae9f3a6292834a989 100644 (file)
@@ -114,20 +114,16 @@ float pathlib_wpp_expand(entity wp)
 
 entity pathlib_wpp_bestopen()
 {
-    entity n, best;
-
     if(best_open_node)
         return best_open_node;
 
-    n = findchainentity(pathlib_list, openlist);
-    best = n;
-    while(n)
-    {
-        if(n.pathlib_node_f < best.pathlib_node_f)
-            best = n;
+    entity best = NULL;
 
-        n = n.chain;
-    }
+    FOREACH_ENTITY_ENT(pathlib_list, openlist,
+    {
+        if(!best || it.pathlib_node_f < best.pathlib_node_f)
+            best = it;
+    });
 
     return best;
 
@@ -135,7 +131,6 @@ entity pathlib_wpp_bestopen()
 
 entity pathlib_waypointpath(entity wp_from, entity wp_to, float callback)
 {
-    entity n;
     float ptime;
 
     ptime                                      = gettime(GETTIME_REALTIME);
@@ -167,20 +162,18 @@ entity pathlib_waypointpath(entity wp_from, entity wp_to, float callback)
     LOG_TRACE("pathlib_waypointpath init\n");
 
     // Initialize waypoint grid
-    // FIXME! presisted chain for better preformance
-    for(n = findchain(classname, "waypoint"); n; n = n.chain)
+    IL_EACH(g_waypoints, true,
     {
-        n.pathlib_list = NULL;
-        n.pathlib_node_g = 0;
-        n.pathlib_node_f = 0;
-        n.pathlib_node_h = 0;
-
-        //setmodel(n, "models/runematch/rune.mdl");
-        //n.effects = EF_LOWPRECISION;
-        //n.colormod = '0 0 0';
-        //n.scale = 1;
-
-    }
+        it.pathlib_list = NULL;
+        it.pathlib_node_g = 0;
+        it.pathlib_node_f = 0;
+        it.pathlib_node_h = 0;
+
+        //setmodel(it, "models/runematch/rune.mdl");
+        //it.effects = EF_LOWPRECISION;
+        //it.colormod = '0 0 0';
+        //it.scale = 1;
+    });
 
     goal_node  = wp_to;
     start_node = wp_from;
index a5f36da4a349d0059bfdc7846e98409847951b52..339a2e7e0e43c73346741e002c58621874ed9864 100644 (file)
@@ -46,7 +46,7 @@ float pathlib_closed_cnt;
 float pathlib_made_cnt;
 float pathlib_merge_cnt;
 float pathlib_searched_cnt;
-float pathlib_bestopen_seached;
+float pathlib_bestopen_searched;
 float pathlib_bestcash_hits;
 float pathlib_bestcash_saved;
 float pathlib_gridsize;
index 9bc0855f5b3c38c82ec67375925c141ad82962a8..34c886fa10ebc67029ab433831117ccecb1e2fcb 100644 (file)
@@ -34,7 +34,7 @@ void playerdemo_open_read(entity this, string f)
        this.playerdemo_starttime = time - 1;
        this.playerdemo_time = stof(fgets(this.playerdemo_fh));
        this.playerdemo_time += this.playerdemo_starttime;
-       this.movetype = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        LOG_INFO("playerdemo: ", this.netname, " reading from ", f, "\n");
 }
 void playerdemo_open_write(entity this, string f)
index 6cb569149fb89be93781f550e3a242eb3cdfaf99..8a40b111840a34ebf2198ba53787d00fc59a8d2a 100644 (file)
@@ -418,7 +418,7 @@ void Portal_Remove(entity portal, float killed)
                fixedmakevectors(portal.mangle);
                sound(portal, CH_SHOTS, SND_PORTO_EXPLODE, VOL_BASE, ATTEN_NORM);
                Send_Effect(EFFECT_ROCKET_EXPLODE, portal.origin + v_forward * 16, v_forward * 1024, 4);
-               remove(portal);
+               delete(portal);
        }
        else
        {
@@ -642,7 +642,7 @@ entity Portal_Spawn(entity own, vector org, vector ang)
 
        if(!Portal_FindSafeOrigin(portal))
        {
-               remove(portal);
+               delete(portal);
                return NULL;
        }
 
index e32968c56d54e1f400bb0c8b6070c0738918836f..a46c8b3d935268f87c4069248fe82398b45c1550 100644 (file)
@@ -905,7 +905,7 @@ vector trigger_race_checkpoint_spawn_evalfunc(entity this, entity player, entity
 spawnfunc(trigger_race_checkpoint)
 {
        vector o;
-       if(!g_race && !g_cts) { remove(this); return; }
+       if(!g_race && !g_cts) { delete(this); return; }
 
        EXACTTRIGGER_INIT;
 
@@ -953,7 +953,7 @@ spawnfunc(trigger_race_checkpoint)
 spawnfunc(target_checkpoint) // defrag entity
 {
        vector o;
-       if(!g_race && !g_cts) { remove(this); return; }
+       if(!g_race && !g_cts) { delete(this); return; }
        defrag_ents = 1;
 
        EXACTTRIGGER_INIT;
@@ -1031,7 +1031,7 @@ void race_RetractPlayer(entity this)
 
 spawnfunc(info_player_race)
 {
-       if(!g_race && !g_cts) { remove(this); return; }
+       if(!g_race && !g_cts) { delete(this); return; }
        ++race_spawns;
        spawnfunc_info_player_deathmatch(this);
 
index d1302a84d7d0212ed1d1440d7bf5f9105e8fee53..3b11c5f9b6f409e0d51948286cab7160041b3270 100644 (file)
@@ -111,6 +111,6 @@ void round_handler_Reset(float next_think)
 
 void round_handler_Remove()
 {
-       remove(round_handler);
+       delete(round_handler);
        round_handler = NULL;
 }
index aa108dd985d9622e167a3db2649d08fec0dfc0d4..1a51c803d5244b86207982ad712cf17ad53ebbfb 100644 (file)
@@ -203,7 +203,7 @@ bool ScoreInfo_SendEntity(entity this, entity to, int sf)
        return true;
 }
 
-void ScoreInfo_Init(float teams)
+void ScoreInfo_Init(int teams)
 {
        if(scores_initialized)
        {
@@ -214,13 +214,13 @@ void ScoreInfo_Init(float teams)
                scores_initialized = new_pure(ent_client_scoreinfo);
                Net_LinkEntity(scores_initialized, false, 0, ScoreInfo_SendEntity);
        }
-       if(teams >= 1)
+       if(teams & BIT(0))
                TeamScore_Spawn(NUM_TEAM_1, "Red");
-       if(teams >= 2)
+       if(teams & BIT(1))
                TeamScore_Spawn(NUM_TEAM_2, "Blue");
-       if(teams >= 3)
+       if(teams & BIT(2))
                TeamScore_Spawn(NUM_TEAM_3, "Yellow");
-       if(teams >= 4)
+       if(teams & BIT(3))
                TeamScore_Spawn(NUM_TEAM_4, "Pink");
 }
 
@@ -327,7 +327,7 @@ void PlayerScore_Detach(entity player)
 {
        if(!player.scorekeeper)
                error("player has no scorekeeper");
-       remove(player.scorekeeper);
+       delete(player.scorekeeper);
        player.scorekeeper = NULL;
 }
 
index 72eeb9a1cccaf10d4ce3142a28a69cee0139ca53..b93c114c06eb40f1c18fa829d3196a93a32ac795 100644 (file)
@@ -3,12 +3,25 @@
 #include "cl_client.qh"
 #include "scores.qh"
 
+int ScoreRules_teams;
+
 void CheckAllowedTeams (entity for_whom);
 
+int NumTeams(int teams)
+{
+       return boolean(teams & BIT(0)) + boolean(teams & BIT(1)) + boolean(teams & BIT(2)) + boolean(teams & BIT(3));
+}
+
+int AvailableTeams()
+{
+       return NumTeams(ScoreRules_teams);
+       // NOTE: this method is unreliable, as forced teams set the c* globals to weird values
+       //return boolean(c1 >= 0) + boolean(c2 >= 0) + boolean(c3 >= 0) + boolean(c4 >= 0);
+}
+
 // NOTE: SP_ constants may not be >= MAX_SCORE; ST_constants may not be >= MAX_TEAMSCORE
 // scores that should be in all modes:
-float ScoreRules_teams;
-void ScoreRules_basics(float teams, float sprio, float stprio, float score_enabled)
+void ScoreRules_basics(int teams, float sprio, float stprio, float score_enabled)
 {
        float i;
        for(i = 0; i < MAX_SCORE; ++i)
@@ -44,7 +57,12 @@ void ScoreRules_generic()
        if(teamplay)
        {
                CheckAllowedTeams(NULL);
-               ScoreRules_basics(((c4>=0) ? 4 : (c3>=0) ? 3 : 2), SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, true);
+               int teams = 0;
+               if(c1 >= 0) teams |= BIT(0);
+               if(c2 >= 0) teams |= BIT(1);
+               if(c3 >= 0) teams |= BIT(2);
+               if(c4 >= 0) teams |= BIT(3);
+               ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, true);
        }
        else
                ScoreRules_basics(0, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, true);
index 1d2646bb83e6d544d6986f3e60d2d8e119d7a9ee..9d1caf5395bff7453a6e558266bc4f1cd0ad3c92 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
-void ScoreRules_basics(float teams, float sprio, float stprio, float score_enabled);
+int NumTeams(int teams);
+int AvailableTeams();
+void ScoreRules_basics(int teams, float sprio, float stprio, float score_enabled);
 void ScoreRules_basics_end();
 void ScoreRules_generic();
index bf0a955515f1a4dfeb39fea923083571a8a8e0e3..8064cd9ae12ecde6f8672058a7cfb798520e6d13 100644 (file)
@@ -556,7 +556,7 @@ void spawn_flocker(entity this)
     setthink(flocker, flocker_think);
     flocker.nextthink  = time + random() * 5;
     PROJECTILE_MAKETRIGGER(flocker);
-    flocker.movetype   = MOVETYPE_BOUNCEMISSILE;
+    set_movetype(flocker, MOVETYPE_BOUNCEMISSILE);
     flocker.effects    = EF_LOWPRECISION;
     flocker.velocity   = randomvec() * 300;
     flocker.angles     = vectoangles(flocker.velocity);
@@ -579,8 +579,7 @@ void flockerspawn_think(entity this)
 void flocker_hunter_think(entity this)
 {
     vector dodgemove,attractmove,newmove;
-    entity e,ee;
-    float d,bd;
+    entity ee;
 
     this.angles_x = this.angles.x * -1;
     makevectors(this.angles);
@@ -597,20 +596,14 @@ void flocker_hunter_think(entity this)
 
     if(!this.enemy)
     {
-        e = findchainfloat(flock_id,this.flock_id);
-        while(e)
+        FOREACH_ENTITY_FLOAT(flock_id, this.flock_id,
         {
-            d = vlen(this.origin - e.origin);
-
-            if(e != this.owner)
-            if(e != ee)
-            if(d > bd)
-            {
-                this.enemy = e;
-                bd = d;
-            }
-            e = e.chain;
-        }
+            if(it == this.owner || it == ee)
+                continue;
+
+            if(!this.enemy || vlen2(this.origin - it.origin) > vlen2(this.origin - this.enemy.origin))
+                this.enemy = it;
+        });
     }
 
     if(this.enemy)
@@ -624,7 +617,6 @@ void flocker_hunter_think(entity this)
     this.velocity = movelib_inertmove_byspeed(this, newmove,1250,0.3,0.7);
     this.velocity = movelib_dragvec(this, 0.01,0.5);
 
-
     this.angles = vectoangles(this.velocity);
     this.nextthink = time + 0.1;
 }
@@ -649,7 +641,7 @@ spawnfunc(flockerspawn)
 
     this.enemy.scale     = 3;
     this.enemy.effects   = EF_LOWPRECISION;
-    this.enemy.movetype  = MOVETYPE_BOUNCEMISSILE;
+    set_movetype(this.enemy, MOVETYPE_BOUNCEMISSILE);
     PROJECTILE_MAKETRIGGER(this.enemy);
     setthink(this.enemy, flocker_hunter_think);
     this.enemy.nextthink = time + 10;
index bc6814879122a116786dfa7074b92eed0766f617..52887cc1550777367194d918df936c70f8b89b6c 100644 (file)
@@ -119,7 +119,7 @@ void CreatureFrame_FallDamage(entity this)
 void CreatureFrame_All()
 {
        FOREACH_ENTITY_FLOAT(damagedbycontents, true, {
-               if (it.movetype == MOVETYPE_NOCLIP) continue;
+               if (it.move_movetype == MOVETYPE_NOCLIP) continue;
                CreatureFrame_Liquids(it);
                CreatureFrame_FallDamage(it);
                it.oldvelocity = it.velocity;
@@ -153,19 +153,20 @@ Called before each frame by the server
 float game_delay;
 float game_delay_last;
 
-bool autocvar_sv_autopause = true;
+bool autocvar_sv_autopause = false;
 float RedirectionThink();
-void PM_Main(Client this);
+void systems_update();
+void sys_phys_update(entity this, float dt);
 void StartFrame()
 {
     // TODO: if move is more than 50ms, split it into two moves (this matches QWSV behavior and the client prediction)
-    FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), PM_Main(it));
+    FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), sys_phys_update(it, frametime));
     FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), PlayerPreThink(it));
 
        execute_next_frame();
        if (autocvar_sv_autopause && !server_is_dedicated) Pause_TryPause(true);
 
-       remove = remove_unsafely; // not during spawning!
+       delete_fn = remove_unsafely; // not during spawning!
        serverprevtime = servertime;
        servertime = time;
        serverframetime = frametime;
@@ -246,7 +247,7 @@ void SV_OnEntityPreSpawnFunction(entity this)
        if (this.gametypefilter != "")
        if (!isGametypeInFilter(MapInfo_LoadedGametype, teamplay, have_team_spawns, this.gametypefilter))
        {
-               remove(this);
+               delete(this);
                __spawnfunc_expecting = false;
                return;
        }
@@ -355,7 +356,7 @@ LABEL(cvar_fail)
                if (!inv)
                {
                        //print("cvarfilter fail\n");
-                       remove(this);
+                       delete(this);
                        __spawnfunc_expecting = false;
                        return;
                }
@@ -363,11 +364,13 @@ LABEL(cvar_fail)
 
        if(DoesQ3ARemoveThisEntity(this))
        {
-               remove(this);
+               delete(this);
                __spawnfunc_expecting = false;
                return;
        }
 
+       set_movetype(this, this.movetype);
+
        // support special -1 and -2 angle from radiant
        if (this.angles == '0 -1 0')
                this.angles = '-90 0 0';
@@ -391,7 +394,7 @@ LABEL(cvar_fail)
 
        if(MUTATOR_CALLHOOK(OnEntityPreSpawn, this))
        {
-               remove(this);
+               delete(this);
                __spawnfunc_expecting = false;
                return;
        }
index e24a790a148a2cdebbe4bf3c40302178e6ee6adb..1ccf6695a185a1ad37558818e8ada3ae1205ccd6 100644 (file)
@@ -2,7 +2,6 @@
 
 #undef droptofloor
 #undef sound
-#undef remove
 #undef cvar_set
 #undef cvar_string
 #undef cvar
@@ -10,7 +9,7 @@
 var float(string name) cvar;
 var string(string name) cvar_string;
 var void(string name, string value) cvar_set;
-var void remove(entity e);
+var void delete_fn(entity e);
 
 #undef IT_SHOTGUN
 #undef IT_SUPER_SHOTGUN
index 7ab3f7b9f62763da2566d9409d6f53cb14ea1e80..9799a087ea0814e7a2d52b98f4f47a5c5d58e622 100644 (file)
@@ -1,7 +1,6 @@
 #pragma once
 
 #define droptofloor builtin_droptofloor
-#define remove builtin_remove
 #define cvar_set builtin_cvar_set
 #define cvar_string builtin_cvar_string
 #define cvar builtin_cvar
index 3dda784eb3d38bfddb6b68f3fa2abbc2cbe2f8ef..e2156705a03b0cd1de67161f0b61ed6ba7d8eb42 100644 (file)
@@ -219,12 +219,10 @@ void CheckAllowedTeams (entity for_whom)
 
        if(!mutator_returnvalue)
        {
-               if(dm >= 4)
-                       c1 = c2 = c3 = c4 = 0;
-               else if(dm >= 3)
-                       c1 = c2 = c3 = 0;
-               else
-                       c1 = c2 = 0;
+               if(dm & BIT(0)) c1 = 0;
+               if(dm & BIT(1)) c2 = 0;
+               if(dm & BIT(2)) c3 = 0;
+               if(dm & BIT(3)) c4 = 0;
        }
 
        // find out what teams are allowed if necessary
@@ -246,24 +244,46 @@ void CheckAllowedTeams (entity for_whom)
        }
 
        // TODO: Balance quantity of bots across > 2 teams when bot_vs_human is set (and remove next line)
-       if(c3==-1 && c4==-1)
+       if(AvailableTeams() == 2)
        if(autocvar_bot_vs_human && for_whom)
        {
                if(autocvar_bot_vs_human > 0)
                {
-                       // bots are all blue
+                       // find last team available
+
                        if(IS_BOT_CLIENT(for_whom))
-                               c1 = c3 = c4 = -1;
+                       {
+                               if(c4 >= 0) { c3 = c2 = c1 = -1; }
+                               else if(c3 >= 0) { c4 = c2 = c1 = -1; }
+                               else { c4 = c3 = c1 = -1; }
+                               // no further cases, we know at least 2 teams exist
+                       }
                        else
-                               c2 = -1;
+                       {
+                               if(c1 >= 0) { c2 = c3 = c4 = -1; }
+                               else if(c2 >= 0) { c1 = c3 = c4 = -1; }
+                               else { c1 = c2 = c4 = -1; }
+                               // no further cases, bots have one of the teams
+                       }
                }
                else
                {
-                       // bots are all red
+                       // find first team available
+
                        if(IS_BOT_CLIENT(for_whom))
-                               c2 = c3 = c4 = -1;
+                       {
+                               if(c1 >= 0) { c2 = c3 = c4 = -1; }
+                               else if(c2 >= 0) { c1 = c3 = c4 = -1; }
+                               else { c1 = c2 = c4 = -1; }
+                               // no further cases, we know at least 2 teams exist
+                       }
                        else
-                               c1 = -1;
+                       {
+                               if(c4 >= 0) { c3 = c2 = c1 = -1; }
+                               else if(c3 >= 0) { c4 = c2 = c1 = -1; }
+                               else { c4 = c3 = c1 = -1; }
+                               // no further cases, bots have one of the teams
+                       }
                }
        }
 
@@ -426,8 +446,12 @@ float TeamSmallerEqThanTeam(float ta, float tb, entity e)
 // NOTE: Assumes CheckAllowedTeams has already been called!
 float FindSmallestTeam(entity pl, float ignore_pl)
 {
-       float totalteams, t;
-       totalteams = 0;
+       int totalteams = 0;
+       int t = 1; // initialize with a random team?
+       if(c4 >= 0) t = 4;
+       if(c3 >= 0) t = 3;
+       if(c2 >= 0) t = 2;
+       if(c1 >= 0) t = 1;
 
        // find out what teams are available
        //CheckAllowedTeams();
@@ -461,7 +485,8 @@ float FindSmallestTeam(entity pl, float ignore_pl)
 
        RandomSelection_Init();
 
-       t = 1;
+       if(TeamSmallerEqThanTeam(1, t, pl))
+               t = 1;
        if(TeamSmallerEqThanTeam(2, t, pl))
                t = 2;
        if(TeamSmallerEqThanTeam(3, t, pl))
index 7bbf00dc51c335262f6b3a757b3d97188d5692c5..96674db702943a933786ca954c4ec20498839ae8 100644 (file)
@@ -3,8 +3,8 @@
 void test_weapons_hurt(entity this)
 {
     EXPECT_NE(100, this.health);
-    remove(this.enemy);
-    remove(this);
+    delete(this.enemy);
+    delete(this);
 }
 
 TEST(Weapons, Hurt)
index abb41ad06a8e812569217467106b04f8e2877600..9efc4ce6a0700f31511eb9dfb2c9a5ae56e92cb9 100644 (file)
@@ -47,7 +47,7 @@ void accuracy_init(entity e)
 
 void accuracy_free(entity e)
 {
-       remove(e.accuracy);
+       delete(e.accuracy);
 }
 
 // force a resend of a player's accuracy stats
index 7e7478e9b8ea8aedd9e71f0b49f839084849bf93..caa367e5d708ac96ef0f047a7fb3f1fdeac299c0 100644 (file)
@@ -83,7 +83,7 @@ void CSQCProjectile(entity e, float clientanimate, int type, float docull)
 
        e.csqcprojectile_clientanimate = clientanimate;
 
-       if(e.movetype == MOVETYPE_TOSS || e.movetype == MOVETYPE_BOUNCE)
+       if(e.move_movetype == MOVETYPE_TOSS || e.move_movetype == MOVETYPE_BOUNCE)
        {
                if(e.gravity == 0)
                        e.gravity = 1;
index 0288347ee1f1e61bdaa47cc70b93479c04f2f02f..8e3e1075899707fdcf6248ce297f5e0394ec061d 100644 (file)
@@ -75,7 +75,7 @@ bool client_hasweapon(entity this, Weapon wpn, float andammo, bool complain)
 
                                // always allow selecting the Mine Layer if we placed mines, so that we can detonate them
                                if(wpn == WEP_MINE_LAYER)
-                                       FOREACH_ENTITY_CLASS("mine", it.owner == this,
+                                       IL_EACH(g_mines, it.owner == this,
                                        {
                                                f = 1;
                                                break; // no need to continue
index 748f434eb325dd3cf002279d599cd8ed2dade4ef..faec22f307315b37f06b47b40d72d0e64cb272e5 100644 (file)
@@ -39,7 +39,7 @@ void weapon_defaultspawnfunc(entity this, Weapon e)
                s = M_ARGV(2, string);
                if (s == "")
                {
-                       remove(this);
+                       delete(this);
                        startitem_failed = true;
                        return;
                }
@@ -76,7 +76,7 @@ void weapon_defaultspawnfunc(entity this, Weapon e)
                }
                if (wpn == WEP_Null)
                {
-                       remove(this);
+                       delete(this);
                        startitem_failed = true;
                        return;
                }
index 5c64a0ec64d3ff6e89f5d7f2efbf8d0ac7383355..e9148e6e27f12aca629fe7d86d2b648c0d3d0f31 100644 (file)
@@ -300,7 +300,7 @@ void FireRailgunBullet (entity this, vector start, vector end, float bdamage, fl
                ));
 
                if(pseudoprojectile)
-                       remove(pseudoprojectile);
+                       delete(pseudoprojectile);
        }
 
        // find all the entities the railgun hit and hurt them
@@ -377,9 +377,9 @@ void fireBullet(entity this, vector start, vector dir, float spread, float max_s
        if(lag)
        {
                FOREACH_CLIENT(IS_PLAYER(it) && it != this, antilag_takeback(it, CS(it), time - lag));
-               FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, {
-                       if (it != this)
-                               antilag_takeback(it, it, time - lag);
+               IL_EACH(g_monsters, it != this,
+               {
+                       antilag_takeback(it, it, time - lag);
                });
        }
 
@@ -492,9 +492,9 @@ void fireBullet(entity this, vector start, vector dir, float spread, float max_s
        if(lag)
        {
                FOREACH_CLIENT(IS_PLAYER(it) && it != this, antilag_restore(it, CS(it)));
-               FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, {
-                       if (it != this)
-                               antilag_restore(it, it);
+               IL_EACH(g_monsters, it != this,
+               {
+                       antilag_restore(it, it);
                });
        }
 
index 32e9a5670299b9dc00de52256f5081c3b77d49ca..3f372371bd3d1af12fd3e1518e434ffb9c6e5871 100644 (file)
@@ -54,7 +54,7 @@ vector CL_Weapon_GetShotOrg(int wpn)
        CL_WeaponEntity_SetModel(e, wi.mdl, false);
        vector ret = e.movedir;
        CL_WeaponEntity_SetModel(e, "", false);
-       remove(e);
+       delete(e);
        return ret;
 }
 
@@ -69,8 +69,8 @@ void CL_Weaponentity_Think(entity this)
        if (this.owner.(weaponentity) != this)
        {
                // owner has new gun; remove old one
-               if (this.weaponchild) remove(this.weaponchild);
-               remove(this);
+               if (this.weaponchild) delete(this.weaponchild);
+               delete(this);
                return;
        }
        if (IS_DEAD(this.owner))
@@ -110,7 +110,7 @@ void CL_ExteriorWeaponentity_Think(entity this)
        this.nextthink = time;
        if (this.owner.exteriorweaponentity != this)
        {
-               remove(this);
+               delete(this);
                return;
        }
        if (IS_DEAD(this.owner))
@@ -215,10 +215,9 @@ bool weapon_prepareattack_checkammo(Weapon thiswep, entity actor, bool secondary
        // always keep the Mine Layer if we placed mines, so that we can detonate them
        if (thiswep == WEP_MINE_LAYER)
        {
-               FOREACH_ENTITY_ENT(owner, actor,
+               IL_EACH(g_mines, it.owner == actor,
                {
-                       if(it.classname != "mine") continue;
-                       if(it.owner == actor) return false;
+                       return false;
                });
        }
 
@@ -391,7 +390,9 @@ void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void(
 
        if ((fr == WFRAME_FIRE1 || fr == WFRAME_FIRE2) && t)
        {
-               int act = (fr == WFRAME_FIRE2 && (PS(actor).m_weapon == WEP_SHOCKWAVE || PS(actor).m_weapon == WEP_SHOTGUN))
+               bool primary_melee = boolean(fr == WFRAME_FIRE1 && (PS(actor).m_weapon.spawnflags & WEP_TYPE_MELEE_PRI));
+               bool secondary_melee = boolean(fr == WFRAME_FIRE2 && (PS(actor).m_weapon.spawnflags & WEP_TYPE_MELEE_SEC));
+               int act = (primary_melee || secondary_melee)
                        ? ANIMACTION_MELEE
                        : ANIMACTION_SHOOT
                        ;
index 98cdab9dd51b3036def6ce08a78f128abdc91d22..b598727223ee7321209bbc9360e9d32cd833a565 100644 (file)
@@ -418,7 +418,7 @@ sp_angle_shift                           = ignore   # ignore/add/remove/force
 sp_permit_cpp11_shift                    = false    # false/true
 
 # Add or remove space before '(' of 'if', 'for', 'switch', and 'while'
-sp_before_sparen                         = add      # ignore/add/remove/force #force
+sp_before_sparen                         = force    # ignore/add/remove/force #force
 
 # Add or remove space inside if-condition '(' and ')'
 # NOTE: is 68 worse than ignore
@@ -431,10 +431,10 @@ sp_inside_sparen_close                   = ignore   # ignore/add/remove/force #f
 sp_inside_sparen_open                    = ignore   # ignore/add/remove/force #force
 
 # Add or remove space after ')' of 'if', 'for', 'switch', and 'while'
-sp_after_sparen                          = add      # ignore/add/remove/force
+sp_after_sparen                          = force    # ignore/add/remove/force
 
 # Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while'
-sp_sparen_brace                          = add      # ignore/add/remove/force
+sp_sparen_brace                          = force    # ignore/add/remove/force
 
 # Add or remove space between 'invariant' and '(' in the D language.
 sp_invariant_paren                       = ignore   # ignore/add/remove/force #ignore
@@ -630,11 +630,11 @@ sp_macro                                 = remove   # ignore/add/remove/force #f
 sp_macro_func                            = remove   # ignore/add/remove/force #force
 
 # Add or remove space between 'else' and '{' if on the same line
-sp_else_brace                            = add      # ignore/add/remove/force
+sp_else_brace                            = force    # ignore/add/remove/force
 
 # Add or remove space between '}' and 'else' if on the same line
 # WARNING: Code doesn't seem to use this feature - delete from the config?
-sp_brace_else                            = ignore   # ignore/add/remove/force
+sp_brace_else                            = force    # ignore/add/remove/force
 
 # Add or remove space between '}' and the name of a typedef on the same line
 sp_brace_typedef                         = add      # ignore/add/remove/force
@@ -1116,17 +1116,17 @@ nl_union_brace                           = ignore   # ignore/add/remove/force
 
 # Add or remove newline between 'if' and '{'
 # NOTE: is 136 worse than ignore
-nl_if_brace                              = add      # ignore/add/remove/force
+nl_if_brace                              = remove   # ignore/add/remove/force
 
 # Add or remove newline between '}' and 'else'
-nl_brace_else                            = add      # ignore/add/remove/force
+nl_brace_else                            = remove   # ignore/add/remove/force
 
 # Add or remove newline between 'else if' and '{'
 # If set to ignore, nl_if_brace is used instead
-nl_elseif_brace                          = add      # ignore/add/remove/force
+nl_elseif_brace                          = remove   # ignore/add/remove/force
 
 # Add or remove newline between 'else' and '{'
-nl_else_brace                            = add      # ignore/add/remove/force
+nl_else_brace                            = remove   # ignore/add/remove/force
 
 # Add or remove newline between 'else' and 'if'
 nl_else_if                               = remove   # ignore/add/remove/force
@@ -1137,7 +1137,7 @@ nl_brace_finally                         = ignore   # ignore/add/remove/force
 
 # Add or remove newline between 'finally' and '{'
 # WARNING: Code doesn't seem to use this feature - delete from the config?
-nl_finally_brace                         = ignore   # ignore/add/remove/force
+nl_finally_brace                         = remove   # ignore/add/remove/force
 
 # Add or remove newline between 'try' and '{'
 # WARNING: Code doesn't seem to use this feature - delete from the config?
@@ -1149,7 +1149,7 @@ nl_getset_brace                          = ignore   # ignore/add/remove/force
 
 # Add or remove newline between 'for' and '{'
 # NOTE: is 109 worse than ignore
-nl_for_brace                             = add      # ignore/add/remove/force
+nl_for_brace                             = remove   # ignore/add/remove/force
 
 # Add or remove newline between 'catch' and '{'
 # WARNING: Code doesn't seem to use this feature - delete from the config?
@@ -1161,7 +1161,7 @@ nl_brace_catch                           = ignore   # ignore/add/remove/force
 
 # Add or remove newline between 'while' and '{'
 # NOTE: is 22 worse than ignore
-nl_while_brace                           = add      # ignore/add/remove/force
+nl_while_brace                           = remove   # ignore/add/remove/force
 
 # Add or remove newline between 'scope (x)' and '{' (D)
 # WARNING: Code doesn't seem to use this feature - delete from the config?
@@ -1570,27 +1570,27 @@ nl_between_annotation                    = ignore   # ignore/add/remove/force
 #
 
 # Add or remove braces on single-line 'do' statement
-mod_full_brace_do                        = add      # ignore/add/remove/force
+mod_full_brace_do                        = force    # ignore/add/remove/force
 
 # Add or remove braces on single-line 'for' statement
 # NOTE: is 3 worse than ignore
-mod_full_brace_for                       = remove   # ignore/add/remove/force
+mod_full_brace_for                       = force    # ignore/add/remove/force
 
 # Add or remove braces on single-line function definitions. (Pawn)
 mod_full_brace_function                  = ignore   # ignore/add/remove/force #ignore
 
 # Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'.
-mod_full_brace_if                        = add      # ignore/add/remove/force
+mod_full_brace_if                        = force    # ignore/add/remove/force
 
 # Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if.
 # If any must be braced, they are all braced.  If all can be unbraced, then the braces are removed.
-mod_full_brace_if_chain                  = true     # false/true #force
+mod_full_brace_if_chain                  = false    # false/true #force
 
 # Don't remove braces around statements that span N newlines
 mod_full_brace_nl                        = 2        # number #force
 
 # Add or remove braces on single-line 'while' statement
-mod_full_brace_while                     = remove   # ignore/add/remove/force
+mod_full_brace_while                     = force    # ignore/add/remove/force
 
 # Add or remove braces on single-line 'using ()' statement
 # WARNING: Code doesn't seem to use this feature - delete from the config?
@@ -1608,7 +1608,7 @@ mod_pawn_semicolon                       = false    # false/true
 mod_full_paren_if_bool                   = false    # false/true
 
 # Whether to remove superfluous semicolons
-mod_remove_extra_semicolon               = false    # false/true
+mod_remove_extra_semicolon               = true     # false/true
 
 # If a function body exceeds the specified number of newlines and doesn't have a comment after
 # the close brace, a comment will be added.