]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into TimePath/physics
authorTimePath <andrew.hardaker1995@gmail.com>
Sun, 31 Jul 2016 09:49:35 +0000 (19:49 +1000)
committerTimePath <andrew.hardaker1995@gmail.com>
Sun, 31 Jul 2016 10:26:14 +0000 (20:26 +1000)
# Conflicts:
# qcsrc/common/physics/player.qc
# qcsrc/common/triggers/trigger/jumppads.qc
# qcsrc/common/weapons/weapon/electro.qc
# qcsrc/server/g_world.qc

311 files changed:
.gitlab-ci.yml
_hud_common.cfg
bal-wep-mario.cfg [new file with mode: 0644]
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 [new file with mode: 0644]
balance-nexuiz25.cfg
balance-overkill.cfg
balance-samual.cfg
balance-xdf.cfg
balance-xonotic.cfg
balance-xpm.cfg
binds-xonotic.cfg
defaultXonotic.cfg
gfx/hud/default/flag_stalemate.tga [new file with mode: 0644]
gfx/hud/luma/flag_blue_lost.tga
gfx/hud/luma/flag_neutral_lost.tga
gfx/hud/luma/flag_pink_lost.tga
gfx/hud/luma/flag_red_lost.tga
gfx/hud/luma/flag_stalemate.tga [new file with mode: 0644]
gfx/hud/luma/flag_yellow_lost.tga
gfx/hud/luma/notify_blue_lost.tga
gfx/hud/luma/notify_neutral_lost.tga
gfx/hud/luma/notify_pink_lost.tga
gfx/hud/luma/notify_red_lost.tga
gfx/hud/luma/notify_yellow_lost.tga
models/items/a_rockets.md3
models/weapons/g_fireball.md3
models/weapons/g_ok_hmg_luma.iqm [new file with mode: 0644]
models/weapons/g_ok_hmg_luma.iqm_0.skin [new file with mode: 0644]
models/weapons/g_ok_hmg_luma.tga [new file with mode: 0644]
models/weapons/g_ok_hmg_simple.iqm [new file with mode: 0644]
models/weapons/g_ok_hmg_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_ok_hmg_simple.tga [new file with mode: 0644]
models/weapons/g_ok_rl_luma.iqm [new file with mode: 0644]
models/weapons/g_ok_rl_luma.iqm_0.skin [new file with mode: 0644]
models/weapons/g_ok_rl_luma.tga [new file with mode: 0644]
models/weapons/g_ok_rl_simple.iqm [new file with mode: 0644]
models/weapons/g_ok_rl_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_ok_rl_simple.tga [new file with mode: 0644]
models/weapons/h_fireball.iqm
models/weapons/v_fireball.md3
notifications.cfg
qcsrc/client/commands/cl_cmd.qc
qcsrc/client/csqc_constants.qh
qcsrc/client/defs.qh
qcsrc/client/hud/hud.qc
qcsrc/client/hud/hud_config.qc
qcsrc/client/hud/panel/centerprint.qc
qcsrc/client/hud/panel/chat.qc
qcsrc/client/hud/panel/infomessages.qc
qcsrc/client/hud/panel/modicons.qc
qcsrc/client/hud/panel/physics.qc
qcsrc/client/hud/panel/quickmenu.qc
qcsrc/client/hud/panel/radar.qc
qcsrc/client/hud/panel/vote.qc
qcsrc/client/hud/panel/weapons.qc
qcsrc/client/main.qc
qcsrc/client/main.qh
qcsrc/client/miscfunctions.qc
qcsrc/client/mutators/events.qh
qcsrc/client/player_skeleton.qc
qcsrc/client/scoreboard.qc
qcsrc/client/shownames.qc
qcsrc/client/teamradar.qc
qcsrc/client/view.qc
qcsrc/client/wall.qc
qcsrc/client/weapons/projectile.qc
qcsrc/client/weapons/projectile.qh
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/globalsound.qc
qcsrc/common/effects/qc/globalsound.qh
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/item/pickup.qh
qcsrc/common/minigames/cl_minigames.qc
qcsrc/common/minigames/cl_minigames_hud.qc
qcsrc/common/minigames/sv_minigames.qc
qcsrc/common/minigames/sv_minigames.qh
qcsrc/common/models/model.qh
qcsrc/common/monsters/monster/mage.qc
qcsrc/common/monsters/monster/shambler.qc
qcsrc/common/monsters/monster/spider.qc
qcsrc/common/monsters/monster/wyvern.qc
qcsrc/common/monsters/monster/zombie.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/monsters/sv_monsters.qh
qcsrc/common/mutators/mutator/buffs/buffs.qc
qcsrc/common/mutators/mutator/bugrigs/bugrigs.qc
qcsrc/common/mutators/mutator/damagetext/damagetext.qc
qcsrc/common/mutators/mutator/dodging/dodging.qc
qcsrc/common/mutators/mutator/itemstime.qc
qcsrc/common/mutators/mutator/nades/nades.qc
qcsrc/common/mutators/mutator/nades/net.qc
qcsrc/common/mutators/mutator/new_toys/new_toys.qc
qcsrc/common/mutators/mutator/overkill/hmg.qc
qcsrc/common/mutators/mutator/overkill/overkill.qc
qcsrc/common/mutators/mutator/overkill/rpc.qc
qcsrc/common/mutators/mutator/physical_items/physical_items.qc
qcsrc/common/mutators/mutator/sandbox/sandbox.qc
qcsrc/common/mutators/mutator/waypoints/all.inc
qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc
qcsrc/common/mutators/mutator/waypoints/waypointsprites.qh
qcsrc/common/net_notice.qc
qcsrc/common/notifications/all.inc
qcsrc/common/physics/movetypes/_mod.inc
qcsrc/common/physics/movetypes/_mod.qh
qcsrc/common/physics/movetypes/all.inc
qcsrc/common/physics/movetypes/follow.qc
qcsrc/common/physics/movetypes/movetypes.qc
qcsrc/common/physics/movetypes/movetypes.qh
qcsrc/common/physics/movetypes/push.qc [deleted file]
qcsrc/common/physics/movetypes/step.qc
qcsrc/common/physics/movetypes/toss.qc
qcsrc/common/physics/movetypes/walk.qc
qcsrc/common/physics/player.qc
qcsrc/common/physics/player.qh
qcsrc/common/sounds/sound.qh
qcsrc/common/state.qc
qcsrc/common/stats.qh
qcsrc/common/t_items.qc
qcsrc/common/t_items.qh
qcsrc/common/triggers/func/breakable.qc
qcsrc/common/triggers/func/button.qc
qcsrc/common/triggers/func/conveyor.qc
qcsrc/common/triggers/func/door.qc
qcsrc/common/triggers/func/door_secret.qc
qcsrc/common/triggers/func/ladder.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/platforms.qh
qcsrc/common/triggers/subs.qc
qcsrc/common/triggers/subs.qh
qcsrc/common/triggers/teleporters.qc
qcsrc/common/triggers/teleporters.qh
qcsrc/common/triggers/trigger/gravity.qc
qcsrc/common/triggers/trigger/heal.qc
qcsrc/common/triggers/trigger/hurt.qc
qcsrc/common/triggers/trigger/impulse.qc
qcsrc/common/triggers/trigger/jumppads.qc
qcsrc/common/triggers/trigger/jumppads.qh
qcsrc/common/triggers/trigger/keylock.qc
qcsrc/common/triggers/trigger/multi.qc
qcsrc/common/triggers/trigger/secret.qc
qcsrc/common/triggers/trigger/swamp.qc
qcsrc/common/triggers/trigger/teleport.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/hk_weapon.qc
qcsrc/common/turrets/turret/phaser_weapon.qc
qcsrc/common/turrets/turret/tesla_weapon.qc
qcsrc/common/turrets/turret/walker.qc
qcsrc/common/turrets/util.qc
qcsrc/common/vehicles/cl_vehicles.qc
qcsrc/common/vehicles/sv_vehicles.qc
qcsrc/common/vehicles/vehicle.qh
qcsrc/common/vehicles/vehicle/bumblebee.qc
qcsrc/common/vehicles/vehicle/bumblebee_weapons.qc
qcsrc/common/vehicles/vehicle/racer.qc
qcsrc/common/vehicles/vehicle/raptor.qc
qcsrc/common/vehicles/vehicle/raptor_weapons.qc
qcsrc/common/vehicles/vehicle/spiderbot.qc
qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc
qcsrc/common/weapons/all.qh
qcsrc/common/weapons/weapon.qh
qcsrc/common/weapons/weapon/arc.qc
qcsrc/common/weapons/weapon/blaster.qc
qcsrc/common/weapons/weapon/crylink.qc
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/electro.qc
qcsrc/common/weapons/weapon/fireball.qc
qcsrc/common/weapons/weapon/hagar.qc
qcsrc/common/weapons/weapon/hlac.qc
qcsrc/common/weapons/weapon/hook.qc
qcsrc/common/weapons/weapon/machinegun.qc
qcsrc/common/weapons/weapon/minelayer.qc
qcsrc/common/weapons/weapon/mortar.qc
qcsrc/common/weapons/weapon/porto.qc
qcsrc/common/weapons/weapon/rifle.qc
qcsrc/common/weapons/weapon/seeker.qc
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/common/weapons/weapon/shotgun.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/dpdefs/menudefs.qh
qcsrc/dpdefs/post.qh
qcsrc/dpdefs/pre.qh
qcsrc/ecs/components/physics.qh
qcsrc/ecs/systems/cl_physics.qc
qcsrc/ecs/systems/physics.qc
qcsrc/lib/_all.inc
qcsrc/lib/counting.qh
qcsrc/lib/csqcmodel/cl_player.qc
qcsrc/lib/csqcmodel/cl_player.qh
qcsrc/lib/intrusivelist.qh [new file with mode: 0644]
qcsrc/lib/iter.qh
qcsrc/lib/log.qh
qcsrc/lib/net.qh
qcsrc/lib/oo.qh
qcsrc/lib/registry.qh
qcsrc/lib/self.qh
qcsrc/lib/static.qh
qcsrc/lib/stats.qh
qcsrc/lib/warpzone/client.qc
qcsrc/lib/warpzone/common.qh
qcsrc/lib/warpzone/server.qc
qcsrc/lib/warpzone/server.qh
qcsrc/lib/warpzone/util_server.qc
qcsrc/menu/item/dialog.qc
qcsrc/menu/item/inputcontainer.qc
qcsrc/menu/menu.qc
qcsrc/menu/xonotic/_mod.inc
qcsrc/menu/xonotic/_mod.qh
qcsrc/menu/xonotic/dialog_settings_misc.qc
qcsrc/menu/xonotic/dialog_settings_video.qc
qcsrc/menu/xonotic/dialog_uid2name.qc [new file with mode: 0644]
qcsrc/menu/xonotic/dialog_uid2name.qh [new file with mode: 0644]
qcsrc/menu/xonotic/gametypelist.qc
qcsrc/menu/xonotic/gametypelist.qh
qcsrc/menu/xonotic/mainwindow.qc
qcsrc/menu/xonotic/serverlist.qc
qcsrc/menu/xonotic/slider_resolution.qc
qcsrc/menu/xonotic/util.qc
qcsrc/server/_all.qh
qcsrc/server/autocvars.qh
qcsrc/server/bot/aim.qc
qcsrc/server/bot/bot.qc
qcsrc/server/bot/bot.qh
qcsrc/server/bot/havocbot/havocbot.qc
qcsrc/server/bot/havocbot/roles.qc
qcsrc/server/bot/navigation.qc
qcsrc/server/bot/navigation.qh
qcsrc/server/bot/scripting.qc
qcsrc/server/bot/waypoints.qc
qcsrc/server/campaign.qc
qcsrc/server/cheats.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_impulse.qc
qcsrc/server/cl_player.qc
qcsrc/server/command/common.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_hook.qc
qcsrc/server/g_lights.qc
qcsrc/server/g_models.qc
qcsrc/server/g_subs.qc
qcsrc/server/g_subs.qh
qcsrc/server/g_world.qc
qcsrc/server/item_key.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/miscfunctions.qh
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_ctf.qh
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/path_waypoint.qc
qcsrc/server/pathlib/pathlib.qh
qcsrc/server/playerdemo.qc
qcsrc/server/portals.qc
qcsrc/server/race.qc
qcsrc/server/scores.qc
qcsrc/server/scores_rules.qc
qcsrc/server/scores_rules.qh
qcsrc/server/spawnpoints.qc
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/weapons/csqcprojectile.qc
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/weaponsystem.qc
scripts/fireball.shader
scripts/luma.shader
scripts/simpleitems.shader
textures/fireball.tga
textures/fireball_gloss.tga
textures/fireball_glow.tga
textures/fireball_norm.tga [new file with mode: 0644]
textures/fireball_pants.tga [new file with mode: 0644]
textures/fireball_shirt.tga [new file with mode: 0644]
textures/items/a_rocket_bottom.jpg [new file with mode: 0644]

index 3cdd43f30510917818e9a8ab0b4365574d83d84d..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=4bd5b0276cdd100c831c73f0400eca71
+    - EXPECT=56bf79831a0a35ab6a3a420e26b09945
     - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
       | tee /dev/stderr
       | grep '^:'
index d8c7713f1965e1d837cfb33d871d969f3f2a4891..7bf9111cd4dab6c5d3d655e4ed3bc765c074ce49 100644 (file)
@@ -37,13 +37,13 @@ seta hud_panel_engineinfo       0 "enable this panel"
 seta hud_panel_infomessages     1 "enable this panel"
 seta hud_panel_physics          3 "enable this panel, 1 = show if not observing, 2 = show always, 3 = show only in race/cts if not observing"
 seta hud_panel_centerprint      1 "enable this panel"
-seta hud_panel_minigameboard    1 "enable this panel"
-seta hud_panel_minigamestatus   1 "enable this panel"
-seta hud_panel_minigamehelp     1 "enable this panel"
-seta hud_panel_minigamemenu     0 "enable this panel"
-seta hud_panel_mapvote          1 "enable this panel"
+//seta hud_panel_minigameboard    1 "enable this panel"
+//seta hud_panel_minigamestatus   1 "enable this panel"
+//seta hud_panel_minigamehelp     1 "enable this panel"
+//seta hud_panel_minigamemenu     0 "enable this panel"
+//seta hud_panel_mapvote          1 "enable this panel"
 seta hud_panel_itemstime        2 "enable this panel, 1 = show when spectating, 2 = even playing in warmup stage"
-seta hud_panel_quickmenu        1 "enable this panel"
+//seta hud_panel_quickmenu        1 "enable this panel"
 
 seta hud_panel_weapons_dynamichud          1 "apply the dynamic hud effects to this panel"
 seta hud_panel_ammo_dynamichud             1 "apply the dynamic hud effects to this panel"
diff --git a/bal-wep-mario.cfg b/bal-wep-mario.cfg
new file mode 100644 (file)
index 0000000..5979b78
--- /dev/null
@@ -0,0 +1,819 @@
+// {{{ #1: Blaster
+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 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
+set g_balance_blaster_primary_radius 60
+set g_balance_blaster_primary_refire 0.7
+set g_balance_blaster_primary_shotangle 0
+set g_balance_blaster_primary_speed 6000
+set g_balance_blaster_primary_spread 0
+set g_balance_blaster_secondary 0
+set g_balance_blaster_secondary_animtime 0.2
+set g_balance_blaster_secondary_damage 25
+set g_balance_blaster_secondary_delay 0
+set g_balance_blaster_secondary_edgedamage 12.5
+set g_balance_blaster_secondary_force 300
+set g_balance_blaster_secondary_force_zscale 1.2
+set g_balance_blaster_secondary_lifetime 5
+set g_balance_blaster_secondary_radius 70
+set g_balance_blaster_secondary_refire 0.7
+set g_balance_blaster_secondary_shotangle 0
+set g_balance_blaster_secondary_speed 6000
+set g_balance_blaster_secondary_spread 0
+set g_balance_blaster_switchdelay_drop 0.2
+set g_balance_blaster_switchdelay_raise 0.2
+set g_balance_blaster_weaponreplace ""
+set g_balance_blaster_weaponstart 1
+set g_balance_blaster_weaponstartoverride -1
+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 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
+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.15
+set g_balance_shotgun_secondary_damage 70
+set g_balance_shotgun_secondary_force 200
+set g_balance_shotgun_secondary_melee_delay 0.25
+set g_balance_shotgun_secondary_melee_multihit 1
+set g_balance_shotgun_secondary_melee_no_doubleslap 1
+set g_balance_shotgun_secondary_melee_nonplayerdamage 40
+set g_balance_shotgun_secondary_melee_range 120
+set g_balance_shotgun_secondary_melee_swing_side 120
+set g_balance_shotgun_secondary_melee_swing_up 30
+set g_balance_shotgun_secondary_melee_time 0.15
+set g_balance_shotgun_secondary_melee_traces 10
+set g_balance_shotgun_secondary_refire 1.25
+set g_balance_shotgun_secondary_alt_animtime 0.2
+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 0
+set g_balance_shotgun_weaponstartoverride -1
+set g_balance_shotgun_weaponthrowable 1
+// }}}
+// {{{ #3: Machine Gun
+set g_balance_machinegun_burst 3
+set g_balance_machinegun_burst_ammo 3
+set g_balance_machinegun_burst_animtime 0.3
+set g_balance_machinegun_burst_refire 0.06
+set g_balance_machinegun_burst_refire2 0.45
+set g_balance_machinegun_burst_speed 0
+set g_balance_machinegun_first 1
+set g_balance_machinegun_first_ammo 1
+set g_balance_machinegun_first_damage 14
+set g_balance_machinegun_first_force 5
+set g_balance_machinegun_first_refire 0.125
+set g_balance_machinegun_first_spread 0.03
+set g_balance_machinegun_mode 1
+set g_balance_machinegun_reload_ammo 60
+set g_balance_machinegun_reload_time 2
+set g_balance_machinegun_solidpenetration 13.1
+set g_balance_machinegun_spread_add 0.012
+set g_balance_machinegun_spread_max 0.05
+set g_balance_machinegun_spread_min 0.02
+set g_balance_machinegun_sustained_ammo 1
+set g_balance_machinegun_sustained_damage 10
+set g_balance_machinegun_sustained_force 5
+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 "arc"
+set g_balance_machinegun_weaponstart 0
+set g_balance_machinegun_weaponstartoverride -1
+set g_balance_machinegun_weaponthrowable 1
+// }}}
+// {{{ #4: Mortar
+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 55
+set g_balance_mortar_primary_damageforcescale 0
+set g_balance_mortar_primary_edgedamage 25
+set g_balance_mortar_primary_force 250
+set g_balance_mortar_primary_health 15
+set g_balance_mortar_primary_lifetime 5
+set g_balance_mortar_primary_lifetime_stick 0
+set g_balance_mortar_primary_radius 120
+set g_balance_mortar_primary_refire 0.8
+set g_balance_mortar_primary_remote_minbouncecnt 0
+set g_balance_mortar_primary_speed 1900
+set g_balance_mortar_primary_speed_up 225
+set g_balance_mortar_primary_speed_z 0
+set g_balance_mortar_primary_spread 0
+set g_balance_mortar_primary_type 0
+set g_balance_mortar_reload_ammo 0
+set g_balance_mortar_reload_time 2
+set g_balance_mortar_secondary_ammo 2
+set g_balance_mortar_secondary_animtime 0.3
+set g_balance_mortar_secondary_damage 55
+set g_balance_mortar_secondary_damageforcescale 4
+set g_balance_mortar_secondary_edgedamage 30
+set g_balance_mortar_secondary_force 250
+set g_balance_mortar_secondary_health 30
+set g_balance_mortar_secondary_lifetime 5
+set g_balance_mortar_secondary_lifetime_bounce 0.5
+set g_balance_mortar_secondary_lifetime_stick 0
+set g_balance_mortar_secondary_radius 120
+set g_balance_mortar_secondary_refire 0.7
+set g_balance_mortar_secondary_remote_detonateprimary 0
+set g_balance_mortar_secondary_speed 1400
+set g_balance_mortar_secondary_speed_up 150
+set g_balance_mortar_secondary_speed_z 0
+set g_balance_mortar_secondary_spread 0
+set g_balance_mortar_secondary_type 1
+set g_balance_mortar_switchdelay_drop 0.2
+set g_balance_mortar_switchdelay_raise 0.2
+set g_balance_mortar_weaponreplace ""
+set g_balance_mortar_weaponstart 0
+set g_balance_mortar_weaponstartoverride -1
+set g_balance_mortar_weaponthrowable 1
+// }}}
+// {{{ #5: Mine Layer (MUTATOR WEAPON)
+set g_balance_minelayer_ammo 4
+set g_balance_minelayer_animtime 0.4
+set g_balance_minelayer_damage 40
+set g_balance_minelayer_damageforcescale 0
+set g_balance_minelayer_detonatedelay -1
+set g_balance_minelayer_edgedamage 20
+set g_balance_minelayer_force 250
+set g_balance_minelayer_health 15
+set g_balance_minelayer_lifetime 10
+set g_balance_minelayer_lifetime_countdown 0.5
+set g_balance_minelayer_limit 3
+set g_balance_minelayer_protection 0
+set g_balance_minelayer_proximityradius 150
+set g_balance_minelayer_radius 175
+set g_balance_minelayer_refire 1.5
+set g_balance_minelayer_reload_ammo 0
+set g_balance_minelayer_reload_time 2
+set g_balance_minelayer_remote_damage 45
+set g_balance_minelayer_remote_edgedamage 40
+set g_balance_minelayer_remote_force 300
+set g_balance_minelayer_remote_radius 200
+set g_balance_minelayer_speed 1000
+set g_balance_minelayer_switchdelay_drop 0.2
+set g_balance_minelayer_switchdelay_raise 0.2
+set g_balance_minelayer_time 0.5
+set g_balance_minelayer_weaponreplace ""
+set g_balance_minelayer_weaponstart 0
+set g_balance_minelayer_weaponstartoverride -1
+set g_balance_minelayer_weaponthrowable 1
+// }}}
+// {{{ #6: Electro
+set g_balance_electro_combo_comboradius 300
+set g_balance_electro_combo_comboradius_thruwall 200
+set g_balance_electro_combo_damage 50
+set g_balance_electro_combo_edgedamage 25
+set g_balance_electro_combo_force 120
+set g_balance_electro_combo_radius 150
+set g_balance_electro_combo_safeammocheck 1
+set g_balance_electro_combo_speed 2000
+set g_balance_electro_primary_ammo 4
+set g_balance_electro_primary_animtime 0.3
+set g_balance_electro_primary_comboradius 300
+set g_balance_electro_primary_damage 40
+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.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
+set g_balance_electro_primary_spread 0
+set g_balance_electro_reload_ammo 0
+set g_balance_electro_reload_time 2
+set g_balance_electro_secondary_ammo 2
+set g_balance_electro_secondary_animtime 0.2
+set g_balance_electro_secondary_bouncefactor 0.3
+set g_balance_electro_secondary_bouncestop 0.05
+set g_balance_electro_secondary_count 3
+set g_balance_electro_secondary_damage 30
+set g_balance_electro_secondary_damagedbycontents 1
+set g_balance_electro_secondary_damageforcescale 4
+set g_balance_electro_secondary_edgedamage 15
+set g_balance_electro_secondary_force 50
+set g_balance_electro_secondary_health 5
+set g_balance_electro_secondary_lifetime 4
+set g_balance_electro_secondary_radius 150
+set g_balance_electro_secondary_refire 0.2
+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
+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 ""
+set g_balance_electro_weaponstart 0
+set g_balance_electro_weaponstartoverride -1
+set g_balance_electro_weaponthrowable 1
+// }}}
+// {{{ #7: Crylink
+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 12
+set g_balance_crylink_primary_edgedamage 6
+set g_balance_crylink_primary_force -50
+set g_balance_crylink_primary_joindelay 0.1
+set g_balance_crylink_primary_joinexplode 1
+set g_balance_crylink_primary_joinexplode_damage 0
+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 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
+set g_balance_crylink_primary_other_lifetime 5
+set g_balance_crylink_primary_radius 80
+set g_balance_crylink_primary_refire 0.7
+set g_balance_crylink_primary_shots 6
+set g_balance_crylink_primary_speed 2000
+set g_balance_crylink_primary_spread 0.08
+set g_balance_crylink_reload_ammo 0
+set g_balance_crylink_reload_time 2
+set g_balance_crylink_secondary 1
+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 35
+set g_balance_crylink_secondary_edgedamage 5
+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
+set g_balance_crylink_secondary_joinexplode_edgedamage 0
+set g_balance_crylink_secondary_joinexplode_force 0
+set g_balance_crylink_secondary_joinexplode_radius 0
+set g_balance_crylink_secondary_joinspread 0
+set g_balance_crylink_secondary_linkexplode 1
+set g_balance_crylink_secondary_middle_fadetime 5
+set g_balance_crylink_secondary_middle_lifetime 5
+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 1
+set g_balance_crylink_secondary_speed 3000
+set g_balance_crylink_secondary_spread 0.01
+set g_balance_crylink_secondary_spreadtype 1
+set g_balance_crylink_switchdelay_drop 0.2
+set g_balance_crylink_switchdelay_raise 0.2
+set g_balance_crylink_weaponreplace ""
+set g_balance_crylink_weaponstart 0
+set g_balance_crylink_weaponstartoverride -1
+set g_balance_crylink_weaponthrowable 1
+// }}}
+// {{{ #8: Vortex
+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 40
+set g_balance_vortex_charge_minspeed 400
+set g_balance_vortex_charge_rate 0.6
+set g_balance_vortex_charge_rot_pause 0
+set g_balance_vortex_charge_rot_rate 0
+set g_balance_vortex_charge_shot_multiplier 0
+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 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 400
+set g_balance_vortex_primary_refire 1.5
+set g_balance_vortex_reload_ammo 0
+set g_balance_vortex_reload_time 2
+set g_balance_vortex_secondary 0
+set g_balance_vortex_secondary_ammo 2
+set g_balance_vortex_secondary_animtime 0
+set g_balance_vortex_secondary_chargepool 0
+set g_balance_vortex_secondary_chargepool_pause_regen 1
+set g_balance_vortex_secondary_chargepool_regen 0.15
+set g_balance_vortex_secondary_damage 0
+set g_balance_vortex_secondary_damagefalloff_forcehalflife 0
+set g_balance_vortex_secondary_damagefalloff_halflife 0
+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.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
+set g_balance_vortex_weaponthrowable 1
+// }}}
+// {{{ #9: Hagar
+set g_balance_hagar_primary_ammo 1
+set g_balance_hagar_primary_damage 25
+set g_balance_hagar_primary_damageforcescale 0
+set g_balance_hagar_primary_edgedamage 12.5
+set g_balance_hagar_primary_force 100
+set g_balance_hagar_primary_health 15
+set g_balance_hagar_primary_lifetime 5
+set g_balance_hagar_primary_radius 65
+set g_balance_hagar_primary_refire 0.16667
+set g_balance_hagar_primary_speed 2200
+set g_balance_hagar_primary_spread 0.03
+set g_balance_hagar_reload_ammo 0
+set g_balance_hagar_reload_time 2
+set g_balance_hagar_secondary 1
+set g_balance_hagar_secondary_ammo 1
+set g_balance_hagar_secondary_damage 35
+set g_balance_hagar_secondary_damageforcescale 0
+set g_balance_hagar_secondary_edgedamage 17.5
+set g_balance_hagar_secondary_force 75
+set g_balance_hagar_secondary_health 15
+set g_balance_hagar_secondary_lifetime_min 10
+set g_balance_hagar_secondary_lifetime_rand 0
+set g_balance_hagar_secondary_load 1
+set g_balance_hagar_secondary_load_abort 1
+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 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
+set g_balance_hagar_switchdelay_drop 0.2
+set g_balance_hagar_switchdelay_raise 0.2
+set g_balance_hagar_weaponreplace ""
+set g_balance_hagar_weaponstart 0
+set g_balance_hagar_weaponstartoverride -1
+set g_balance_hagar_weaponthrowable 1
+// }}}
+// {{{ #10: Devastator
+set g_balance_devastator_ammo 4
+set g_balance_devastator_animtime 0.4
+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 400
+set g_balance_devastator_guidedelay 0.2
+set g_balance_devastator_guidegoal 512
+set g_balance_devastator_guiderate 90
+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 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 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 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
+set g_balance_devastator_weaponreplace ""
+set g_balance_devastator_weaponstart 0
+set g_balance_devastator_weaponstartoverride -1
+set g_balance_devastator_weaponthrowable 1
+// }}}
+// {{{ #11: Port-O-Launch
+set g_balance_porto_primary_animtime 0.3
+set g_balance_porto_primary_lifetime 5
+set g_balance_porto_primary_refire 1.5
+set g_balance_porto_primary_speed 1000
+set g_balance_porto_secondary 1
+set g_balance_porto_secondary_animtime 0.3
+set g_balance_porto_secondary_lifetime 5
+set g_balance_porto_secondary_refire 1.5
+set g_balance_porto_secondary_speed 1000
+set g_balance_porto_switchdelay_drop 0.2
+set g_balance_porto_switchdelay_raise 0.2
+set g_balance_porto_weaponreplace ""
+set g_balance_porto_weaponstart 0
+set g_balance_porto_weaponstartoverride -1
+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
+set g_balance_vaporizer_secondary_ammo 0
+set g_balance_vaporizer_secondary_animtime 0.2
+set g_balance_vaporizer_secondary_damage 25
+set g_balance_vaporizer_secondary_delay 0
+set g_balance_vaporizer_secondary_edgedamage 12.5
+set g_balance_vaporizer_secondary_force 400
+set g_balance_vaporizer_secondary_lifetime 5
+set g_balance_vaporizer_secondary_radius 70
+set g_balance_vaporizer_secondary_refire 0.7
+set g_balance_vaporizer_secondary_shotangle 0
+set g_balance_vaporizer_secondary_speed 6000
+set g_balance_vaporizer_secondary_spread 0
+set g_balance_vaporizer_switchdelay_drop 0.2
+set g_balance_vaporizer_switchdelay_raise 0.2
+set g_balance_vaporizer_weaponreplace ""
+set g_balance_vaporizer_weaponstart 0
+set g_balance_vaporizer_weaponstartoverride -1
+set g_balance_vaporizer_weaponthrowable 0
+// }}}
+// {{{ #13: Grappling Hook
+set g_balance_hook_primary_ammo 5
+set g_balance_hook_primary_animtime 0.3
+set g_balance_hook_primary_hooked_ammo 5
+set g_balance_hook_primary_hooked_time_free 2
+set g_balance_hook_primary_hooked_time_max 0
+set g_balance_hook_primary_refire 0.2
+set g_balance_hook_secondary_animtime 0.3
+set g_balance_hook_secondary_damage 25
+set g_balance_hook_secondary_damageforcescale 0
+set g_balance_hook_secondary_duration 1.5
+set g_balance_hook_secondary_edgedamage 5
+set g_balance_hook_secondary_force -2000
+set g_balance_hook_secondary_gravity 5
+set g_balance_hook_secondary_health 15
+set g_balance_hook_secondary_lifetime 5
+set g_balance_hook_secondary_power 3
+set g_balance_hook_secondary_radius 500
+set g_balance_hook_secondary_refire 3
+set g_balance_hook_secondary_speed 0
+set g_balance_hook_switchdelay_drop 0.2
+set g_balance_hook_switchdelay_raise 0.2
+set g_balance_hook_weaponreplace ""
+set g_balance_hook_weaponstart 0
+set g_balance_hook_weaponstartoverride -1
+set g_balance_hook_weaponthrowable 1
+// }}}
+// {{{ #14: Heavy Laser Assault Cannon (MUTATOR WEAPON)
+set g_balance_hlac_primary_ammo 1
+set g_balance_hlac_primary_animtime 0.4
+set g_balance_hlac_primary_damage 18
+set g_balance_hlac_primary_edgedamage 9
+set g_balance_hlac_primary_force 90
+set g_balance_hlac_primary_lifetime 5
+set g_balance_hlac_primary_radius 70
+set g_balance_hlac_primary_refire 0.15
+set g_balance_hlac_primary_speed 9000
+set g_balance_hlac_primary_spread_add 0.0045
+set g_balance_hlac_primary_spread_crouchmod 0.25
+set g_balance_hlac_primary_spread_max 0.25
+set g_balance_hlac_primary_spread_min 0.01
+set g_balance_hlac_reload_ammo 0
+set g_balance_hlac_reload_time 2
+set g_balance_hlac_secondary 1
+set g_balance_hlac_secondary_ammo 10
+set g_balance_hlac_secondary_animtime 0.3
+set g_balance_hlac_secondary_damage 15
+set g_balance_hlac_secondary_edgedamage 7.5
+set g_balance_hlac_secondary_force 90
+set g_balance_hlac_secondary_lifetime 5
+set g_balance_hlac_secondary_radius 70
+set g_balance_hlac_secondary_refire 1
+set g_balance_hlac_secondary_shots 6
+set g_balance_hlac_secondary_speed 9000
+set g_balance_hlac_secondary_spread 0.15
+set g_balance_hlac_secondary_spread_crouchmod 0.5
+set g_balance_hlac_switchdelay_drop 0.2
+set g_balance_hlac_switchdelay_raise 0.2
+set g_balance_hlac_weaponreplace ""
+set g_balance_hlac_weaponstart 0
+set g_balance_hlac_weaponstartoverride -1
+set g_balance_hlac_weaponthrowable 1
+// }}}
+// {{{ #15: @!#%'n Tuba
+set g_balance_tuba_animtime 0.05
+set g_balance_tuba_attenuation 0.5
+set g_balance_tuba_damage 5
+set g_balance_tuba_edgedamage 0
+set g_balance_tuba_fadetime 0.25
+set g_balance_tuba_force 40
+set g_balance_tuba_pitchstep 6
+set g_balance_tuba_radius 200
+set g_balance_tuba_refire 0.05
+set g_balance_tuba_switchdelay_drop 0.2
+set g_balance_tuba_switchdelay_raise 0.2
+set g_balance_tuba_volume 1
+set g_balance_tuba_weaponreplace ""
+set g_balance_tuba_weaponstart 0
+set g_balance_tuba_weaponstartoverride -1
+set g_balance_tuba_weaponthrowable 1
+// }}}
+// {{{ #16: Rifle (MUTATOR WEAPON)
+set g_balance_rifle_bursttime 0
+set g_balance_rifle_primary_ammo 10
+set g_balance_rifle_primary_animtime 0.4
+set g_balance_rifle_primary_bullethail 0
+set g_balance_rifle_primary_burstcost 0
+set g_balance_rifle_primary_damage 80
+set g_balance_rifle_primary_force 100
+set g_balance_rifle_primary_refire 1.2
+set g_balance_rifle_primary_shots 1
+set g_balance_rifle_primary_solidpenetration 62.2
+set g_balance_rifle_primary_spread 0
+set g_balance_rifle_primary_tracer 1
+set g_balance_rifle_reload_ammo 80
+set g_balance_rifle_reload_time 2
+set g_balance_rifle_secondary 1
+set g_balance_rifle_secondary_ammo 10
+set g_balance_rifle_secondary_animtime 0.3
+set g_balance_rifle_secondary_bullethail 0
+set g_balance_rifle_secondary_burstcost 0
+set g_balance_rifle_secondary_damage 20
+set g_balance_rifle_secondary_force 50
+set g_balance_rifle_secondary_refire 0.9
+set g_balance_rifle_secondary_reload 0
+set g_balance_rifle_secondary_shots 4
+set g_balance_rifle_secondary_solidpenetration 15.5
+set g_balance_rifle_secondary_spread 0.04
+set g_balance_rifle_secondary_tracer 0
+set g_balance_rifle_switchdelay_drop 0.2
+set g_balance_rifle_switchdelay_raise 0.2
+set g_balance_rifle_weaponreplace ""
+set g_balance_rifle_weaponstart 0
+set g_balance_rifle_weaponstartoverride -1
+set g_balance_rifle_weaponthrowable 1
+// }}}
+// {{{ #17: Fireball
+set g_balance_fireball_primary_animtime 0.4
+set g_balance_fireball_primary_bfgdamage 100
+set g_balance_fireball_primary_bfgforce 0
+set g_balance_fireball_primary_bfgradius 1000
+set g_balance_fireball_primary_damage 200
+set g_balance_fireball_primary_damageforcescale 0
+set g_balance_fireball_primary_edgedamage 50
+set g_balance_fireball_primary_force 600
+set g_balance_fireball_primary_health 0
+set g_balance_fireball_primary_laserburntime 0.5
+set g_balance_fireball_primary_laserdamage 80
+set g_balance_fireball_primary_laseredgedamage 20
+set g_balance_fireball_primary_laserradius 256
+set g_balance_fireball_primary_lifetime 15
+set g_balance_fireball_primary_radius 200
+set g_balance_fireball_primary_refire 2
+set g_balance_fireball_primary_refire2 0
+set g_balance_fireball_primary_speed 1200
+set g_balance_fireball_primary_spread 0
+set g_balance_fireball_secondary_animtime 0.3
+set g_balance_fireball_secondary_damage 40
+set g_balance_fireball_secondary_damageforcescale 4
+set g_balance_fireball_secondary_damagetime 5
+set g_balance_fireball_secondary_laserburntime 0.5
+set g_balance_fireball_secondary_laserdamage 50
+set g_balance_fireball_secondary_laseredgedamage 20
+set g_balance_fireball_secondary_laserradius 110
+set g_balance_fireball_secondary_lifetime 7
+set g_balance_fireball_secondary_refire 1.5
+set g_balance_fireball_secondary_speed 900
+set g_balance_fireball_secondary_speed_up 100
+set g_balance_fireball_secondary_speed_z 0
+set g_balance_fireball_secondary_spread 0
+set g_balance_fireball_switchdelay_drop 0.2
+set g_balance_fireball_switchdelay_raise 0.2
+set g_balance_fireball_weaponreplace ""
+set g_balance_fireball_weaponstart 0
+set g_balance_fireball_weaponstartoverride -1
+set g_balance_fireball_weaponthrowable 0
+// }}}
+// {{{ #18: T.A.G. Seeker (MUTATOR WEAPON)
+set g_balance_seeker_flac_ammo 1
+set g_balance_seeker_flac_animtime 0.1
+set g_balance_seeker_flac_damage 15
+set g_balance_seeker_flac_edgedamage 10
+set g_balance_seeker_flac_force 50
+set g_balance_seeker_flac_lifetime 0.1
+set g_balance_seeker_flac_lifetime_rand 0.05
+set g_balance_seeker_flac_radius 100
+set g_balance_seeker_flac_refire 0.1
+set g_balance_seeker_flac_speed 3000
+set g_balance_seeker_flac_speed_up 1000
+set g_balance_seeker_flac_speed_z 0
+set g_balance_seeker_flac_spread 0.4
+set g_balance_seeker_missile_accel 1400
+set g_balance_seeker_missile_ammo 2
+set g_balance_seeker_missile_animtime 0.2
+set g_balance_seeker_missile_count 3
+set g_balance_seeker_missile_damage 30
+set g_balance_seeker_missile_damageforcescale 4
+set g_balance_seeker_missile_decel 1400
+set g_balance_seeker_missile_delay 0.25
+set g_balance_seeker_missile_edgedamage 10
+set g_balance_seeker_missile_force 150
+set g_balance_seeker_missile_health 5
+set g_balance_seeker_missile_lifetime 15
+set g_balance_seeker_missile_proxy 0
+set g_balance_seeker_missile_proxy_delay 0.2
+set g_balance_seeker_missile_proxy_maxrange 45
+set g_balance_seeker_missile_radius 80
+set g_balance_seeker_missile_refire 0.5
+set g_balance_seeker_missile_smart 1
+set g_balance_seeker_missile_smart_mindist 800
+set g_balance_seeker_missile_smart_trace_max 2500
+set g_balance_seeker_missile_smart_trace_min 1000
+set g_balance_seeker_missile_speed 700
+set g_balance_seeker_missile_speed_max 1300
+set g_balance_seeker_missile_speed_up 300
+set g_balance_seeker_missile_speed_z 0
+set g_balance_seeker_missile_spread 0
+set g_balance_seeker_missile_turnrate 0.65
+set g_balance_seeker_reload_ammo 0
+set g_balance_seeker_reload_time 2
+set g_balance_seeker_switchdelay_drop 0.2
+set g_balance_seeker_switchdelay_raise 0.2
+set g_balance_seeker_tag_ammo 1
+set g_balance_seeker_tag_animtime 0.2
+set g_balance_seeker_tag_damageforcescale 4
+set g_balance_seeker_tag_health 5
+set g_balance_seeker_tag_lifetime 15
+set g_balance_seeker_tag_refire 0.75
+set g_balance_seeker_tag_speed 5000
+set g_balance_seeker_tag_spread 0
+set g_balance_seeker_tag_tracker_lifetime 10
+set g_balance_seeker_type 0
+set g_balance_seeker_weaponreplace ""
+set g_balance_seeker_weaponstart 0
+set g_balance_seeker_weaponstartoverride -1
+set g_balance_seeker_weaponthrowable 1
+// }}}
+// {{{ #19: Shockwave (MUTATOR WEAPON)
+set g_balance_shockwave_blast_animtime 0.3
+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 15
+set g_balance_shockwave_blast_force_forwardbias 50
+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 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.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
+set g_balance_shockwave_blast_splash_edgedamage 0
+set g_balance_shockwave_blast_splash_force 100
+set g_balance_shockwave_blast_splash_force_forwardbias 50
+set g_balance_shockwave_blast_splash_multiplier_accuracy 0.5
+set g_balance_shockwave_blast_splash_multiplier_distance 0.5
+set g_balance_shockwave_blast_splash_multiplier_min 0
+set g_balance_shockwave_blast_splash_radius 70
+set g_balance_shockwave_blast_spread_max 120
+set g_balance_shockwave_blast_spread_min 25
+set g_balance_shockwave_melee_animtime 1.3
+set g_balance_shockwave_melee_damage 80
+set g_balance_shockwave_melee_delay 0.25
+set g_balance_shockwave_melee_force 200
+set g_balance_shockwave_melee_multihit 1
+set g_balance_shockwave_melee_no_doubleslap 1
+set g_balance_shockwave_melee_nonplayerdamage 40
+set g_balance_shockwave_melee_range 120
+set g_balance_shockwave_melee_refire 1.25
+set g_balance_shockwave_melee_swing_side 120
+set g_balance_shockwave_melee_swing_up 30
+set g_balance_shockwave_melee_time 0.15
+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 1
+set g_balance_shockwave_weaponstartoverride -1
+set g_balance_shockwave_weaponthrowable 0
+// }}}
+// {{{ #20: Arc
+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 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 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 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.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
+set g_balance_arc_burst_healing_hps 100
+set g_balance_arc_switchdelay_drop 0.2
+set g_balance_arc_switchdelay_raise 0.2
+set g_balance_arc_weaponreplace ""
+set g_balance_arc_weaponstart 0
+set g_balance_arc_weaponstartoverride -1
+set g_balance_arc_weaponthrowable 1
+// }}}
+// {{{ #21: Heavy Machine Gun
+set g_balance_hmg_ammo 1
+set g_balance_hmg_damage 10
+set g_balance_hmg_force 5
+set g_balance_hmg_refire 0.05
+set g_balance_hmg_reload_ammo 120
+set g_balance_hmg_reload_time 1
+set g_balance_hmg_solidpenetration 32
+set g_balance_hmg_spread_add 0.01
+set g_balance_hmg_spread_max 0.05
+set g_balance_hmg_spread_min 0.02
+set g_balance_hmg_switchdelay_drop 0.2
+set g_balance_hmg_switchdelay_raise 0.2
+set g_balance_hmg_weaponreplace ""
+set g_balance_hmg_weaponstart 0
+set g_balance_hmg_weaponstartoverride 0
+set g_balance_hmg_weaponthrowable 0
+// }}}
+// {{{ #22: Rocket Propelled Chainsaw
+set g_balance_rpc_ammo 10
+set g_balance_rpc_animtime 1
+set g_balance_rpc_damage 150
+set g_balance_rpc_damage2 500
+set g_balance_rpc_damageforcescale 2
+set g_balance_rpc_edgedamage 50
+set g_balance_rpc_force 400
+set g_balance_rpc_health 25
+set g_balance_rpc_lifetime 30
+set g_balance_rpc_radius 300
+set g_balance_rpc_refire 1
+set g_balance_rpc_reload_ammo 10
+set g_balance_rpc_reload_time 1
+set g_balance_rpc_speed 1250
+set g_balance_rpc_speedaccel 5000
+set g_balance_rpc_switchdelay_drop 0.2
+set g_balance_rpc_switchdelay_raise 0.2
+set g_balance_rpc_weaponreplace ""
+set g_balance_rpc_weaponstart 0
+set g_balance_rpc_weaponstartoverride 0
+set g_balance_rpc_weaponthrowable 0
+// }}}
index 97707a7255789ab49f96602d9b5a5373a8f673d1..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
@@ -720,7 +721,7 @@ set g_balance_shockwave_melee_traces 10
 set g_balance_shockwave_switchdelay_drop 0.15
 set g_balance_shockwave_switchdelay_raise 0.15
 set g_balance_shockwave_weaponreplace ""
-set g_balance_shockwave_weaponstart 1
+set g_balance_shockwave_weaponstart 0
 set g_balance_shockwave_weaponstartoverride -1
 set g_balance_shockwave_weaponthrowable 0
 // }}}
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
diff --git a/balance-mario.cfg b/balance-mario.cfg
new file mode 100644 (file)
index 0000000..022d62e
--- /dev/null
@@ -0,0 +1,235 @@
+g_mod_balance Mario
+
+// {{{ starting gear
+set g_balance_health_start 100
+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
+set g_start_ammo_plasma 0
+set g_start_ammo_fuel 0
+set g_warmup_start_health 100 "starting values when being in warmup-stage"
+set g_warmup_start_armor 100 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_shells 30 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_nails 160 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_rockets 80 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_cells 90 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_plasma 90 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_fuel 0 "starting values when being in warmup-stage"
+set g_lms_start_health 200
+set g_lms_start_armor 200
+set g_lms_start_ammo_shells 60
+set g_lms_start_ammo_nails 320
+set g_lms_start_ammo_rockets 160
+set g_lms_start_ammo_cells 180
+set g_lms_start_ammo_plasma 180
+set g_lms_start_ammo_fuel 0
+set g_balance_nix_roundtime 25
+set g_balance_nix_incrtime 1.6
+set g_balance_nix_ammo_shells 60
+set g_balance_nix_ammo_nails 320
+set g_balance_nix_ammo_rockets 160
+set g_balance_nix_ammo_cells 180
+set g_balance_nix_ammo_plasma 180
+set g_balance_nix_ammo_fuel 100
+set g_balance_nix_ammoincr_shells 2 // eh this will need figured out later I assume
+set g_balance_nix_ammoincr_nails 6
+set g_balance_nix_ammoincr_rockets 2
+set g_balance_nix_ammoincr_cells 2
+set g_balance_nix_ammoincr_plasma 2
+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 15
+set g_pickup_shells_weapon 15
+set g_pickup_shells_max 60
+set g_pickup_nails 80
+set g_pickup_nails_weapon 80
+set g_pickup_nails_max 320
+set g_pickup_rockets 40
+set g_pickup_rockets_weapon 40
+set g_pickup_rockets_max 160
+set g_pickup_cells 30
+set g_pickup_cells_weapon 30
+set g_pickup_cells_max 180
+set g_pickup_plasma 30
+set g_pickup_plasma_weapon 30
+set g_pickup_plasma_max 180
+set g_pickup_fuel 50
+set g_pickup_fuel_weapon 50
+set g_pickup_fuel_jetpack 100
+set g_pickup_fuel_max 100
+set g_pickup_armorsmall 5
+set g_pickup_armorsmall_max 200
+set g_pickup_armorsmall_anyway 1
+set g_pickup_armormedium 25
+set g_pickup_armormedium_max 200
+set g_pickup_armormedium_anyway 1
+set g_pickup_armorbig 50
+set g_pickup_armorbig_max 200
+set g_pickup_armorbig_anyway 1
+set g_pickup_armorlarge 100
+set g_pickup_armorlarge_max 200
+set g_pickup_armorlarge_anyway 1
+set g_pickup_healthsmall 5
+set g_pickup_healthsmall_max 200
+set g_pickup_healthsmall_anyway 1
+set g_pickup_healthmedium 25
+set g_pickup_healthmedium_max 200
+set g_pickup_healthmedium_anyway 1
+set g_pickup_healthlarge 50
+set g_pickup_healthlarge_max 200
+set g_pickup_healthlarge_anyway 1
+set g_pickup_healthmega 100
+set g_pickup_healthmega_max 200
+set g_pickup_healthmega_anyway 1
+set g_pickup_respawntime_short 15
+set g_pickup_respawntime_medium 20
+set g_pickup_respawntime_long 30
+set g_pickup_respawntime_powerup 120
+set g_pickup_respawntime_weapon 10
+set g_pickup_respawntime_superweapon 120
+set g_pickup_respawntime_ammo 10
+set g_pickup_respawntimejitter_short 0
+set g_pickup_respawntimejitter_medium 0
+set g_pickup_respawntimejitter_long 0
+set g_pickup_respawntimejitter_powerup 0
+set g_pickup_respawntimejitter_weapon 0
+set g_pickup_respawntimejitter_superweapon 10
+set g_pickup_respawntimejitter_ammo 0
+// }}}
+
+// {{{ regen/rot
+set g_balance_health_regen 0.08
+set g_balance_health_regenlinear 0.5
+set g_balance_pause_health_regen 5
+set g_balance_pause_health_regen_spawn 0
+set g_balance_health_rot 0.02
+set g_balance_health_rotlinear 1
+set g_balance_pause_health_rot 1
+set g_balance_pause_health_rot_spawn 5
+set g_balance_health_regenstable 100
+set g_balance_health_rotstable 100
+set g_balance_health_limit 999
+set g_balance_armor_regen 0
+set g_balance_armor_regenlinear 0
+set g_balance_armor_rot 0.02
+set g_balance_armor_rotlinear 1
+set g_balance_pause_armor_rot 1
+set g_balance_pause_armor_rot_spawn 5
+set g_balance_armor_regenstable 100
+set g_balance_armor_rotstable 100
+set g_balance_armor_limit 999
+set g_balance_armor_blockpercent 0.7
+set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)"
+set g_balance_fuel_regenlinear 0
+set g_balance_pause_fuel_regen 2 // other than this, fuel uses the health regen counter
+set g_balance_fuel_rot 0.05
+set g_balance_fuel_rotlinear 0
+set g_balance_pause_fuel_rot 5
+set g_balance_pause_fuel_rot_spawn 10
+set g_balance_fuel_regenstable 50
+set g_balance_fuel_rotstable 100
+set g_balance_fuel_limit 999
+// }}}
+
+// {{{ misc
+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"
+set g_weaponforcefactor 1 "weapon force multiplier"
+set g_weaponspreadfactor 1 "weapon spread multiplier"
+set g_balance_firetransfer_time 0.9
+set g_balance_firetransfer_damage 0.8
+set g_throughfloor_damage 0.75
+set g_throughfloor_force 0.75
+set g_projectiles_damage -2
+// possible values:
+// -2: absolutely no damage to projectiles (no exceptions)
+// -1: no damage other than the exceptions (electro combo, hagar join explode, ML mines)
+// 0: only damage from contents (lava/slime) or exceptions
+// 1: only self damage or damage from contents or exceptions
+// 2: allow all damage to projectiles normally
+set g_projectiles_keep_owner 1
+set g_projectiles_newton_style 0
+// possible values:
+// 0: absolute velocity projectiles (like Quake)
+// 1: relative velocity projectiles, "Newtonian" (like Tribes 2)
+// 2: relative velocity projectiles, but aim is precorrected so projectiles hit the crosshair (note: strafe rockets then are SLOWER than ones shot while standing, happens in 1 too when aiming correctly which is hard)
+set g_projectiles_newton_style_2_minfactor 0.8
+set g_projectiles_newton_style_2_maxfactor 1.5
+set g_projectiles_spread_style 7
+// possible values:
+// 0: forward + solid sphere (like Quake) - varies velocity
+// 1: forward + flattened solid sphere
+// 2: forward + solid circle
+// 3: forward + normal distribution 3D - varies velocity
+// 4: forward + normal distribution on a plane
+// 5: forward + circle with 1-r falloff
+// 6: forward + circle with 1-r^2 falloff
+// 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.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
+set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
+set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+set g_balance_contents_playerdamage_lava_burn 0 // extra burning damage after leaving lava
+set g_balance_contents_playerdamage_lava_burn_time 2.5 // time across which the damage is applied (note: not dps!)
+set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
+set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
+set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
+// }}}
+
+// {{{ powerups
+set g_balance_powerup_invincible_takedamage 0.33 // only 1/3rd damage is taken
+set g_balance_powerup_invincible_time 30
+set g_balance_powerup_strength_damage 3
+set g_balance_powerup_strength_force 3
+set g_balance_powerup_strength_time 30
+set g_balance_powerup_strength_selfdamage 1.5
+set g_balance_powerup_strength_selfforce 1.5
+set g_balance_superweapons_time 30
+// }}}
+
+// {{{ jetpack/hook
+set g_jetpack_antigravity 0.8 "factor of gravity compensation of the jetpack"
+set g_jetpack_acceleration_side 1200 "acceleration of the jetpack in xy direction"
+set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (note: you have to factor in gravity here, if antigravity is not 1)"
+set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
+set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
+set g_jetpack_fuel 8 "fuel per second for jetpack"
+set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
+
+set g_grappling_hook_tarzan 2 // 2: can also pull players
+set g_balance_grapplehook_speed_fly 1800
+set g_balance_grapplehook_speed_pull 2000
+set g_balance_grapplehook_force_rubber 2000
+set g_balance_grapplehook_force_rubber_overstretch 1000
+set g_balance_grapplehook_length_min 50
+set g_balance_grapplehook_stretch 50
+set g_balance_grapplehook_airfriction 0.2
+set g_balance_grapplehook_health 50
+set g_balance_grapplehook_damagedbycontents 1
+set g_balance_grapplehook_refire 0.2
+set g_balance_grapplehook_nade_time 0.7
+set g_balance_grapplehook_crouchslide 0
+set g_balance_grapplehook_gravity 0
+set g_balance_grapplehook_pull_frozen 0
+// }}}
+
+// {{{ port-o-launch
+set g_balance_portal_health 200 // these get recharged whenever the portal is used
+set g_balance_portal_lifetime 15 // these get recharged whenever the portal is used
+// }}}
+
+exec bal-wep-mario.cfg
index 3ac47371ee350ab68ce3fe4c5c2c3d2dfe769696..ebce2fabe7978327e5c6388dc4c570a304dec8b5 100644 (file)
@@ -32,7 +32,7 @@ set g_balance_nix_ammo_nails 45
 set g_balance_nix_ammo_rockets 15
 set g_balance_nix_ammo_cells 15
 set g_balance_nix_ammo_plasma 15
-set g_balance_nix_ammo_fuel 0
+set g_balance_nix_ammo_fuel 25
 set g_balance_nix_ammoincr_shells 2 // eh this will need figured out later I assume
 set g_balance_nix_ammoincr_nails 6
 set g_balance_nix_ammoincr_rockets 2
@@ -208,6 +208,7 @@ set g_jetpack_maxspeed_side 1500 "max speed of the jetpack in xy direction"
 set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
 set g_jetpack_fuel 8 "fuel per second for jetpack"
 set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
 
 set g_grappling_hook_tarzan 2 // 2: can also pull players
 set g_balance_grapplehook_speed_fly 1800
index a691a191838bdae351692863f639a759fb1e5059..7571001c67d01b143ab62216856087ff4b304a98 100644 (file)
@@ -32,7 +32,7 @@ set g_balance_nix_ammo_nails 320
 set g_balance_nix_ammo_rockets 160
 set g_balance_nix_ammo_cells 180
 set g_balance_nix_ammo_plasma 180
-set g_balance_nix_ammo_fuel 0
+set g_balance_nix_ammo_fuel 100
 set g_balance_nix_ammoincr_shells 2 // eh this will need figured out later I assume
 set g_balance_nix_ammoincr_nails 6
 set g_balance_nix_ammoincr_rockets 2
@@ -208,6 +208,7 @@ set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
 set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
 set g_jetpack_fuel 8 "fuel per second for jetpack"
 set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
 
 set g_grappling_hook_tarzan 2 // 2: can also pull players
 set g_balance_grapplehook_speed_fly 1800
index 6d7831adac2624bbe88528ddc4388f7059cd18d5..58a0f37584392c4ba613e3fa07b1575938adf645 100644 (file)
@@ -32,7 +32,7 @@ set g_balance_nix_ammo_nails 320
 set g_balance_nix_ammo_rockets 160
 set g_balance_nix_ammo_cells 180
 set g_balance_nix_ammo_plasma 180
-set g_balance_nix_ammo_fuel 0
+set g_balance_nix_ammo_fuel 100
 set g_balance_nix_ammoincr_shells 2 // eh this will need figured out later I assume
 set g_balance_nix_ammoincr_nails 6
 set g_balance_nix_ammoincr_rockets 2
@@ -208,6 +208,7 @@ set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
 set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
 set g_jetpack_fuel 8 "fuel per second for jetpack"
 set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
 
 set g_grappling_hook_tarzan 2 // 2: can also pull players
 set g_balance_grapplehook_speed_fly 1800
index 07b38e830a8f988235a1ba0306db0c488f8c21f3..ff2ec1871639c7c7917496de6f7bfdd0cd0d70b8 100644 (file)
@@ -32,7 +32,7 @@ set g_balance_nix_ammo_nails 320
 set g_balance_nix_ammo_rockets 160
 set g_balance_nix_ammo_cells 180
 set g_balance_nix_ammo_plasma 180
-set g_balance_nix_ammo_fuel 0
+set g_balance_nix_ammo_fuel 100
 set g_balance_nix_ammoincr_shells 2 // eh this will need figured out later I assume
 set g_balance_nix_ammoincr_nails 6
 set g_balance_nix_ammoincr_rockets 2
@@ -208,6 +208,7 @@ set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
 set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
 set g_jetpack_fuel 8 "fuel per second for jetpack"
 set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
 
 set g_grappling_hook_tarzan 2 // 2: can also pull players
 set g_balance_grapplehook_speed_fly 1800
index ddc40e288eda5c3a8aaa18e47b96ac2f9772236b..e9fb9994dd6a317a6b3bc58e081ab3e50af03003 100644 (file)
@@ -32,7 +32,7 @@ set g_balance_nix_ammo_nails 320
 set g_balance_nix_ammo_rockets 160
 set g_balance_nix_ammo_cells 180
 set g_balance_nix_ammo_plasma 180
-set g_balance_nix_ammo_fuel 0
+set g_balance_nix_ammo_fuel 100
 set g_balance_nix_ammoincr_shells 2 // eh this will need figured out later I assume
 set g_balance_nix_ammoincr_nails 6
 set g_balance_nix_ammoincr_rockets 2
@@ -208,6 +208,7 @@ set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
 set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
 set g_jetpack_fuel 8 "fuel per second for jetpack"
 set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
 
 set g_grappling_hook_tarzan 2 // 2: can also pull players
 set g_balance_grapplehook_speed_fly 1800
index e0aa8b08270ddd73312518916661e2db0fb101cb..0c24cf206753edc261a1c16727e9f0165556c1eb 100644 (file)
@@ -32,7 +32,7 @@ set g_balance_nix_ammo_nails 320
 set g_balance_nix_ammo_rockets 160
 set g_balance_nix_ammo_cells 180
 set g_balance_nix_ammo_plasma 180
-set g_balance_nix_ammo_fuel 0
+set g_balance_nix_ammo_fuel 100
 set g_balance_nix_ammoincr_shells 2 // eh this will need figured out later I assume
 set g_balance_nix_ammoincr_nails 6
 set g_balance_nix_ammoincr_rockets 2
@@ -208,6 +208,7 @@ set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
 set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
 set g_jetpack_fuel 8 "fuel per second for jetpack"
 set g_jetpack_attenuation 2 "jetpack sound attenuation"
+set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
 
 set g_grappling_hook_tarzan 2 // 2: can also pull players
 set g_balance_grapplehook_speed_fly 1800
index 361621c6a83b413a270f1458f56a4ab362ffd338..82ea7815e566bcdce4077e4857d513b3934974d5 100644 (file)
@@ -17,7 +17,6 @@ bind LEFTARROW +moveleft
 bind DOWNARROW +back
 bind RIGHTARROW +moveright
 bind SHIFT +crouch
-bind ENTER +jump
 bind SPACE +jump
 
 // weapons
@@ -51,6 +50,7 @@ bind ` toggleconsole
 bind ~ toggleconsole
 bind TAB +showscores
 bind ESCAPE togglemenu
+bind ENTER messagemode
 bind t messagemode
 bind y messagemode2
 bind z messagemode2
index dea35012a76a36546bfb922a8247b4ea67c904e4..11ba8e4ff3428a486bd95b67d71d032b77c63f4f 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"
@@ -774,7 +774,7 @@ seta g_waypointsprite_turrets 1 "disable turret waypoints"
 seta g_waypointsprite_turrets_maxdist 5000 "max distace for turret sprites"
 seta g_waypointsprite_tactical 1 "tactical overlay on turrets when in a vehicle"
 
-seta cl_damagetext "0" "Draw damage dealt where you hit the enemy"
+seta cl_damagetext "1" "Draw damage dealt where you hit the enemy"
 seta cl_damagetext_format "-{total}" "How to format the damage text. {health}, {armor}, {total}"
 seta cl_damagetext_color "1 1 0" "Damage text color"
 seta cl_damagetext_color_per_weapon "0" "Damage text uses weapon color"
@@ -784,6 +784,8 @@ seta cl_damagetext_alpha_lifetime "3" "Damage text lifetime in seconds"
 seta cl_damagetext_velocity "0 0 20" "Damage text move direction"
 seta cl_damagetext_offset "0 -40 0" "Damage text offset"
 seta cl_damagetext_accumulate_range "30" "Damage text spawned within this range is accumulated"
+seta cl_damagetext_friendlyfire "1" "Show damage text for friendlyfire too"
+seta cl_damagetext_friendlyfire_color "1 0 0" "Damage text color for friendlyfire"
 
 set sv_itemstime 1 "enable networking of left time until respawn for items such as mega health and large armor"
 
@@ -936,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
@@ -961,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
@@ -978,6 +978,8 @@ gl_texturecompression_lightcubemaps 1
 gl_texturecompression_q3bsplightmaps 0
 gl_texturecompression_sky 1
 
+cl_maxfps 200
+
 seta menu_mouse_absolute 1 "use the OS mouse pointer motion for menu"
 seta menu_mouse_speed 1 "speed multiplier for the mouse in the menu (does not affect in-game aiming)"
 set menu_use_default_hostname 1
@@ -1005,6 +1007,8 @@ seta menu_cdtrack "rising-of-the-phoenix"
 
 set sv_maxidle 0 "kick players idle for more than this amount of time in seconds"
 set sv_maxidle_spectatorsareidle 0 "when sv_maxidle is not 0, assume spectators are idle too"
+set sv_maxidle_slots 0 "when not 0, only kick idlers when this many or less player slots are available"
+set sv_maxidle_slots_countbots 1 "count bots as player slots"
 
 // these entities are not referenced by anything directly, they just represent
 // teams and are found by find() when needed
@@ -1016,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"
@@ -1193,6 +1197,7 @@ seta cl_forcemyplayermodel "" "set to the model file name you want to show yours
 seta cl_forcemyplayerskin 0 "set to the skin number you want to show yourself as (does not affect how enemies look with cl_forceplayermodels)"
 seta cl_forcemyplayercolors 0 "set to the color value (encoding is same as _cl_color) for your own player model (ignored in teamplay; does not affect how enemies look with cl_forceplayermodels)"
 seta cl_movement_errorcompensation 1 "try to compensate for prediction errors and reduce preceived lag"
+seta cl_movement_intermissionrunning 0 "keep velocity after the match ends, players may appear to continue running while stationary"
 
 // campaign internal, set when loading a campaign map1G
 set _campaign_index ""
@@ -1290,6 +1295,8 @@ r_fakelight 1
 r_water_hideplayer 1 // hide your own feet/player model in refraction views, this way you don't see half of your body under water
 r_water_refractdistort 0.019
 
+set cl_rainsnow_maxdrawdist 2048
+
 // strength sound settings
 set sv_strengthsound_antispam_time 0.1 "minimum distance of strength sounds"
 set sv_strengthsound_antispam_refire_threshold 0.04 "apply minimum distance only if refire of the gun is smaller than this"
diff --git a/gfx/hud/default/flag_stalemate.tga b/gfx/hud/default/flag_stalemate.tga
new file mode 100644 (file)
index 0000000..c52ebb8
Binary files /dev/null and b/gfx/hud/default/flag_stalemate.tga differ
index 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 61384b5fe7d861ad0ce3ea0af0d34546d91f63de..3f1a594d0692979666b44cc660ac2493adf01597 100644 (file)
Binary files a/models/items/a_rockets.md3 and b/models/items/a_rockets.md3 differ
index c953426724ec3ba219dd00b6a5659e5fa837254d..b1463090f7d2d5783b86cf2c9c032b089c5e2f56 100644 (file)
Binary files a/models/weapons/g_fireball.md3 and b/models/weapons/g_fireball.md3 differ
diff --git a/models/weapons/g_ok_hmg_luma.iqm b/models/weapons/g_ok_hmg_luma.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_ok_hmg_luma.iqm differ
diff --git a/models/weapons/g_ok_hmg_luma.iqm_0.skin b/models/weapons/g_ok_hmg_luma.iqm_0.skin
new file mode 100644 (file)
index 0000000..2c77f8e
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_ok_hmg_luma
diff --git a/models/weapons/g_ok_hmg_luma.tga b/models/weapons/g_ok_hmg_luma.tga
new file mode 100644 (file)
index 0000000..5f8e135
Binary files /dev/null and b/models/weapons/g_ok_hmg_luma.tga differ
diff --git a/models/weapons/g_ok_hmg_simple.iqm b/models/weapons/g_ok_hmg_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_ok_hmg_simple.iqm differ
diff --git a/models/weapons/g_ok_hmg_simple.iqm_0.skin b/models/weapons/g_ok_hmg_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..f4316a5
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_ok_hmg_simple
\ No newline at end of file
diff --git a/models/weapons/g_ok_hmg_simple.tga b/models/weapons/g_ok_hmg_simple.tga
new file mode 100644 (file)
index 0000000..c811a59
Binary files /dev/null and b/models/weapons/g_ok_hmg_simple.tga differ
diff --git a/models/weapons/g_ok_rl_luma.iqm b/models/weapons/g_ok_rl_luma.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_ok_rl_luma.iqm differ
diff --git a/models/weapons/g_ok_rl_luma.iqm_0.skin b/models/weapons/g_ok_rl_luma.iqm_0.skin
new file mode 100644 (file)
index 0000000..502ff5b
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_ok_rl_luma
diff --git a/models/weapons/g_ok_rl_luma.tga b/models/weapons/g_ok_rl_luma.tga
new file mode 100644 (file)
index 0000000..b2471c8
Binary files /dev/null and b/models/weapons/g_ok_rl_luma.tga differ
diff --git a/models/weapons/g_ok_rl_simple.iqm b/models/weapons/g_ok_rl_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_ok_rl_simple.iqm differ
diff --git a/models/weapons/g_ok_rl_simple.iqm_0.skin b/models/weapons/g_ok_rl_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..804fe52
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_ok_rl_simple
\ No newline at end of file
diff --git a/models/weapons/g_ok_rl_simple.tga b/models/weapons/g_ok_rl_simple.tga
new file mode 100644 (file)
index 0000000..53f1be5
Binary files /dev/null and b/models/weapons/g_ok_rl_simple.tga differ
index 40a6b06a8341072f8d3a99f40e044535459ff544..3a9db00cedc20461beaf21a73e8527ec8e0b0d43 100644 (file)
Binary files a/models/weapons/h_fireball.iqm and b/models/weapons/h_fireball.iqm differ
index a5e847c37b375d7222611e30f63d6ce38fbfccd3..18fbf7489035b48c291686663142d718c2376058 100644 (file)
Binary files a/models/weapons/v_fireball.md3 and b/models/weapons/v_fireball.md3 differ
index 2ee0a4084e51df9668f970647cf2d1cbe0faa406..2409b83d68e961634a316d738c81beb1b030fcb5 100644 (file)
@@ -420,7 +420,7 @@ seta notification_INFO_WEAPON_TUBA_SUICIDE "1" "0 = off, 1 = print to console, 2
 seta notification_INFO_WEAPON_VAPORIZER_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
 seta notification_INFO_WEAPON_VORTEX_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
 
-// MSG_CENTER notifications (count = 224):
+// MSG_CENTER notifications (count = 225):
 seta notification_CENTER_ALONE "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_ASSAULT_ATTACKING "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_ASSAULT_DEFENDING "1" "0 = off, 1 = centerprint"
@@ -478,6 +478,7 @@ seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE_PINK "1" "0 = off, 1 = centerpr
 seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE_RED "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE_YELLOW "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_CTF_PICKUP_TEAM_YELLOW "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_VISIBLE "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_CTF_PICKUP_YELLOW "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_CTF_RETURN_BLUE "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_CTF_RETURN_PINK "1" "0 = off, 1 = centerprint"
@@ -868,4 +869,4 @@ seta notification_show_sprees_info "3" "Show spree information in MSG_INFO messa
 seta notification_show_sprees_info_newline "1" "Show attacker spree information for MSG_INFO messages on a separate line than the death notification itself"
 seta notification_show_sprees_info_specialonly "1" "Don't show attacker spree information in MSG_INFO messages if it isn't an achievement"
 
-// Notification counts (total = 806): MSG_ANNCE = 89, MSG_INFO = 316, MSG_CENTER = 224, MSG_MULTI = 153, MSG_CHOICE = 24
+// Notification counts (total = 807): MSG_ANNCE = 89, MSG_INFO = 316, MSG_CENTER = 225, MSG_MULTI = 153, MSG_CHOICE = 24
index 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 84bcb2b3d1de61b9417c250c5f28d1ad4ce79270..e62f0704f16119b2236c847d90abeba704347da5 100644 (file)
@@ -47,8 +47,10 @@ string race_penaltyreason; // reason for penalty
 float race_server_record; // server record
 float race_speedaward;
 string race_speedaward_holder;
+string race_speedaward_unit;
 float race_speedaward_alltimebest;
 string race_speedaward_alltimebest_holder;
+string race_speedaward_alltimebest_unit;
 
 // RACE
 float race_mycheckpoint;
index c6cb5257b132fc9787ace53ac97bd9d51c338d90..d575e8cb546eb06ee5ded7a65ef60a864d7db649 100644 (file)
@@ -493,7 +493,7 @@ void Hud_Dynamic_Frame()
 void HUD_Main()
 {
        int i;
-       // global hud theAlpha fade
+       // global hud alpha fade
        if(menu_enabled == 1)
                hud_fade_alpha = 1;
        else
index f45a052aa1859d94ca8e9d5c2658f4f9d5178865..56a79364d49bbef3142efd7021ce3ea634885463 100644 (file)
@@ -671,10 +671,8 @@ float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary)
        }
 
        // allow console bind to work
-       string con_keys;
-       float keys;
-       con_keys = findkeysforcommand("toggleconsole", 0);
-       keys = tokenize(con_keys); // findkeysforcommand returns data for this
+       string con_keys = findkeysforcommand("toggleconsole", 0);
+       int keys = tokenize(con_keys); // findkeysforcommand returns data for this
 
        bool hit_con_bind = false;
        int i;
index afda329838c623f9d1e8b98712de71b82d8f5014..e2e82acffe4efa33ab7275d2bfdb776399da0f70 100644 (file)
@@ -128,7 +128,10 @@ void HUD_CenterPrint ()
        else
        {
                if(!hud_configure_prev)
+               {
                        reset_centerprint_messages();
+                       hud_configure_cp_generation_time = time; // show a message immediately
+               }
                if (time > hud_configure_cp_generation_time)
                {
                        if(highlightedPanel == HUD_PANEL(CENTERPRINT))
@@ -260,12 +263,14 @@ void HUD_CenterPrint ()
                // also fade it based on positioning
                if(autocvar_hud_panel_centerprint_fade_subsequent)
                {
-                       a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passone_minalpha, (1 - (g / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passone))), 1); // pass one: all messages after the first have half theAlpha
-                       a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passtwo_minalpha, (1 - (g / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passtwo))), 1); // pass two: after that, gradually lower theAlpha even more for each message
+                       // pass one: all messages after the first have half alpha
+                       a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passone_minalpha, (1 - (g / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passone))), 1);
+                       // pass two: after that, gradually lower alpha even more for each message
+                       a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passtwo_minalpha, (1 - (g / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passtwo))), 1);
                }
                a *= panel_fg_alpha;
 
-               // finally set the size based on the new theAlpha from subsequent fading
+               // finally set the size based on the new alpha from subsequent fading
                sz = sz * (autocvar_hud_panel_centerprint_fade_subsequent_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_subsequent_minfontsize));
                drawfontscale = hud_scale * sz;
 
index a27e7b9070f109e2786edde44affdf1ff7f9193d..5817142ae609d79ab7359fb5b91a7f4354fa1faa 100644 (file)
@@ -47,7 +47,7 @@ void HUD_Chat()
                        panel.current_panel_bg = strzone(panel_bg);
                        chat_panel_modified = true;
                }
-               panel_bg_alpha = max(0.75, panel_bg_alpha); // force an theAlpha of at least 0.75
+               panel_bg_alpha = max(0.75, panel_bg_alpha);
        }
 
        vector pos, mySize;
@@ -77,7 +77,7 @@ void HUD_Chat()
        {
                vector chatsize;
                chatsize = '1 1 0' * autocvar_con_chatsize;
-               cvar_set("con_chatrect_x", "9001"); // over 9000, we'll fake it instead for more control over theAlpha and such
+               cvar_set("con_chatrect_x", "9001"); // over 9000, we'll fake it instead for more control over alpha and such
                float i, a;
                for(i = 0; i < autocvar_con_chat; ++i)
                {
index a197963e75492145545a315b9de468585059cdce..30b7fa8a7929bf46a9b618e3e7c2b67d918b8aa6 100644 (file)
@@ -83,7 +83,7 @@ void HUD_InfoMessages()
                        if(spectatee_status == -1)
                                s = sprintf(_("^1Use ^3%s^1 or ^3%s^1 to change the speed"), getcommandkey("next weapon", "weapnext"), getcommandkey("previous weapon", "weapprev"));
                        else
-                               s = sprintf(_("^1Press ^3%s^1 to observe"), getcommandkey("secondary fire", "+fire2"));
+                               s = sprintf(_("^1Press ^3%s^1 to observe, ^3%s^1 to change camera mode"), getcommandkey("secondary fire", "+fire2"), getcommandkey("drop weapon", "dropweapon"));
                        drawInfoMessage(s);
 
                        s = sprintf(_("^1Press ^3%s^1 for gamemode info"), getcommandkey("server info", "+show_info"));
index 54c835831dec0b27510d9d41953fd2ac8c265955..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;
@@ -117,10 +118,13 @@ void HUD_Mod_CTF(vector pos, vector mySize)
        int redflag, blueflag, yellowflag, pinkflag, neutralflag; // current status
        float redflag_statuschange_elapsedtime = 0, blueflag_statuschange_elapsedtime = 0, yellowflag_statuschange_elapsedtime = 0, pinkflag_statuschange_elapsedtime = 0, neutralflag_statuschange_elapsedtime = 0; // time since the status changed
        bool ctf_oneflag; // one-flag CTF mode enabled/disabled
+       bool ctf_stalemate; // currently in stalemate
        int stat_items = STAT(CTF_FLAGSTATUS);
        float fs, fs2, fs3, size1, size2;
        vector e1, e2;
 
+       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;
@@ -129,14 +133,16 @@ void HUD_Mod_CTF(vector pos, vector mySize)
 
        ctf_oneflag = (stat_items & CTF_FLAG_NEUTRAL);
 
+       ctf_stalemate = (stat_items & CTF_STALEMATE);
+
        mod_active = (redflag || blueflag || yellowflag || pinkflag || neutralflag || (stat_items & CTF_SHIELDED));
 
        if (autocvar__hud_configure) {
                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?
        }
@@ -198,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;
@@ -264,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 371a9f344bf2990bfda62a2a3730d771f6f4d60b..5fc8c1ca9018cba6b656bf6628d4c59a9edd59bc 100644 (file)
@@ -1,5 +1,6 @@
 #include "physics.qh"
 
+#include <client/main.qh>
 #include <common/mapinfo.qh>
 #include <lib/csqcmodel/cl_player.qh>
 
@@ -43,34 +44,8 @@ void HUD_Physics()
                text_scale = min(autocvar_hud_panel_physics_text_scale, 1);
 
        //compute speed
-       float speed, conversion_factor;
-       string unit;
-
-       switch(autocvar_hud_panel_physics_speed_unit)
-       {
-               default:
-               case 1:
-                       unit = _(" qu/s");
-                       conversion_factor = 1.0;
-                       break;
-               case 2:
-                       unit = _(" m/s");
-                       conversion_factor = 0.0254;
-                       break;
-               case 3:
-                       unit = _(" km/h");
-                       conversion_factor = 0.0254 * 3.6;
-                       break;
-               case 4:
-                       unit = _(" mph");
-                       conversion_factor = 0.0254 * 3.6 * 0.6213711922;
-                       break;
-               case 5:
-                       unit = _(" knots");
-                       conversion_factor = 0.0254 * 1.943844492; // 1 m/s = 1.943844492 knots, because 1 knot = 1.852 km/h
-                       break;
-       }
-
+       float speed, conversion_factor = GetSpeedUnitFactor(autocvar_hud_panel_physics_speed_unit);
+       string unit = GetSpeedUnit(autocvar_hud_panel_physics_speed_unit);
        vector vel = (csqcplayer ? csqcplayer.velocity : pmove_vel);
 
        float max_speed = floor( autocvar_hud_panel_physics_speed_max * conversion_factor + 0.5 );
index 08d97ffd2e5a64027eb730017bce4f2ad9b2d17a..4cb5c9fd4e752fbabea639ce94c0658c854cc061 100644 (file)
@@ -58,6 +58,7 @@ void QuickMenu_Page_ClearEntry(int i)
        if (QuickMenu_Page_Command[i])
                strunzone(QuickMenu_Page_Command[i]);
        QuickMenu_Page_Command[i] = string_null;
+       QuickMenu_Page_Command_Type[i] = 0;
 }
 
 float QuickMenu_Page_Load(string target_submenu, float new_page);
@@ -430,11 +431,8 @@ bool QuickMenu_InputEvent(int bInputType, float nPrimary, float nSecondary)
        }
 
        // allow console bind to work
-       string con_keys;
-       float keys;
-       con_keys = findkeysforcommand("toggleconsole", 0);
-       keys = tokenize(con_keys); // findkeysforcommand returns data for this
-
+       string con_keys = findkeysforcommand("toggleconsole", 0);
+       int keys = tokenize(con_keys); // findkeysforcommand returns data for this
        bool hit_con_bind = false;
        int i;
        for (i = 0; i < keys; ++i)
@@ -660,7 +658,7 @@ void HUD_QuickMenu()
                                else
                                        tokenize_console(substring(QuickMenu_Page_Command[i], 0, end));
 
-                               //if(argv(1) && argv(0) == "toggle") // already checked
+                               if(argv(1) && argv(0) == "toggle")
                                {
                                        // "enable feature xxx" "toggle xxx" (or "toggle xxx 1 0")
                                        // "disable feature xxx" "toggle xxx 0 1"
index 1642e41891a8d75eed766cbe826bad92636feaa7..e935d0cb2b27eba1b395593ca192b412afc13c2e 100644 (file)
@@ -26,6 +26,13 @@ void HUD_Radar_Show_Maximized(bool doshow,float clickable)
                        if(autocvar_hud_cursormode)
                                setcursormode(1);
                        hud_panel_radar_mouse = 1;
+
+                       // we must unset the player's buttons, as they aren't released elsewhere
+                       localcmd("-fire\n");
+                       localcmd("-fire2\n");
+                       localcmd("-use\n");
+                       localcmd("-hook\n");
+                       localcmd("-jump\n");
                }
        }
        else if ( hud_panel_radar_mouse )
@@ -78,11 +85,9 @@ float HUD_Radar_InputEvent(int bInputType, float nPrimary, float nSecondary)
        else
        {
                // allow console/use binds to work without hiding the map
-               string con_keys;
-               float keys;
-               float i;
-               con_keys = strcat(findkeysforcommand("toggleconsole", 0)," ",findkeysforcommand("+use", 0)) ;
-               keys = tokenize(con_keys); // findkeysforcommand returns data for this
+               string con_keys = strcat(findkeysforcommand("toggleconsole", 0), " ", findkeysforcommand("+use", 0)) ;
+               int keys = tokenize(con_keys); // findkeysforcommand returns data for this
+               int i;
                for (i = 0; i < keys; ++i)
                {
                        if(nPrimary == stof(argv(i)))
@@ -346,12 +351,12 @@ 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 )
+               if ( it.health >= 0 )
+               if ( it.team == myteam+1 || gametype == MAPINFO_TYPE_RACE || !(serverflags & SERVERFLAG_TEAMPLAY) )
                {
                        vector coord = teamradar_texcoord_to_2dcoord(teamradar_3dcoord_to_texcoord(it.origin));
                        if(vdist((mousepos - coord), <, 8))
index 89c784a1083be4e0ece863ca00419549520c05de..d7d4d252bec67441f178311e5f593bde24220536 100644 (file)
@@ -7,6 +7,15 @@ void HUD_Vote()
 {
        if(autocvar_cl_allow_uid2name == -1 && (gametype == MAPINFO_TYPE_CTS || gametype == MAPINFO_TYPE_RACE || (serverflags & SERVERFLAG_PLAYERSTATS)))
        {
+               // this dialog gets overriden by the uid2name menu dialog, if it exists
+               // TODO remove this client side uid2name dialog in the next release
+               if(autocvar__menu_alpha)
+                       hud_fade_alpha = 0;
+               else
+                       uid2name_dialog = 0;
+               if (!uid2name_dialog)
+                       localcmd("menu_cmd directmenu Uid2Name\n");
+
                vote_active = 1;
                if (autocvar__hud_configure)
                {
index 984cb4f50519097481f08ee8d701babcf058e160..a30006c26377f7b93f3fdd9d37f35d934cd73221 100644 (file)
@@ -56,6 +56,8 @@ void HUD_Weapons()
        float when = max(1, autocvar_hud_panel_weapons_complainbubble_time);
        float fadetime = max(0, autocvar_hud_panel_weapons_complainbubble_fadetime);
 
+       bool infinite_ammo = (STAT(ITEMS) & IT_UNLIMITED_WEAPON_AMMO);
+
        vector weapon_pos, weapon_size = '0 0 0';
        vector color;
 
@@ -330,7 +332,7 @@ void HUD_Weapons()
        }
 
        // calculate position/size for visual bar displaying ammount of ammo status
-       if (autocvar_hud_panel_weapons_ammo)
+       if (!infinite_ammo && autocvar_hud_panel_weapons_ammo)
        {
                ammo_color = stov(autocvar_hud_panel_weapons_ammo_color);
                ammo_alpha = panel_fg_alpha * autocvar_hud_panel_weapons_ammo_alpha;
@@ -466,7 +468,7 @@ void HUD_Weapons()
                        }
 
                        // draw ammo status bar
-                       if(autocvar_hud_panel_weapons_ammo && (it.ammo_field != ammo_none))
+                       if(!infinite_ammo && autocvar_hud_panel_weapons_ammo && (it.ammo_field != ammo_none))
                        {
                                float ammo_full;
                                a = getstati(GetAmmoStat(it.ammo_field)); // how much ammo do we have?
index 963cc9e418d6b8b153048486c5bc45139a63b981..bd9e82ed21dac1c9af805b844ba63767bd2878cc 100644 (file)
@@ -684,6 +684,8 @@ NET_HANDLE(ENT_CLIENT_SPAWNPOINT, bool is_new)
        spn_origin.y = ReadCoord();
        spn_origin.z = ReadCoord();
 
+       this.team = (teamnum + 1);
+
        //if(is_new)
        //{
                this.origin = spn_origin;
@@ -697,8 +699,9 @@ NET_HANDLE(ENT_CLIENT_SPAWNPOINT, bool is_new)
                        precache_model(this.mdl);
                        setmodel(this, this.mdl);
                        this.drawmask = MASK_NORMAL;
-                       //this.movetype = MOVETYPE_NOCLIP;
+                       //this.move_movetype = MOVETYPE_NOCLIP;
                        //this.draw = Spawn_Draw;
+                       IL_PUSH(g_drawables, this);
                }*/
                if(autocvar_cl_spawn_point_particles)
                {
@@ -716,6 +719,7 @@ NET_HANDLE(ENT_CLIENT_SPAWNPOINT, bool is_new)
                        else { this.cnt = particleeffectnum(EFFECT_SPAWNPOINT_NEUTRAL); }
 
                        this.draw = Spawn_Draw;
+                       if (is_new) IL_PUSH(g_drawables, this);
                        setpredraw(this, Spawn_PreDraw);
                        this.fade_start = autocvar_cl_spawn_point_dist_min;
                        this.fade_end = autocvar_cl_spawn_point_dist_max;
@@ -825,6 +829,7 @@ void CSQC_Ent_Update(entity this, bool isnew)
                if (autocvar_developer_csqcentities)
             LOG_INFOF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)\n", isnew, savetime, this, this.entnum, this.enttype, this.classname, t);
                done = it.m_read(this, NULL, isnew);
+               MUTATOR_CALLHOOK(Ent_Update, this, isnew);
                break;
        });
        time = savetime;
@@ -983,6 +988,42 @@ NET_HANDLE(ENT_CLIENT_INIT, bool isnew)
        if (!postinit) PostInit();
 }
 
+float GetSpeedUnitFactor(int speed_unit)
+{
+       switch(speed_unit)
+       {
+               default:
+               case 1:
+                       return 1.0;
+               case 2:
+                       return 0.0254;
+               case 3:
+                       return 0.0254 * 3.6;
+               case 4:
+                       return 0.0254 * 3.6 * 0.6213711922;
+               case 5:
+                       return 0.0254 * 1.943844492; // 1 m/s = 1.943844492 knots, because 1 knot = 1.852 km/h
+       }
+}
+
+string GetSpeedUnit(int speed_unit)
+{
+       switch(speed_unit)
+       {
+               default:
+               case 1:
+                       return _(" qu/s");
+               case 2:
+                       return _(" m/s");
+               case 3:
+                       return _(" km/h");
+               case 4:
+                       return _(" mph");
+               case 5:
+                       return _(" knots");
+       }
+}
+
 NET_HANDLE(TE_CSQC_RACE, bool isNew)
 {
        int b = ReadByte();
@@ -1071,16 +1112,22 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        race_server_record = ReadInt24_t();
                        break;
                case RACE_NET_SPEED_AWARD:
-                       race_speedaward = ReadInt24_t();
+                       race_speedaward = ReadInt24_t() * GetSpeedUnitFactor(autocvar_hud_panel_physics_speed_unit);
                        if(race_speedaward_holder)
                                strunzone(race_speedaward_holder);
                        race_speedaward_holder = strzone(ReadString());
+                       if(race_speedaward_unit)
+                               strunzone(race_speedaward_unit);
+                       race_speedaward_unit = strzone(GetSpeedUnit(autocvar_hud_panel_physics_speed_unit));
                        break;
                case RACE_NET_SPEED_AWARD_BEST:
-                       race_speedaward_alltimebest = ReadInt24_t();
+                       race_speedaward_alltimebest = ReadInt24_t() * GetSpeedUnitFactor(autocvar_hud_panel_physics_speed_unit);
                        if(race_speedaward_alltimebest_holder)
                                strunzone(race_speedaward_alltimebest_holder);
                        race_speedaward_alltimebest_holder = strzone(ReadString());
+                       if(race_speedaward_alltimebest_unit)
+                               strunzone(race_speedaward_alltimebest_unit);
+                       race_speedaward_alltimebest_unit = strzone(GetSpeedUnit(autocvar_hud_panel_physics_speed_unit));
                        break;
                case RACE_NET_SERVER_RANKINGS:
                        float prevpos, del;
index 8601d26b589338b2dc8b18a342e0a68abc230396..e1cbbe79c39673d2fd36c8d65019f4ec8fe9a7e2 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;
@@ -142,3 +151,6 @@ float hud;
 float view_quality;
 int framecount;
 .float health;
+
+float GetSpeedUnitFactor(int speed_unit);
+string GetSpeedUnit(int speed_unit);
index d3b3e46d73526d230e87fe3da69a82f366833f18..01b0ee3cb440c09d4b00503500f9a2561d697fd7 100644 (file)
@@ -68,11 +68,11 @@ void RemovePlayer(entity player)
 void MoveToLast(entity e)
 {
        AuditLists();
-       other = e.sort_next;
-       while(other)
+       entity ent = e.sort_next;
+       while(ent)
        {
-               SORT_SWAP(other, e);
-               other = e.sort_next;
+               SORT_SWAP(ent, e);
+               ent = e.sort_next;
        }
        AuditLists();
 }
index 9a2e8b1373be23d9d79db6e53fe9326384beb8b3..b72f7abe1a3bdcb8cef50d10333d6f997259299a 100644 (file)
@@ -124,3 +124,21 @@ MUTATOR_HOOKABLE(Weapon_ImpactEffect, EV_Weapon_ImpactEffect);
        /** argc (also, argv() can be used) */ i(int, MUTATOR_ARGV_0_int) \
        /**/
 MUTATOR_HOOKABLE(HUD_Command, EV_HUD_Command);
+
+/** Draw the grapple hook, allows changing hook texture and colour */
+#define EV_DrawGrapplingHook(i, o) \
+       /** hook */                     i(entity, MUTATOR_ARGV_0_entity) \
+       /** texture */                  i(string, MUTATOR_ARGV_1_string) \
+       /***/                                   o(string, MUTATOR_ARGV_1_string) \
+       /** colour */                   i(vector, MUTATOR_ARGV_2_vector) \
+       /***/                                   o(vector, MUTATOR_ARGV_2_vector) \
+       /** team */                     i(float, MUTATOR_ARGV_3_float) \
+       /**/
+MUTATOR_HOOKABLE(DrawGrapplingHook, EV_DrawGrapplingHook);
+
+/** Called when an entity is updated (either by SVQC networking or PVS) */
+#define EV_Ent_Update(i, o) \
+       /** entity id */                i(entity, MUTATOR_ARGV_0_entity) \
+       /** is new to client */ i(bool, MUTATOR_ARGV_1_bool) \
+       /**/
+MUTATOR_HOOKABLE(Ent_Update, EV_Ent_Update);
index c8abdc6f57b6cf7d62f20ae5c6288aae3397549f..85a798f3f427f39e122f7f6187161d4e00d859ec 100644 (file)
@@ -178,7 +178,7 @@ void skeleton_from_frames(entity e, bool is_dead)
 
        if(!is_dead)
        {
-               if(e == csqcplayer)
+               if(e == csqcplayer && !intermission)
                        e.v_angle_x = input_angles_x;
                int i;
                for(i = 0; i < MAX_AIM_BONES; ++i)
index 2fb239ba10e21932239c8463d1d48c7dd6fd00c6..b86e0d8f6ad51a29f0f4159c39ff00f19f52d6e8 100644 (file)
@@ -194,13 +194,14 @@ float HUD_ComparePlayerScores(entity left, entity right)
 
 void HUD_UpdatePlayerPos(entity player)
 {
-       for(other = player.sort_next; other && HUD_ComparePlayerScores(player, other); other = player.sort_next)
+       entity ent;
+       for(ent = player.sort_next; ent && HUD_ComparePlayerScores(player, ent); ent = player.sort_next)
        {
-               SORT_SWAP(player, other);
+               SORT_SWAP(player, ent);
        }
-       for(other = player.sort_prev; other != players && HUD_ComparePlayerScores(other, player); other = player.sort_prev)
+       for(ent = player.sort_prev; ent != players && HUD_ComparePlayerScores(ent, player); ent = player.sort_prev)
        {
-               SORT_SWAP(other, player);
+               SORT_SWAP(ent, player);
        }
 }
 
@@ -236,13 +237,14 @@ float HUD_CompareTeamScores(entity left, entity right)
 
 void HUD_UpdateTeamPos(entity Team)
 {
-       for(other = Team.sort_next; other && HUD_CompareTeamScores(Team, other); other = Team.sort_next)
+       entity ent;
+       for(ent = Team.sort_next; ent && HUD_CompareTeamScores(Team, ent); ent = Team.sort_next)
        {
-               SORT_SWAP(Team, other);
+               SORT_SWAP(Team, ent);
        }
-       for(other = Team.sort_prev; other != teams && HUD_CompareTeamScores(other, Team); other = Team.sort_prev)
+       for(ent = Team.sort_prev; ent != teams && HUD_CompareTeamScores(ent, Team); ent = Team.sort_prev)
        {
-               SORT_SWAP(other, Team);
+               SORT_SWAP(ent, Team);
        }
 }
 
@@ -1370,11 +1372,11 @@ void HUD_DrawScoreboard()
 
        if(gametype == MAPINFO_TYPE_CTS || gametype == MAPINFO_TYPE_RACE) {
                if(race_speedaward) {
-                       drawcolorcodedstring(pos, sprintf(_("Speed award: %d ^7(%s^7)"), race_speedaward, race_speedaward_holder), hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+                       drawcolorcodedstring(pos, sprintf(_("Speed award: %d%s ^7(%s^7)"), race_speedaward, race_speedaward_unit, race_speedaward_holder), hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
                        pos.y += 1.25 * hud_fontsize.y;
                }
                if(race_speedaward_alltimebest) {
-                       drawcolorcodedstring(pos, sprintf(_("All-time fastest: %d ^7(%s^7)"), race_speedaward_alltimebest, race_speedaward_alltimebest_holder), hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+                       drawcolorcodedstring(pos, sprintf(_("All-time fastest: %d%s ^7(%s^7)"), race_speedaward_alltimebest, race_speedaward_alltimebest_unit, race_speedaward_alltimebest_holder), hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
                        pos.y += 1.25 * hud_fontsize.y;
                }
                pos = HUD_DrawScoreboardRankings(pos, playerslots[player_localnum], rgb, bg_size);
index 6700ba61c7b87cadfee0438093ffdf46a2d5ee7e..165b033fb3558c8197e6e758b4dd4b39f3156f4e 100644 (file)
@@ -34,7 +34,7 @@ const float SHOWNAMES_FADESPEED = 4;
 const float SHOWNAMES_FADEDELAY = 0.4;
 void Draw_ShowNames(entity this)
 {
-       if (this.sv_entnum == player_localentnum)  // self or spectatee
+       if (this.sv_entnum == (current_player + 1))  // self or spectatee
                if (!(autocvar_hud_shownames_self && autocvar_chase_active)) return;
        if (!this.sameteam && !autocvar_hud_shownames_enemies) return;
        bool hit;
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 af7eb35b338418556d0ceda77c9690910ff85352..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;
 }
 
@@ -447,7 +448,7 @@ vector GetCurrentFov(float fov)
                        zoomspeed = 3.5;
 
        zoomdir = button_zoom;
-       if(hud == HUD_NORMAL)
+       if(hud == HUD_NORMAL && !spectatee_status)
        if(switchweapon == activeweapon)
        if((activeweapon == WEP_VORTEX && !WEP_CVAR(vortex, secondary)) || (activeweapon == WEP_RIFLE && !WEP_CVAR(rifle, secondary))) // do NOT use switchweapon here
                zoomdir += button_attack2;
@@ -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 6261fa842f987773298274395246d7a32f782739..4015828e555fc6a41db87329254197072e3d9d58 100644 (file)
@@ -16,9 +16,9 @@
 .float scale;
 .vector colormod;
 
-void SUB_Stop(entity this)
+void SUB_Stop(entity this, entity toucher)
 {
-       this.move_velocity = this.move_avelocity = '0 0 0';
+       this.velocity = this.avelocity = '0 0 0';
        this.move_movetype = MOVETYPE_NONE;
 }
 
@@ -58,11 +58,11 @@ void Projectile_Draw(entity this)
        float t;
        float a;
 
-       f = this.move_flags;
+       f = this.flags;
 
        if (this.count & 0x80)
        {
-               // this.move_flags &= ~FL_ONGROUND;
+               // UNSET_ONGROUND(this);
                if (this.move_movetype == MOVETYPE_NONE || this.move_movetype == MOVETYPE_FLY)
                        Movetype_Physics_NoMatchServer(this);
                // the trivial movetypes do not have to match the
@@ -72,9 +72,9 @@ void Projectile_Draw(entity this)
                // moving, we might still be ticrate dependent.
                else
                        Movetype_Physics_MatchServer(this, autocvar_cl_projectiles_sloppy);
-               if (!(this.move_flags & FL_ONGROUND))
+               if (!IS_ONGROUND(this))
                        if (this.velocity != '0 0 0')
-                               this.move_angles = this.angles = vectoangles(this.velocity);
+                               this.angles = vectoangles(this.velocity);
        }
        else
        {
@@ -209,9 +209,9 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
        // projectiles no longer being able to lie on a bmodel
        this.move_nomonsters = MOVE_WORLDONLY;
        if (f & 0x40)
-               this.move_flags |= FL_ONGROUND;
+               SET_ONGROUND(this);
        else
-               this.move_flags &= ~FL_ONGROUND;
+               UNSET_ONGROUND(this);
 
        if (!this.move_time)
        {
@@ -243,8 +243,6 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
                                this.gravity = ReadCoord();
                        else
                                this.gravity = 0;  // none
-                       this.move_origin = this.origin;
-                       this.move_velocity = this.velocity;
                }
 
                if (time == this.spawntime || (this.count & 0x80) || (f & 0x08))
@@ -340,12 +338,12 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
                        case PROJECTILE_ELECTRO:
                                // only new engines support sound moving with object
                                loopsound(this, CH_SHOTS_SINGLE, SND(ELECTRO_FLY), VOL_BASE, ATTEN_NORM);
-                               this.mins = '0 0 -4';
-                               this.maxs = '0 0 -4';
+                               this.mins = '-4 -4 -4';
+                               this.maxs = '4 4 4';
                                this.move_movetype = MOVETYPE_BOUNCE;
                                settouch(this, func_null);
-                               this.move_bounce_factor = WEP_CVAR_SEC(electro, bouncefactor);
-                               this.move_bounce_stopspeed = WEP_CVAR_SEC(electro, bouncestop);
+                               this.bouncefactor = WEP_CVAR_SEC(electro, bouncefactor);
+                               this.bouncestop = WEP_CVAR_SEC(electro, bouncestop);
                                break;
                        case PROJECTILE_RPC:
                        case PROJECTILE_ROCKET:
@@ -362,8 +360,8 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
                                this.maxs = '3 3 3';
                                this.move_movetype = MOVETYPE_BOUNCE;
                                settouch(this, func_null);
-                               this.move_bounce_factor = WEP_CVAR(mortar, bouncefactor);
-                               this.move_bounce_stopspeed = WEP_CVAR(mortar, bouncestop);
+                               this.bouncefactor = WEP_CVAR(mortar, bouncefactor);
+                               this.bouncestop = WEP_CVAR(mortar, bouncestop);
                                break;
                        case PROJECTILE_SHAMBLER_LIGHTNING:
                                this.mins = '-8 -8 -8';
@@ -443,9 +441,9 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
                            this.mins = '0 0 -4';
                            this.maxs = '0 0 -4';
                            this.move_movetype = MOVETYPE_BOUNCE;
-                           this.move_touch = func_null;
-                           this.move_bounce_factor = WEP_CVAR_SEC(electro, bouncefactor);
-                           this.move_bounce_stopspeed = WEP_CVAR_SEC(electro, bouncestop);
+                           settouch(this, func_null);
+                           this.bouncefactor = WEP_CVAR_SEC(electro, bouncefactor);
+                           this.bouncestop = WEP_CVAR_SEC(electro, bouncestop);
                            break;
                        */
                        default:
@@ -479,6 +477,7 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
 
        this.classname = "csqcprojectile";
        this.draw = Projectile_Draw;
+       if (isnew) IL_PUSH(g_drawables, this);
        this.entremove = Ent_RemoveProjectile;
 }
 
index 66e1be4707629bffeee90a18f694373958a4a2b1..27bca00c80008daa7a9c943af478aa49245a2576 100644 (file)
@@ -16,7 +16,7 @@ class(Projectile).float gravity;
 class(Projectile).int snd_looping;
 class(Projectile).bool silent;
 
-void SUB_Stop(entity this);
+void SUB_Stop(entity this, entity toucher);
 
 void Projectile_ResetTrail(entity this, vector to);
 
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 e69a03f729cf534468c8559314a0ba1e714b3e7b..b6f378d47221e8892c85503685ab7b539c0f61a6 100644 (file)
@@ -91,4 +91,6 @@ void Send_Effect_(string eff_name, vector eff_loc, vector eff_vel, int eff_cnt)
 }
 #endif
 
-#include "effectinfo.qc"
+#ifdef EFFECTINFO
+       #include "effectinfo.qc"
+#endif
index 605d42e671a86dd7cf55b020d720fb1d83ac64ac..a4ade38366e709e8a14e90d086fb60258c4ceeca 100644 (file)
@@ -49,11 +49,11 @@ void Casing_Delete(entity this)
 
 void Casing_Draw(entity this)
 {
-    if (this.move_flags & FL_ONGROUND)
+    if (IS_ONGROUND(this))
     {
-        this.move_angles_x = 0;
-        this.move_angles_z = 0;
-        UNSET_ONGROUND(this);
+        this.angles_x = 0;
+        this.angles_z = 0;
+        //UNSET_ONGROUND(this);
     }
 
     Movetype_Physics_MatchTicrate(this, autocvar_cl_casings_ticrate, autocvar_cl_casings_sloppy);
@@ -83,7 +83,7 @@ Sound SND_CASINGS_RANDOM() {
     return Sounds_from(SND_CASINGS1.m_id + floor(prandom() * 3));
 }
 
-void Casing_Touch(entity this)
+void Casing_Touch(entity this, entity toucher)
 {
     if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
     {
@@ -121,8 +121,8 @@ void Casing_Damage(entity this, float thisdmg, int hittype, vector org, vector t
 {
     if (thisforce.z < 0)
         thisforce.z = 0;
-    this.move_velocity = this.move_velocity + thisforce + '0 0 100';
-    this.move_flags &= ~FL_ONGROUND;
+    this.velocity = this.velocity + thisforce + '0 0 100';
+    UNSET_ONGROUND(this);
 }
 
 NET_HANDLE(casings, bool isNew)
@@ -151,10 +151,9 @@ NET_HANDLE(casings, bool isNew)
     casing.drawmask = MASK_NORMAL;
 
     casing.draw = Casing_Draw;
-    casing.move_origin = casing.origin;
-    casing.move_velocity = casing.velocity + 2 * prandomvec();
-    casing.move_angles = casing.angles;
-    casing.move_avelocity = '0 250 0' + 100 * prandomvec();
+    if (isNew) IL_PUSH(g_drawables, casing);
+    casing.velocity = casing.velocity + 2 * prandomvec();
+    casing.avelocity = '0 250 0' + 100 * prandomvec();
     casing.move_movetype = MOVETYPE_BOUNCE;
     settouch(casing, Casing_Touch);
     casing.move_time = time;
index c1144d2616c9b58991d5d6e5d5c1af89b340314e..b53b605058a1fc340322ca225dcd33b500a044bc 100644 (file)
@@ -255,8 +255,8 @@ NET_HANDLE(ENT_CLIENT_DAMAGEINFO, bool isNew)
                if(it.damageforcescale)
                        if(vdist(thisforce, !=, 0))
                        {
-                               it.move_velocity = it.move_velocity + damage_explosion_calcpush(it.damageforcescale * thisforce, it.move_velocity, autocvar_g_balance_damagepush_speedfactor);
-                               it.move_flags &= ~FL_ONGROUND;
+                               it.velocity = it.velocity + damage_explosion_calcpush(it.damageforcescale * thisforce, it.velocity, autocvar_g_balance_damagepush_speedfactor);
+                               UNSET_ONGROUND(it);
                        }
 
                if(w_issilent)
index bc82b50d0c8e955355afaf0ed491ea0cca7e73c0..78f1a27cc6c0a0eba824fa7899e1a099d117b3e3 100644 (file)
@@ -111,13 +111,13 @@ void new_te_bloodshower (int ef, vector org, float explosionspeed, int howmany)
                __pointparticles(ef, org, randomvec() * explosionspeed, howmany / 50);
 }
 
-void SUB_RemoveOnNoImpact(entity this)
+void SUB_RemoveOnNoImpact(entity this, entity toucher)
 {
        if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
                Gib_Delete(this);
 }
 
-void Gib_Touch(entity this)
+void Gib_Touch(entity this, entity toucher)
 {
        // TODO maybe bounce of walls, make more gibs, etc.
 
@@ -180,6 +180,7 @@ void TossGib (string mdlname, vector safeorg, vector org, vector vconst, vector
        setsize (gib, '-8 -8 -8', '8 8 8');
 
        gib.draw = Gib_Draw;
+       IL_PUSH(g_drawables, gib);
        if(destroyontouch)
                settouch(gib, Gib_Touch);
        else
@@ -192,10 +193,9 @@ void TossGib (string mdlname, vector safeorg, vector org, vector vconst, vector
                org = trace_endpos;
        }
 
-       gib.move_origin = org;
        setorigin(gib, org);
-       gib.move_velocity = vconst * autocvar_cl_gibs_velocity_scale + vrand * autocvar_cl_gibs_velocity_random + '0 0 1' * autocvar_cl_gibs_velocity_up;
-       gib.move_avelocity = prandomvec() * vlen(gib.move_velocity) * autocvar_cl_gibs_avelocity_scale;
+       gib.velocity = vconst * autocvar_cl_gibs_velocity_scale + vrand * autocvar_cl_gibs_velocity_random + '0 0 1' * autocvar_cl_gibs_velocity_up;
+       gib.avelocity = prandomvec() * vlen(gib.velocity) * autocvar_cl_gibs_avelocity_scale;
        gib.move_time = time;
        gib.damageforcescale = autocvar_cl_gibs_damageforcescale;
 
index a2653238e7ebea30ad5a22f26203adf9156c66e1..8c1ed1ca8305759ef85ee3a7cb691975c51ca7f7 100644 (file)
 
        #ifdef SVQC
 
-               void _GlobalSound(entity this, entity gs, entity ps, string sample, int chan, int voicetype, bool fake)
+               void _GlobalSound(entity this, entity gs, entity ps, string sample, int chan, float vol, int voicetype, bool fake)
                {
                        if (gs == NULL && ps == NULL && sample == "") return;
                        if(this.classname == "body") return;
                                                if (IS_REAL_CLIENT(msg_entity))
                                                {
                                                        float atten = (msg_entity.cvar_cl_voice_directional == 1) ? ATTEN_MIN : ATTEN_NONE;
-                                                       if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASEVOICE, atten);
-                                                       else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASEVOICE, atten);
-                                                       else soundto(MSG_ONE, this, chan, sample, VOL_BASEVOICE, atten);
+                                                       if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, atten);
+                                                       else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, atten);
+                                                       else soundto(MSG_ONE, this, chan, sample, vol, atten);
                                                }
                                        }
                                        if (voicetype == VOICETYPE_LASTATTACKER_ONLY) break;
                                                MACRO_BEGIN \
                                                { \
                                                        float atten = (msg_entity.cvar_cl_voice_directional == 1) ? ATTEN_MIN : ATTEN_NONE; \
-                                                       if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASEVOICE, atten); \
-                                                       else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASEVOICE, atten); \
-                                                       else soundto(MSG_ONE, this, chan, sample, VOL_BASEVOICE, atten); \
+                                                       if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, atten); \
+                                                       else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, atten); \
+                                                       else soundto(MSG_ONE, this, chan, sample, vol, atten); \
                                                } MACRO_END
 
                                        if (fake) { msg_entity = this; X(); }
                                        else
                                        {
-                                               FOREACH_CLIENT(IS_REAL_CLIENT(it) && (!teamplay || msg_entity.team == this.team), {
+                                               FOREACH_CLIENT(IS_REAL_CLIENT(it) && SAME_TEAM(it, this), {
                                                        msg_entity = it;
                                                        X();
                                                });
                                                                    ? bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, \
                                                                        ATTEN_MAX) \
                                                                        : ATTEN_NONE; \
-                                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASEVOICE, atten); \
-                                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASEVOICE, atten); \
-                                                               else soundto(MSG_ONE, this, chan, sample, VOL_BASEVOICE, atten); \
+                                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, atten); \
+                                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, atten); \
+                                                               else soundto(MSG_ONE, this, chan, sample, vol, atten); \
                                                        } \
                                                } MACRO_END
                                        if (fake)
                                        msg_entity = this;
                                        if (fake)
                                        {
-                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, VOL_BASE, ATTEN_NORM);
-                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, VOL_BASE, ATTEN_NORM);
-                                               else soundto(MSG_ONE, this, chan, sample, VOL_BASE, ATTEN_NORM);
+                                               if (gs) globalsound(MSG_ONE, this, gs, r, chan, vol, ATTEN_NORM);
+                                               else if (ps) playersound(MSG_ONE, this, ps, r, chan, vol, ATTEN_NORM);
+                                               else soundto(MSG_ONE, this, chan, sample, vol, ATTEN_NORM);
                                        }
                                        else
                                        {
-                                               if (gs) globalsound(MSG_ALL, this, gs, r, chan, VOL_BASE, ATTEN_NORM);
-                                               else if (ps) playersound(MSG_ALL, this, ps, r, chan, VOL_BASE, ATTEN_NORM);
-                                               else _sound(this, chan, sample, VOL_BASE, ATTEN_NORM);
+                                               if (gs) globalsound(MSG_ALL, this, gs, r, chan, vol, ATTEN_NORM);
+                                               else if (ps) playersound(MSG_ALL, this, ps, r, chan, vol, ATTEN_NORM);
+                                               else _sound(this, chan, sample, vol, ATTEN_NORM);
                                        }
                                        break;
                                }
index 44925cd510cf81c71fe4018b792de9a2f46bda22..640d330f1c0cc139d46266e77b05115507c7cc9d 100644 (file)
@@ -122,10 +122,10 @@ entity GetVoiceMessage(string type);
 
 #ifdef SVQC
 
-       void _GlobalSound(entity this, entity gs, entity ps, string sample, float chan, float voicetype, bool fake);
-       #define GlobalSound(this, def, chan, voicetype) _GlobalSound(this, def, NULL, string_null, chan, voicetype, false)
-       #define GlobalSound_string(this, def, chan, voicetype) _GlobalSound(this, NULL, NULL, def, chan, voicetype, false)
-       #define PlayerSound(this, def, chan, voicetype) _GlobalSound(this, NULL, def, string_null, chan, voicetype, false)
+       void _GlobalSound(entity this, entity gs, entity ps, string sample, float chan, float vol, float voicetype, bool fake);
+       #define GlobalSound(this, def, chan, vol, voicetype) _GlobalSound(this, def, NULL, string_null, chan, vol, voicetype, false)
+       #define GlobalSound_string(this, def, chan, vol, voicetype) _GlobalSound(this, NULL, NULL, def, chan, vol, voicetype, false)
+       #define PlayerSound(this, def, chan, vol, voicetype) _GlobalSound(this, NULL, def, string_null, chan, vol, voicetype, false)
        #define VoiceMessage(this, def, msg) \
                MACRO_BEGIN \
                { \
@@ -137,7 +137,7 @@ entity GetVoiceMessage(string type);
                        if (IS_SPEC(this) || IS_OBSERVER(this) || flood < 0) fake = true; \
                        else if (flood > 0) fake = false; \
                        else break; \
-                       _GlobalSound(this, NULL, VM, string_null, CH_VOICE, voicetype, fake); \
+                       _GlobalSound(this, NULL, VM, string_null, CH_VOICE, VOL_BASEVOICE, voicetype, fake); \
                } MACRO_END
 
 #endif
index f577762906b6737427a9f0edd2289123f78729ac..28b8bb496bc6438f81367081ec6f28e54be9cc9b 100644 (file)
@@ -156,6 +156,7 @@ NET_HANDLE(ENT_CLIENT_MODELEFFECT, bool isnew)
        e.cnt = ReadByte() / 255.0; // actually alpha
 
        e.draw = ModelEffect_Draw;
+       if (isnew) IL_PUSH(g_drawables, e);
 
        if (!isnew) remove(e); // yes, this IS stupid, but I don't need to duplicate all the read* stuff then
        return true;
index 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 cafef4868b540cd274de8d2f253fd113a6d43623..e69998563d281f1f49f344bd361e7b6e146c2c95 100644 (file)
@@ -61,8 +61,9 @@
                sf |= this.m_forceupdate;
                this.m_forceupdate = 0;
                bool valid =
-                   IS_PLAYER(player)             // player must be active
-                   || player == to               // player is self
+                       time > game_starttime
+                   && (IS_PLAYER(player)          // player must be active
+                   || player == to)               // player is self
                ;
                if (!valid) sf = 0;
                if (chan == MSG_ENTITY)
index 46b4e034558b69f45e150d03a8cbf732155dd197..35fe31c2bd6ea49295a0697d68cf0e7d55c85cc0 100644 (file)
@@ -52,8 +52,8 @@ float autocvar_g_balance_nexball_secondary_lifetime;
 float autocvar_g_balance_nexball_secondary_refire;
 float autocvar_g_balance_nexball_secondary_speed;
 
-void basketball_touch(entity this);
-void football_touch(entity this);
+void basketball_touch(entity this, entity toucher);
+void football_touch(entity this, entity toucher);
 void ResetBall(entity this);
 const int NBM_NONE = 0;
 const int NBM_FOOTBALL = 2;
@@ -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,15 +283,15 @@ 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;
        }
 }
 
-void football_touch(entity this)
+void football_touch(entity this, entity toucher)
 {
-       if(other.solid == SOLID_BSP)
+       if(toucher.solid == SOLID_BSP)
        {
                if(time > this.lastground + 0.1)
                {
@@ -302,54 +302,54 @@ void football_touch(entity this)
                        this.nextthink = time + autocvar_g_nexball_delay_idle;
                return;
        }
-       if (!IS_PLAYER(other))
+       if (!IS_PLAYER(toucher))
                return;
-       if(other.health < 1)
+       if(toucher.health < 1)
                return;
        if(!this.cnt)
                this.nextthink = time + autocvar_g_nexball_delay_idle;
 
-       this.pusher = other;
-       this.team = other.team;
+       this.pusher = toucher;
+       this.team = toucher.team;
 
        if(autocvar_g_nexball_football_physics == -1)   // MrBougo try 1, before decompiling Rev's original
        {
-               if(other.velocity)
-                       this.velocity = other.velocity * 1.5 + '0 0 1' * autocvar_g_nexball_football_boost_up;
+               if(toucher.velocity)
+                       this.velocity = toucher.velocity * 1.5 + '0 0 1' * autocvar_g_nexball_football_boost_up;
        }
        else if(autocvar_g_nexball_football_physics == 1)         // MrBougo's modded Rev style: partially independant of the height of the aiming point
        {
-               makevectors(other.v_angle);
-               this.velocity = other.velocity + v_forward * autocvar_g_nexball_football_boost_forward + '0 0 1' * autocvar_g_nexball_football_boost_up;
+               makevectors(toucher.v_angle);
+               this.velocity = toucher.velocity + v_forward * autocvar_g_nexball_football_boost_forward + '0 0 1' * autocvar_g_nexball_football_boost_up;
        }
        else if(autocvar_g_nexball_football_physics == 2)         // 2nd mod try: totally independant. Really playable!
        {
-               makevectors(other.v_angle.y * '0 1 0');
-               this.velocity = other.velocity + v_forward * autocvar_g_nexball_football_boost_forward + v_up * autocvar_g_nexball_football_boost_up;
+               makevectors(toucher.v_angle.y * '0 1 0');
+               this.velocity = toucher.velocity + v_forward * autocvar_g_nexball_football_boost_forward + v_up * autocvar_g_nexball_football_boost_up;
        }
        else     // Revenant's original style (from the original mod's disassembly, acknowledged by Revenant)
        {
-               makevectors(other.v_angle);
-               this.velocity = other.velocity + v_forward * autocvar_g_nexball_football_boost_forward + v_up * autocvar_g_nexball_football_boost_up;
+               makevectors(toucher.v_angle);
+               this.velocity = toucher.velocity + v_forward * autocvar_g_nexball_football_boost_forward + v_up * autocvar_g_nexball_football_boost_up;
        }
        this.avelocity = -250 * v_forward;  // maybe there is a way to make it look better?
 }
 
-void basketball_touch(entity this)
+void basketball_touch(entity this, entity toucher)
 {
-       if(other.ballcarried)
+       if(toucher.ballcarried)
        {
-               football_touch(this);
+               football_touch(this, toucher);
                return;
        }
-       if(!this.cnt && IS_PLAYER(other) && !STAT(FROZEN, other) && !IS_DEAD(other) && (other != this.nb_dropper || time > this.nb_droptime + autocvar_g_nexball_delay_collect))
+       if(!this.cnt && IS_PLAYER(toucher) && !STAT(FROZEN, toucher) && !IS_DEAD(toucher) && (toucher != this.nb_dropper || time > this.nb_droptime + autocvar_g_nexball_delay_collect))
        {
-               if(other.health <= 0)
+               if(toucher.health <= 0)
                        return;
-               LogNB("caught", other);
-               GiveBall(other, this);
+               LogNB("caught", toucher);
+               GiveBall(toucher, this);
        }
-       else if(other.solid == SOLID_BSP)
+       else if(toucher.solid == SOLID_BSP)
        {
                _sound(this, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
                if(this.velocity && !this.cnt)
@@ -357,26 +357,26 @@ void basketball_touch(entity this)
        }
 }
 
-void GoalTouch(entity this)
+void GoalTouch(entity this, entity toucher)
 {
        entity ball;
        float isclient, pscore, otherteam;
        string pname;
 
        if(gameover) return;
-       if((this.spawnflags & GOAL_TOUCHPLAYER) && other.ballcarried)
-               ball = other.ballcarried;
+       if((this.spawnflags & GOAL_TOUCHPLAYER) && toucher.ballcarried)
+               ball = toucher.ballcarried;
        else
-               ball = other;
+               ball = toucher;
        if(ball.classname != "nexball_basketball")
                if(ball.classname != "nexball_football")
                        return;
        if((!ball.pusher && this.team != GOAL_OUT) || ball.cnt)
                return;
-       EXACTTRIGGER_TOUCH;
+       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)
        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)
 
        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);
@@ -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;
                }
@@ -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 = "";
@@ -609,11 +613,10 @@ spawnfunc(nexball_football)
        SpawnBall(this);
 }
 
-float nb_Goal_Customize(entity this)
+bool nb_Goal_Customize(entity this, entity client)
 {
-       entity e, wp_owner;
-       e = WaypointSprite_getviewentity(other);
-       wp_owner = this.owner;
+       entity e = WaypointSprite_getviewentity(client);
+       entity wp_owner = this.owner;
        if(SAME_TEAM(e, wp_owner)) { return false; }
 
        return true;
@@ -730,32 +733,32 @@ void W_Nexball_Think(entity this)
        this.nextthink = time;
 }
 
-void W_Nexball_Touch(entity this)
+void W_Nexball_Touch(entity this, entity toucher)
 {
        entity ball, attacker;
        attacker = this.owner;
        //this.think = func_null;
        //this.enemy = NULL;
 
-       PROJECTILE_TOUCH(this);
-       if(attacker.team != other.team || autocvar_g_nexball_basketball_teamsteal)
-               if((ball = other.ballcarried) && !STAT(FROZEN, other) && !IS_DEAD(other) && (IS_PLAYER(attacker)))
+       PROJECTILE_TOUCH(this, toucher);
+       if(attacker.team != toucher.team || autocvar_g_nexball_basketball_teamsteal)
+               if((ball = toucher.ballcarried) && !STAT(FROZEN, toucher) && !IS_DEAD(toucher) && (IS_PLAYER(attacker)))
                {
-                       other.velocity = other.velocity + normalize(this.velocity) * other.damageforcescale * autocvar_g_balance_nexball_secondary_force;
-                       UNSET_ONGROUND(other);
+                       toucher.velocity = toucher.velocity + normalize(this.velocity) * toucher.damageforcescale * autocvar_g_balance_nexball_secondary_force;
+                       UNSET_ONGROUND(toucher);
                        if(!attacker.ballcarried)
                        {
                                LogNB("stole", attacker);
-                               _sound(other, CH_TRIGGER, ball.noise2, VOL_BASE, ATTEN_NORM);
+                               _sound(toucher, CH_TRIGGER, ball.noise2, VOL_BASE, ATTEN_NORM);
 
-                               if(SAME_TEAM(attacker, other) && time > attacker.teamkill_complain)
+                               if(SAME_TEAM(attacker, toucher) && time > attacker.teamkill_complain)
                                {
                                        attacker.teamkill_complain = time + 5;
                                        attacker.teamkill_soundtime = time + 0.4;
-                                       attacker.teamkill_soundsource = other;
+                                       attacker.teamkill_soundsource = toucher;
                                }
 
-                               GiveBall(attacker, other.ballcarried);
+                               GiveBall(attacker, toucher.ballcarried);
                        }
                }
        remove(this);
@@ -819,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
@@ -838,7 +841,7 @@ void W_Nexball_Attack2(entity actor)
        CSQCProjectile(missile, true, PROJECTILE_ELECTRO, true);
 }
 
-float ball_customize(entity this)
+bool ball_customize(entity this, entity client)
 {
        if(!this.owner)
        {
@@ -848,7 +851,7 @@ float ball_customize(entity this)
                return true;
        }
 
-       if(other == this.owner)
+       if(client == this.owner)
        {
                this.scale = autocvar_g_nexball_viewmodel_scale;
                if(this.enemy)
@@ -1073,6 +1076,17 @@ MUTATOR_HOOKFUNCTION(nb, FilterItem)
        return false;
 }
 
+MUTATOR_HOOKFUNCTION(nb, ItemTouch)
+{
+       entity item = M_ARGV(0, entity);
+       entity toucher = M_ARGV(1, entity);
+
+       if(item.weapon && toucher.ballcarried)
+               return MUT_ITEMTOUCH_RETURN; // no new weapons for you, mister!
+
+       return MUT_ITEMTOUCH_CONTINUE;
+}
+
 MUTATOR_HOOKFUNCTION(nb, GetTeamCount)
 {
        M_ARGV(1, string) = "nexball_team";
index 8389b22dae1ee0945aceb633a91592dadaeb8917..013479242bb1b0a5a69857f635ed8b324b09f83f 100644 (file)
@@ -74,9 +74,9 @@ void cpicon_draw(entity this)
                }
 
                this.angles_x = this.punchangle_x;
-               this.angles_y = this.punchangle_y + this.move_angles_y;
+               this.angles_y = this.punchangle_y + this.angles_y;
                this.angles_z = this.punchangle_z;
-               this.move_angles_y = this.move_angles_y + 45 * frametime;
+               this.angles_y = this.angles_y + 45 * frametime;
        }
 
        setorigin(this, this.cp_origin + this.cp_bob_origin + this.cp_bob_dmg);
@@ -117,17 +117,15 @@ void cpicon_construct(entity this)
                setmodel(this.icon_realmodel, MDL_Null);
                setorigin(this.icon_realmodel, this.origin);
                setsize(this.icon_realmodel, CPICON_MIN, CPICON_MAX);
-               this.icon_realmodel.movetype = MOVETYPE_NOCLIP;
+               this.icon_realmodel.move_movetype = MOVETYPE_NOCLIP;
                this.icon_realmodel.solid = SOLID_NOT;
-               this.icon_realmodel.move_origin = this.icon_realmodel.origin;
        }
 
        if(this.iscaptured) { this.icon_realmodel.solid = SOLID_BBOX; }
 
        this.move_movetype      = MOVETYPE_NOCLIP;
        this.solid                      = SOLID_NOT;
-       this.movetype           = MOVETYPE_NOCLIP;
-       this.move_origin        = this.origin;
+       this.move_movetype              = MOVETYPE_NOCLIP;
        this.move_time          = time;
        this.drawmask           = MASK_NORMAL;
        this.alpha                      = 1;
index 03e81f4bdea092deee9f965d104cf4f3d4c8f2af..0135f467ed0eb5fb84e9180048ce2df87bb67077 100644 (file)
@@ -33,13 +33,13 @@ void ons_generator_ray_spawn(vector org)
        setmodel(e, MDL_ONS_RAY);
        setorigin(e, org);
        e.angles = randomvec() * 360;
-       e.move_origin = org;
-       e.movetype = MOVETYPE_NONE;
+       e.move_movetype = MOVETYPE_NONE;
        e.alpha = 0;
        e.scale = random() * 5 + 8;
        e.move_time = time + 0.05;
        e.drawmask = MASK_NORMAL;
        e.draw = ons_generator_ray_draw;
+       IL_PUSH(g_drawables, e);
 }
 
 void generator_draw(entity this)
@@ -154,8 +154,7 @@ void generator_construct(entity this)
 
        this.move_movetype      = MOVETYPE_NOCLIP;
        this.solid                      = SOLID_BBOX;
-       this.movetype           = MOVETYPE_NOCLIP;
-       this.move_origin        = this.origin;
+       this.move_movetype              = MOVETYPE_NOCLIP;
        this.move_time          = time;
        this.drawmask           = MASK_NORMAL;
        this.alpha                      = 1;
index 9a30445ace86c042517f62ede9b19a360e0dbdfb..89c5eef51dc2edb0897676f0e7de8e1a3289e7f7 100644 (file)
@@ -162,9 +162,9 @@ void FixSize(entity e);
 // CaptureShield Functions
 // =======================
 
-bool ons_CaptureShield_Customize(entity this)
+bool ons_CaptureShield_Customize(entity this, entity client)
 {
-       entity e = WaypointSprite_getviewentity(other);
+       entity e = WaypointSprite_getviewentity(client);
 
        if(!this.enemy.isshielded && (ons_ControlPoint_Attackable(this.enemy, e.team) > 0 || this.enemy.classname != "onslaught_controlpoint")) { return false; }
        if(SAME_TEAM(this, e)) { return false; }
@@ -172,25 +172,25 @@ bool ons_CaptureShield_Customize(entity this)
        return true;
 }
 
-void ons_CaptureShield_Touch(entity this)
+void ons_CaptureShield_Touch(entity this, entity toucher)
 {
-       if(!this.enemy.isshielded && (ons_ControlPoint_Attackable(this.enemy, other.team) > 0 || this.enemy.classname != "onslaught_controlpoint")) { return; }
-       if(!IS_PLAYER(other)) { return; }
-       if(SAME_TEAM(other, this)) { return; }
+       if(!this.enemy.isshielded && (ons_ControlPoint_Attackable(this.enemy, toucher.team) > 0 || this.enemy.classname != "onslaught_controlpoint")) { return; }
+       if(!IS_PLAYER(toucher)) { return; }
+       if(SAME_TEAM(toucher, this)) { return; }
 
        vector mymid = (this.absmin + this.absmax) * 0.5;
-       vector othermid = (other.absmin + other.absmax) * 0.5;
+       vector theirmid = (toucher.absmin + toucher.absmax) * 0.5;
 
-       Damage(other, this, this, 0, DEATH_HURTTRIGGER.m_id, mymid, normalize(othermid - mymid) * ons_captureshield_force);
+       Damage(toucher, this, this, 0, DEATH_HURTTRIGGER.m_id, mymid, normalize(theirmid - mymid) * ons_captureshield_force);
 
-       if(IS_REAL_CLIENT(other))
+       if(IS_REAL_CLIENT(toucher))
        {
-               play2(other, SND(ONS_DAMAGEBLOCKEDBYSHIELD));
+               play2(toucher, SND(ONS_DAMAGEBLOCKEDBYSHIELD));
 
                if(this.enemy.classname == "onslaught_generator")
-                       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_ONS_GENERATOR_SHIELDED);
+                       Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_ONS_GENERATOR_SHIELDED);
                else
-                       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_ONS_CONTROLPOINT_SHIELDED);
+                       Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_ONS_CONTROLPOINT_SHIELDED);
        }
 }
 
@@ -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;
+       });
 }
 
 
@@ -776,9 +774,8 @@ void ons_ControlPoint_UpdateSprite(entity e)
        }
 }
 
-void ons_ControlPoint_Touch(entity this)
+void ons_ControlPoint_Touch(entity this, entity toucher)
 {
-       entity toucher = other;
        int attackable;
 
        if(IS_VEHICLE(toucher) && toucher.owner)
@@ -864,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;
@@ -883,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
@@ -1083,13 +1080,13 @@ void ons_DelayedGeneratorSetup(entity this)
 }
 
 
-void onslaught_generator_touch(entity this)
+void onslaught_generator_touch(entity this, entity toucher)
 {
-       if ( IS_PLAYER(other) )
-       if ( SAME_TEAM(this,other) )
+       if ( IS_PLAYER(toucher) )
+       if ( SAME_TEAM(this,toucher) )
        if ( this.iscaptured )
        {
-               Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_ONS_TELEPORT);
+               Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_ONS_TELEPORT);
        }
 }
 
@@ -1106,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;
@@ -1290,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?
@@ -1299,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)
@@ -1316,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)
@@ -1598,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;
 }
@@ -1629,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;
 }
@@ -1676,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;
 }
 
@@ -2251,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 08f7ff9c3d6b23c5c67cbfc6ee7595e9bd906625..6d914948182482ea6267a1a49352231188dd6c3b 100644 (file)
@@ -29,7 +29,7 @@ CLASS(Pickup, GameItem)
         TC(Pickup, this);
         bool b = Item_GiveTo(item, player);
         if (b) {
-            LOG_TRACEF("entity %i picked up %s\n", player, this.m_name);
+            LOG_DEBUGF("entity %i picked up %s\n", player, this.m_name);
             player.inventory.inv_items[this.m_id]++;
             Inventory_update(player);
         }
index 3d3ef42dff444d3d57dc273cf451204602ff979c..1aa748faab08c38ebc7955b3a12c88f4475c3ab2 100644 (file)
@@ -226,6 +226,7 @@ NET_HANDLE(ENT_CLIENT_MINIGAME, bool isnew)
                {
                        minigame_self = this;
                        activate_minigame(this.owner);
+                       minigame_self = this; // set it again (needed before, but may also be reset)
                }
        }
        MINIGAME_SIMPLELINKED_ENTITIES
index f64ed44c84e800b919c901c501c134dbb3df4f8a..c26109bfd39e488179eddba303a3d5f5b974aac2 100644 (file)
@@ -598,10 +598,10 @@ float HUD_Minigame_InputEvent(float bInputType, float nPrimary, float nSecondary
                }
 
                // allow some binds
-               string con_keys;
-               con_keys = findkeysforcommand("toggleconsole", 0);
+               string con_keys = findkeysforcommand("toggleconsole", 0);
                int keys = tokenize(con_keys); // findkeysforcommand returns data for this
-               for (int i = 0; i < keys; ++i)
+               int i;
+               for (i = 0; i < keys; ++i)
                {
                        if(nPrimary == stof(argv(i)))
                                return false;
index 689ce83d0295968e7e1ede2e3923fdeb4ed53465..0d0efb05dcdf0b201b00191371b8cbb79d7bc9ac 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;
 }
 
@@ -112,11 +112,11 @@ void minigame_resend(entity minigame)
        }
 }
 
-bool minigame_CheckSend(entity this)
+bool minigame_CheckSend(entity this, entity client)
 {
        entity e;
        for ( e = this.owner.minigame_players; e != NULL; e = e.list_next )
-               if ( e.minigame_players == other )
+               if ( e.minigame_players == client )
                        return true;
        return false;
 }
index 70c9bf80581c05e797ae76b79cc3d2a69ebc649b..de9e3f69610d41b3a42b3eeb5ac1fffc01c99914 100644 (file)
@@ -24,7 +24,7 @@ void end_minigames();
 
 // Only sends entities to players who joined the minigame
 // Use on customizeentityforclient for gameplay entities
-bool minigame_CheckSend(entity this);
+bool minigame_CheckSend(entity this, entity client);
 
 // Check for minigame impulses
 bool MinigameImpulse(entity this, int imp);
index 1c34a2547ee07117b1f52d5707bbebd3b1c80eae..91fb278ae0a5ec975c1580d4f7e023f8b96793e2 100644 (file)
@@ -19,7 +19,7 @@ CLASS(Model, Object)
             LOG_WARNINGF("Missing model: \"%s\"\n", s);
             return;
         }
-        LOG_DEBUGF("precache_model(\"%s\")\n", s);
+        profile(sprintf("precache_model(\"%s\")\n", s));
         precache_model(s);
     }
 ENDCLASS(Model)
index c964b30827141bb9117abf762c4d1608bdf1c1f4..65c82ab37dbaaeb7216c1118e259ccecead06470 100644 (file)
@@ -146,7 +146,7 @@ bool M_Mage_Defend_Heal_Check(entity this, entity targ)
        return false;
 }
 
-void M_Mage_Attack_Spike_Explode(entity this)
+void M_Mage_Attack_Spike_Explode(entity this, entity directhitentity)
 {
        this.event_damage = func_null;
 
@@ -155,16 +155,16 @@ void M_Mage_Attack_Spike_Explode(entity this)
        this.realowner.mage_spike = NULL;
 
        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, other);
+       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);
 }
 
-void M_Mage_Attack_Spike_Touch(entity this)
+void M_Mage_Attack_Spike_Touch(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
 
-       M_Mage_Attack_Spike_Explode(this);
+       M_Mage_Attack_Spike_Explode(this, toucher);
 }
 
 .float wait;
@@ -174,7 +174,7 @@ void M_Mage_Attack_Spike_Think(entity this)
 {
        if (time > this.ltime || (this.enemy && this.enemy.health <= 0) || this.owner.health <= 0) {
                this.projectiledeathtype |= HITTYPE_SPLASH;
-               M_Mage_Attack_Spike_Explode(this);
+               M_Mage_Attack_Spike_Explode(this, NULL);
        }
 
        float spd = vlen(this.velocity);
@@ -233,7 +233,7 @@ void M_Mage_Attack_Spike(entity this, vector dir)
        missile.ltime = time + 7;
        missile.nextthink = time;
        missile.solid = SOLID_BBOX;
-       missile.movetype = MOVETYPE_FLYMISSILE;
+       set_movetype(missile, MOVETYPE_FLYMISSILE);
        missile.flags = FL_PROJECTILE;
        setorigin(missile, this.origin + v_forward * 14 + '0 0 30' + v_right * -14);
        setsize(missile, '0 0 0', '0 0 0');
index b94332c30143e697fedba7401f460a8135db04da..afbb954c0b3590f7f42925b7525570ddb8e7256e 100644 (file)
@@ -78,20 +78,21 @@ void M_Shambler_Attack_Swing(entity this)
 
 #include <common/effects/qc/all.qh>
 
-void M_Shambler_Attack_Lightning_Explode(entity this)
+void M_Shambler_Attack_Lightning_Explode(entity this, entity directhitentity)
 {
        sound(this, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_NORM);
        Send_Effect(EFFECT_ELECTRO_IMPACT, this.origin, '0 0 0', 1);
 
        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), NULL, NULL, (autocvar_g_monster_shambler_attack_lightning_force), this.projectiledeathtype, other);
+       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), 
+                                       NULL, NULL, (autocvar_g_monster_shambler_attack_lightning_force), this.projectiledeathtype, directhitentity);
 
        FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_monster_shambler_attack_lightning_radius_zap, it != this.realowner && it.takedamage,
        {
@@ -105,7 +106,7 @@ void M_Shambler_Attack_Lightning_Explode(entity this)
 
 void M_Shambler_Attack_Lightning_Explode_use(entity this, entity actor, entity trigger)
 {
-       M_Shambler_Attack_Lightning_Explode(this);
+       M_Shambler_Attack_Lightning_Explode(this, trigger);
 }
 
 void M_Shambler_Attack_Lightning_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
@@ -122,11 +123,11 @@ void M_Shambler_Attack_Lightning_Damage(entity this, entity inflictor, entity at
                W_PrepareExplosionByDamage(this, attacker, adaptor_think2use);
 }
 
-void M_Shambler_Attack_Lightning_Touch(entity this)
+void M_Shambler_Attack_Lightning_Touch(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
 
-       this.use(this, NULL, NULL);
+       this.use(this, NULL, toucher);
 }
 
 void M_Shambler_Attack_Lightning_Think(entity this)
@@ -134,8 +135,7 @@ void M_Shambler_Attack_Lightning_Think(entity this)
        this.nextthink = time;
        if (time > this.cnt)
        {
-               other = NULL;
-               M_Shambler_Attack_Lightning_Explode(this);
+               M_Shambler_Attack_Lightning_Explode(this, NULL);
                return;
        }
 }
@@ -150,7 +150,7 @@ void M_Shambler_Attack_Lightning(entity this)
        gren.owner = gren.realowner = this;
        gren.bot_dodge = true;
        gren.bot_dodgerating = (autocvar_g_monster_shambler_attack_lightning_damage);
-       gren.movetype = MOVETYPE_BOUNCE;
+       set_movetype(gren, MOVETYPE_BOUNCE);
        PROJECTILE_MAKETRIGGER(gren);
        gren.projectiledeathtype = DEATH_MONSTER_SHAMBLER_ZAP.m_id;
        setorigin(gren, CENTER_OR_VIEWOFS(this));
index d1ff169b6803d7bf2e29816066bfe7ea81618001..c7ffece15158c36af25677639988bdb42d2bf7be 100644 (file)
@@ -157,9 +157,9 @@ void M_Spider_Attack_Web_Explode_use(entity this, entity actor, entity trigger)
        M_Spider_Attack_Web_Explode(this);
 }
 
-void M_Spider_Attack_Web_Touch(entity this)
+void M_Spider_Attack_Web_Touch(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
 
        M_Spider_Attack_Web_Explode(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');
index 001b2e24d84a5bf3216d97282f1a241669999c82..53d08effa84a0e387dd3ebec1dac8911aacf3c48 100644 (file)
@@ -46,7 +46,7 @@ float autocvar_g_monster_wyvern_attack_fireball_radius;
 float autocvar_g_monster_wyvern_attack_fireball_speed;
 
 void M_Wyvern_Attack_Fireball_Explode(entity this);
-void M_Wyvern_Attack_Fireball_Touch(entity this);
+void M_Wyvern_Attack_Fireball_Touch(entity this, entity toucher);
 
 SOUND(WyvernAttack_FIRE, W_Sound("electro_fire"));
 METHOD(WyvernAttack, wr_think, void(WyvernAttack thiswep, entity actor, .entity weaponentity, int fire))
@@ -64,7 +64,7 @@ METHOD(WyvernAttack, wr_think, void(WyvernAttack thiswep, entity actor, .entity
                entity missile = spawn();
                missile.owner = missile.realowner = actor;
                missile.solid = SOLID_TRIGGER;
-               missile.movetype = MOVETYPE_FLYMISSILE;
+               set_movetype(missile, MOVETYPE_FLYMISSILE);
                missile.projectiledeathtype = DEATH_MONSTER_WYVERN.m_id;
                setsize(missile, '-6 -6 -6', '6 6 6');
                setorigin(missile, actor.origin + actor.view_ofs + v_forward * 14);
@@ -116,9 +116,9 @@ void M_Wyvern_Attack_Fireball_Explode(entity this)
        remove(this);
 }
 
-void M_Wyvern_Attack_Fireball_Touch(entity this)
+void M_Wyvern_Attack_Fireball_Touch(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
 
        M_Wyvern_Attack_Fireball_Explode(this);
 }
index 1eafd4bfd103897ef3993192221ec9a1f9c12237..fd270a1e1efaf2142ecea7a7fd0475b38c7ccae5 100644 (file)
@@ -75,18 +75,18 @@ const float zombie_anim_spawn                               = 30;
 
 .vector moveto;
 
-void M_Zombie_Attack_Leap_Touch(entity this)
+void M_Zombie_Attack_Leap_Touch(entity this, entity toucher)
 {
        if (this.health <= 0)
                return;
 
        vector angles_face;
 
-       if(other.takedamage)
+       if(toucher.takedamage)
        {
                angles_face = vectoangles(this.moveto - this.origin);
                angles_face = normalize(angles_face) * (autocvar_g_monster_zombie_attack_leap_force);
-               Damage(other, this, this, (autocvar_g_monster_zombie_attack_leap_damage) * MONSTER_SKILLMOD(this), DEATH_MONSTER_ZOMBIE_JUMP.m_id, other.origin, angles_face);
+               Damage(toucher, this, this, (autocvar_g_monster_zombie_attack_leap_damage) * MONSTER_SKILLMOD(this), DEATH_MONSTER_ZOMBIE_JUMP.m_id, toucher.origin, angles_face);
                settouch(this, Monster_Touch); // instantly turn it off to stop damage spam
                this.state = 0;
        }
index 5e9eaef32fa6633f52ef52459e1ff6195b63cf5e..60c2777ca7bd12b5774f953999a0dad99b729687 100644 (file)
@@ -50,7 +50,7 @@ void monster_dropitem(entity this, entity attacker)
                e.noalign = true;
                e.monster_loot(e);
                e.gravity = 1;
-               e.movetype = MOVETYPE_TOSS;
+               set_movetype(e, MOVETYPE_TOSS);
                e.reset = SUB_Remove;
                setorigin(e, org);
                e.velocity = randomvec() * 175 + '0 0 325';
@@ -338,7 +338,7 @@ void Monster_Sound(entity this, .string samplefield, float sound_delay, float de
        if(delaytoo)
        if(time < this.msound_delay)
                return; // too early
-       GlobalSound_string(this, this.(samplefield), chan, VOICETYPE_PLAYERSOUND);
+       GlobalSound_string(this, this.(samplefield), chan, VOL_BASE, VOICETYPE_PLAYERSOUND);
 
        this.msound_delay = time + sound_delay;
 }
@@ -391,7 +391,7 @@ bool Monster_Attack_Leap_Check(entity this, vector vel)
        return true;
 }
 
-bool Monster_Attack_Leap(entity this, vector anm, void(entity this) touchfunc, vector vel, float animtime)
+bool Monster_Attack_Leap(entity this, vector anm, void(entity this, entity toucher) touchfunc, vector vel, float animtime)
 {
        if(!Monster_Attack_Leap_Check(this, vel))
                return false;
@@ -463,15 +463,15 @@ void Monster_UpdateModel(entity this)
        mon.mr_anim(mon, this);
 }
 
-void Monster_Touch(entity this)
+void Monster_Touch(entity this, entity toucher)
 {
-       if(other == NULL) { return; }
+       if(toucher == NULL) { return; }
 
-       if(other.monster_attack)
-       if(this.enemy != other)
-       if(!IS_MONSTER(other))
-       if(Monster_ValidTarget(this, other))
-               this.enemy = other;
+       if(toucher.monster_attack)
+       if(this.enemy != toucher)
+       if(!IS_MONSTER(toucher))
+       if(Monster_ValidTarget(this, toucher))
+               this.enemy = toucher;
 }
 
 void Monster_Miniboss_Check(entity this)
@@ -763,15 +763,15 @@ void Monster_Move(entity this, float runspeed, float walkspeed, float stpspeed)
                        }
 
 
-                       this.movetype = MOVETYPE_BOUNCE;
+                       set_movetype(this, MOVETYPE_BOUNCE);
                        //this.velocity_z = -200;
 
                        return;
                }
-               else if(this.movetype == MOVETYPE_BOUNCE)
+               else if(this.move_movetype == MOVETYPE_BOUNCE)
                {
                        this.angles_x = 0;
-                       this.movetype = MOVETYPE_WALK;
+                       set_movetype(this, MOVETYPE_WALK);
                }
        }
 
@@ -1010,7 +1010,7 @@ void Monster_Dead(entity this, entity attacker, float gibbed)
        this.takedamage         = DAMAGE_AIM;
        this.deadflag           = DEAD_DEAD;
        this.enemy                      = NULL;
-       this.movetype           = MOVETYPE_TOSS;
+       set_movetype(this, MOVETYPE_TOSS);
        this.moveto                     = this.origin;
        settouch(this, Monster_Touch); // reset incase monster was pouncing
        this.reset                      = func_null;
@@ -1290,6 +1290,9 @@ bool Monster_Spawn(entity this, int mon_id)
 
        if(!autocvar_g_monsters) { Monster_Remove(this); return false; }
 
+       if(!(this.spawnflags & MONSTERFLAG_RESPAWNED))
+               IL_PUSH(g_monsters, this);
+
        if(Monster_Appear_Check(this, mon_id)) { return true; } // return true so the monster isn't removed
 
        if(!this.monster_skill)
@@ -1320,7 +1323,7 @@ bool Monster_Spawn(entity this, int mon_id)
        settouch(this, Monster_Touch);
        this.use                                = Monster_Use;
        this.solid                              = SOLID_BBOX;
-       this.movetype                   = MOVETYPE_WALK;
+       set_movetype(this, MOVETYPE_WALK);
        this.spawnshieldtime    = time + autocvar_g_monsters_spawnshieldtime;
        this.enemy                              = NULL;
        this.velocity                   = '0 0 0';
@@ -1355,7 +1358,7 @@ bool Monster_Spawn(entity this, int mon_id)
        if(mon.spawnflags & MONSTER_TYPE_FLY)
        {
                this.flags |= FL_FLY;
-               this.movetype = MOVETYPE_FLY;
+               set_movetype(this, MOVETYPE_FLY);
        }
 
        if(!(this.spawnflags & MONSTERFLAG_RESPAWNED))
index f8501fc758e1b8184f67e9ff222beab022d647ac..ffade7b6a2accc4ccbfeb0fac9c82a1ebb5e7a0e 100644 (file)
@@ -77,7 +77,7 @@ bool Monster_Spawn(entity this, int mon_id);
 
 void monster_setupcolors(entity this);
 
-void Monster_Touch(entity this);
+void Monster_Touch(entity this, entity toucher);
 
 void Monster_Move_2D(entity this, float mspeed, float allow_jumpoff);
 
@@ -85,7 +85,7 @@ void Monster_Delay(entity this, int repeat_count, float defer_amnt, void(entity)
 
 float Monster_Attack_Melee(entity this, entity targ, float damg, vector anim, float er, float animtime, int deathtype, float dostop);
 
-bool Monster_Attack_Leap(entity this, vector anm, void(entity this) touchfunc, vector vel, float animtime);
+bool Monster_Attack_Leap(entity this, vector anm, void(entity this, entity toucher) touchfunc, vector vel, float animtime);
 
 entity Monster_FindTarget(entity this);
 
index 1507a5f13c3d577fb91ced23d9cbf8efa04ca158..5c2987e0e74922eac1b0e5c516cbaf6d2995e10b 100644 (file)
@@ -92,12 +92,12 @@ REGISTER_MUTATOR(buffs, cvar("g_buffs"))
        }
 }
 
-bool buffs_BuffModel_Customize(entity this)
+bool buffs_BuffModel_Customize(entity this, entity client)
 {
        entity player, myowner;
        bool same_team;
 
-       player = WaypointSprite_getviewentity(other);
+       player = WaypointSprite_getviewentity(client);
        myowner = this.owner;
        same_team = (SAME_TEAM(player, myowner) || SAME_TEAM(player, myowner));
 
@@ -107,7 +107,7 @@ bool buffs_BuffModel_Customize(entity this)
        if(MUTATOR_CALLHOOK(BuffModel_Customize, this, player))
                return false;
 
-       if(player == myowner || (IS_SPEC(other) && other.enemy == myowner))
+       if(player == myowner || (IS_SPEC(client) && client.enemy == myowner))
        {
                // somewhat hide the model, but keep the glow
                this.effects = 0;
@@ -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';
@@ -222,7 +222,7 @@ void buff_Respawn(entity this)
        sound(this, CH_TRIGGER, SND_KA_RESPAWN, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
 }
 
-void buff_Touch(entity this)
+void buff_Touch(entity this, entity toucher)
 {
        if(gameover) { return; }
 
@@ -232,9 +232,9 @@ void buff_Touch(entity this)
                return;
        }
 
-       if((this.team && DIFF_TEAM(other, this))
-       || (STAT(FROZEN, other))
-       || (other.vehicle)
+       if((this.team && DIFF_TEAM(toucher, this))
+       || (STAT(FROZEN, toucher))
+       || (toucher.vehicle)
        || (!this.buff_active)
        )
        {
@@ -242,37 +242,37 @@ void buff_Touch(entity this)
                return;
        }
 
-       if(MUTATOR_CALLHOOK(BuffTouch, this, other))
+       if(MUTATOR_CALLHOOK(BuffTouch, this, toucher))
                return;
-       other = M_ARGV(1, entity);
+       toucher = M_ARGV(1, entity);
 
-       if(!IS_PLAYER(other))
-               return; // incase mutator changed other
+       if(!IS_PLAYER(toucher))
+               return; // incase mutator changed toucher
 
-       if (other.buffs)
+       if (toucher.buffs)
        {
-               if (other.cvar_cl_buffs_autoreplace && other.buffs != this.buffs)
+               if (toucher.cvar_cl_buffs_autoreplace && toucher.buffs != this.buffs)
                {
-                       int buffid = buff_FirstFromFlags(other.buffs).m_id;
-                       //Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_BUFF_DROP, other.buffs);
-                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ITEM_BUFF_LOST, other.netname, buffid);
+                       int buffid = buff_FirstFromFlags(toucher.buffs).m_id;
+                       //Send_Notification(NOTIF_ONE, toucher, MSG_MULTI, ITEM_BUFF_DROP, toucher.buffs);
+                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ITEM_BUFF_LOST, toucher.netname, buffid);
 
-                       other.buffs = 0;
-                       //sound(other, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
+                       toucher.buffs = 0;
+                       //sound(toucher, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
                }
                else { return; } // do nothing
        }
 
-       this.owner = other;
+       this.owner = toucher;
        this.buff_active = false;
        this.lifetime = 0;
        int buffid = buff_FirstFromFlags(this.buffs).m_id;
-       Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_BUFF_GOT, buffid);
-       Send_Notification(NOTIF_ALL_EXCEPT, other, MSG_INFO, INFO_ITEM_BUFF, other.netname, buffid);
+       Send_Notification(NOTIF_ONE, toucher, MSG_MULTI, ITEM_BUFF_GOT, buffid);
+       Send_Notification(NOTIF_ALL_EXCEPT, toucher, MSG_INFO, INFO_ITEM_BUFF, toucher.netname, buffid);
 
        Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
-       sound(other, CH_TRIGGER, SND_SHIELD_RESPAWN, VOL_BASE, ATTN_NORM);
-       other.buffs |= (this.buffs);
+       sound(toucher, CH_TRIGGER, SND_SHIELD_RESPAWN, VOL_BASE, ATTN_NORM);
+       toucher.buffs |= (this.buffs);
 }
 
 float buff_Available(entity buff)
@@ -390,9 +390,9 @@ void buff_Reset(entity this)
                buff_Respawn(this);
 }
 
-float buff_Customize(entity this)
+bool buff_Customize(entity this, entity client)
 {
-       entity player = WaypointSprite_getviewentity(other);
+       entity player = WaypointSprite_getviewentity(client);
        if(!this.buff_active || (this.team && DIFF_TEAM(player, this)))
        {
                this.alpha = 0.3;
@@ -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);
@@ -910,12 +910,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
                        if(boxesoverlap(player.absmin - pickup_size, player.absmax + pickup_size, it.absmin, it.absmax))
                        {
                                if(gettouch(it))
-                               {
-                                       entity oldother = other;
-                                       other = player;
-                                       gettouch(it)(it);
-                                       other = oldother;
-                               }
+                                       gettouch(it)(it, player);
                        }
                });
        }
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 2a1795d63c94afad39c367c52eb0decd51172575..8de4f2b8549d09d9a99f12903a3870b9629fee04 100644 (file)
@@ -12,7 +12,7 @@ REGISTER_MUTATOR(damagetext, true);
 
 #if defined(CSQC) || defined(MENUQC)
 // no translatable cvar description please
-AUTOCVAR_SAVE(cl_damagetext,                    bool,   false,      "Draw damage dealt where you hit the enemy");
+AUTOCVAR_SAVE(cl_damagetext,                    bool,   true,      "Draw damage dealt where you hit the enemy");
 AUTOCVAR_SAVE(cl_damagetext_format,             string, "-{total}", "How to format the damage text. {health}, {armor}, {total}");
 STATIC_INIT(DamageText_LegacyFormat) {
     if (strstrofs(autocvar_cl_damagetext_format, "{", 0) < 0) autocvar_cl_damagetext_format = "-{total}";
@@ -25,16 +25,20 @@ AUTOCVAR_SAVE(cl_damagetext_alpha_lifetime,     float,  3,          "Damage text
 AUTOCVAR_SAVE(cl_damagetext_velocity,           vector, '0 0 20',   "Damage text move direction");
 AUTOCVAR_SAVE(cl_damagetext_offset,             vector, '0 -40 0',  "Damage text offset");
 AUTOCVAR_SAVE(cl_damagetext_accumulate_range,   float,  30,         "Damage text spawned within this range is accumulated");
+AUTOCVAR_SAVE(cl_damagetext_friendlyfire,       bool,   true,       "Show damage text for friendlyfire too");
+AUTOCVAR_SAVE(cl_damagetext_friendlyfire_color, vector, '1 0 0',    "Damage text color for friendlyfire");
 #endif
 
 #ifdef CSQC
 CLASS(DamageText, Object)
     ATTRIB(DamageText, m_color, vector, autocvar_cl_damagetext_color)
+    ATTRIB(DamageText, m_color_friendlyfire, vector, autocvar_cl_damagetext_friendlyfire_color)
     ATTRIB(DamageText, m_size, float, autocvar_cl_damagetext_size)
     ATTRIB(DamageText, alpha, float, autocvar_cl_damagetext_alpha_start)
     ATTRIB(DamageText, fade_rate, float, 1 / autocvar_cl_damagetext_alpha_lifetime)
     ATTRIB(DamageText, velocity, vector, autocvar_cl_damagetext_velocity)
     ATTRIB(DamageText, m_group, int, 0)
+    ATTRIB(DamageText, m_friendlyfire, bool, false)
     ATTRIB(DamageText, m_damage, int, 0)
     ATTRIB(DamageText, m_armordamage, int, 0)
     ATTRIB(DamageText, m_deathtype, int, 0)
@@ -49,7 +53,13 @@ CLASS(DamageText, Object)
         vector pos = project_3d_to_2d(this.origin) + autocvar_cl_damagetext_offset;
         if (pos.z >= 0 && this.m_size > 0) {
             pos.z = 0;
-            vector rgb = this.m_color;
+            vector rgb;
+            if (this.m_friendlyfire) {
+                rgb = this.m_color_friendlyfire;
+            }
+            else {
+                rgb = this.m_color;
+            }
             if (autocvar_cl_damagetext_color_per_weapon) {
                 Weapon w = DEATH_WEAPONOF(this.m_deathtype);
                 if (w != WEP_Null) rgb = w.wpcolor;
@@ -71,10 +81,12 @@ CLASS(DamageText, Object)
         this.alpha = 1;
     }
 
-    CONSTRUCTOR(DamageText, int _group, vector _origin, int _health, int _armor, int _deathtype) {
+    CONSTRUCTOR(DamageText, int _group, vector _origin, int _health, int _armor, int _deathtype, bool _friendlyfire) {
         CONSTRUCT(DamageText);
         this.m_group = _group;
+        this.m_friendlyfire = _friendlyfire;
         DamageText_update(this, _origin, _health, _armor, _deathtype);
+               IL_PUSH(g_drawables_2d, this);
     }
 ENDCLASS(DamageText)
 #endif
@@ -111,6 +123,7 @@ MUTATOR_HOOKFUNCTION(damagetext, PlayerDamaged) {
             WriteCoord(MSG_ONE, location.y);
             WriteCoord(MSG_ONE, location.z);
             WriteInt24_t(MSG_ONE, deathtype);
+            WriteByte(MSG_ONE, SAME_TEAM(hit, attacker));
         }
     ));
 }
@@ -124,8 +137,12 @@ NET_HANDLE(damagetext, bool isNew)
     int group = ReadShort();
     vector location = vec3(ReadCoord(), ReadCoord(), ReadCoord());
     int deathtype = ReadInt24_t();
+    bool friendlyfire = ReadByte();
     return = true;
     if (autocvar_cl_damagetext) {
+        if (friendlyfire && !autocvar_cl_damagetext_friendlyfire) {
+            return;
+        }
         if (autocvar_cl_damagetext_accumulate_range) {
             for (entity e = findradius(location, autocvar_cl_damagetext_accumulate_range); e; e = e.chain) {
                 if (e.instanceOfDamageText && e.m_group == group) {
@@ -134,7 +151,7 @@ NET_HANDLE(damagetext, bool isNew)
                 }
             }
         }
-        NEW(DamageText, group, location, health, armor, deathtype);
+        make_impure(NEW(DamageText, group, location, health, armor, deathtype, friendlyfire));
     }
 }
 #endif
@@ -174,6 +191,17 @@ CLASS(XonoticDamageTextSettings, XonoticTab)
                 setDependent(e, "cl_damagetext", 1, 1);
             this.TD(this, 2, 2, e = makeXonoticColorpickerString("cl_damagetext_color", "cl_damagetext_color"));
                 setDependent(e, "cl_damagetext", 1, 1);
+        this.TR(this);
+        this.TR(this);
+        // friendly fire
+            this.TD(this, 1, 3, e = makeXonoticCheckBox(0, "cl_damagetext_friendlyfire", _("Draw damage numbers for friendly fire")));
+                setDependent(e, "cl_damagetext", 1, 1);
+        this.TR(this);
+            this.TD(this, 1, 1, e = makeXonoticTextLabel(0, _("Color (Friendly Fire):")));
+                setDependentAND(e, "cl_damagetext", 1, 1, "cl_damagetext_friendlyfire", 1, 1);
+            this.TD(this, 2, 2, e = makeXonoticColorpickerString("cl_damagetext_friendlyfire_color", "cl_damagetext_friendlyfire_color"));
+                setDependentAND(e, "cl_damagetext", 1, 1, "cl_damagetext_friendlyfire", 1, 1);
+        this.TR(this);
     }
 ENDCLASS(XonoticDamageTextSettings)
 #endif
index 0d20ff7af895f831c7c11cd41c29798f3fbd8c6b..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
@@ -226,7 +229,7 @@ void PM_dodging(entity this)
 
 #ifdef SVQC
                if (autocvar_sv_dodging_sound)
-                       PlayerSound(this, playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+                       PlayerSound(this, playersound_jump, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
 
                animdecide_setaction(this, ANIMACTION_JUMP, true);
 #endif
index 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 7336c34a4b00dab5a0b434306c5df9ef15caee6b..5570a1b084aa6befa6a67ca796e1dae109504c7a 100644 (file)
@@ -94,7 +94,7 @@ MUTATOR_HOOKFUNCTION(cl_nades, EditProjectile)
                proj.maxs = '16 16 16';
        }
        proj.colormod = nade_type.m_color;
-       proj.move_movetype = MOVETYPE_BOUNCE;
+       set_movetype(proj, MOVETYPE_BOUNCE);
        settouch(proj, func_null);
        proj.scale = 1.5;
        proj.avelocity = randomvec() * 720;
@@ -273,7 +273,7 @@ void nade_napalm_ball(entity this)
        proj.team = this.owner.team;
        proj.bot_dodge = true;
        proj.bot_dodgerating = autocvar_g_nades_napalm_ball_damage;
-       proj.movetype = MOVETYPE_BOUNCE;
+       set_movetype(proj, MOVETYPE_BOUNCE);
        proj.projectiledeathtype = DEATH_NADE_NAPALM.m_id;
        PROJECTILE_MAKETRIGGER(proj);
        setmodel(proj, MDL_Null);
@@ -356,7 +356,7 @@ void nade_napalm_boom(entity this)
        fountain.ltime = time + autocvar_g_nades_napalm_fountain_lifetime;
        fountain.pushltime = fountain.ltime;
        fountain.team = this.team;
-       fountain.movetype = MOVETYPE_TOSS;
+       set_movetype(fountain, MOVETYPE_TOSS);
        fountain.projectiledeathtype = DEATH_NADE_NAPALM.m_id;
        fountain.bot_dodge = true;
        fountain.bot_dodgerating = autocvar_g_nades_napalm_fountain_damage;
@@ -448,7 +448,7 @@ void nade_ice_boom(entity this)
        fountain.ltime = time + autocvar_g_nades_ice_freeze_time;
        fountain.pushltime = fountain.wait = fountain.ltime;
        fountain.team = this.team;
-       fountain.movetype = MOVETYPE_TOSS;
+       set_movetype(fountain, MOVETYPE_TOSS);
        fountain.projectiledeathtype = DEATH_NADE_ICE.m_id;
        fountain.bot_dodge = false;
        setsize(fountain, '-16 -16 -16', '16 16 16');
@@ -494,7 +494,7 @@ void nade_spawn_boom(entity this)
        entity spawnloc = spawn();
        setorigin(spawnloc, this.origin);
        setsize(spawnloc, this.realowner.mins, this.realowner.maxs);
-       spawnloc.movetype = MOVETYPE_NONE;
+       set_movetype(spawnloc, MOVETYPE_NONE);
        spawnloc.solid = SOLID_NOT;
        spawnloc.drawonlytoclient = this.realowner;
        spawnloc.effects = EF_STARDUST;
@@ -559,35 +559,33 @@ entity nades_spawn_orb(entity own, entity realown, vector org, float orb_ltime,
        return orb;
 }
 
-void nade_entrap_touch(entity this)
+void nade_entrap_touch(entity this, entity toucher)
 {
-       if(DIFF_TEAM(other, this.realowner)) // TODO: what if realowner changes team or disconnects?
+       if(DIFF_TEAM(toucher, this.realowner)) // TODO: what if realowner changes team or disconnects?
        {
-               if (!isPushable(other))
+               if (!isPushable(toucher))
                        return;
 
-               float pushdeltatime = time - other.lastpushtime;
+               float pushdeltatime = time - toucher.lastpushtime;
                if (pushdeltatime > 0.15) pushdeltatime = 0;
-               other.lastpushtime = time;
+               toucher.lastpushtime = time;
                if(!pushdeltatime) return;
 
                // div0: ticrate independent, 1 = identity (not 20)
-#ifdef SVQC
-               other.velocity = other.velocity * pow(autocvar_g_nades_entrap_strength, pushdeltatime);
+               toucher.velocity = toucher.velocity * pow(autocvar_g_nades_entrap_strength, pushdeltatime);
 
-               UpdateCSQCProjectile(other);
-#elif defined(CSQC)
-               other.move_velocity = other.move_velocity * pow(autocvar_g_nades_entrap_strength, pushdeltatime);
-#endif
+       #ifdef SVQC
+               UpdateCSQCProjectile(toucher);
+       #endif
        }
 
-       if ( IS_REAL_CLIENT(other) || IS_VEHICLE(other) || IS_MONSTER(other) )
+       if ( IS_REAL_CLIENT(toucher) || IS_VEHICLE(toucher) || IS_MONSTER(toucher) )
        {
-               entity show_tint = (IS_VEHICLE(other)) ? other.owner : other;
+               entity show_tint = (IS_VEHICLE(toucher)) ? toucher.owner : toucher;
                STAT(ENTRAP_ORB, show_tint) = time + 0.1;
 
                float tint_alpha = 0.75;
-               if(SAME_TEAM(other, this.realowner))
+               if(SAME_TEAM(toucher, this.realowner))
                        tint_alpha = 0.45;
                STAT(ENTRAP_ORB_ALPHA, show_tint) = tint_alpha * (this.ltime - time) / this.orb_lifetime;
        }
@@ -601,43 +599,43 @@ void nade_entrap_boom(entity this)
        orb.colormod = NADE_TYPE_ENTRAP.m_color;
 }
 
-void nade_heal_touch(entity this)
+void nade_heal_touch(entity this, entity toucher)
 {
        float maxhealth;
        float health_factor;
-       if(IS_PLAYER(other) || IS_MONSTER(other))
-       if(!IS_DEAD(other))
-       if(!STAT(FROZEN, other))
+       if(IS_PLAYER(toucher) || IS_MONSTER(toucher))
+       if(!IS_DEAD(toucher))
+       if(!STAT(FROZEN, toucher))
        {
                health_factor = autocvar_g_nades_heal_rate*frametime/2;
-               if ( other != this.realowner )
+               if ( toucher != this.realowner )
                {
-                       if ( SAME_TEAM(other,this) )
+                       if ( SAME_TEAM(toucher,this) )
                                health_factor *= autocvar_g_nades_heal_friend;
                        else
                                health_factor *= autocvar_g_nades_heal_foe;
                }
                if ( health_factor > 0 )
                {
-                       maxhealth = (IS_MONSTER(other)) ? other.max_health : g_pickup_healthmega_max;
-                       if ( other.health < maxhealth )
+                       maxhealth = (IS_MONSTER(toucher)) ? toucher.max_health : g_pickup_healthmega_max;
+                       if ( toucher.health < maxhealth )
                        {
                                if ( this.nade_show_particles )
-                                       Send_Effect(EFFECT_HEALING, other.origin, '0 0 0', 1);
-                               other.health = min(other.health+health_factor, maxhealth);
+                                       Send_Effect(EFFECT_HEALING, toucher.origin, '0 0 0', 1);
+                               toucher.health = min(toucher.health+health_factor, maxhealth);
                        }
-                       other.pauserothealth_finished = max(other.pauserothealth_finished, time + autocvar_g_balance_pause_health_rot);
+                       toucher.pauserothealth_finished = max(toucher.pauserothealth_finished, time + autocvar_g_balance_pause_health_rot);
                }
                else if ( health_factor < 0 )
                {
-                       Damage(other,this,this.realowner,-health_factor,DEATH_NADE_HEAL.m_id,other.origin,'0 0 0');
+                       Damage(toucher,this,this.realowner,-health_factor,DEATH_NADE_HEAL.m_id,toucher.origin,'0 0 0');
                }
 
        }
 
-       if ( IS_REAL_CLIENT(other) || IS_VEHICLE(other) )
+       if ( IS_REAL_CLIENT(toucher) || IS_VEHICLE(toucher) )
        {
-               entity show_red = (IS_VEHICLE(other)) ? other.owner : other;
+               entity show_red = (IS_VEHICLE(toucher)) ? toucher.owner : toucher;
                show_red.stat_healing_orb = time+0.1;
                show_red.stat_healing_orb_alpha = 0.75 * (this.ltime - time) / this.orb_lifetime;
        }
@@ -756,22 +754,22 @@ void nade_pickup(entity this, entity thenade)
 }
 
 bool CanThrowNade(entity this);
-void nade_touch(entity this)
+void nade_touch(entity this, entity toucher)
 {
-       if(other)
+       if(toucher)
                UpdateCSQCProjectile(this);
 
-       if(other == this.realowner)
+       if(toucher == this.realowner)
                return; // no this impacts
 
        if(autocvar_g_nades_pickup)
        if(time >= this.spawnshieldtime)
-       if(!other.nade && this.health == this.max_health) // no boosted shot pickups, thank you very much
-       if(!other.frozen)
-       if(CanThrowNade(other)) // prevent some obvious things, like dead players
-       if(IS_REAL_CLIENT(other)) // above checks for IS_PLAYER, don't need to do it here
+       if(!toucher.nade && this.health == this.max_health) // no boosted shot pickups, thank you very much
+       if(!STAT(FROZEN, toucher))
+       if(CanThrowNade(toucher)) // prevent some obvious things, like dead players
+       if(IS_REAL_CLIENT(toucher)) // above checks for IS_PLAYER, don't need to do it here
        {
-               nade_pickup(other, this);
+               nade_pickup(toucher, this);
                sound(this, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, 0.5 *(ATTEN_LARGE + ATTEN_MAX));
                remove(this);
                return;
@@ -792,7 +790,7 @@ void nade_touch(entity this)
                return;
        }
 
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
 
        //setsize(this, '-2 -2 -2', '2 2 2');
        //UpdateCSQCProjectile(this);
@@ -802,7 +800,7 @@ void nade_touch(entity this)
                return;
        }
 
-       this.enemy = other;
+       this.enemy = toucher;
        nade_boom(this);
 }
 
@@ -909,7 +907,7 @@ void toss_nade(entity e, bool set_owner, vector _velocity, float _time)
                setsize(_nade, '-8 -8 -8', '8 8 8');
        else
                setsize(_nade, '-16 -16 -16', '16 16 16');
-       _nade.movetype = MOVETYPE_BOUNCE;
+       set_movetype(_nade, MOVETYPE_BOUNCE);
 
        tracebox(_nade.origin, _nade.mins, _nade.maxs, _nade.origin, false, _nade);
        if (trace_startsolid)
@@ -999,10 +997,10 @@ MUTATOR_HOOKFUNCTION(nades, PutClientInServer)
        nades_RemoveBonus(player);
 }
 
-float nade_customize(entity this)
+bool nade_customize(entity this, entity client)
 {
-       //if(IS_SPEC(other)) { return false; }
-       if(other == this.exteriormodeltoclient || (IS_SPEC(other) && other.enemy == this.exteriormodeltoclient))
+       //if(IS_SPEC(client)) { return false; }
+       if(client == this.exteriormodeltoclient || (IS_SPEC(client) && client.enemy == this.exteriormodeltoclient))
        {
                // somewhat hide the model, but keep the glow
                //this.effects = 0;
index af320d9c15555c866f30505e72dee4d0c41c237a..9488e02a527a098620f9848cd971e412a205f92e 100644 (file)
@@ -29,12 +29,13 @@ void orb_setup(entity e)
        e.orb_radius = e.orb_radius/model_radius*0.6;
 
        e.draw = orb_draw;
+       IL_PUSH(g_drawables, e);
        e.health = 255;
-       e.movetype = MOVETYPE_NONE;
+       e.move_movetype = MOVETYPE_NONE;
        e.solid = SOLID_NOT;
        e.drawmask = MASK_NORMAL;
        e.scale = 0.01;
-       e.avelocity = e.move_avelocity = '7 0 11';
+       e.avelocity = '7 0 11';
        e.renderflags |= RF_ADDITIVE;
 }
 #endif
index 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 e0ae539318c3db8dd949079bf789dda1521a9e43..2000ffd5dd758ccdeb05beb2ce6ee099662e57bf 100644 (file)
@@ -62,8 +62,7 @@ void W_HeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weapone
                return;
        }
 
-       if(!thiswep.wr_checkammo1(thiswep, actor))
-       if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+       if((!thiswep.wr_checkammo1(thiswep, actor) && !(actor.items & IT_UNLIMITED_WEAPON_AMMO)) || (!(actor.items & IT_SUPERWEAPON) && !(actor.items & IT_UNLIMITED_SUPERWEAPONS)))
        {
                W_SwitchWeapon_Force(actor, w_getbestweapon(actor));
                w_ready(thiswep, actor, weaponentity, fire);
@@ -91,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..ef76ab51519ceb1f61ee16caefb622a4126e5816 100644 (file)
@@ -130,7 +130,7 @@ void ok_DropItem(entity this, entity targ)
        e.spawnfunc_checked = true;
        spawnfunc_item_armor_small(e);
        if (!wasfreed(e)) { // might have been blocked by a mutator
-        e.movetype = MOVETYPE_TOSS;
+        set_movetype(e, MOVETYPE_TOSS);
         e.gravity = 1;
         e.reset = SUB_Remove;
         setorigin(e, this.origin + '0 0 32');
index 90c671a6094d36f39fa46d060972b44bcdf4879a..4c59f183a39e53c41104d2c75edb64c107adbc40 100644 (file)
@@ -50,23 +50,28 @@ REGISTER_WEAPON(RPC, rpc, NEW(RocketPropelledChainsaw));
 #ifdef SVQC
 spawnfunc(weapon_rpc) { weapon_defaultspawnfunc(this, WEP_RPC); }
 
-void W_RocketPropelledChainsaw_Explode(entity this)
+void W_RocketPropelledChainsaw_Explode(entity this, entity directhitentity)
 {
        this.event_damage = func_null;
        this.takedamage = DAMAGE_NO;
 
-       RadiusDamage (this, this.realowner, WEP_CVAR(rpc, damage), WEP_CVAR(rpc, edgedamage), WEP_CVAR(rpc, radius), NULL, NULL, WEP_CVAR(rpc, force), this.projectiledeathtype, other);
+       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);
 }
 
-void W_RocketPropelledChainsaw_Touch (entity this)
+void W_RocketPropelledChainsaw_Explode_think(entity this)
 {
-       if(WarpZone_Projectile_Touch(this))
+       W_RocketPropelledChainsaw_Explode(this, NULL);
+}
+
+void W_RocketPropelledChainsaw_Touch (entity this, entity toucher)
+{
+       if(WarpZone_Projectile_Touch(this, toucher))
                if(wasfreed(this))
                        return;
 
-       W_RocketPropelledChainsaw_Explode(this);
+       W_RocketPropelledChainsaw_Explode(this, toucher);
 }
 
 void W_RocketPropelledChainsaw_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
@@ -80,7 +85,7 @@ void W_RocketPropelledChainsaw_Damage(entity this, entity inflictor, entity atta
        this.health = this.health - damage;
 
        if (this.health <= 0)
-               W_PrepareExplosionByDamage(this, attacker, W_RocketPropelledChainsaw_Explode);
+               W_PrepareExplosionByDamage(this, attacker, W_RocketPropelledChainsaw_Explode_think);
 }
 
 void W_RocketPropelledChainsaw_Think(entity this)
@@ -124,7 +129,7 @@ void W_RocketPropelledChainsaw_Attack (Weapon thiswep, entity actor)
        missile.health = WEP_CVAR(rpc, health);
        missile.event_damage = W_RocketPropelledChainsaw_Damage;
        missile.damagedbycontents = true;
-       missile.movetype = MOVETYPE_FLY;
+       set_movetype(missile, MOVETYPE_FLY);
 
        missile.projectiledeathtype = WEP_RPC.m_id;
        setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
index 10ec0cf5a8976cd7a83ef553fcc2701d4e3a0d02..8e9d4699e895c8ac33257ce54026472d8ac9e714 100644 (file)
@@ -53,13 +53,13 @@ void physical_item_think(entity this)
                                this.angles = this.spawn_angles;
                                this.solid = SOLID_NOT;
                                this.alpha = -1;
-                               this.movetype = MOVETYPE_NONE;
+                               set_movetype(this, MOVETYPE_NONE);
                        }
                        else
                        {
                                this.alpha = 1;
                                this.solid = SOLID_CORPSE;
-                               this.movetype = MOVETYPE_PHYSICS;
+                               set_movetype(this, MOVETYPE_PHYSICS);
                        }
                }
        }
@@ -68,7 +68,7 @@ void physical_item_think(entity this)
                remove(this); // the real item is gone, remove this
 }
 
-void physical_item_touch(entity this)
+void physical_item_touch(entity this, entity toucher)
 {
        if(!this.cnt) // not for dropped items
        if (ITEM_TOUCH_NEEDKILL())
@@ -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 1805d720117c9bf60725937a6005479fb59a3f4e..6adc964be48374e6d109f0e902a09406b2122b01 100644 (file)
@@ -34,7 +34,7 @@ float object_count;
 .string material;
 
 .float touch_timer;
-void sandbox_ObjectFunction_Touch(entity this)
+void sandbox_ObjectFunction_Touch(entity this, entity toucher)
 {
        // apply material impact effects
 
@@ -46,7 +46,7 @@ void sandbox_ObjectFunction_Touch(entity this)
 
        // make particle count and sound volume depend on impact speed
        float intensity;
-       intensity = vlen(this.velocity) + vlen(other.velocity);
+       intensity = vlen(this.velocity) + vlen(toucher.velocity);
        if(intensity) // avoid divisions by 0
                intensity /= 2; // average the two velocities
        if (!(intensity >= autocvar_g_sandbox_object_material_velocity_min))
@@ -129,8 +129,8 @@ void sandbox_ObjectAttach_Set(entity e, entity parent, string s)
        sandbox_ObjectAttach_Remove(e);
 
        e.old_solid = e.solid; // persist solidity
-       e.old_movetype = e.movetype; // persist physics
-       e.movetype = MOVETYPE_FOLLOW;
+       e.old_movetype = e.move_movetype; // persist physics
+       set_movetype(e, MOVETYPE_FOLLOW);
        e.solid = SOLID_NOT;
        e.takedamage = DAMAGE_NO;
 
@@ -156,7 +156,7 @@ void sandbox_ObjectAttach_Remove(entity e)
                it.angles = e.angles; // don't allow detached objects to spin or roll
 
                it.solid = it.old_solid; // restore persisted solidity
-               it.movetype = it.old_movetype; // restore persisted physics
+               set_movetype(it, it.old_movetype); // restore persisted physics
                it.takedamage = DAMAGE_AIM;
        });
 }
@@ -169,7 +169,7 @@ entity sandbox_ObjectSpawn(entity this, float database)
        e.takedamage = DAMAGE_AIM;
        e.damageforcescale = 1;
        e.solid = SOLID_BBOX; // SOLID_BSP would be best, but can lag the server badly
-       e.movetype = MOVETYPE_TOSS;
+       set_movetype(e, MOVETYPE_TOSS);
        e.frame = 0;
        e.skin = 0;
        e.material = string_null;
@@ -240,7 +240,7 @@ string sandbox_ObjectPort_Save(entity e, float database)
                {
                        slot = 0;
                        solidity = head.solid; // applied solidity is normal solidity for children
-                       physics = head.movetype; // applied physics are normal physics for parents
+                       physics = head.move_movetype; // applied physics are normal physics for parents
                }
                else if(head.owner == e) // child object, list them in order
                {
@@ -347,7 +347,8 @@ entity sandbox_ObjectPort_Load(entity this, string s, float database)
                e.frame = stof(argv(argv_num)); ++argv_num;
                sandbox_ObjectEdit_Scale(e, stof(argv(argv_num)));      ++argv_num;
                e.solid = e.old_solid = stof(argv(argv_num));   ++argv_num;
-               e.movetype = e.old_movetype = stof(argv(argv_num));     ++argv_num;
+               e.old_movetype = stof(argv(argv_num));  ++argv_num;
+               set_movetype(e, e.old_movetype);
                e.damageforcescale = stof(argv(argv_num));      ++argv_num;
                if(e.material)  strunzone(e.material);  if(argv(argv_num) != "")        e.material = strzone(argv(argv_num));   else    e.material = string_null;       ++argv_num;
                if(database)
@@ -683,13 +684,13 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
                                                        switch(argv(3))
                                                        {
                                                                case "0": // static
-                                                                       e.movetype = MOVETYPE_NONE;
+                                                                       set_movetype(e, MOVETYPE_NONE);
                                                                        break;
                                                                case "1": // movable
-                                                                       e.movetype = MOVETYPE_TOSS;
+                                                                       set_movetype(e, MOVETYPE_TOSS);
                                                                        break;
                                                                case "2": // physical
-                                                                       e.movetype = MOVETYPE_PHYSICS;
+                                                                       set_movetype(e, MOVETYPE_PHYSICS);
                                                                        break;
                                                                default:
                                                                        break;
index c74715ea714f6c2b92652a369a9e59a6d8de0973..0fb3d6139c64ff3f60750188f0a501a2c821f548 100644 (file)
@@ -27,6 +27,7 @@ REGISTER_WAYPOINT(FlagBaseRed, _("Red base"), '0.8 0.8 0', 1);
 REGISTER_WAYPOINT(FlagBaseBlue, _("Blue base"), '0.8 0.8 0', 1);
 REGISTER_WAYPOINT(FlagBaseYellow, _("Yellow base"), '0.8 0.8 0', 1);
 REGISTER_WAYPOINT(FlagBasePink, _("Pink base"), '0.8 0.8 0', 1);
+REGISTER_WAYPOINT(FlagReturn, _("Return flag here"), '0 0.8 0.8', 1);
 
 REGISTER_WAYPOINT(DomNeut, _("Control point"), '0 1 1', 1);
 REGISTER_WAYPOINT(DomRed, _("Control point"), '0 1 1', 1);
index 5fdb7ec428535661a7f8a40ab685aa034dfe2d88..070379b4ae7b00caf0c674f0517a6eb572c8585b 100644 (file)
@@ -24,6 +24,8 @@ bool WaypointSprite_SendEntity(entity this, entity to, float sendflags)
         f |= 2; // my own
 
     MUTATOR_CALLHOOK(SendWaypoint, this, to, sendflags, f);
+    sendflags = M_ARGV(2, int);
+    f = M_ARGV(3, int);
 
     WriteByte(MSG_ENTITY, sendflags);
     WriteByte(MSG_ENTITY, this.wp_extra);
@@ -98,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;
 }
 
@@ -112,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();
@@ -121,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;
@@ -225,6 +231,7 @@ float spritelookupblinkvalue(entity this, string s)
             return 2;
     }
     if (s == WP_Item.netname) return Items_from(this.wp_extra).m_waypointblink;
+    if(s == WP_FlagReturn.netname) return 2;
 
     return 1;
 }
@@ -479,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;
@@ -932,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)
@@ -963,17 +970,17 @@ float WaypointSprite_isteammate(entity e, entity e2)
     return e2 == e;
 }
 
-float WaypointSprite_Customize(entity this)
+bool WaypointSprite_Customize(entity this, entity client)
 {
     // this is not in SendEntity because it shall run every frame, not just every update
 
     // make spectators see what the player would see
-    entity e = WaypointSprite_getviewentity(other);
+    entity e = WaypointSprite_getviewentity(client);
 
-    if (MUTATOR_CALLHOOK(CustomizeWaypoint, this, other))
+    if (MUTATOR_CALLHOOK(CustomizeWaypoint, this, client))
         return false;
 
-    return this.waypointsprite_visible_for_player(this, other, e);
+    return this.waypointsprite_visible_for_player(this, client, e);
 }
 
 bool WaypointSprite_SendEntity(entity this, entity to, float sendflags);
index 7fb578f82438477dd41d19c4aa1edebb4a0978d6..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);
 
@@ -168,7 +168,7 @@ entity WaypointSprite_getviewentity(entity e);
 
 float WaypointSprite_isteammate(entity e, entity e2);
 
-float WaypointSprite_Customize(entity this);
+bool WaypointSprite_Customize(entity this, entity client);
 
 bool WaypointSprite_SendEntity(entity this, entity to, float sendflags);
 
index 1e1726ae452fe716041d291f30581eb3a1d3cab9..20d1351ebcae9475043db8b86de15a2df2df370d 100644 (file)
@@ -41,24 +41,30 @@ NET_HANDLE(TE_CSQC_SVNOTICE, bool isNew)
        return true;
 }
 entity cl_notices;
-STATIC_INIT(cl_notice)
-{
-    cl_notices = LL_NEW();
-}
 void cl_notice_read()
 {
     entity _notice = new_pure(sv_notice);
     _notice.netname = strzone(ReadString());
     _notice.alpha = ReadLong() + time;
     _notice.skin = ReadByte();
+    if(!cl_notices)
+       cl_notices = LL_NEW();
     LL_PUSH(cl_notices, _notice);
 }
 
 void cl_notice_run()
 {
+       if (!cl_notices)
+               return;
+
     bool flag = false;
     LL_EACH(cl_notices, it.alpha > time, { flag = true; break; });
-    if (!flag) return;
+       if (!flag)
+       {
+               LL_DELETE(cl_notices);
+               return;
+       }
+
     const int M1 = 30;
     const int M2 = 10;
 
@@ -76,10 +82,18 @@ void cl_notice_run()
     vector v3 = v1 + '10 10 0';
     #define OUT(s, z) MACRO_BEGIN { drawcolorcodedstring(v3, s, '1 1 0' * z, 1, DRAWFLAG_NORMAL); v3.y += z + 4; } MACRO_END
 
+    float cur_time = 0;
+    float time_width = 48;
     OUT(_("^1Server notices:"), 32);
     LL_EACH(cl_notices, it.alpha > time, {
-        string s = sprintf(_("^7%s (^3%d sec left)"), it.netname , rint(it.alpha - time));
-        OUT(s, 16);
+        if(it.alpha - cur_time > 0.1)
+        {
+            cur_time = it.alpha;
+            string s = sprintf("^3%d", ceil(cur_time - time));
+            drawcolorcodedstring(v3 + eX * 0.5 * (time_width - stringwidth(s, true, '1 1 0' * 16)), s, '1 1 0' * 16, 1, DRAWFLAG_NORMAL);
+            v3.x = v1.x + 10 + time_width;
+        }
+        OUT(it.netname, 16);
     });
     #undef OUT
 }
index 42cf6a21493376c6aab2ff9a4013bc0bfc8d902f..25c7c63befde9fbdf268584be2110c3f5ee553e4 100644 (file)
     MSG_INFO_NOTIF(WEAPON_SEEKER_MURDER_SPRAY,              1,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",       "weaponseeker",             _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Seeker rockets%s%s"), "")
     MSG_INFO_NOTIF(WEAPON_SEEKER_MURDER_TAG,                1,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",       "weaponseeker",             _("^BG%s%s^K1 was tagged by ^BG%s^K1's Seeker%s%s"), "")
     MSG_INFO_NOTIF(WEAPON_SEEKER_SUICIDE,                   1,  2, 1, "s1 s2loc spree_lost", "s1",                      "weaponseeker",             _("^BG%s^K1 played with tiny Seeker rockets%s%s"), "")
-    MSG_INFO_NOTIF(WEAPON_SHOCKWAVE_MURDER,                 1,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",       "weaponshotgun",            _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shockwave%s%s"), "")
+    MSG_INFO_NOTIF(WEAPON_SHOCKWAVE_MURDER,                 1,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",       "weaponshockwave",          _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shockwave%s%s"), "")
     MSG_INFO_NOTIF(WEAPON_SHOCKWAVE_MURDER_SLAP,            1,  3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1",       "notify_melee_shotgun",     _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shockwave%s%s"), "")
     MSG_INFO_NOTIF(WEAPON_SHOTGUN_MURDER,                   1,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",       "weaponshotgun",            _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shotgun%s%s"), "")
     MSG_INFO_NOTIF(WEAPON_SHOTGUN_MURDER_SLAP,              1,  3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1",       "notify_melee_shotgun",     _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shotgun%s%s"), "")
     MULTITEAM_CENTER(CTF_PICKUP_TEAM_VERBOSE, 4,        1,      2, 0, "s1 s2 s1",       CPID_CTF_LOWPRIO,       "0 0",  _("^BGYour %steam mate (^BG%s%s)^BG got the ^TC^TT^BG flag! Protect them!"), "", FLAG)
     MSG_CENTER_NOTIF(CTF_PICKUP_TEAM_NEUTRAL,           1,      1, 0, "s1",             CPID_CTF_LOWPRIO,       "0 0",  _("^BGYour %steam mate^BG got the flag! Protect them!"), "")
     MSG_CENTER_NOTIF(CTF_PICKUP_TEAM_VERBOSE_NEUTRAL,   1,      2, 0, "s1 s2 s1",       CPID_CTF_LOWPRIO,       "0 0",  _("^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"), "")
+    MSG_CENTER_NOTIF(CTF_PICKUP_VISIBLE,                1,      0, 0, "",               CPID_STALEMATE,         "0 0",  _("^BGEnemies can now see you on radar!"), "")
     MULTITEAM_CENTER(CTF_RETURN, 4,                     1,      0, 0, "",               CPID_CTF_LOWPRIO,       "0 0",  _("^BGYou returned the ^TC^TT^BG flag!"), "", FLAG)
     MSG_CENTER_NOTIF(CTF_STALEMATE_CARRIER,             1,      0, 0, "",               CPID_STALEMATE,         "0 0",  _("^BGStalemate! Enemies can now see you on radar!"), "")
     MSG_CENTER_NOTIF(CTF_STALEMATE_OTHER,               1,      0, 0, "",               CPID_STALEMATE,         "0 0",  _("^BGStalemate! Flag carriers can now be seen by enemies on radar!"), "")
index 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 a68e3e3a08121a9493c041cb07d06f0702e0ed89..090144dd16069f16573489d72f8a8cae53c7cdb0 100644 (file)
        #include <server/autocvars.qh>
 #endif
 
+#ifdef SVQC
+void set_movetype(entity this, int mt)
+{
+       if(mt == MOVETYPE_PHYSICS || mt == MOVETYPE_PUSH || mt == MOVETYPE_FAKEPUSH)
+       {
+               this.movetype = this.move_movetype = mt; // we still set move_movetype, for other code that checks movetype
+               this.move_qcphysics = false;
+               return;
+       }
+
+       this.move_movetype = mt;
+
+       if(!this.move_qcphysics)
+               this.movetype = mt;
+}
+#elif defined(CSQC)
+void set_movetype(entity this, int mt)
+{
+       this.move_movetype = mt;
+}
+#endif
+
 void _Movetype_WallFriction(entity this, vector stepnormal)  // SV_WallFriction
 {
        /*float d, i;
@@ -21,11 +43,11 @@ void _Movetype_WallFriction(entity this, vector stepnormal)  // SV_WallFriction
 
        if(d < 0)
        {
-           i = (stepnormal * this.move_velocity);
+           i = (stepnormal * this.velocity);
            into = i * stepnormal;
-           side = this.move_velocity - into;
-           this.move_velocity_x = side.x * (1 * d);
-           this.move_velocity_y = side.y * (1 * d);
+           side = this.velocity - into;
+           this.velocity_x = side.x * (1 * d);
+           this.velocity_y = side.y * (1 * d);
        }*/
 }
 
@@ -46,23 +68,23 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                this.move_didgravity = 1;
                grav = dt * (PHYS_ENTGRAVITY(this) ? PHYS_ENTGRAVITY(this) : 1) * PHYS_GRAVITY(this);
 
-               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(this.move_flags & FL_ONGROUND))
+               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !IS_ONGROUND(this))
                {
                        if(GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                               this.move_velocity_z -= grav * 0.5;
+                               this.velocity_z -= grav * 0.5;
                        else
-                               this.move_velocity_z -= grav;
+                               this.velocity_z -= grav;
                }
        }
 
-       original_velocity = primal_velocity = restore_velocity = this.move_velocity;
+       original_velocity = primal_velocity = restore_velocity = this.velocity;
 
        for(bumpcount = 0;bumpcount < MAX_CLIP_PLANES;bumpcount++)
        {
-               if(this.move_velocity == '0 0 0')
+               if(this.velocity == '0 0 0')
                        break;
 
-               push = this.move_velocity * time_left;
+               push = this.velocity * time_left;
                _Movetype_PushEntity(this, push, true);
                if(trace_startsolid)
                {
@@ -76,7 +98,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                // abort move if we're stuck in the world (and didn't make it out)
                if(trace_startsolid && trace_allsolid)
                {
-                       this.move_velocity = restore_velocity;
+                       this.velocity = restore_velocity;
                        return 3;
                }
 
@@ -99,14 +121,14 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                                        trace_ent = NULL;
                                }
 
-                               this.move_flags |= FL_ONGROUND;
-                               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 +144,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                                break;
                        }
                        float trace2_fraction = trace_fraction;
-                       steppush = '0 0 1' * (org_z - this.move_origin_z);
+                       steppush = '0 0 1' * (org_z - this.origin_z);
                        _Movetype_PushEntity(this, steppush, true);
                        if(trace_startsolid)
                        {
@@ -131,15 +153,15 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                        }
 
                        // accept the new position if it made some progress...
-                       if(fabs(this.move_origin_x - org_x) >= 0.03125 || fabs(this.move_origin_y - org_y) >= 0.03125)
+                       if(fabs(this.origin_x - org_x) >= 0.03125 || fabs(this.origin_y - org_y) >= 0.03125)
                        {
-                               trace_endpos = this.move_origin;
+                               trace_endpos = this.origin;
                                time_left *= 1 - trace2_fraction;
                                numplanes = 0;
                                continue;
                        }
                        else
-                               this.move_origin = org;
+                               this.origin = org;
                }
                else
                {
@@ -153,7 +175,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                if(my_trace_fraction >= 0.001)
                {
                        // actually covered some distance
-                       original_velocity = this.move_velocity;
+                       original_velocity = this.velocity;
                        numplanes = 0;
                }
 
@@ -163,7 +185,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                if(numplanes >= MAX_CLIP_PLANES)
                {
                        // this shouldn't really happen
-                       this.move_velocity = '0 0 0';
+                       this.velocity = '0 0 0';
                        blocked = 3;
                        break;
                }
@@ -192,14 +214,14 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                if(i != numplanes)
                {
                        // go along this plane
-                       this.move_velocity = new_velocity;
+                       this.velocity = new_velocity;
                }
                else
                {
                        // go along the crease
                        if(numplanes != 2)
                        {
-                               this.move_velocity = '0 0 0';
+                               this.velocity = '0 0 0';
                                blocked = 7;
                                break;
                        }
@@ -211,29 +233,29 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
                        dir.x *= ilength;
                        dir.y *= ilength;
                        dir.z *= ilength;
-                       float d = (dir * this.move_velocity);
-                       this.move_velocity = dir * d;
+                       float d = (dir * this.velocity);
+                       this.velocity = dir * d;
                }
 
                // if current velocity is against the original velocity,
                // stop dead to avoid tiny occilations in sloping corners
-               if((this.move_velocity * primal_velocity) <= 0)
+               if((this.velocity * primal_velocity) <= 0)
                {
-                       this.move_velocity = '0 0 0';
+                       this.velocity = '0 0 0';
                        break;
                }
        }
 
        // LordHavoc: this came from QW and allows you to get out of water more easily
-       if(GAMEPLAYFIX_EASIERWATERJUMP(this) && (this.move_flags & FL_WATERJUMP) && !(blocked & 8))
-               this.move_velocity = primal_velocity;
+       if(GAMEPLAYFIX_EASIERWATERJUMP(this) && (this.flags & FL_WATERJUMP) && !(blocked & 8))
+               this.velocity = primal_velocity;
 
        if(applygravity)
        {
-               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(this.move_flags & FL_ONGROUND))
+               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !IS_ONGROUND(this))
                {
                        if(GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                               this.move_velocity_z -= grav * 0.5f;
+                               this.velocity_z -= grav * 0.5f;
                }
        }
 
@@ -242,98 +264,84 @@ 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);
        }
 }
 
 void _Movetype_Impact(entity this, entity oth)  // SV_Impact
 {
-       entity oldother = other;
-
        if(gettouch(this))
-       {
-               other = oth;
-
-               gettouch(this)(this);
-
-               other = oldother;
-       }
+               gettouch(this)(this, oth);
 
        if(gettouch(oth))
-       {
-               other = this;
-
-               gettouch(oth)(oth);
-
-               other = oldother;
-       }
+               gettouch(oth)(oth, this);
 }
 
 void _Movetype_LinkEdict_TouchAreaGrid(entity this)  // SV_LinkEdict_TouchAreaGrid
@@ -341,30 +349,24 @@ void _Movetype_LinkEdict_TouchAreaGrid(entity this)  // SV_LinkEdict_TouchAreaGr
        if(this.solid == SOLID_NOT)
                return;
 
-       entity oldother = other;
-
     FOREACH_ENTITY_RADIUS(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin), true, {
                if (it.solid == SOLID_TRIGGER && it != this)
                if (it.move_nomonsters != MOVE_NOMONSTERS && it.move_nomonsters != MOVE_WORLDONLY)
                if (gettouch(it) && boxesoverlap(it.absmin, it.absmax, this.absmin, this.absmax))
                {
-                       other = this;
-
                        trace_allsolid = false;
                        trace_startsolid = false;
                        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;
 
-                       gettouch(it)(it);
+                       gettouch(it)(it, this);
                }
     });
-
-       other = oldother;
 }
 
 void _Movetype_LinkEdict(entity this, bool touch_triggers)  // SV_LinkEdict
@@ -381,10 +383,10 @@ void _Movetype_LinkEdict(entity this, bool touch_triggers)  // SV_LinkEdict
                mi = this.mins;
                ma = this.maxs;
        }
-       mi += this.move_origin;
-       ma += this.move_origin;
+       mi += this.origin;
+       ma += this.origin;
 
-       if(this.move_flags & FL_ITEM)
+       if(this.flags & FL_ITEM)
        {
                mi.x -= 15;
                mi.y -= 15;
@@ -414,18 +416,18 @@ entity _Movetype_TestEntityPosition_ent;
 bool _Movetype_TestEntityPosition(vector ofs)  // SV_TestEntityPosition
 {
     entity this = _Movetype_TestEntityPosition_ent;
-//     vector org = this.move_origin + ofs;
+//     vector org = this.origin + ofs;
 
        int cont = this.dphitcontentsmask;
        this.dphitcontentsmask = DPCONTENTS_SOLID;
-       tracebox(this.move_origin, this.mins, this.maxs, this.move_origin, ((this.move_movetype == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), this);
+       tracebox(this.origin, this.mins, this.maxs, this.origin, ((this.move_movetype == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), this);
        this.dphitcontentsmask = cont;
 
        if(trace_startsolid)
                return true;
 
-       if(vdist(trace_endpos - this.move_origin, >, 0.0001))
-               this.move_origin = trace_endpos;
+       if(vdist(trace_endpos - this.origin, >, 0.0001))
+               this.origin = trace_endpos;
        return false;
 }
 
@@ -451,12 +453,12 @@ bool _Movetype_UnstickEntity(entity this)  // SV_UnstickEntity
         #undef X
         {
             LOG_DEBUGF("Can't unstick an entity (edict: %d, classname: %s, origin: %s)\n",
-                etof(this), this.classname, vtos(this.move_origin));
+                etof(this), this.classname, vtos(this.origin));
             return false;
         }
        }
        LOG_DEBUGF("Sucessfully unstuck an entity (edict: %d, classname: %s, origin: %s)\n",
-               etof(this), this.classname, vtos(this.move_origin));
+               etof(this), this.classname, vtos(this.origin));
        _Movetype_LinkEdict(this, true);
        return true;
 }
@@ -474,7 +476,7 @@ vector _Movetype_ClipVelocity(vector vel, vector norm, float f)  // SV_ClipVeloc
 
 void _Movetype_PushEntityTrace(entity this, vector push)
 {
-       vector end = this.move_origin + push;
+       vector end = this.origin + push;
        int type;
        if(this.move_nomonsters)
                type = max(0, this.move_nomonsters);
@@ -487,7 +489,7 @@ void _Movetype_PushEntityTrace(entity this, vector push)
        else
                type = MOVE_NORMAL;
 
-       tracebox(this.move_origin, this.mins, this.maxs, end, type, this);
+       tracebox(this.origin, this.mins, this.maxs, end, type, this);
 }
 
 float _Movetype_PushEntity(entity this, vector push, bool failonstartsolid)  // SV_PushEntity
@@ -497,10 +499,10 @@ float _Movetype_PushEntity(entity this, vector push, bool failonstartsolid)  //
        if(trace_startsolid && failonstartsolid)
                return trace_fraction;
 
-       this.move_origin = trace_endpos;
+       this.origin = trace_endpos;
 
        if(trace_fraction < 1)
-               if(this.solid >= SOLID_TRIGGER && (!(this.move_flags & FL_ONGROUND) || (this.move_groundentity != trace_ent)))
+               if(this.solid >= SOLID_TRIGGER && (!IS_ONGROUND(this) || (this.groundentity != trace_ent)))
                        _Movetype_Impact(this, trace_ent);
 
        return trace_fraction;
@@ -571,7 +573,7 @@ void _Movetype_Physics_Frame(entity this, float movedt)
        {
                case MOVETYPE_PUSH:
                case MOVETYPE_FAKEPUSH:
-                       _Movetype_Physics_Pusher(this, movedt);
+                       LOG_DEBUGF("Physics: Lacking QuakeC support for Push movetype, FIX ME by using engine physics!\n");
                        break;
                case MOVETYPE_NONE:
                        break;
@@ -580,8 +582,8 @@ void _Movetype_Physics_Frame(entity this, float movedt)
                        break;
                case MOVETYPE_NOCLIP:
                        _Movetype_CheckWater(this);
-                       this.move_origin = this.move_origin + TICRATE * this.move_velocity;
-                       this.move_angles = this.move_angles + TICRATE * this.move_avelocity;
+                       this.origin = this.origin + movedt * this.velocity;
+                       this.angles = this.angles + movedt * this.avelocity;
                        _Movetype_LinkEdict(this, false);
                        break;
                case MOVETYPE_STEP:
@@ -611,7 +613,7 @@ void _Movetype_Physics_ClientFrame(entity this, float movedt)
        {
                case MOVETYPE_PUSH:
                case MOVETYPE_FAKEPUSH:
-                       _Movetype_Physics_Pusher(this, movedt);
+                       LOG_DEBUGF("Physics: Lacking QuakeC support for Push movetype, FIX ME by using engine physics!\n");
                        break;
                case MOVETYPE_NONE:
                        break;
@@ -620,8 +622,8 @@ void _Movetype_Physics_ClientFrame(entity this, float movedt)
                        break;
                case MOVETYPE_NOCLIP:
                        _Movetype_CheckWater(this);
-                       this.move_origin = this.move_origin + movedt * this.move_velocity;
-                       this.move_angles = this.move_angles + movedt * this.move_avelocity;
+                       this.origin = this.origin + movedt * this.velocity;
+                       this.angles = this.angles + movedt * this.avelocity;
                        _Movetype_LinkEdict(this, false);
                        break;
                case MOVETYPE_STEP:
@@ -643,6 +645,20 @@ void _Movetype_Physics_ClientFrame(entity this, float movedt)
        }
 }
 
+void Movetype_Physics_NoMatchTicrate(entity this, float movedt, bool isclient)  // to be run every move frame
+{
+       this.move_time = time;
+
+       if(isclient)
+               _Movetype_Physics_ClientFrame(this, movedt);
+       else
+               _Movetype_Physics_Frame(this, movedt);
+       if(wasfreed(this))
+               return;
+
+       setorigin(this, this.origin);
+}
+
 void Movetype_Physics_NoMatchServer(entity this)  // optimized
 {
        float movedt = time - this.move_time;
@@ -652,10 +668,7 @@ void Movetype_Physics_NoMatchServer(entity this)  // optimized
        if(wasfreed(this))
                return;
 
-       this.avelocity = this.move_avelocity;
-       this.velocity = this.move_velocity;
-       this.angles = this.move_angles;
-       setorigin(this, this.move_origin);
+       setorigin(this, this.origin);
 }
 
 void Movetype_Physics_MatchServer(entity this, bool sloppy)
@@ -663,11 +676,49 @@ void Movetype_Physics_MatchServer(entity this, bool sloppy)
        Movetype_Physics_MatchTicrate(this, TICRATE, sloppy);
 }
 
+.vector tic_origin;
+.vector tic_velocity;
+.int tic_flags;
+.vector tic_avelocity;
+.vector tic_angles;
+
+.vector tic_saved_origin;
+.vector tic_saved_velocity;
+.int tic_saved_flags;
+.vector tic_saved_avelocity;
+.vector tic_saved_angles;
 void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Physics_Entity
 {
+#define X(s) \
+       if(this.(s) != this.tic_saved_##s) \
+               this.tic_##s = this.(s)
+
+       X(origin);
+       X(velocity);
+       X(flags);
+       X(avelocity);
+       X(angles);
+#undef X
+
        if(tr <= 0)
        {
+               this.flags = this.tic_flags;
+               this.velocity = this.tic_velocity;
+               this.origin = this.tic_origin;
+               this.avelocity = this.tic_avelocity;
+               this.angles = this.tic_angles;
                Movetype_Physics_NoMatchServer(this);
+               this.tic_origin = this.origin;
+               this.tic_velocity = this.velocity;
+               this.tic_avelocity = this.avelocity;
+               this.tic_angles = this.angles;
+               this.tic_flags = this.flags;
+
+               this.tic_saved_flags = this.flags;
+               this.tic_saved_velocity = this.velocity;
+               this.tic_saved_origin = this.origin;
+               this.tic_saved_avelocity = this.avelocity;
+               this.tic_saved_angles = this.angles;
                return;
        }
 
@@ -678,21 +729,31 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
        this.move_time += n * tr;
 
        if(!this.move_didgravity)
-               this.move_didgravity = ((this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS) && !(this.move_flags & FL_ONGROUND));
+               this.move_didgravity = ((this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS) && !(this.tic_flags & FL_ONGROUND));
 
        for (int i = 0; i < n; ++i)
        {
+               this.flags = this.tic_flags;
+               this.velocity = this.tic_velocity;
+               setorigin(this, this.tic_origin);
+               this.avelocity = this.tic_avelocity;
+               this.angles = this.tic_angles;
                _Movetype_Physics_Frame(this, tr);
+               this.tic_origin = this.origin;
+               this.tic_velocity = this.velocity;
+               this.tic_avelocity = this.avelocity;
+               this.tic_angles = this.angles;
+               this.tic_flags = this.flags;
                if(wasfreed(this))
                        return;
        }
 
-       this.avelocity = this.move_avelocity;
+       this.avelocity = this.tic_avelocity;
 
-       if(dt > 0 && this.move_movetype != MOVETYPE_NONE && !(this.move_flags & FL_ONGROUND))
+       if(dt > 0 && this.move_movetype != MOVETYPE_NONE && !(this.tic_flags & FL_ONGROUND))
        {
                // now continue the move from move_time to time
-               this.velocity = this.move_velocity;
+               this.velocity = this.tic_velocity;
 
                if(this.move_didgravity > 0)
                {
@@ -702,15 +763,18 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
                            * PHYS_GRAVITY(this);
                }
 
-               this.angles = this.move_angles + dt * this.avelocity;
+               this.angles = this.tic_angles + dt * this.avelocity;
 
                if(sloppy || this.move_movetype == MOVETYPE_NOCLIP)
                {
-                       setorigin(this, this.move_origin + dt * this.velocity);
+                       setorigin(this, this.tic_origin + dt * this.velocity);
                }
                else
                {
+                       vector oldorg = this.origin;
+                       this.origin = this.tic_origin;
                        _Movetype_PushEntityTrace(this, dt * this.velocity);
+                       this.origin = oldorg;
                        if(!trace_startsolid)
                                setorigin(this, trace_endpos);
                }
@@ -720,8 +784,14 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
        }
        else
        {
-               this.velocity = this.move_velocity;
-               this.angles = this.move_angles;
-               setorigin(this, this.move_origin);
+               this.velocity = this.tic_velocity;
+               this.angles = this.tic_angles;
+               setorigin(this, this.tic_origin);
        }
+
+       this.tic_saved_flags = this.flags;
+       this.tic_saved_velocity = this.velocity;
+       this.tic_saved_origin = this.origin;
+       this.tic_saved_avelocity = this.avelocity;
+       this.tic_saved_angles = this.angles;
 }
index 764b993805ad55ec44a864e806e79dd98ad5529d..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) 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 0d03bff..0000000
+++ /dev/null
@@ -1,154 +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;
-               other = NULL;
-               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 f515a75f9fbbb09c17bd5abc78ef07312650372d..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;
                }
        }
@@ -23,21 +23,27 @@ void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
 
        _Movetype_CheckVelocity(this);
 
-       if (this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_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);
+       }*/
+
+       if (this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS)
+       {
+               this.move_didgravity = true;
+               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;
@@ -57,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);
                        }
                }
 
@@ -104,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 907784d356ad96e31abf6f61997dea106fb323ae..74a44252fe8bd6d7fc8a11a177ca7ad9c1dfd8ee 100644 (file)
@@ -13,7 +13,7 @@ bool Physics_Valid(string thecvar)
        return autocvar_g_physics_clientselect && strhasword(autocvar_g_physics_clientselect_options, thecvar);
 }
 
-float Physics_ClientOption(entity this, string option)
+float Physics_ClientOption(entity this, string option, float defaultval)
 {
        if(Physics_Valid(this.cvar_cl_physics))
        {
@@ -27,40 +27,40 @@ float Physics_ClientOption(entity this, string option)
                if(cvar_type(s) & CVAR_TYPEFLAG_EXISTS)
                        return cvar(s);
        }
-       return cvar(strcat("sv_", option));
+       return defaultval;
 }
 
 void Physics_UpdateStats(entity this, float maxspd_mod)
 {
-       STAT(MOVEVARS_AIRACCEL_QW, this) = AdjustAirAccelQW(Physics_ClientOption(this, "airaccel_qw"), maxspd_mod);
-       STAT(MOVEVARS_AIRSTRAFEACCEL_QW, this) = (Physics_ClientOption(this, "airstrafeaccel_qw"))
-               ? AdjustAirAccelQW(Physics_ClientOption(this, "airstrafeaccel_qw"), maxspd_mod)
+       STAT(MOVEVARS_AIRACCEL_QW, this) = AdjustAirAccelQW(Physics_ClientOption(this, "airaccel_qw", autocvar_sv_airaccel_qw), maxspd_mod);
+       STAT(MOVEVARS_AIRSTRAFEACCEL_QW, this) = (Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw))
+               ? AdjustAirAccelQW(Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw), maxspd_mod)
                : 0;
-       STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, this) = Physics_ClientOption(this, "airspeedlimit_nonqw") * maxspd_mod;
-       STAT(MOVEVARS_MAXSPEED, this) = Physics_ClientOption(this, "maxspeed") * maxspd_mod; // also slow walking
+       STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, this) = Physics_ClientOption(this, "airspeedlimit_nonqw", autocvar_sv_airspeedlimit_nonqw) * maxspd_mod;
+       STAT(MOVEVARS_MAXSPEED, this) = Physics_ClientOption(this, "maxspeed", autocvar_sv_maxspeed) * maxspd_mod; // also slow walking
 
        // old stats
        // fix some new settings
-       STAT(MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, this) = Physics_ClientOption(this, "airaccel_qw_stretchfactor");
-       STAT(MOVEVARS_MAXAIRSTRAFESPEED, this) = Physics_ClientOption(this, "maxairstrafespeed");
-       STAT(MOVEVARS_MAXAIRSPEED, this) = Physics_ClientOption(this, "maxairspeed");
-       STAT(MOVEVARS_AIRSTRAFEACCELERATE, this) = Physics_ClientOption(this, "airstrafeaccelerate");
-       STAT(MOVEVARS_WARSOWBUNNY_TURNACCEL, this) = Physics_ClientOption(this, "warsowbunny_turnaccel");
-       STAT(MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, this) = Physics_ClientOption(this, "airaccel_sideways_friction");
-       STAT(MOVEVARS_AIRCONTROL, this) = Physics_ClientOption(this, "aircontrol");
-       STAT(MOVEVARS_AIRCONTROL_POWER, this) = Physics_ClientOption(this, "aircontrol_power");
-       STAT(MOVEVARS_AIRCONTROL_PENALTY, this) = Physics_ClientOption(this, "aircontrol_penalty");
-       STAT(MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, this) = Physics_ClientOption(this, "warsowbunny_airforwardaccel");
-       STAT(MOVEVARS_WARSOWBUNNY_TOPSPEED, this) = Physics_ClientOption(this, "warsowbunny_topspeed");
-       STAT(MOVEVARS_WARSOWBUNNY_ACCEL, this) = Physics_ClientOption(this, "warsowbunny_accel");
-       STAT(MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, this) = Physics_ClientOption(this, "warsowbunny_backtosideratio");
-       STAT(MOVEVARS_FRICTION, this) = Physics_ClientOption(this, "friction");
-       STAT(MOVEVARS_ACCELERATE, this) = Physics_ClientOption(this, "accelerate");
-       STAT(MOVEVARS_STOPSPEED, this) = Physics_ClientOption(this, "stopspeed");
-       STAT(MOVEVARS_AIRACCELERATE, this) = Physics_ClientOption(this, "airaccelerate");
-       STAT(MOVEVARS_AIRSTOPACCELERATE, this) = Physics_ClientOption(this, "airstopaccelerate");
-       STAT(MOVEVARS_JUMPVELOCITY, this) = Physics_ClientOption(this, "jumpvelocity");
-       STAT(MOVEVARS_TRACK_CANJUMP, this) = Physics_ClientOption(this, "track_canjump");
+       STAT(MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, this) = Physics_ClientOption(this, "airaccel_qw_stretchfactor", autocvar_sv_airaccel_qw_stretchfactor);
+       STAT(MOVEVARS_MAXAIRSTRAFESPEED, this) = Physics_ClientOption(this, "maxairstrafespeed", autocvar_sv_maxairstrafespeed);
+       STAT(MOVEVARS_MAXAIRSPEED, this) = Physics_ClientOption(this, "maxairspeed", autocvar_sv_maxairspeed);
+       STAT(MOVEVARS_AIRSTRAFEACCELERATE, this) = Physics_ClientOption(this, "airstrafeaccelerate", autocvar_sv_airstrafeaccelerate);
+       STAT(MOVEVARS_WARSOWBUNNY_TURNACCEL, this) = Physics_ClientOption(this, "warsowbunny_turnaccel", autocvar_sv_warsowbunny_turnaccel);
+       STAT(MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, this) = Physics_ClientOption(this, "airaccel_sideways_friction", autocvar_sv_airaccel_sideways_friction);
+       STAT(MOVEVARS_AIRCONTROL, this) = Physics_ClientOption(this, "aircontrol", autocvar_sv_aircontrol);
+       STAT(MOVEVARS_AIRCONTROL_POWER, this) = Physics_ClientOption(this, "aircontrol_power", autocvar_sv_aircontrol_power);
+       STAT(MOVEVARS_AIRCONTROL_PENALTY, this) = Physics_ClientOption(this, "aircontrol_penalty", autocvar_sv_aircontrol_penalty);
+       STAT(MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, this) = Physics_ClientOption(this, "warsowbunny_airforwardaccel", autocvar_sv_warsowbunny_airforwardaccel);
+       STAT(MOVEVARS_WARSOWBUNNY_TOPSPEED, this) = Physics_ClientOption(this, "warsowbunny_topspeed", autocvar_sv_warsowbunny_topspeed);
+       STAT(MOVEVARS_WARSOWBUNNY_ACCEL, this) = Physics_ClientOption(this, "warsowbunny_accel", autocvar_sv_warsowbunny_accel);
+       STAT(MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, this) = Physics_ClientOption(this, "warsowbunny_backtosideratio", autocvar_sv_warsowbunny_backtosideratio);
+       STAT(MOVEVARS_FRICTION, this) = Physics_ClientOption(this, "friction", autocvar_sv_friction);
+       STAT(MOVEVARS_ACCELERATE, this) = Physics_ClientOption(this, "accelerate", autocvar_sv_accelerate);
+       STAT(MOVEVARS_STOPSPEED, this) = Physics_ClientOption(this, "stopspeed", autocvar_sv_stopspeed);
+       STAT(MOVEVARS_AIRACCELERATE, this) = Physics_ClientOption(this, "airaccelerate", autocvar_sv_airaccelerate);
+       STAT(MOVEVARS_AIRSTOPACCELERATE, this) = Physics_ClientOption(this, "airstopaccelerate", autocvar_sv_airstopaccelerate);
+       STAT(MOVEVARS_JUMPVELOCITY, this) = Physics_ClientOption(this, "jumpvelocity", autocvar_sv_jumpvelocity);
+       STAT(MOVEVARS_TRACK_CANJUMP, this) = Physics_ClientOption(this, "track_canjump", autocvar_sv_track_canjump);
 }
 #endif
 
@@ -73,11 +73,11 @@ float IsMoveInDirection(vector mv, float ang) // key mix factor
        return ang > 1 ? 0 : ang < -1 ? 0 : 1 - fabs(ang);
 }
 
-float GeomLerp(float a, float lerp, float b)
+float GeomLerp(float a, float _lerp, float b)
 {
-       return a == 0 ? (lerp < 1 ? 0 : b)
-               : b == 0 ? (lerp > 0 ? 0 : a)
-               : a * pow(fabs(b / a), lerp);
+       return a == 0 ? (_lerp < 1 ? 0 : b)
+               : b == 0 ? (_lerp > 0 ? 0 : a)
+               : a * pow(fabs(b / a), _lerp);
 }
 
 #define unstick_offsets(X) \
@@ -118,24 +118,25 @@ void PM_ClientMovement_Unstick(entity this)
        #undef X
 }
 
-void PM_ClientMovement_UpdateStatus(entity this, bool ground)
+void PM_ClientMovement_UpdateStatus(entity this)
 {
 #ifdef CSQC
        if(!IS_PLAYER(this))
                return;
-       // make sure player is not stuck
-       if(autocvar_cl_movement == 3)
-               PM_ClientMovement_Unstick(this);
 
        // set crouched
        bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
        if(this.hook && !wasfreed(this.hook))
                do_crouch = false;
+       if(this.waterlevel >= WATERLEVEL_SWIMMING)
+               do_crouch = false;
        if(hud != HUD_NORMAL)
                do_crouch = false;
        if(STAT(FROZEN, this))
                do_crouch = false;
-       if((activeweapon == WEP_SHOCKWAVE || activeweapon == WEP_SHOTGUN) && viewmodel.animstate_startframe == viewmodel.anim_fire2_x && time < viewmodel.weapon_nextthink)
+       if((activeweapon.spawnflags & WEP_TYPE_MELEE_PRI) && viewmodel.animstate_startframe == viewmodel.anim_fire1_x && time < viewmodel.weapon_nextthink)
+               do_crouch = false;
+       if((activeweapon.spawnflags & WEP_TYPE_MELEE_SEC) && viewmodel.animstate_startframe == viewmodel.anim_fire2_x && time < viewmodel.weapon_nextthink)
                do_crouch = false;
 
        if (do_crouch)
@@ -153,148 +154,11 @@ void PM_ClientMovement_UpdateStatus(entity this, bool ground)
                }
        }
 
-       // set onground
-       vector origin1 = this.origin + '0 0 1';
-       vector origin2 = this.origin - '0 0 1';
-
-       if (ground && autocvar_cl_movement == 3)
-       {
-               tracebox(origin1, this.mins, this.maxs, origin2, MOVE_NORMAL, this);
-               if (trace_fraction < 1.0 && trace_plane_normal.z > 0.7)
-               {
-                       SET_ONGROUND(this);
-
-                       // this code actually "predicts" an impact; so let's clip velocity first
-                       this.velocity -= this.velocity * trace_plane_normal * trace_plane_normal;
-               }
-               else
-                       UNSET_ONGROUND(this);
-       }
-
-       if(autocvar_cl_movement == 3)
-       {
-               // set watertype/waterlevel
-               origin1 = this.origin;
-               origin1.z += this.mins_z + 1;
-               this.waterlevel = WATERLEVEL_NONE;
-
-               int thepoint = pointcontents(origin1);
-
-               this.watertype = (thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME);
-
-               if (this.watertype)
-               {
-                       this.waterlevel = WATERLEVEL_WETFEET;
-                       origin1.z = this.origin.z + (this.mins.z + this.maxs.z) * 0.5;
-                       thepoint = pointcontents(origin1);
-                       if (thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME)
-                       {
-                               this.waterlevel = WATERLEVEL_SWIMMING;
-                               origin1.z = this.origin.z + 22;
-                               thepoint = pointcontents(origin1);
-                               if (thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME)
-                                       this.waterlevel = WATERLEVEL_SUBMERGED;
-                       }
-               }
-       }
-
        if (IS_ONGROUND(this) || this.velocity.z <= 0 || PHYS_WATERJUMP_TIME(this) <= 0)
                PHYS_WATERJUMP_TIME(this) = 0;
 #endif
 }
 
-void PM_ClientMovement_Move(entity this)
-{
-#ifdef CSQC
-
-       PM_ClientMovement_UpdateStatus(this, false);
-       if(autocvar_cl_movement == 1)
-               return;
-
-       int bump;
-       float t;
-       float f;
-       vector neworigin;
-       vector currentorigin2;
-       vector neworigin2;
-       vector primalvelocity;
-
-       vector trace1_endpos = '0 0 0';
-       vector trace2_endpos = '0 0 0';
-       vector trace3_endpos = '0 0 0';
-       float trace1_fraction = 0;
-       float trace2_fraction = 0;
-       float trace3_fraction = 0;
-       vector trace1_plane_normal = '0 0 0';
-       vector trace2_plane_normal = '0 0 0';
-       vector trace3_plane_normal = '0 0 0';
-
-       primalvelocity = this.velocity;
-       for(bump = 0, t = PHYS_INPUT_TIMELENGTH; bump < 8 && (this.velocity * this.velocity) > 0; bump++)
-       {
-               neworigin = this.origin + t * this.velocity;
-               tracebox(this.origin, this.mins, this.maxs, neworigin, MOVE_NORMAL, this);
-               trace1_endpos = trace_endpos;
-               trace1_fraction = trace_fraction;
-               trace1_plane_normal = trace_plane_normal;
-               if(trace1_fraction < 1 && trace1_plane_normal_z == 0)
-               {
-                       // may be a step or wall, try stepping up
-                       // first move forward at a higher level
-                       currentorigin2 = this.origin;
-                       currentorigin2_z += PHYS_STEPHEIGHT(this);
-                       neworigin2 = neworigin;
-                       neworigin2_z += PHYS_STEPHEIGHT(this);
-                       tracebox(currentorigin2, this.mins, this.maxs, neworigin2, MOVE_NORMAL, this);
-                       trace2_endpos = trace_endpos;
-                       trace2_fraction = trace_fraction;
-                       trace2_plane_normal = trace_plane_normal;
-                       if(!trace_startsolid)
-                       {
-                               // then move down from there
-                               currentorigin2 = trace2_endpos;
-                               neworigin2 = trace2_endpos;
-                               neworigin2_z = this.origin_z;
-                               tracebox(currentorigin2, this.mins, this.maxs, neworigin2, MOVE_NORMAL, this);
-                               trace3_endpos = trace_endpos;
-                               trace3_fraction = trace_fraction;
-                               trace3_plane_normal = trace_plane_normal;
-                               // accept the new trace if it made some progress
-                               if(fabs(trace3_endpos_x - trace1_endpos_x) >= 0.03125 || fabs(trace3_endpos_y - trace1_endpos_y) >= 0.03125)
-                               {
-                                       trace1_endpos = trace2_endpos;
-                                       trace1_fraction = trace2_fraction;
-                                       trace1_plane_normal = trace2_plane_normal;
-                                       trace1_endpos = trace3_endpos;
-                               }
-                       }
-               }
-
-               // check if it moved at all
-               if(trace1_fraction >= 0.001)
-                       setorigin(this, trace1_endpos);
-
-               // check if it moved all the way
-               if(trace1_fraction == 1)
-                       break;
-
-               // this is only really needed for nogravityonground combined with gravityunaffectedbyticrate
-               // <LordHavoc> I'm pretty sure I commented it out solely because it seemed redundant
-               // this got commented out in a change that supposedly makes the code match QW better
-               // so if this is broken, maybe put it in an if(cls.protocol != PROTOCOL_QUAKEWORLD) block
-               if(trace1_plane_normal_z > 0.7)
-                       SET_ONGROUND(this);
-
-               t -= t * trace1_fraction;
-
-               f = (this.velocity * trace1_plane_normal);
-               this.velocity = this.velocity + -f * trace1_plane_normal;
-       }
-       if(PHYS_TELEPORT_TIME(this) > 0)
-               this.velocity = primalvelocity;
-#endif
-}
-
 void CPM_PM_Aircontrol(entity this, vector wishdir, float wishspeed)
 {
        float k = 32 * (2 * IsMoveInDirection(this.movement, 0) - 1);
@@ -541,7 +405,7 @@ bool PlayerJump(entity this)
        animdecide_setaction(this, ANIMACTION_JUMP, true);
 
        if (autocvar_g_jump_grunt)
-               PlayerSound(this, playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+               PlayerSound(this, playersound_jump, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
 #endif
        return true;
 }
@@ -781,7 +645,8 @@ void PM_check_hitground(entity this)
     entity gs = (trace_dphitq3surfaceflags & Q3SURFACEFLAG_METALSTEPS)
        ? GS_FALL_METAL
        : GS_FALL;
-    GlobalSound(this, gs, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+    float vol = ((IS_DUCKED(this)) ? VOL_MUFFLED : VOL_BASE);
+    GlobalSound(this, gs, CH_PLAYER, vol, VOICETYPE_PLAYERSOUND);
 #endif
 }
 
@@ -801,7 +666,7 @@ void PM_Footsteps(entity this)
                entity gs = (trace_dphitq3surfaceflags & Q3SURFACEFLAG_METALSTEPS)
                        ? GS_STEP_METAL
                        : GS_STEP;
-               GlobalSound(this, gs, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+               GlobalSound(this, gs, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
        }
 #endif
 }
@@ -839,11 +704,15 @@ void PM_jetpack(entity this, float maxspd_mod)
        float a_up = PHYS_JETPACK_ACCEL_UP(this);
        float a_add = PHYS_JETPACK_ANTIGRAVITY(this) * PHYS_GRAVITY(this);
 
+       if(PHYS_JETPACK_REVERSE_THRUST(this) && PHYS_INPUT_BUTTON_CROUCH(self)) { a_up = PHYS_JETPACK_REVERSE_THRUST(this); }
+
        wishvel_x *= a_side;
        wishvel_y *= a_side;
        wishvel_z *= a_up;
        wishvel_z += a_add;
 
+       if(PHYS_JETPACK_REVERSE_THRUST(this) && PHYS_INPUT_BUTTON_CROUCH(self)) { wishvel_z *= -1; }
+
        float best = 0;
        //////////////////////////////////////////////////////////////////////////////////////
        // finding the maximum over all vectors of above form
@@ -920,24 +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
 }
 
 // used for calculating airshots
@@ -962,4 +813,8 @@ void CSQC_ClientMovement_PlayerMove_Frame(entity this)
 #endif
 {
        sys_phys_update(this, PHYS_INPUT_TIMELENGTH);
+
+#ifdef SVQC
+       this.pm_frametime = frametime;
+#endif
 }
index 5ce35dedceb80398e374662084de1bfe6b63f56e..f1553f2f130c7e4f2f6f07098ac2a84242b84cd4 100644 (file)
@@ -3,6 +3,8 @@
 
 // Client/server mappings
 
+.float pm_frametime;
+
 .entity conveyor;
 
 .float race_penalty;
@@ -35,6 +37,7 @@ bool IsFlying(entity a);
 #define GAMEPLAYFIX_STEPDOWN(s)             STAT(GAMEPLAYFIX_STEPDOWN, s)
 #define GAMEPLAYFIX_STEPMULTIPLETIMES(s)    STAT(GAMEPLAYFIX_STEPMULTIPLETIMES, s)
 #define GAMEPLAYFIX_UNSTICKPLAYERS(s)       STAT(GAMEPLAYFIX_UNSTICKPLAYERS, s)
+#define GAMEPLAYFIX_WATERTRANSITION(s) STAT(GAMEPLAYFIX_WATERTRANSITION, s)
 
 #define PHYS_ACCELERATE(s)                  STAT(MOVEVARS_ACCELERATE, s)
 #define PHYS_AIRACCELERATE(s)               STAT(MOVEVARS_AIRACCELERATE, s)
@@ -67,6 +70,7 @@ bool IsFlying(entity a);
 #define PHYS_JETPACK_FUEL(s)                STAT(JETPACK_FUEL, s)
 #define PHYS_JETPACK_MAXSPEED_SIDE(s)       STAT(JETPACK_MAXSPEED_SIDE, s)
 #define PHYS_JETPACK_MAXSPEED_UP(s)         STAT(JETPACK_MAXSPEED_UP, s)
+#define PHYS_JETPACK_REVERSE_THRUST(s)         STAT(JETPACK_REVERSE_THRUST, s)
 
 #define PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS(s) STAT(MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS, s)
 #define PHYS_JUMPSTEP(s)                    STAT(MOVEVARS_JUMPSTEP, s)
index 90b2758aca3569e841d6cfa185ca2a556847bd2d..519f910b0d3fee4721a698c549a59316841d658b 100644 (file)
@@ -35,6 +35,7 @@ const float ATTEN_MAX = 3.984375;
 
 const float VOL_BASE = 0.7;
 const float VOL_BASEVOICE = 1.0;
+const float VOL_MUFFLED = 0.35;
 
 // Play all sounds via sound7, for access to the extra channels.
 // Otherwise, channels 8 to 15 would be blocked for a weird QW feature.
@@ -125,7 +126,7 @@ CLASS(Sound, Object)
            TC(Sound, this);
                string s = Sound_fixpath(this);
                if (!s) return;
-               LOG_DEBUGF("precache_sound(\"%s\")\n", s);
+               profile(sprintf("precache_sound(\"%s\")\n", s));
                precache_sound(s);
        }
 ENDCLASS(Sound)
index 0ffe55eb4fa50ba77a3c0c22ddb5c2b4defa2812..7c6882088dba4a604998fe824b866a66a16f2d68 100644 (file)
@@ -15,6 +15,12 @@ void PlayerState_detach(entity this)
     PlayerState ps = PS(this);
        if (!ps) return;  // initial connect
        PS(this) = NULL;
+
+       ps.m_switchweapon = WEP_Null;
+       ps.m_weapon = WEP_Null;
+       ps.m_switchingweapon = WEP_Null;
+       ps.ps_push(ps, this);
+
        if (ps.m_client != this) return;  // don't own state, spectator
        FOREACH_CLIENT(PS(it) == ps, { PS(it) = NULL; });
        remove(ps);
index 2c471f0db30bb63d39b53966ed92ff6bf2e573ad..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)
@@ -227,6 +239,7 @@ REGISTER_STAT(JETPACK_ANTIGRAVITY, float, autocvar_g_jetpack_antigravity)
 REGISTER_STAT(JETPACK_FUEL, float, autocvar_g_jetpack_fuel)
 REGISTER_STAT(JETPACK_MAXSPEED_SIDE, float, autocvar_g_jetpack_maxspeed_side)
 REGISTER_STAT(JETPACK_MAXSPEED_UP, float, autocvar_g_jetpack_maxspeed_up)
+REGISTER_STAT(JETPACK_REVERSE_THRUST, float, autocvar_g_jetpack_reverse_thrust)
 
 REGISTER_STAT(MOVEVARS_HIGHSPEED, float, autocvar_g_movement_highspeed)
 
@@ -246,6 +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 1bf751f91cfacb703ed09af2323df67a9ba614bf..8563349fd920f74e725c66bd4cd9609ae8142fa3 100644 (file)
@@ -68,18 +68,18 @@ void ItemDraw(entity this)
     if(this.gravity)
     {
         Movetype_Physics_MatchServer(this, false);
-        if(this.move_flags & FL_ONGROUND)
-        { // For some reason move_avelocity gets set to '0 0 0' here ...
+        if(IS_ONGROUND(this))
+        { // For some reason avelocity gets set to '0 0 0' here ...
             this.oldorigin = this.origin;
             this.gravity = 0;
 
             if(autocvar_cl_animate_items)
             { // ... so reset it if animations are requested.
                 if(this.ItemStatus & ITS_ANIMATE1)
-                    this.move_avelocity = '0 180 0';
+                    this.avelocity = '0 180 0';
 
                 if(this.ItemStatus & ITS_ANIMATE2)
-                    this.move_avelocity = '0 -90 0';
+                    this.avelocity = '0 -90 0';
             }
         }
     }
@@ -87,13 +87,13 @@ void ItemDraw(entity this)
     {
         if(this.ItemStatus & ITS_ANIMATE1)
         {
-            this.angles += this.move_avelocity * frametime;
+            this.angles += this.avelocity * frametime;
             setorigin(this, '0 0 10' + this.oldorigin + '0 0 8' * sin(time * 2));
         }
 
         if(this.ItemStatus & ITS_ANIMATE2)
         {
-            this.angles += this.move_avelocity * frametime;
+            this.angles += this.avelocity * frametime;
             setorigin(this, '0 0 8' + this.oldorigin + '0 0 4' * sin(time * 3));
         }
     }
@@ -107,7 +107,7 @@ void ItemDrawSimple(entity this)
     {
         Movetype_Physics_MatchServer(this, false);
 
-        if(this.move_flags & FL_ONGROUND)
+        if(IS_ONGROUND(this))
             this.gravity = 0;
     }
 
@@ -164,7 +164,6 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
         this.angles_x = ReadAngle();
         this.angles_y = ReadAngle();
         this.angles_z = ReadAngle();
-        this.move_angles = this.angles;
     }
 
     if(sf & ISF_SIZE)
@@ -196,9 +195,10 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
     {
         this.drawmask  = MASK_NORMAL;
                this.move_movetype = MOVETYPE_TOSS;
+               if (isnew) IL_PUSH(g_drawables, this);
         this.draw       = ItemDraw;
         this.solid = SOLID_TRIGGER;
-        //this.move_flags |= FL_ITEM;
+        //this.flags |= FL_ITEM;
 
         bool use_bigsize = ReadByte();
 
@@ -253,13 +253,12 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
     {
         this.gravity = 1;
         this.pushable = true;
-        //this.move_angles = '0 0 0';
+        //this.angles = '0 0 0';
         this.move_movetype = MOVETYPE_TOSS;
-        this.move_velocity_x = ReadCoord();
-        this.move_velocity_y = ReadCoord();
-        this.move_velocity_z = ReadCoord();
-        this.velocity = this.move_velocity;
-        this.move_origin = this.oldorigin;
+        this.velocity_x = ReadCoord();
+        this.velocity_y = ReadCoord();
+        this.velocity_z = ReadCoord();
+        setorigin(this, this.oldorigin);
 
         if(!this.move_time)
         {
@@ -273,10 +272,10 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
     if(autocvar_cl_animate_items)
     {
         if(this.ItemStatus & ITS_ANIMATE1)
-            this.move_avelocity = '0 180 0';
+            this.avelocity = '0 180 0';
 
         if(this.ItemStatus & ITS_ANIMATE2)
-            this.move_avelocity = '0 -90 0';
+            this.avelocity = '0 -90 0';
     }
 
     this.entremove = ItemRemove;
@@ -761,7 +760,7 @@ LABEL(skip)
        return 1;
 }
 
-void Item_Touch(entity this)
+void Item_Touch(entity this, entity toucher)
 {
 
        // remove the item if it's currnetly in a NODROP brush or hits a NOIMPACT surface (such as sky)
@@ -774,21 +773,21 @@ void Item_Touch(entity this)
                }
        }
 
-       if(!(other.flags & FL_PICKUPITEMS)
-       || STAT(FROZEN, other)
-       || IS_DEAD(other)
+       if(!(toucher.flags & FL_PICKUPITEMS)
+       || STAT(FROZEN, toucher)
+       || IS_DEAD(toucher)
        || (this.solid != SOLID_TRIGGER)
-       || (this.owner == other)
+       || (this.owner == toucher)
        || (time < this.item_spawnshieldtime)
        ) { return; }
 
-       switch (MUTATOR_CALLHOOK(ItemTouch, this, other))
+       switch (MUTATOR_CALLHOOK(ItemTouch, this, toucher))
        {
                case MUT_ITEMTOUCH_RETURN: { return; }
-               case MUT_ITEMTOUCH_PICKUP: { other = M_ARGV(1, entity); goto pickup; }
+               case MUT_ITEMTOUCH_PICKUP: { toucher = M_ARGV(1, entity); goto pickup; }
        }
 
-       other = M_ARGV(1, entity);
+       toucher = M_ARGV(1, entity);
 
        if (this.classname == "droppedweapon")
        {
@@ -797,7 +796,7 @@ void Item_Touch(entity this)
                this.superweapons_finished = max(0, this.superweapons_finished - time);
        }
        entity it = this.itemdef;
-       bool gave = ITEM_HANDLE(Pickup, it, this, other);
+       bool gave = ITEM_HANDLE(Pickup, it, this, toucher);
        if (!gave)
        {
                if (this.classname == "droppedweapon")
@@ -812,10 +811,10 @@ void Item_Touch(entity this)
 
 LABEL(pickup)
 
-       other.last_pickup = time;
+       toucher.last_pickup = time;
 
        Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
-       _sound (other, (this.itemdef.instanceOfPowerup ? CH_TRIGGER_SINGLE : CH_TRIGGER), (this.item_pickupsound ? this.item_pickupsound : Sound_fixpath(this.item_pickupsound_ent)), VOL_BASE, ATTEN_NORM);
+       _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);
@@ -1079,7 +1078,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default
        {
                this.reset = SUB_Remove;
                // it's a dropped weapon
-               this.movetype = MOVETYPE_TOSS;
+               set_movetype(this, MOVETYPE_TOSS);
 
                // Savage: remove thrown items after a certain period of time ("garbage collection")
                setthink(this, RemoveItem);
@@ -1120,9 +1119,9 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default
                if(this.spawnflags & 1)
                        this.noalign = 1;
                if (this.noalign > 0)
-                       this.movetype = MOVETYPE_NONE;
+                       set_movetype(this, MOVETYPE_NONE);
                else
-                       this.movetype = MOVETYPE_TOSS;
+                       set_movetype(this, MOVETYPE_TOSS);
                // do item filtering according to game mode and other things
                if (this.noalign <= 0)
                {
@@ -1421,11 +1420,9 @@ spawnfunc(item_quad) { this.classname = "item_strength";spawnfunc_item_strength(
 
 void target_items_use(entity this, entity actor, entity trigger)
 {
-       other = trigger; // TODO
-
        if(actor.classname == "droppedweapon")
        {
-               EXACTTRIGGER_TOUCH;
+               EXACTTRIGGER_TOUCH(this, trigger);
                remove(actor);
                return;
        }
@@ -1436,7 +1433,7 @@ void target_items_use(entity this, entity actor, entity trigger)
                return;
        if(trigger.solid == SOLID_TRIGGER)
        {
-               EXACTTRIGGER_TOUCH;
+               EXACTTRIGGER_TOUCH(this, trigger);
        }
 
        FOREACH_ENTITY_ENT(enemy, actor,
@@ -1451,7 +1448,7 @@ void target_items_use(entity this, entity actor, entity trigger)
 
 spawnfunc(target_items)
 {
-       float n, i;
+       int n, j;
        string s;
 
        this.use = target_items_use;
@@ -1469,20 +1466,20 @@ spawnfunc(target_items)
        }
        else
        {
-               for(i = 0; i < n; ++i)
+               for(j = 0; j < n; ++j)
                {
-                       if     (argv(i) == "unlimited_ammo")         this.items |= IT_UNLIMITED_AMMO;
-                       else if(argv(i) == "unlimited_weapon_ammo")  this.items |= IT_UNLIMITED_WEAPON_AMMO;
-                       else if(argv(i) == "unlimited_superweapons") this.items |= IT_UNLIMITED_SUPERWEAPONS;
-                       else if(argv(i) == "strength")               this.items |= ITEM_Strength.m_itemid;
-                       else if(argv(i) == "invincible")             this.items |= ITEM_Shield.m_itemid;
-                       else if(argv(i) == "superweapons")           this.items |= IT_SUPERWEAPON;
-                       else if(argv(i) == "jetpack")                this.items |= ITEM_Jetpack.m_itemid;
-                       else if(argv(i) == "fuel_regen")             this.items |= ITEM_JetpackRegen.m_itemid;
+                       if     (argv(j) == "unlimited_ammo")         this.items |= IT_UNLIMITED_AMMO;
+                       else if(argv(j) == "unlimited_weapon_ammo")  this.items |= IT_UNLIMITED_WEAPON_AMMO;
+                       else if(argv(j) == "unlimited_superweapons") this.items |= IT_UNLIMITED_SUPERWEAPONS;
+                       else if(argv(j) == "strength")               this.items |= ITEM_Strength.m_itemid;
+                       else if(argv(j) == "invincible")             this.items |= ITEM_Shield.m_itemid;
+                       else if(argv(j) == "superweapons")           this.items |= IT_SUPERWEAPON;
+                       else if(argv(j) == "jetpack")                this.items |= ITEM_Jetpack.m_itemid;
+                       else if(argv(j) == "fuel_regen")             this.items |= ITEM_JetpackRegen.m_itemid;
                        else
                        {
                                FOREACH(Weapons, it != WEP_Null, {
-                                       s = W_UndeprecateName(argv(i));
+                                       s = W_UndeprecateName(argv(j));
                                        if(s == it.netname)
                                        {
                                                this.weapons |= (it.m_wepset);
@@ -1543,9 +1540,9 @@ spawnfunc(target_items)
        //print(this.netname, "\n");
 
        n = tokenize_console(this.netname);
-       for(i = 0; i < n; ++i)
+       for(j = 0; j < n; ++j)
        {
-               FOREACH(Weapons, it != WEP_Null && argv(i) == it.netname, {
+               FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(argv(j)) == it.netname, {
             it.wr_init(it);
             break;
                });
@@ -1768,7 +1765,7 @@ float GiveItems(entity e, float beginarg, float endarg)
                                got += GiveValue(e, ammo_fuel, op, val);
                                break;
                        default:
-                               FOREACH(Weapons, it != WEP_Null && cmd == it.netname, {
+                               FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(cmd) == it.netname, {
                     got += GiveWeapon(e, it.m_id, op, val);
                     break;
                                });
index 5ebc9d7e6234f4e8bd06d1233f0584a91946a254..1ed807c7c1ecea93a1059a50eb96f42bf577beed 100644 (file)
@@ -88,7 +88,7 @@ float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax
 
 float Item_GiveTo(entity item, entity player);
 
-void Item_Touch(entity this);
+void Item_Touch(entity this, entity toucher);
 
 void Item_Reset(entity this);
 
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 a8ec50a86540a7be10fed5418c2bcd1b2b1786a3..b186066e602b1523586a6d4f299a162445ee7efa 100644 (file)
@@ -28,7 +28,7 @@ void button_return(entity this)
 }
 
 
-void button_blocked(entity this)
+void button_blocked(entity this, entity blocker)
 {
        // do nothing, just don't come all the way back out
 }
@@ -68,17 +68,17 @@ void button_use(entity this, entity actor, entity trigger)
        button_fire(this);
 }
 
-void button_touch(entity this)
+void button_touch(entity this, entity toucher)
 {
-       if (!other)
+       if (!toucher)
                return;
-       if (!other.iscreature)
+       if (!toucher.iscreature)
                return;
-       if(other.velocity * this.movedir < 0)
+       if(toucher.velocity * this.movedir < 0)
                return;
-       this.enemy = other;
-       if (other.owner)
-               this.enemy = other.owner;
+       this.enemy = toucher;
+       if (toucher.owner)
+               this.enemy = toucher.owner;
        button_fire (this);
 }
 
index ab4cc12d5ac27abf6a1cc530947086a13625023b..8bd6016f28a5498f33cb0a0c544fbeca29a93d3d 100644 (file)
@@ -140,7 +140,7 @@ spawnfunc(func_conveyor)
 {
        SetMovedir(this);
        InitMovingBrushTrigger(this);
-       this.movetype = MOVETYPE_NONE;
+       set_movetype(this, MOVETYPE_NONE);
        conveyor_init(this);
 }
 
@@ -151,12 +151,12 @@ void conveyor_draw(entity this) { conveyor_think(this); }
 void conveyor_init(entity this)
 {
        this.draw = conveyor_draw;
+       IL_PUSH(g_drawables, this);
        this.drawmask = MASK_NORMAL;
 
-       this.movetype = MOVETYPE_NONE;
+       this.move_movetype = MOVETYPE_NONE;
        this.model = "";
        this.solid = SOLID_TRIGGER;
-       this.move_origin = this.origin;
        this.move_time = time;
 }
 
index f32a8d75ded3ac456e217e5af07c07a22c1c27e1..a0fb12a4c4806c10140a7f32645e75f6b190ae70 100644 (file)
@@ -23,33 +23,33 @@ THINK FUNCTIONS
 void door_go_down(entity this);
 void door_go_up(entity this);
 void door_rotating_go_down(entity this);
-void door_rotating_go_up(entity this);
+void door_rotating_go_up(entity this, entity oth);
 
-void door_blocked(entity this)
+void door_blocked(entity this, entity blocker)
 {
        if((this.spawnflags & 8)
 #ifdef SVQC
-               && (other.takedamage != DAMAGE_NO)
+               && (blocker.takedamage != DAMAGE_NO)
 #elif defined(CSQC)
-               && !IS_DEAD(other)
+               && !IS_DEAD(blocker)
 #endif
        )
        { // KIll Kill Kill!!
 #ifdef SVQC
-               Damage (other, this, this, 10000, DEATH_HURTTRIGGER.m_id, other.origin, '0 0 0');
+               Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, blocker.origin, '0 0 0');
 #endif
        }
        else
        {
 #ifdef SVQC
-               if((this.dmg) && (other.takedamage == DAMAGE_YES))    // Shall we bite?
-                       Damage (other, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, other.origin, '0 0 0');
+               if((this.dmg) && (blocker.takedamage == DAMAGE_YES))    // Shall we bite?
+                       Damage (blocker, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, blocker.origin, '0 0 0');
 #endif
 
                 // don't change direction for dead or dying stuff
-               if(IS_DEAD(other)
+               if(IS_DEAD(blocker)
 #ifdef SVQC
-                       && (other.takedamage == DAMAGE_NO)
+                       && (blocker.takedamage == DAMAGE_NO)
 #endif
                )
                {
@@ -61,7 +61,7 @@ void door_blocked(entity this)
                                door_go_up (this);
                        } else
                        {
-                               door_rotating_go_up (this);
+                               door_rotating_go_up(this, blocker);
                        }
                                else
                        if (this.classname == "door")
@@ -77,8 +77,8 @@ void door_blocked(entity this)
                else
                {
                        //gib dying stuff just to make sure
-                       if((this.dmg) && (other.takedamage != DAMAGE_NO))    // Shall we bite?
-                               Damage (other, this, this, 10000, DEATH_HURTTRIGGER.m_id, other.origin, '0 0 0');
+                       if((this.dmg) && (blocker.takedamage != DAMAGE_NO))    // Shall we bite?
+                               Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, blocker.origin, '0 0 0');
                }
 #endif
        }
@@ -235,15 +235,15 @@ void door_fire(entity this, entity actor, entity trigger)
                        door_go_up(e);
                } else {
                        // if the BIDIR spawnflag (==2) is set and the trigger has set trigger_reverse, reverse the opening direction
-                       if ((e.spawnflags & 2) && other.trigger_reverse!=0 && e.lip != 666 && e.state == STATE_BOTTOM) {
+                       if ((e.spawnflags & 2) && trigger.trigger_reverse!=0 && e.lip != 666 && e.state == STATE_BOTTOM) {
                                e.lip = 666; // e.lip is used to remember reverse opening direction for door_rotating
                                e.pos2 = '0 0 0' - e.pos2;
                        }
                        // if BIDIR_IN_DOWN (==8) is set, prevent the door from reoping during closing if it is triggered from the wrong side
                        if (!((e.spawnflags & 2) &&  (e.spawnflags & 8) && e.state == STATE_DOWN
-                               && (((e.lip == 666) && (other.trigger_reverse == 0)) || ((e.lip != 666) && (other.trigger_reverse != 0)))))
+                               && (((e.lip == 666) && (trigger.trigger_reverse == 0)) || ((e.lip != 666) && (trigger.trigger_reverse != 0)))))
                        {
-                               door_rotating_go_up(e);
+                               door_rotating_go_up(e, trigger);
                        }
                }
                e = e.enemy;
@@ -289,9 +289,9 @@ Prints messages
 ================
 */
 
-void door_touch(entity this)
+void door_touch(entity this, entity toucher)
 {
-       if (!IS_PLAYER(other))
+       if (!IS_PLAYER(toucher))
                return;
        if (this.owner.door_finished > time)
                return;
@@ -301,36 +301,35 @@ void door_touch(entity this)
 #ifdef SVQC
        if (!(this.owner.dmg) && (this.owner.message != ""))
        {
-               if (IS_CLIENT(other))
-                       centerprint(other, this.owner.message);
-               play2(other, this.owner.noise);
+               if (IS_CLIENT(toucher))
+                       centerprint(toucher, this.owner.message);
+               play2(toucher, this.owner.noise);
        }
 #endif
 }
 
-void door_generic_plat_blocked(entity this)
+void door_generic_plat_blocked(entity this, entity blocker)
 {
-
-       if((this.spawnflags & 8) && (other.takedamage != DAMAGE_NO)) { // KIll Kill Kill!!
+       if((this.spawnflags & 8) && (blocker.takedamage != DAMAGE_NO)) { // Kill Kill Kill!!
 #ifdef SVQC
-               Damage (other, this, this, 10000, DEATH_HURTTRIGGER.m_id, other.origin, '0 0 0');
+               Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, blocker.origin, '0 0 0');
 #endif
        }
        else
        {
 
 #ifdef SVQC
-               if((this.dmg) && (other.takedamage == DAMAGE_YES))    // Shall we bite?
-                       Damage (other, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, other.origin, '0 0 0');
+               if((this.dmg) && (blocker.takedamage == DAMAGE_YES))    // Shall we bite?
+                       Damage (blocker, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, blocker.origin, '0 0 0');
 #endif
 
                 //Dont chamge direction for dead or dying stuff
-               if(IS_DEAD(other) && (other.takedamage == DAMAGE_NO))
+               if(IS_DEAD(blocker) && (blocker.takedamage == DAMAGE_NO))
                {
                        if (this.wait >= 0)
                        {
                                if (this.state == STATE_DOWN)
-                                       door_rotating_go_up (this);
+                                       door_rotating_go_up (this, blocker);
                                else
                                        door_rotating_go_down (this);
                        }
@@ -339,8 +338,8 @@ void door_generic_plat_blocked(entity this)
                else
                {
                        //gib dying stuff just to make sure
-                       if((this.dmg) && (other.takedamage != DAMAGE_NO))    // Shall we bite?
-                               Damage (other, this, this, 10000, DEATH_HURTTRIGGER.m_id, other.origin, '0 0 0');
+                       if((this.dmg) && (blocker.takedamage != DAMAGE_NO))    // Shall we bite?
+                               Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, blocker.origin, '0 0 0');
                }
 #endif
        }
@@ -383,7 +382,7 @@ void door_rotating_go_down(entity this)
        SUB_CalcAngleMove (this, this.pos1, TSPEED_LINEAR, this.speed, door_rotating_hit_bottom);
 }
 
-void door_rotating_go_up(entity this)
+void door_rotating_go_up(entity this, entity oth)
 {
        if (this.state == STATE_UP)
                return;         // already going up
@@ -401,7 +400,7 @@ void door_rotating_go_up(entity this)
        string oldmessage;
        oldmessage = this.message;
        this.message = "";
-       SUB_UseTargets(this, NULL, other); // TODO: is other needed here?
+       SUB_UseTargets(this, NULL, oth); // TODO: is oth needed here?
        this.message = oldmessage;
 }
 
@@ -414,13 +413,13 @@ Spawned if a door lacks a real activator
 =========================================
 */
 
-void door_trigger_touch(entity this)
+void door_trigger_touch(entity this, entity toucher)
 {
-       if (other.health < 1)
+       if (toucher.health < 1)
 #ifdef SVQC
-               if (!((other.iscreature || (other.flags & FL_PROJECTILE)) && !IS_DEAD(other)))
+               if (!((toucher.iscreature || (toucher.flags & FL_PROJECTILE)) && !IS_DEAD(toucher)))
 #elif defined(CSQC)
-               if(!((IS_CLIENT(other) || other.classname == "csqcprojectile") && !IS_DEAD(other)))
+               if(!((IS_CLIENT(toucher) || toucher.classname == "csqcprojectile") && !IS_DEAD(toucher)))
 #endif
                        return;
 
@@ -428,12 +427,12 @@ void door_trigger_touch(entity this)
                return;
 
        // check if door is locked
-       if (!door_check_keys(this, other))
+       if (!door_check_keys(this, toucher))
                return;
 
        this.door_finished = time + 1;
 
-       door_use(this.owner, other, NULL);
+       door_use(this.owner, toucher, NULL);
 }
 
 void door_spawnfield(entity this, vector fmins, vector fmaxs)
@@ -442,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
@@ -816,7 +815,7 @@ NET_HANDLE(ENT_CLIENT_DOOR, bool isnew)
                this.SUB_LTIME = ReadCoord();
 
                this.solid = SOLID_BSP;
-               this.movetype = MOVETYPE_PUSH;
+               this.move_movetype = MOVETYPE_PUSH;
                this.use = door_use;
 
                LinkDoors(this);
@@ -825,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;
        }
 
        if(sf & SF_TRIGGER_RESET)
@@ -842,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 f02fc61f646219626c5cf270df04e4763fb4d0a6..600949fe5c0528f598c0c7692108cae2578058f9 100644 (file)
@@ -135,7 +135,7 @@ void fd_secret_done(entity this)
 
 .float door_finished;
 
-void secret_blocked(entity this)
+void secret_blocked(entity this, entity blocker)
 {
        if (time < this.door_finished)
                return;
@@ -150,9 +150,9 @@ secret_touch
 Prints messages
 ================
 */
-void secret_touch(entity this)
+void secret_touch(entity this, entity toucher)
 {
-       if (!other.iscreature)
+       if (!toucher.iscreature)
                return;
        if (this.door_finished > time)
                return;
@@ -161,9 +161,9 @@ void secret_touch(entity this)
 
        if (this.message)
        {
-               if (IS_CLIENT(other))
-                       centerprint(other, this.message);
-               play2(other, this.noise);
+               if (IS_CLIENT(toucher))
+                       centerprint(toucher, this.message);
+               play2(toucher, this.noise);
        }
 }
 
index af5065643bf9a6957fd0de37d50cba53a7f58d9c..ae9160dfdab1300e6e0aa0142dc08fdc848dae54 100644 (file)
@@ -1,21 +1,21 @@
 REGISTER_NET_LINKED(ENT_CLIENT_LADDER)
 
-void func_ladder_touch(entity this)
+void func_ladder_touch(entity this, entity toucher)
 {
 #ifdef SVQC
-       if (!other.iscreature)
+       if (!toucher.iscreature)
                return;
-       if(IS_VEHICLE(other))
+       if(IS_VEHICLE(toucher))
                return;
 #elif defined(CSQC)
-       if(!other.isplayermodel)
+       if(!toucher.isplayermodel)
                return;
 #endif
 
-       EXACTTRIGGER_TOUCH;
+       EXACTTRIGGER_TOUCH(this, toucher);
 
-       other.ladder_time = time + 0.1;
-       other.ladder_entity = this;
+       toucher.ladder_time = time + 0.1;
+       toucher.ladder_entity = this;
 }
 
 #ifdef SVQC
index 6f7ebaad31522130f7b69bf3509346c2e1e5098c..341ca460feb28eef5bcf954e59b3f9aee7c18c30 100644 (file)
@@ -168,17 +168,16 @@ NET_HANDLE(ENT_CLIENT_PLAT, bool isnew)
 
                this.classname = "plat";
                this.solid = SOLID_BSP;
-               this.movetype = MOVETYPE_PUSH;
+               this.move_movetype = 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;
                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 dc569f69a1a738a1f8dbecefa82d6d69ee12fbc9..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)
@@ -92,14 +92,24 @@ spawnfunc(func_snow)
        Net_LinkEntity(this, false, 0, rainsnow_SendEntity);
 }
 #elif defined(CSQC)
+float autocvar_cl_rainsnow_maxdrawdist = 2048;
+
 void Draw_Rain(entity this)
 {
-    te_particlerain(this.origin + this.mins, this.origin + this.maxs, this.velocity, floor(this.count * drawframetime + random()), this.glow_color);
+       vector maxdist = '1 1 0' * autocvar_cl_rainsnow_maxdrawdist;
+       maxdist.z = 5;
+       if(boxesoverlap(vec2(view_origin) - maxdist, vec2(view_origin) + maxdist, vec2(this.absmin) - '0 0 5', vec2(this.absmax) + '0 0 5'))
+       //if(autocvar_cl_rainsnow_maxdrawdist <= 0 || vdist(vec2(this.origin) - vec2(this.absmin + this.absmax * 0.5), <=, autocvar_cl_rainsnow_maxdrawdist))
+       te_particlerain(this.origin + this.mins, this.origin + this.maxs, this.velocity, floor(this.count * drawframetime + random()), this.glow_color);
 }
 
 void Draw_Snow(entity this)
 {
-    te_particlesnow(this.origin + this.mins, this.origin + this.maxs, this.velocity, floor(this.count * drawframetime + random()), this.glow_color);
+       vector maxdist = '1 1 0' * autocvar_cl_rainsnow_maxdrawdist;
+       maxdist.z = 5;
+       if(boxesoverlap(vec2(view_origin) - maxdist, vec2(view_origin) + maxdist, vec2(this.absmin) - '0 0 5', vec2(this.absmax) + '0 0 5'))
+       //if(autocvar_cl_rainsnow_maxdrawdist <= 0 || vdist(vec2(this.origin) - vec2(this.absmin + this.absmax * 0.5), <=, autocvar_cl_rainsnow_maxdrawdist))
+       te_particlesnow(this.origin + this.mins, this.origin + this.maxs, this.velocity, floor(this.count * drawframetime + random()), this.glow_color);
 }
 
 NET_HANDLE(ENT_CLIENT_RAINSNOW, bool isnew)
@@ -124,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..29c7d0a7b125898ae519ced47c7bd42fc1ac850f 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;
+               this.move_movetype = 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;
                this.move_time = time;
        }
 
index 69222bf2d81a2ecf03113904c6c97c8053e4a0ac..fa242beb97ceb0fe6adec70a4bd34dee60468be3 100644 (file)
@@ -47,7 +47,7 @@ void follow_init(entity this)
        {
                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;
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 c089039a60bccf1549b1602fb643380c7b64129c..391172fe0f157fc17a3585abd98dfc007df81737 100644 (file)
@@ -1,17 +1,17 @@
-void generic_plat_blocked(entity this)
+void generic_plat_blocked(entity this, entity blocker)
 {
 #ifdef SVQC
-       if(this.dmg && other.takedamage != DAMAGE_NO)
+       if(this.dmg && blocker.takedamage != DAMAGE_NO)
        {
                if(this.dmgtime2 < time)
                {
-                       Damage (other, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, other.origin, '0 0 0');
+                       Damage (blocker, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, blocker.origin, '0 0 0');
                        this.dmgtime2 = time + this.dmgtime;
                }
 
                // Gib dead/dying stuff
-               if(IS_DEAD(other))
-                       Damage (other, this, this, 10000, DEATH_HURTTRIGGER.m_id, other.origin, '0 0 0');
+               if(IS_DEAD(blocker))
+                       Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, blocker.origin, '0 0 0');
        }
 #endif
 }
@@ -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;
 
@@ -86,18 +86,18 @@ void plat_go_up(entity this)
        SUB_CalcMove (this, this.pos1, TSPEED_LINEAR, this.speed, plat_hit_top);
 }
 
-void plat_center_touch(entity this)
+void plat_center_touch(entity this, entity toucher)
 {
 #ifdef SVQC
-       if (!other.iscreature)
+       if (!toucher.iscreature)
                return;
 
-       if (other.health <= 0)
+       if (toucher.health <= 0)
                return;
 #elif defined(CSQC)
-       if (!IS_PLAYER(other))
+       if (!IS_PLAYER(toucher))
                return;
-       if(IS_DEAD(other))
+       if(IS_DEAD(toucher))
                return;
 #endif
 
@@ -107,16 +107,16 @@ void plat_center_touch(entity this)
                this.enemy.SUB_NEXTTHINK = this.enemy.SUB_LTIME + 1;
 }
 
-void plat_outside_touch(entity this)
+void plat_outside_touch(entity this, entity toucher)
 {
 #ifdef SVQC
-       if (!other.iscreature)
+       if (!toucher.iscreature)
                return;
 
-       if (other.health <= 0)
+       if (toucher.health <= 0)
                return;
 #elif defined(CSQC)
-       if (!IS_PLAYER(other))
+       if (!IS_PLAYER(toucher))
                return;
 #endif
 
@@ -128,34 +128,29 @@ void plat_outside_touch(entity this)
 
 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);
 }
 
 
-void plat_crush(entity this)
+void plat_crush(entity this, entity blocker)
 {
-       if((this.spawnflags & 4) && (other.takedamage != DAMAGE_NO))
+       if((this.spawnflags & 4) && (blocker.takedamage != DAMAGE_NO))
        { // KIll Kill Kill!!
 #ifdef SVQC
-               Damage (other, this, this, 10000, DEATH_HURTTRIGGER.m_id, other.origin, '0 0 0');
+               Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, blocker.origin, '0 0 0');
 #endif
        }
        else
        {
 #ifdef SVQC
-               if((this.dmg) && (other.takedamage != DAMAGE_NO))
+               if((this.dmg) && (blocker.takedamage != DAMAGE_NO))
                {   // Shall we bite?
-                       Damage (other, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, other.origin, '0 0 0');
+                       Damage (blocker, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, blocker.origin, '0 0 0');
                        // Gib dead/dying stuff
-                       if(IS_DEAD(other))
-                               Damage (other, this, this, 10000, DEATH_HURTTRIGGER.m_id, other.origin, '0 0 0');
+                       if(IS_DEAD(blocker))
+                               Damage (blocker, this, this, 10000, DEATH_HURTTRIGGER.m_id, blocker.origin, '0 0 0');
                }
 #endif
 
index 6bdfb23d68bf0ced7ea0ee836e6cbcb4bb6d0368..f0727be3ca1fe59cf57b8779d60e20178ffc533b 100644 (file)
@@ -3,12 +3,12 @@
 
 .float dmgtime2;
 
-void plat_center_touch(entity this);
-void plat_outside_touch(entity this);
+void plat_center_touch(entity this, entity toucher);
+void plat_outside_touch(entity this, entity toucher);
 void plat_trigger_use(entity this, entity actor, entity trigger);
 void plat_go_up(entity this);
 void plat_go_down(entity this);
-void plat_crush(entity this);
+void plat_crush(entity this, entity blocker);
 const float PLAT_LOW_TRIGGER = 1;
 
 .float dmg;
index 51ef002736a32201d391cc9831b9a4f84f06389f..3120aa33d90361b1e5f88a75f49f72ae0f16c220 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);
 }
 
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 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 ef47b0c6c8d00f180394f9f882d6bac61950d80d..c0f45f263d588087d724d1e52a59e590275f6b38 100644 (file)
@@ -17,7 +17,7 @@ const float TELEPORT_SIMPLE = 2; // only do teleport, nothing special
 
 entity Simple_TeleportPlayer(entity teleporter, entity player);
 
-void Teleport_Touch (entity this);
+void Teleport_Touch(entity this, entity toucher);
 
 void teleport_findtarget(entity this);
 
index 9dcc710f0356b2102c0f20248c9a3e2e6739184b..cef8cb8bbe5f94838504e47b154e8f7e052549c7 100644 (file)
@@ -37,50 +37,50 @@ void trigger_gravity_use(entity this, entity actor, entity trigger)
        this.state = !this.state;
 }
 
-void trigger_gravity_touch(entity this)
+void trigger_gravity_touch(entity this, entity toucher)
 {
        float g;
 
        if(this.state != true)
                return;
 
-       EXACTTRIGGER_TOUCH;
+       EXACTTRIGGER_TOUCH(this, toucher);
 
        g = this.gravity;
 
        if (!(this.spawnflags & 1))
        {
-               if(other.trigger_gravity_check)
+               if(toucher.trigger_gravity_check)
                {
-                       if(this == other.trigger_gravity_check.enemy)
+                       if(this == toucher.trigger_gravity_check.enemy)
                        {
                                // same?
-                               other.trigger_gravity_check.count = 2; // gravity one more frame...
+                               toucher.trigger_gravity_check.count = 2; // gravity one more frame...
                                return;
                        }
 
                        // compare prio
-                       if(this.cnt > other.trigger_gravity_check.enemy.cnt)
-                               trigger_gravity_remove(other);
+                       if(this.cnt > toucher.trigger_gravity_check.enemy.cnt)
+                               trigger_gravity_remove(toucher);
                        else
                                return;
                }
-               other.trigger_gravity_check = spawn();
-               other.trigger_gravity_check.enemy = this;
-               other.trigger_gravity_check.owner = other;
-               other.trigger_gravity_check.gravity = other.gravity;
-               setthink(other.trigger_gravity_check, trigger_gravity_check_think);
-               other.trigger_gravity_check.nextthink = time;
-               other.trigger_gravity_check.count = 2;
-               if(other.gravity)
-                       g *= other.gravity;
+               toucher.trigger_gravity_check = spawn();
+               toucher.trigger_gravity_check.enemy = this;
+               toucher.trigger_gravity_check.owner = toucher;
+               toucher.trigger_gravity_check.gravity = toucher.gravity;
+               setthink(toucher.trigger_gravity_check, trigger_gravity_check_think);
+               toucher.trigger_gravity_check.nextthink = time;
+               toucher.trigger_gravity_check.count = 2;
+               if(toucher.gravity)
+                       g *= toucher.gravity;
        }
 
-       if (other.gravity != g)
+       if (toucher.gravity != g)
        {
-               other.gravity = g;
+               toucher.gravity = g;
                if(this.noise != "")
-                       _sound (other, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
+                       _sound (toucher, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
                UpdateCSQCProjectile(this.owner);
        }
 }
index 41519e20cc622c4547bae54d7c226cd147f17e0c..5a2bc78de8a16017afc95b71b8be8d2fa643f24a 100644 (file)
@@ -1,25 +1,25 @@
 #ifdef SVQC
 .float triggerhealtime;
-void trigger_heal_touch(entity this)
+void trigger_heal_touch(entity this, entity toucher)
 {
        if (this.active != ACTIVE_ACTIVE)
                return;
 
        // only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu)
-       if (other.iscreature)
+       if (toucher.iscreature)
        {
-               if (other.takedamage)
-               if (!IS_DEAD(other))
-               if (other.triggerhealtime < time)
+               if (toucher.takedamage)
+               if (!IS_DEAD(toucher))
+               if (toucher.triggerhealtime < time)
                {
-                       EXACTTRIGGER_TOUCH;
-                       other.triggerhealtime = time + 1;
+                       EXACTTRIGGER_TOUCH(this, toucher);
+                       toucher.triggerhealtime = time + 1;
 
-                       if (other.health < this.max_health)
+                       if (toucher.health < this.max_health)
                        {
-                               other.health = min(other.health + this.health, this.max_health);
-                               other.pauserothealth_finished = max(other.pauserothealth_finished, time + autocvar_g_balance_pause_health_rot);
-                               _sound (other, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
+                               toucher.health = min(toucher.health + this.health, this.max_health);
+                               toucher.pauserothealth_finished = max(toucher.pauserothealth_finished, time + autocvar_g_balance_pause_health_rot);
+                               _sound (toucher, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
                        }
                }
        }
index 92a4dd0299e66d50607e4a1e3cf7675c673d2a09..4579fd7524af53601118a5e3e11f2c57dc780f58 100644 (file)
@@ -8,23 +8,23 @@ void trigger_hurt_use(entity this, entity actor, entity trigger)
 }
 
 .float triggerhurttime;
-void trigger_hurt_touch(entity this)
+void trigger_hurt_touch(entity this, entity toucher)
 {
        if (this.active != ACTIVE_ACTIVE)
                return;
 
        if(this.team)
-               if(((this.spawnflags & 4) == 0) == (this.team != other.team))
+               if(((this.spawnflags & 4) == 0) == (this.team != toucher.team))
                        return;
 
        // only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu)
-       if (other.iscreature)
+       if (toucher.iscreature)
        {
-               if (other.takedamage)
-               if (other.triggerhurttime < time)
+               if (toucher.takedamage)
+               if (toucher.triggerhurttime < time)
                {
-                       EXACTTRIGGER_TOUCH;
-                       other.triggerhurttime = time + 1;
+                       EXACTTRIGGER_TOUCH(this, toucher);
+                       toucher.triggerhurttime = time + 1;
 
                        entity own;
                        own = this.enemy;
@@ -34,15 +34,15 @@ void trigger_hurt_touch(entity this)
                                this.enemy = NULL; // I still hate you all
                        }
 
-                       Damage (other, this, own, this.dmg, DEATH_HURTTRIGGER.m_id, other.origin, '0 0 0');
+                       Damage (toucher, this, own, this.dmg, DEATH_HURTTRIGGER.m_id, toucher.origin, '0 0 0');
                }
        }
-       else if(other.damagedbytriggers)
+       else if(toucher.damagedbytriggers)
        {
-               if(other.takedamage)
+               if(toucher.takedamage)
                {
-                       EXACTTRIGGER_TOUCH;
-                       Damage(other, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, other.origin, '0 0 0');
+                       EXACTTRIGGER_TOUCH(this, toucher);
+                       Damage(toucher, this, this, this.dmg, DEATH_HURTTRIGGER.m_id, toucher.origin, '0 0 0');
                }
        }
 
index 91381f4877c9954ccc54ca618640503cd32bd058..cdf4a72918b79c9ab5326814dd1040e12f061620 100644 (file)
@@ -1,5 +1,5 @@
 // targeted (directional) mode
-void trigger_impulse_touch1(entity this)
+void trigger_impulse_touch1(entity this, entity toucher)
 {
        entity targ;
        float pushdeltatime;
@@ -8,10 +8,10 @@ void trigger_impulse_touch1(entity this)
        if (this.active != ACTIVE_ACTIVE)
                return;
 
-       if (!isPushable(other))
+       if (!isPushable(toucher))
                return;
 
-       EXACTTRIGGER_TOUCH;
+       EXACTTRIGGER_TOUCH(this, toucher);
 
        targ = find(NULL, targetname, this.target);
        if(!targ)
@@ -21,11 +21,7 @@ void trigger_impulse_touch1(entity this)
                return;
        }
 
-#ifdef SVQC
-       str = min(this.radius, vlen(this.origin - other.origin));
-#elif defined(CSQC)
-       str = min(this.radius, vlen(this.origin - other.move_origin));
-#endif
+       str = min(this.radius, vlen(this.origin - toucher.origin));
 
        if(this.falloff == 1)
                str = (str / this.radius) * this.strength;
@@ -34,75 +30,58 @@ void trigger_impulse_touch1(entity this)
        else
                str = this.strength;
 
-       pushdeltatime = time - other.lastpushtime;
+       pushdeltatime = time - toucher.lastpushtime;
        if (pushdeltatime > 0.15) pushdeltatime = 0;
-       other.lastpushtime = time;
+       toucher.lastpushtime = time;
        if(!pushdeltatime) return;
 
        if(this.spawnflags & 64)
        {
-#ifdef SVQC
-               float addspeed = str - other.velocity * normalize(targ.origin - this.origin);
+               float addspeed = str - toucher.velocity * normalize(targ.origin - this.origin);
                if (addspeed > 0)
                {
                        float accelspeed = min(8 * pushdeltatime * str, addspeed);
-                       other.velocity += accelspeed * normalize(targ.origin - this.origin);
+                       toucher.velocity += accelspeed * normalize(targ.origin - this.origin);
                }
-#elif defined(CSQC)
-               float addspeed = str - other.move_velocity * normalize(targ.origin - this.origin);
-               if (addspeed > 0)
-               {
-                       float accelspeed = min(8 * pushdeltatime * str, addspeed);
-                       other.move_velocity += accelspeed * normalize(targ.origin - this.origin);
-               }
-#endif
        }
        else
-#ifdef SVQC
-               other.velocity = other.velocity + normalize(targ.origin - this.origin) * str * pushdeltatime;
-#elif defined(CSQC)
-               other.move_velocity = other.move_velocity + normalize(targ.origin - this.origin) * str * pushdeltatime;
-#endif
+               toucher.velocity = toucher.velocity + normalize(targ.origin - this.origin) * str * pushdeltatime;
 
-#ifdef SVQC
-       UNSET_ONGROUND(other);
+       UNSET_ONGROUND(toucher);
 
-       UpdateCSQCProjectile(other);
-#elif defined(CSQC)
-       other.move_flags &= ~FL_ONGROUND;
+#ifdef SVQC
+       UpdateCSQCProjectile(toucher);
 #endif
 }
 
 // Directionless (accelerator/decelerator) mode
-void trigger_impulse_touch2(entity this)
+void trigger_impulse_touch2(entity this, entity toucher)
 {
        float pushdeltatime;
 
        if (this.active != ACTIVE_ACTIVE)
                return;
 
-       if (!isPushable(other))
+       if (!isPushable(toucher))
                return;
 
-       EXACTTRIGGER_TOUCH;
+       EXACTTRIGGER_TOUCH(this, toucher);
 
-       pushdeltatime = time - other.lastpushtime;
+       pushdeltatime = time - toucher.lastpushtime;
        if (pushdeltatime > 0.15) pushdeltatime = 0;
-       other.lastpushtime = time;
+       toucher.lastpushtime = time;
        if(!pushdeltatime) return;
 
        // div0: ticrate independent, 1 = identity (not 20)
-#ifdef SVQC
-       other.velocity = other.velocity * pow(this.strength, pushdeltatime);
+       toucher.velocity = toucher.velocity * pow(this.strength, pushdeltatime);
 
-       UpdateCSQCProjectile(other);
-#elif defined(CSQC)
-       other.move_velocity = other.move_velocity * pow(this.strength, pushdeltatime);
+#ifdef SVQC
+       UpdateCSQCProjectile(toucher);
 #endif
 }
 
 // Spherical (gravity/repulsor) mode
-void trigger_impulse_touch3(entity this)
+void trigger_impulse_touch3(entity this, entity toucher)
 {
        float pushdeltatime;
        float str;
@@ -110,23 +89,19 @@ void trigger_impulse_touch3(entity this)
        if (this.active != ACTIVE_ACTIVE)
                return;
 
-       if (!isPushable(other))
+       if (!isPushable(toucher))
                return;
 
-       EXACTTRIGGER_TOUCH;
+       EXACTTRIGGER_TOUCH(this, toucher);
 
-       pushdeltatime = time - other.lastpushtime;
+       pushdeltatime = time - toucher.lastpushtime;
        if (pushdeltatime > 0.15) pushdeltatime = 0;
-       other.lastpushtime = time;
+       toucher.lastpushtime = time;
        if(!pushdeltatime) return;
 
        setsize(this, '-1 -1 -1' * this.radius,'1 1 1' * this.radius);
 
-#ifdef SVQC
-       str = min(this.radius, vlen(this.origin - other.origin));
-#elif defined(CSQC)
-       str = min(this.radius, vlen(this.origin - other.move_origin));
-#endif
+       str = min(this.radius, vlen(this.origin - toucher.origin));
 
        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)
        else
                str = this.strength;
 
-#ifdef SVQC
-       other.velocity = other.velocity + normalize(other.origin - this.origin) * str * pushdeltatime;
+       toucher.velocity = toucher.velocity + normalize(toucher.origin - this.origin) * str * pushdeltatime;
 
-       UpdateCSQCProjectile(other);
-#elif defined(CSQC)
-       other.move_velocity = other.move_velocity + normalize(other.move_origin - this.origin) * str * pushdeltatime;
+#ifdef SVQC
+       UpdateCSQCProjectile(toucher);
 #endif
 }
 
index caa62e03607a408195f55151ffda88e348c46738..5ec7b41fd484c84fe3cbbe8ce7f32452038c8d9e 100644 (file)
@@ -129,24 +129,23 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht)
        return sdir * vs + '0 0 1' * vz;
 }
 
-void trigger_push_touch(entity this)
+void trigger_push_touch(entity this, entity toucher)
 {
        if (this.active == ACTIVE_NOT)
                return;
 
-       if (!isPushable(other))
+       if (!isPushable(toucher))
                return;
 
        if(this.team)
-               if(((this.spawnflags & 4) == 0) == (DIFF_TEAM(this, other)))
+               if(((this.spawnflags & 4) == 0) == (DIFF_TEAM(this, toucher)))
                        return;
 
-       EXACTTRIGGER_TOUCH;
+       EXACTTRIGGER_TOUCH(this, toucher);
 
        if(this.enemy)
        {
-               other.velocity = trigger_push_calculatevelocity(other.origin, this.enemy, this.height);
-               other.move_velocity = other.velocity;
+               toucher.velocity = trigger_push_calculatevelocity(toucher.origin, this.enemy, this.height);
        }
        else if(this.target && this.target != "")
        {
@@ -159,106 +158,102 @@ void trigger_push_touch(entity this)
                        else
                                RandomSelection_Add(e, 0, string_null, 1, 1);
                }
-               other.velocity = trigger_push_calculatevelocity(other.origin, RandomSelection_chosen_ent, this.height);
-               other.move_velocity = other.velocity;
+               toucher.velocity = trigger_push_calculatevelocity(toucher.origin, RandomSelection_chosen_ent, this.height);
        }
        else
        {
-               other.velocity = this.movedir;
-               other.move_velocity = other.velocity;
+               toucher.velocity = this.movedir;
        }
 
-#ifdef SVQC
-       UNSET_ONGROUND(other);
-#elif defined(CSQC)
-       other.move_flags &= ~FL_ONGROUND;
+       UNSET_ONGROUND(toucher);
 
-       if (other.flags & FL_PROJECTILE)
+#ifdef CSQC
+       if (toucher.flags & FL_PROJECTILE)
        {
-               other.move_angles = vectoangles (other.move_velocity);
-               switch(other.move_movetype)
+               toucher.angles = vectoangles (toucher.velocity);
+               switch(toucher.move_movetype)
                {
                        case MOVETYPE_FLY:
-                               other.move_movetype = MOVETYPE_TOSS;
-                               other.gravity = 1;
+                               toucher.move_movetype = MOVETYPE_TOSS;
+                               toucher.gravity = 1;
                                break;
                        case MOVETYPE_BOUNCEMISSILE:
-                               other.move_movetype = MOVETYPE_BOUNCE;
-                               other.gravity = 1;
+                               toucher.move_movetype = MOVETYPE_BOUNCE;
+                               toucher.gravity = 1;
                                break;
                }
        }
 #endif
 
 #ifdef SVQC
-       if (IS_PLAYER(other))
+       if (IS_PLAYER(toucher))
        {
                // reset tracking of oldvelocity for impact damage (sudden velocity changes)
-               other.oldvelocity = other.velocity;
+               toucher.oldvelocity = toucher.velocity;
 
                if(this.pushltime < time)  // prevent "snorring" sound when a player hits the jumppad more than once
                {
                        // flash when activated
-                       Send_Effect(EFFECT_JUMPPAD, other.origin, other.velocity, 1);
-                       _sound (other, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
+                       Send_Effect(EFFECT_JUMPPAD, toucher.origin, toucher.velocity, 1);
+                       _sound (toucher, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
                        this.pushltime = time + 0.2;
                }
-               if(IS_REAL_CLIENT(other) || IS_BOT_CLIENT(other))
+               if(IS_REAL_CLIENT(toucher) || IS_BOT_CLIENT(toucher))
                {
                        bool found = false;
-                       for(int i = 0; i < other.jumppadcount && i < NUM_JUMPPADSUSED; ++i)
-                               if(other.(jumppadsused[i]) == this)
+                       for(int i = 0; i < toucher.jumppadcount && i < NUM_JUMPPADSUSED; ++i)
+                               if(toucher.(jumppadsused[i]) == this)
                                        found = true;
                        if(!found)
                        {
-                               other.(jumppadsused[other.jumppadcount % NUM_JUMPPADSUSED]) = this;
-                               other.jumppadcount = other.jumppadcount + 1;
+                               toucher.(jumppadsused[toucher.jumppadcount % NUM_JUMPPADSUSED]) = this;
+                               toucher.jumppadcount = toucher.jumppadcount + 1;
                        }
 
-                       if(IS_REAL_CLIENT(other))
+                       if(IS_REAL_CLIENT(toucher))
                        {
                                if(this.message)
-                                       centerprint(other, this.message);
+                                       centerprint(toucher, this.message);
                        }
                        else
-                               other.lastteleporttime = time;
+                               toucher.lastteleporttime = time;
 
-                       if (!IS_DEAD(other))
-                               animdecide_setaction(other, ANIMACTION_JUMP, true);
+                       if (!IS_DEAD(toucher))
+                               animdecide_setaction(toucher, ANIMACTION_JUMP, true);
                }
                else
-                       other.jumppadcount = true;
+                       toucher.jumppadcount = true;
 
                // reset tracking of who pushed you into a hazard (for kill credit)
-               other.pushltime = 0;
-               other.istypefrag = 0;
+               toucher.pushltime = 0;
+               toucher.istypefrag = 0;
        }
 
        if(this.enemy.target)
-               SUB_UseTargets(this.enemy, other, other); // TODO: do we need other as trigger too?
+               SUB_UseTargets(this.enemy, toucher, toucher); // TODO: do we need toucher as trigger too?
 
-       if (other.flags & FL_PROJECTILE)
+       if (toucher.flags & FL_PROJECTILE)
        {
-               other.angles = vectoangles (other.velocity);
-               other.com_phys_gravity_factor = 1;
-               switch(other.movetype)
+               toucher.angles = vectoangles (toucher.velocity);
+               toucher.com_phys_gravity_factor = 1;
+               switch(toucher.move_movetype)
                {
                        case MOVETYPE_FLY:
-                               other.movetype = MOVETYPE_TOSS;
-                               other.gravity = 1;
+                               set_movetype(toucher, MOVETYPE_TOSS);
+                               toucher.gravity = 1;
                                break;
                        case MOVETYPE_BOUNCEMISSILE:
-                               other.movetype = MOVETYPE_BOUNCE;
-                               other.gravity = 1;
+                               set_movetype(toucher, MOVETYPE_BOUNCE);
+                               toucher.gravity = 1;
                                break;
                }
-               UpdateCSQCProjectile(other);
+               UpdateCSQCProjectile(toucher);
        }
 
-       /*if (other.flags & FL_ITEM)
+       /*if (toucher.flags & FL_ITEM)
        {
-               ItemUpdate(other);
-               other.SendFlags |= ISF_DROP;
+               ItemUpdate(toucher);
+               toucher.SendFlags |= ISF_DROP;
        }*/
 
        if (this.spawnflags & PUSH_ONCE)
@@ -295,7 +290,7 @@ 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);
 #endif
index 4e8bf1809fd24840637abeb5a3aa27e31109bd41..e03f14d335a2bf9aad0db26bbc11e1bcf7b9e832 100644 (file)
@@ -35,7 +35,7 @@ void trigger_push_use(entity this, entity actor, entity trigger);
 
 vector trigger_push_calculatevelocity(vector org, entity tgt, float ht);
 
-void trigger_push_touch(entity this);
+void trigger_push_touch(entity this, entity toucher);
 
 .vector dest;
 void trigger_push_findtarget(entity this);
index 133397876857999c1eecad47467b8a09fa86e8e1..2cc81e597c0815a6de9d60b5780a24c240dfc210 100644 (file)
@@ -18,18 +18,18 @@ void trigger_keylock_kill(string s)
                remove(t);
 }
 
-void trigger_keylock_touch(entity this)
+void trigger_keylock_touch(entity this, entity toucher)
 {
        bool key_used = false;
        bool started_delay = false;
 
        // only player may trigger the lock
-       if(!IS_PLAYER(other))
+       if(!IS_PLAYER(toucher))
                return;
 
        // check silver key
        if(this.itemkeys)
-               key_used = item_keys_usekey(this, other);
+               key_used = item_keys_usekey(this, toucher);
 
        if(this.itemkeys)
        {
@@ -38,16 +38,16 @@ void trigger_keylock_touch(entity this)
                if(key_used)
                {
                        // one or more keys were given, but others are still missing!
-                       play2(other, this.noise1);
-                       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_LOCKED_ALSONEED, item_keys_keylist(this.itemkeys));
-                       other.key_door_messagetime = time + 2;
+                       play2(toucher, this.noise1);
+                       Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_DOOR_LOCKED_ALSONEED, item_keys_keylist(this.itemkeys));
+                       toucher.key_door_messagetime = time + 2;
                }
-               else if(other.key_door_messagetime <= time)
+               else if(toucher.key_door_messagetime <= time)
                {
                        // no keys were given
-                       play2(other, this.noise2);
-                       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_LOCKED_NEED, item_keys_keylist(this.itemkeys));
-                       other.key_door_messagetime = time + 2;
+                       play2(toucher, this.noise2);
+                       Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_DOOR_LOCKED_NEED, item_keys_keylist(this.itemkeys));
+                       toucher.key_door_messagetime = time + 2;
                }
 #endif
 
@@ -55,7 +55,7 @@ void trigger_keylock_touch(entity this)
                if(this.delay <= time || started_delay == true)
                if(this.target2)
                {
-                       trigger_keylock_trigger(this, other, this.target2);
+                       trigger_keylock_trigger(this, toucher, this.target2);
                        started_delay = true;
                        this.delay = time + this.wait;
                }
@@ -64,12 +64,12 @@ void trigger_keylock_touch(entity this)
        {
 #ifdef SVQC
                // all keys were given!
-               play2(other, this.noise);
-               centerprint(other, this.message);
+               play2(toucher, this.noise);
+               centerprint(toucher, this.message);
 #endif
 
                if(this.target)
-                       trigger_keylock_trigger(this, other, this.target);
+                       trigger_keylock_trigger(this, toucher, this.target);
 
                if(this.killtarget)
                        trigger_keylock_kill(this.killtarget);
index 14d7fda04b7fbcd4420eee464cda96613497239a..b801e9f4f35cb169470cd0c87e62061ae19bb3f3 100644 (file)
@@ -66,34 +66,34 @@ void multi_use(entity this, entity actor, entity trigger)
        multi_trigger(this);
 }
 
-void multi_touch(entity this)
+void multi_touch(entity this, entity toucher)
 {
        if(!(this.spawnflags & 2))
-       if(!other.iscreature)
+       if(!toucher.iscreature)
                        return;
 
        if(this.team)
-               if(((this.spawnflags & 4) == 0) == (this.team != other.team))
+               if(((this.spawnflags & 4) == 0) == (this.team != toucher.team))
                        return;
 
 // if the trigger has an angles field, check player's facing direction
        if (this.movedir != '0 0 0')
        {
-               makevectors (other.angles);
+               makevectors (toucher.angles);
                if (v_forward * this.movedir < 0)
                        return;         // not facing the right way
        }
 
        // if the trigger has pressed keys, check that the player is pressing those keys
        if(this.pressedkeys)
-       if(IS_PLAYER(other)) // only for players
-       if(!(other.pressedkeys & this.pressedkeys))
+       if(IS_PLAYER(toucher)) // only for players
+       if(!(toucher.pressedkeys & this.pressedkeys))
                return;
 
-       EXACTTRIGGER_TOUCH;
+       EXACTTRIGGER_TOUCH(this, toucher);
 
-       this.enemy = other;
-       this.goalentity = other;
+       this.enemy = toucher;
+       this.goalentity = toucher;
        multi_trigger(this);
 }
 
index bf4178beae33396b3742a6bedabe5f950cc0d21d..b54f99dcd411eead96c2cfcc723767ba3b087850 100644 (file)
@@ -17,10 +17,10 @@ void secrets_setstatus(entity this)
 /**
  * A secret has been found (maybe :P)
  */
-void trigger_secret_touch(entity this)
+void trigger_secret_touch(entity this, entity toucher)
 {
        // only a player can trigger this
-       if (!IS_PLAYER(other))
+       if (!IS_PLAYER(toucher))
                return;
 
        // update secrets found counter
@@ -29,11 +29,11 @@ void trigger_secret_touch(entity this)
        //print(ftos(secret_counter.count), "\n");
 
        // centerprint message (multi_touch() doesn't always call centerprint())
-       centerprint(other, this.message);
+       centerprint(toucher, this.message);
        this.message = "";
 
        // handle normal trigger features
-       multi_touch(this);
+       multi_touch(this, toucher);
        remove(this);
 }
 
index fb792b94bb926bdec1cd410746dd62fe94837471..0f8d1a73eebb46b4780f2b2e1758fbeda3d7aff2 100644 (file)
@@ -22,7 +22,7 @@
 #ifdef SVQC
 spawnfunc(trigger_swamp);
 #endif
-void swamp_touch(entity this);
+void swamp_touch(entity this, entity toucher);
 void swampslug_think(entity this);
 
 
@@ -54,42 +54,42 @@ void swampslug_think(entity this)
        // Or we have exited it very recently.
        // Do the damage and renew the timer.
 #ifdef SVQC
-       Damage (this.owner, this, this, this.dmg, DEATH_SWAMP.m_id, other.origin, '0 0 0');
+       Damage (this.owner, this, this, this.dmg, DEATH_SWAMP.m_id, this.owner.origin, '0 0 0');
 #endif
 
        this.nextthink = time + this.swamp_interval;
 }
 
-void swamp_touch(entity this)
+void swamp_touch(entity this, entity toucher)
 {
        // If whatever thats touching the swamp is not a player
        // or if its a dead player, just dont care abt it.
-       if(!IS_PLAYER(other) || IS_DEAD(other))
+       if(!IS_PLAYER(toucher) || IS_DEAD(toucher))
                return;
 
-       EXACTTRIGGER_TOUCH;
+       EXACTTRIGGER_TOUCH(this, toucher);
 
        // Chech if player alredy got a swampslug.
-       if(other.in_swamp != 1)
+       if(toucher.in_swamp != 1)
        {
                // If not attach one.
-               //centerprint(other,"Entering swamp!\n");
-               other.swampslug = spawn();
-               other.swampslug.health = 2;
-               setthink(other.swampslug, swampslug_think);
-               other.swampslug.nextthink = time;
-               other.swampslug.owner = other;
-               other.swampslug.dmg = this.dmg;
-               other.swampslug.swamp_interval = this.swamp_interval;
-               other.swamp_slowdown = this.swamp_slowdown;
-               other.in_swamp = 1;
+               //centerprint(toucher,"Entering swamp!\n");
+               toucher.swampslug = spawn();
+               toucher.swampslug.health = 2;
+               setthink(toucher.swampslug, swampslug_think);
+               toucher.swampslug.nextthink = time;
+               toucher.swampslug.owner = toucher;
+               toucher.swampslug.dmg = this.dmg;
+               toucher.swampslug.swamp_interval = this.swamp_interval;
+               toucher.swamp_slowdown = this.swamp_slowdown;
+               toucher.in_swamp = 1;
                return;
        }
 
-       //other.in_swamp = 1;
+       //toucher.in_swamp = 1;
 
        //Revitalize players swampslug
-       other.swampslug.health = 2;
+       toucher.swampslug.health = 2;
 }
 
 REGISTER_NET_LINKED(ENT_CLIENT_SWAMP)
index 8ee6b7a69727e091f5a83459b4309b6e9172686f..69e2c49c1d9c83b3ceb2b13fb3a14bc9f96e8f65 100644 (file)
@@ -11,49 +11,49 @@ void trigger_teleport_use(entity this, entity actor, entity trigger)
 }
 #endif
 
-void Teleport_Touch (entity this)
+void Teleport_Touch(entity this, entity toucher)
 {
        if (this.active != ACTIVE_ACTIVE)
                return;
 
 #ifdef SVQC
-       if (!other.teleportable)
+       if (!toucher.teleportable)
                return;
 
-       if(other.vehicle)
-       if(!other.vehicle.teleportable)
+       if(toucher.vehicle)
+       if(!toucher.vehicle.teleportable)
                return;
 
-       if(IS_TURRET(other))
+       if(IS_TURRET(toucher))
                return;
 #elif defined(CSQC)
-       if(!IS_PLAYER(other))
+       if(!IS_PLAYER(toucher))
                return;
 #endif
 
-       if(IS_DEAD(other))
+       if(IS_DEAD(toucher))
                return;
 
        if(this.team)
-               if(((this.spawnflags & 4) == 0) == (DIFF_TEAM(this, other)))
+               if(((this.spawnflags & 4) == 0) == (DIFF_TEAM(this, toucher)))
                        return;
 
-       EXACTTRIGGER_TOUCH;
+       EXACTTRIGGER_TOUCH(this, toucher);
 
 #ifdef SVQC
-       if(IS_PLAYER(other))
-               RemoveGrapplingHook(other);
+       if(IS_PLAYER(toucher))
+               RemoveGrapplingHook(toucher);
 #endif
 
        entity e;
-       e = Simple_TeleportPlayer(this, other);
+       e = Simple_TeleportPlayer(this, toucher);
 
 #ifdef SVQC
        string s = this.target; this.target = string_null;
-       SUB_UseTargets(this, other, other); // TODO: should we be using other for trigger too?
+       SUB_UseTargets(this, toucher, toucher); // TODO: should we be using toucher for trigger too?
        if (!this.target) this.target = s;
 
-       SUB_UseTargets(e, other, other);
+       SUB_UseTargets(e, toucher, toucher);
 #endif
 }
 
@@ -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 55719cb3f59eb38fe30ef856de28f90dfe568b8f..8fd5cb08cf363e9dac1ee8f074082083234e0b3e 100644 (file)
@@ -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;
@@ -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 57bb008fcdb133516ec9e0ca0c1ebbdf57a54678..71181f209eeed787652d166d2a9e0e1e345a425c 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;
@@ -443,9 +443,9 @@ void turret_projectile_explode(entity this)
        remove(this);
 }
 
-void turret_projectile_touch(entity this)
+void turret_projectile_touch(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
        turret_projectile_explode(this);
 }
 
@@ -474,7 +474,7 @@ 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.enemy                = actor.enemy;
@@ -1199,7 +1199,7 @@ void turrets_manager_think(entity this)
 
        if (autocvar_g_turrets_reloadcvars == 1)
        {
-               FOREACH_ENTITY(IS_TURRET(it), {
+               FOREACH_ENTITY_FLAGS(turret_flags, TUR_FLAG_ISTURRET, {
                        load_unit_settings(it, true);
                        Turret tur = get_turretinfo(it.m_id);
                        tur.tr_think(tur, it);
@@ -1329,7 +1329,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 +1349,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;
+       this.tur_head.move_movetype             = this.move_movetype;
 
        if(!this.tur_defend)
        if(this.target != "")
index 15dbaec4f009b0c8d87fba54e6c0269c72f41709..62ed2fb722dc6cca55a20d4460f391681cc058e3 100644 (file)
@@ -1,13 +1,13 @@
 spawnfunc(turret_targettrigger);
-void turret_targettrigger_touch(entity this);
+void turret_targettrigger_touch(entity this, entity toucher);
 
-void turret_targettrigger_touch(entity this)
+void turret_targettrigger_touch(entity this, entity toucher)
 {
     if (this.cnt > time) return;
     FOREACH_ENTITY_STRING_ORDERED(targetname, this.target, {
         if (!(it.turret_flags & TUR_FLAG_RECIEVETARGETS)) continue;
         if (!it.turret_addtarget) continue;
-        it.turret_addtarget(it, other, this);
+        it.turret_addtarget(it, toucher, this);
     });
     this.cnt = time + 0.5;
 }
index a72a9f016ca35f111b661d813dde11213bcc8354..62d7222ce496003b284e43342d766159a08f3ab1 100644 (file)
@@ -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;
+            it.move_movetype = MOVETYPE_BOUNCE;
             it.move_time               = time;
             it.draw                    = ewheel_draw;
         }
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 ea48a6479024734fd4a425f044c37548d40118e9..df68e1ce7feb7e3db811ef084a3798938ed6ab8f 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;
index e21cd498f71738dc66921e209e83b28282ebbb55..38a9335f7a8937d67a07802629f556cc0c2736e2 100644 (file)
@@ -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 1a5c3f09ab03aa5f51ec97d3b98ff386861781b9..3f55280e8fa372cf790d726b29eb41bde633e703 100644 (file)
@@ -103,6 +103,11 @@ void walker_rocket_explode(entity this)
     remove (this);
 }
 
+void walker_rocket_touch(entity this, entity toucher)
+{
+    walker_rocket_explode(this);
+}
+
 void walker_rocket_damage(entity this, entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
 {
     this.health = this.health - damage;
@@ -250,10 +255,10 @@ 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_explode);
+    settouch(rocket, walker_rocket_touch);
     rocket.flags                         = FL_PROJECTILE;
     rocket.solid                         = SOLID_BBOX;
     rocket.max_health           = time + 9;
@@ -566,7 +571,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);
@@ -585,7 +590,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);
@@ -593,7 +598,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;
 
@@ -637,8 +642,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)
@@ -648,9 +652,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;
             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 57f5990bb77a3915f9296c4f530074dad7485af8..aeb7de83b7a60b77b22e9fdcfc2b67fbc44c2ab2 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;
+                               remove(axh);
+                       }
+               }
                return;
        }
 
@@ -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)
index 28ba057c0d41ad3fdefb84b2081fd42fb5a80cc0..4fd9a0d5231d38abfe5941e419717db50f2ae98d 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)
@@ -179,28 +198,33 @@ void vehicles_projectile_damage(entity this, entity inflictor, entity attacker,
        }
 }
 
-void vehicles_projectile_explode(entity this)
+void vehicles_projectile_explode(entity this, entity toucher)
 {
-       if(this.owner && other != NULL)
+       if(this.owner && toucher != NULL)
        {
-               if(other == this.owner.vehicle)
+               if(toucher == this.owner.vehicle)
                        return;
 
-               if(other == this.owner.vehicle.tur_head)
+               if(toucher == this.owner.vehicle.tur_head)
                        return;
        }
 
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
 
        this.event_damage = func_null;
-       RadiusDamage (this, this.realowner, this.shot_dmg, 0, this.shot_radius, this, NULL, this.shot_force, this.totalfrags, other);
+       RadiusDamage (this, this.realowner, this.shot_dmg, 0, this.shot_radius, this, NULL, this.shot_force, this.totalfrags, toucher);
 
        remove (this);
 }
 
+void vehicles_projectile_explode_think(entity this)
+{
+       vehicles_projectile_explode(this, NULL);
+}
+
 void vehicles_projectile_explode_use(entity this, entity actor, entity trigger)
 {
-       vehicles_projectile_explode(this);
+       vehicles_projectile_explode(this, trigger);
 }
 
 entity vehicles_projectile(entity this, string _mzlfx, Sound _mzlsound,
@@ -222,7 +246,7 @@ entity vehicles_projectile(entity this, string _mzlfx, Sound _mzlsound,
        proj.shot_force    = _force;
        proj.totalfrags    = _deahtype;
        proj.solid                      = SOLID_BBOX;
-       proj.movetype            = MOVETYPE_FLYMISSILE;
+       set_movetype(proj, MOVETYPE_FLYMISSILE);
        proj.flags                      = FL_PROJECTILE;
        proj.bot_dodge          = true;
        proj.bot_dodgerating  = _dmg;
@@ -264,6 +288,11 @@ void vehicles_gib_explode(entity this)
        remove(this);
 }
 
+void vehicles_gib_touch(entity this, entity toucher)
+{
+       vehicles_gib_explode(this);
+}
+
 void vehicles_gib_think(entity this)
 {
        this.alpha -= 0.1;
@@ -280,7 +309,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;
@@ -293,7 +322,7 @@ entity vehicle_tossgib(entity this, entity _template, vector _vel, string _tag,
        {
                setthink(_gib, vehicles_gib_explode);
                _gib.nextthink = time + random() * _explode;
-               settouch(_gib, vehicles_gib_explode);
+               settouch(_gib, vehicles_gib_touch);
        }
        else
        {
@@ -767,7 +796,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;
@@ -817,21 +846,21 @@ void vehicles_exit(entity vehic, bool eject)
        vehicles_exit_running = false;
 }
 
-void vehicles_touch(entity this)
+void vehicles_touch(entity this, entity toucher)
 {
-       if(MUTATOR_CALLHOOK(VehicleTouch, this, other))
+       if(MUTATOR_CALLHOOK(VehicleTouch, this, toucher))
                return;
 
        // Vehicle currently in use
        if(this.owner)
        {
                if(!forbidWeaponUse(this.owner))
-               if(other != NULL)
-               if((this.origin_z + this.maxs_z) > (other.origin_z))
-               if(vehicles_crushable(other))
+               if(toucher != NULL)
+               if((this.origin_z + this.maxs_z) > (toucher.origin_z))
+               if(vehicles_crushable(toucher))
                {
                        if(vdist(this.velocity, >=, 30))
-                               Damage(other, this, this.owner, autocvar_g_vehicles_crush_dmg, DEATH_VH_CRUSH.m_id, '0 0 0', normalize(other.origin - this.origin) * autocvar_g_vehicles_crush_force);
+                               Damage(toucher, this, this.owner, autocvar_g_vehicles_crush_dmg, DEATH_VH_CRUSH.m_id, '0 0 0', normalize(toucher.origin - this.origin) * autocvar_g_vehicles_crush_force);
 
                        return; // Dont do selfdamage when hitting "soft targets".
                }
@@ -847,7 +876,7 @@ void vehicles_touch(entity this)
        if(autocvar_g_vehicles_enter)
                return;
 
-       vehicles_enter(other, this);
+       vehicles_enter(toucher, this);
 }
 
 bool vehicle_impulse(entity this, int imp)
@@ -882,23 +911,20 @@ void vehicles_enter(entity pl, entity veh)
        || (pl.vehicle)
        ) { return; }
 
+       Vehicle info = Vehicles_from(veh.vehicleid);
+
        if(autocvar_g_vehicles_enter) // vehicle's touch function should handle this if entering via use key is disabled (TODO)
        if(veh.vehicle_flags & VHF_MULTISLOT)
        if(veh.owner && SAME_TEAM(pl, veh))
        {
-               if(!veh.gunner1)
-               if(time >= veh.gun1.phase)
-               if(veh.gun1.vehicle_enter)
-               if(veh.gun1.vehicle_enter(veh, pl))
-                       return;
-
-               if(!veh.gunner2)
-               if(time >= veh.gun2.phase)
-               if(veh.gun2.vehicle_enter)
-               if(veh.gun2.vehicle_enter(veh, pl))
-                       return;
+               // we don't need a return value or anything here
+               // if successful the owner check below will prevent anything weird
+               info.vr_gunner_enter(info, veh, pl);
        }
 
+       if(veh.owner)
+               return; // got here and didn't enter the gunner, return
+
        if(teamplay)
        if(veh.team)
        if(DIFF_TEAM(pl, veh))
@@ -940,7 +966,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;
@@ -998,7 +1025,6 @@ void vehicles_enter(entity pl, entity veh)
        MUTATOR_CALLHOOK(VehicleEnter, pl, veh);
 
        CSQCModel_UnlinkEntity(veh);
-       Vehicle info = Vehicles_from(veh.vehicleid);
        info.vr_enter(info, veh);
 
        antilag_clear(pl, CS(pl));
@@ -1019,6 +1045,17 @@ void vehicles_think(entity this)
        CSQCMODEL_AUTOUPDATE(this);
 }
 
+void vehicles_reset(entity this)
+{
+       if(this.owner)
+               vehicles_exit(this, VHEF_RELEASE);
+
+       vehicles_clearreturn(this);
+
+       if(this.active != ACTIVE_NOT)
+               vehicles_spawn(this);
+}
+
 // initialization
 void vehicles_spawn(entity this)
 {
@@ -1030,10 +1067,11 @@ void vehicles_spawn(entity this)
        this.owner                              = NULL;
        settouch(this, vehicles_touch);
        this.event_damage               = vehicles_damage;
+       this.reset                              = vehicles_reset;
        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;
@@ -1159,6 +1197,8 @@ bool vehicle_initialize(entity this, Vehicle info, bool nodrop)
 
        setsize(this, info.mins, info.maxs);
 
+       info.vr_setup(info, this);
+
        if(!nodrop)
        {
                setorigin(this, this.origin);
@@ -1170,8 +1210,6 @@ bool vehicle_initialize(entity this, Vehicle info, bool nodrop)
        this.pos2 = this.angles;
        this.tur_head.team = this.team;
 
-       info.vr_setup(info, this);
-
        if(this.active == ACTIVE_NOT)
                this.nextthink = 0; // wait until activated
        else if(autocvar_g_vehicles_delayspawn)
index 8dacc66346030df4d8787699fa11880f36be4993..927465ea6b933ee0d98cf4bbdffc553567d56f7d 100644 (file)
@@ -46,6 +46,8 @@ CLASS(Vehicle, Object)
     METHOD(Vehicle, vr_precache, void(Vehicle this)) { }
     /** (SERVER) called when a player enters this vehicle */
     METHOD(Vehicle, vr_enter, void(Vehicle this, entity instance)) { }
+    /** (SERVER) called when a player enters this vehicle while occupied */
+    METHOD(Vehicle, vr_gunner_enter, void(Vehicle this, entity instance, entity actor)) { }
     /** (SERVER) called when the vehicle re-spawns */
     METHOD(Vehicle, vr_spawn, void(Vehicle this, entity instance)) { }
     /** (SERVER) called when a vehicle hits something */
index 2750621f2c5e427b11fc152ff01ad59e33ceca7a..ff7f333ab27ce189d65aaac74740c0e04cf94f12 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;
@@ -297,15 +298,17 @@ bool bumblebee_gunner_enter(entity this, entity player)
        if(!vehic.gunner1 && !vehic.gunner2 && ((time >= vehic.gun1.phase) + (time >= vehic.gun2.phase)) == 2)
        {
                // we can have some fun
-               if(vlen2(real_origin(vehic.gun2) - player.origin) < vlen2(real_origin(vehic.gun1) - player.origin))
+               vector v1 = gettaginfo(vehic, gettagindex(vehic, "cannon_right"));
+               vector v2 = gettaginfo(vehic, gettagindex(vehic, "cannon_left"));
+               if(vlen2(player.origin - v1) < vlen2(player.origin - v2))
                {
-                       gunner = vehic.gun2;
-                       vehic.gunner2 = player;
+                       gunner = vehic.gun1;
+                       vehic.gunner1 = player;
                }
                else
                {
-                       gunner = vehic.gun1;
-                       vehic.gunner1 = player;
+                       gunner = vehic.gun2;
+                       vehic.gunner2 = player;
                }
        }
        else if(!vehic.gunner1 && time >= vehic.gun1.phase)     { gunner = vehic.gun1; vehic.gunner1 = player; }
@@ -317,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;
@@ -328,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);
 
@@ -369,26 +372,26 @@ bool vehicles_valid_pilot(entity this, entity toucher)
        return true;
 }
 
-void bumblebee_touch(entity this)
+void bumblebee_touch(entity this, entity toucher)
 {
        if(autocvar_g_vehicles_enter) { return; }
 
        if(this.gunner1 != NULL && this.gunner2 != NULL)
        {
-               vehicles_touch(this);
+               vehicles_touch(this, toucher);
                return;
        }
 
-       if(vehicles_valid_pilot(this, other))
+       if(vehicles_valid_pilot(this, toucher))
        {
                float phase_time = (time >= this.gun1.phase) + (time >= this.gun2.phase);
 
-               if(time >= other.vehicle_enter_delay && phase_time)
-               if(bumblebee_gunner_enter(this, other))
+               if(time >= toucher.vehicle_enter_delay && phase_time)
+               if(bumblebee_gunner_enter(this, toucher))
                        return;
        }
 
-       vehicles_touch(this);
+       vehicles_touch(this, toucher);
 }
 
 void bumblebee_regen(entity this)
@@ -508,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))
                {
@@ -658,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;
@@ -701,6 +704,11 @@ void bumblebee_blowup(entity this)
        remove(this);
 }
 
+void bumblebee_dead_touch(entity this, entity toucher)
+{
+       bumblebee_blowup(this);
+}
+
 void bumblebee_diethink(entity this)
 {
        if(time >= this.wait)
@@ -730,7 +738,21 @@ 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))
+{
+       if(!instance.gunner1)
+       if(time >= instance.gun1.phase)
+       if(instance.gun1.vehicle_enter)
+       if(instance.gun1.vehicle_enter(instance, actor))
+               return;
+
+       if(!instance.gunner2)
+       if(time >= instance.gun2.phase)
+       if(instance.gun2.vehicle_enter)
+       if(instance.gun2.vehicle_enter(instance, actor))
+               return;
 }
 METHOD(Bumblebee, vr_think, void(Bumblebee thisveh, entity instance))
 {
@@ -745,11 +767,8 @@ METHOD(Bumblebee, vr_think, void(Bumblebee thisveh, entity instance))
         {
                entity e = instance.gunner1;
                instance.gun1.vehicle_exit(instance.gun1, VHEF_EJECT);
-               entity oldother = other;
-               other = e;
                instance.phase = 0;
-               gettouch(instance)(instance);
-               other = oldother;
+               gettouch(instance)(instance, e);
                return;
         }
 
@@ -757,11 +776,8 @@ METHOD(Bumblebee, vr_think, void(Bumblebee thisveh, entity instance))
         {
                entity e = instance.gunner2;
                instance.gun2.vehicle_exit(instance.gun2, VHEF_EJECT);
-               entity oldother = other;
-               other = e;
                instance.phase = 0;
-               gettouch(instance)(instance);
-               other = oldother;
+               gettouch(instance)(instance, e);
             return;
         }
     }
@@ -790,7 +806,7 @@ METHOD(Bumblebee, vr_death, void(Bumblebee thisveh, entity instance))
     entity _body = vehicle_tossgib(instance, instance, instance.velocity + randomvec() * 200, "", rint(random()), rint(random()), 6, randomvec() * 100);
 
     if(random() > 0.5)
-        settouch(_body, bumblebee_blowup);
+        settouch(_body, bumblebee_dead_touch);
     else
         settouch(_body, func_null);
 
@@ -809,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';
@@ -886,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 254f9bfc4a74b5772023f786f1425ad37fd97734..277326ffd2a18e055ab6c2b3ff8258356c23639a 100644 (file)
@@ -186,7 +186,7 @@ bool racer_frame(entity this)
 
        traceline(vehic.origin, vehic.origin + '0 0 1', MOVE_NOMONSTERS, this);
        int cont = trace_dpstartcontents;
-       if(cont & DPCONTENTS_WATER)
+       if(!(cont & DPCONTENTS_WATER))
                vehic.air_finished = time + autocvar_g_vehicle_racer_water_time;
 
        if(IS_DEAD(vehic))
@@ -199,12 +199,6 @@ bool racer_frame(entity this)
 
        PHYS_INPUT_BUTTON_ZOOM(this) = PHYS_INPUT_BUTTON_CROUCH(this) = false;
 
-       if(time >= vehic.vehicle_last_trace)
-       {
-               crosshair_trace(this);
-               vehic.vehicle_last_trace = time + autocvar_g_vehicle_racer_thinkrate;
-       }
-
        vehic.angles_x *= -1;
 
        // Yaw
@@ -337,10 +331,16 @@ bool racer_frame(entity this)
 
        if(autocvar_g_vehicle_racer_rocket_locktarget)
        {
-               if(vehic.vehicle_last_trace == time + autocvar_g_vehicle_racer_thinkrate)
-               vehicles_locktarget(vehic, (1 / autocvar_g_vehicle_racer_rocket_locking_time) * frametime,
-                                                (1 / autocvar_g_vehicle_racer_rocket_locking_releasetime) * frametime,
-                                                autocvar_g_vehicle_racer_rocket_locked_time);
+               if(time >= vehic.vehicle_last_trace)
+               {
+                       crosshair_trace(this);
+
+                       vehicles_locktarget(vehic, (1 / autocvar_g_vehicle_racer_rocket_locking_time) * frametime,
+                                                        (1 / autocvar_g_vehicle_racer_rocket_locking_releasetime) * frametime,
+                                                        autocvar_g_vehicle_racer_rocket_locked_time);
+
+                       vehic.vehicle_last_trace = time + autocvar_g_vehicle_racer_thinkrate;
+               }
 
                if(vehic.lock_target)
                {
@@ -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;
 
@@ -511,7 +511,7 @@ void racer_blowup_think(entity this)
        CSQCMODEL_AUTOUPDATE(this);
 }
 
-void racer_deadtouch(entity this)
+void racer_deadtouch(entity this, entity toucher)
 {
        this.avelocity_x *= 0.7;
        this.cnt -= 1;
@@ -527,41 +527,6 @@ spawnfunc(vehicle_racer)
 
 #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,7 +538,7 @@ 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;
 
@@ -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 59510c78f069e7e4d6d22787af5f5171d6560f4a..d938c4ad396cd6f760d78ad22a0a9857a4706b87 100644 (file)
@@ -47,6 +47,8 @@ float autocvar_g_vehicle_raptor_speed_up = 1700;
 float autocvar_g_vehicle_raptor_speed_down = 1700;
 float autocvar_g_vehicle_raptor_friction = 2;
 
+bool autocvar_g_vehicle_raptor_swim = false;
+
 float autocvar_g_vehicle_raptor_cannon_turnspeed = 120;
 float autocvar_g_vehicle_raptor_cannon_turnlimit = 20;
 float autocvar_g_vehicle_raptor_cannon_pitchlimit_up = 12;
@@ -94,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;
        }
@@ -285,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))
                {
@@ -311,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)
@@ -508,14 +510,14 @@ bool raptor_takeoff(entity this)
        PHYS_INPUT_BUTTON_ATCK(this) = PHYS_INPUT_BUTTON_ATCK2(this) = PHYS_INPUT_BUTTON_CROUCH(this) = false;
 }
 
-void raptor_blowup(entity this)
+void raptor_blowup(entity this, entity toucher)
 {
        this.deadflag   = DEAD_DEAD;
        this.vehicle_exit(this, VHEF_NORMAL);
        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';
@@ -529,7 +531,10 @@ void raptor_blowup(entity this)
 void raptor_diethink(entity this)
 {
        if(time >= this.wait)
-               setthink(this, raptor_blowup);
+       {
+               raptor_blowup(this, NULL);
+               return;
+       }
 
        if(random() < 0.05)
        {
@@ -608,11 +613,11 @@ 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;
-    instance.velocity_z = 1; // Nudge upwards to takeoff sequense can work.
+    instance.velocity = '0 0 1'; // nudge upwards so takeoff sequence can work
     instance.tur_head.exteriormodeltoclient = instance.owner;
 
     instance.delay = time + autocvar_g_vehicle_raptor_bombs_refire;
@@ -630,7 +635,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);
@@ -697,7 +702,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;
 
@@ -705,7 +710,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;
 
@@ -719,10 +724,13 @@ 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;
 
+    if(!autocvar_g_vehicle_raptor_swim)
+       instance.dphitcontentsmask |= DPCONTENTS_LIQUIDSMASK;
+
     instance.PlayerPhysplug = raptor_frame;
 
     instance.bomb1.gun1.avelocity_y = 90;
@@ -755,6 +763,9 @@ METHOD(Raptor, vr_setup, void(Raptor thisveh, entity instance))
     instance.vehicle_health = autocvar_g_vehicle_raptor_health;
     instance.vehicle_shield = autocvar_g_vehicle_raptor_shield;
     instance.max_health = instance.vehicle_health;
+
+    if(!autocvar_g_vehicle_raptor_swim)
+       instance.dphitcontentsmask |= DPCONTENTS_LIQUIDSMASK;
 }
 
 #endif
@@ -778,7 +789,7 @@ METHOD(Raptor, vr_crosshair, void(Raptor thisveh, entity player))
     }
 
     vector tmpSize = '0 0 0';
-    if(weapon2mode != RSM_FLARE)
+    if(weapon2mode != RSM_FLARE && !spectatee_status)
     {
         vector where;
 
index 56c3e8c610ade76c871b28f091e84fc1f1a8fe9d..86f4b22b8b6735dcc7c69a2f28bc97754008bc31 100644 (file)
@@ -53,7 +53,7 @@ METHOD(RaptorBomb, wr_think, void(entity thiswep, entity actor, .entity weaponen
 
 void raptor_flare_think(entity this);
 void raptor_flare_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
-void raptor_flare_touch(entity this);
+void raptor_flare_touch(entity this, entity toucher);
 
 METHOD(RaptorFlare, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) {
     bool isPlayer = IS_PLAYER(actor);
@@ -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);
@@ -94,12 +94,12 @@ void raptor_bomblet_boom(entity this)
     remove(this);
 }
 
-void raptor_bomblet_touch(entity this)
+void raptor_bomblet_touch(entity this, entity toucher)
 {
-    if(other == this.owner)
+    if(toucher == this.owner)
         return;
 
-    PROJECTILE_TOUCH(this);
+    PROJECTILE_TOUCH(this, toucher);
     setthink(this, raptor_bomblet_boom);
     this.nextthink = time + random() * autocvar_g_vehicle_raptor_bomblet_explode_delay;
 }
@@ -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;
@@ -143,6 +143,11 @@ void raptor_bomb_burst(entity this)
     remove(this);
 }
 
+void raptor_bomb_touch(entity this, entity toucher)
+{
+       raptor_bomb_burst(this);
+}
+
 void raptor_bombdrop(entity this)
 {
     entity bomb_1, bomb_2;
@@ -155,10 +160,11 @@ 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_burst);
-    settouch(bomb_2, raptor_bomb_burst);
+    settouch(bomb_1, raptor_bomb_touch);
+    settouch(bomb_2, raptor_bomb_touch);
     setthink(bomb_1, raptor_bomb_burst);
     setthink(bomb_2, raptor_bomb_burst);
     bomb_1.cnt           = bomb_2.cnt          = time + 10;
@@ -180,7 +186,7 @@ void raptor_bombdrop(entity this)
     CSQCProjectile(bomb_2, true, PROJECTILE_RAPTORBOMB, true);
 }
 
-void raptor_flare_touch(entity this)
+void raptor_flare_touch(entity this, entity toucher)
 {
     remove(this);
 }
@@ -195,15 +201,13 @@ void raptor_flare_damage(entity this, entity inflictor, entity attacker, float d
 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);
@@ -219,7 +223,7 @@ 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)
@@ -235,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..8140de8646d6b85b366c1b277029ada2ff4f7d36 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;
@@ -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;
@@ -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 dba8a72a8f021e0720abaa9c8c563c94e0c7be8a..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;
@@ -196,7 +192,7 @@ void spiderbot_rocket_do(entity this)
             float _dist = (random() * autocvar_g_vehicle_spiderbot_rocket_radius) + vlen(v - trace_endpos);
             _dist -= (random() * autocvar_g_vehicle_spiderbot_rocket_radius) ;
             rocket.nextthink  = time + (_dist / autocvar_g_vehicle_spiderbot_rocket_speed);
-            setthink(rocket, vehicles_projectile_explode);
+            setthink(rocket, vehicles_projectile_explode_think);
 
             if(PHYS_INPUT_BUTTON_ATCK2(this.owner) && this.tur_head.frame == 1)
                 this.wait = -10;
@@ -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 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 9262698daa6c09a8f63840bb05ecf88ce5528499..3e3af5e0f1e0f18f89d1b2a25ab044693b07c7d9 100644 (file)
@@ -231,17 +231,17 @@ void Arc_Player_SetHeat(entity player)
        //dprint("Heat: ",ftos(player.arc_heat_percent*100),"%\n");
 }
 
-void W_Arc_Bolt_Explode(entity this)
+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, other);
+       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);
 }
 
 void W_Arc_Bolt_Explode_use(entity this, entity actor, entity trigger)
 {
-       W_Arc_Bolt_Explode(this);
+       W_Arc_Bolt_Explode(this, trigger);
 }
 
 void W_Arc_Bolt_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
@@ -259,10 +259,10 @@ void W_Arc_Bolt_Damage(entity this, entity inflictor, entity attacker, float dam
                W_PrepareExplosionByDamage(this, attacker, getthink(this));
 }
 
-void W_Arc_Bolt_Touch(entity this)
+void W_Arc_Bolt_Touch(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
-       this.use(this, NULL, NULL);
+       PROJECTILE_TOUCH(this, toucher);
+       this.use(this, NULL, toucher);
 }
 
 void W_Arc_Attack_Bolt(Weapon thiswep, entity actor)
@@ -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);
@@ -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))
@@ -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;
@@ -857,6 +855,7 @@ METHOD(Arc, wr_drop, void(entity thiswep, entity actor))
     weapon_dropevent_item.arc_cooldown = actor.arc_cooldown;
     actor.arc_overheat = 0;
     actor.arc_cooldown = 0;
+    actor.arc_BUTTON_ATCK_prev = false;
 }
 METHOD(Arc, wr_pickup, void(entity thiswep, entity actor))
 {
@@ -867,6 +866,18 @@ METHOD(Arc, wr_pickup, void(entity thiswep, entity actor))
         actor.arc_cooldown = weapon_dropevent_item.arc_cooldown;
     }
 }
+METHOD(Arc, wr_resetplayer, void(entity thiswep, entity actor))
+{
+    actor.arc_overheat = 0;
+    actor.arc_cooldown = 0;
+    actor.arc_BUTTON_ATCK_prev = false;
+}
+METHOD(Arc, wr_playerdeath, void(entity thiswep, entity actor))
+{
+    actor.arc_overheat = 0;
+    actor.arc_cooldown = 0;
+    actor.arc_BUTTON_ATCK_prev = false;
+}
 #endif
 #ifdef CSQC
 bool autocvar_cl_arcbeam_teamcolor = true;
@@ -1285,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 a4fb13c44ee0176212dfa59cd09dfc9592d99cf1..3a9bf365da35186132ee44561cdf13e6e39b2322 100644 (file)
@@ -56,9 +56,9 @@ REGISTER_WEAPON(BLASTER, blaster, NEW(Blaster));
 spawnfunc(weapon_blaster) { weapon_defaultspawnfunc(this, WEP_BLASTER); }
 spawnfunc(weapon_laser) { spawnfunc_weapon_blaster(this); }
 
-void W_Blaster_Touch(entity this)
+void W_Blaster_Touch(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
 
        this.event_damage = func_null;
 
@@ -72,7 +72,7 @@ void W_Blaster_Touch(entity this)
                NULL,
                this.blaster_force,
                this.projectiledeathtype,
-               other
+               toucher
        );
 
        remove(this);
@@ -80,7 +80,7 @@ void W_Blaster_Touch(entity 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);
index eb3e72f8ac0535e3c13d06f0d774a31fa2080202..47fa8efcadaec3d884717b8f0bf710436656a5b8 100644 (file)
@@ -118,7 +118,7 @@ void W_Crylink_Reset(entity this)
 }
 
 // force projectile to explode
-void W_Crylink_LinkExplode(entity e, entity e2)
+void W_Crylink_LinkExplode(entity e, entity e2, entity directhitentity)
 {
        float a;
 
@@ -132,9 +132,10 @@ void W_Crylink_LinkExplode(entity e, entity e2)
 
        float isprimary = !(e.projectiledeathtype & HITTYPE_SECONDARY);
 
-       RadiusDamage(e, e.realowner, WEP_CVAR_BOTH(crylink, isprimary, damage) * a, WEP_CVAR_BOTH(crylink, isprimary, edgedamage) * a, WEP_CVAR_BOTH(crylink, isprimary, radius), NULL, NULL, WEP_CVAR_BOTH(crylink, isprimary, force) * a, e.projectiledeathtype, other);
+       RadiusDamage(e, e.realowner, WEP_CVAR_BOTH(crylink, isprimary, damage) * a, WEP_CVAR_BOTH(crylink, isprimary, edgedamage) * a, WEP_CVAR_BOTH(crylink, isprimary, radius), 
+                               NULL, NULL, WEP_CVAR_BOTH(crylink, isprimary, force) * a, e.projectiledeathtype, directhitentity);
 
-       W_Crylink_LinkExplode(e.queuenext, e2);
+       W_Crylink_LinkExplode(e.queuenext, e2, directhitentity);
 
        e.classname = "spike_oktoremove";
        remove(e);
@@ -261,7 +262,7 @@ void W_Crylink_LinkJoinEffect_Think(entity this)
                                        NULL,
                                        WEP_CVAR_BOTH(crylink, isprimary, joinexplode_force) * n,
                                        e.projectiledeathtype,
-                                       other
+                                       NULL
                                );
                                Send_Effect(EFFECT_CRYLINK_JOINEXPLODE, this.origin, '0 0 0', n);
                        }
@@ -293,17 +294,17 @@ float W_Crylink_Touch_WouldHitFriendly(entity projectile, float rad)
 }
 
 // NO bounce protection, as bounces are limited!
-void W_Crylink_Touch(entity this)
+void W_Crylink_Touch(entity this, entity toucher)
 {
        float finalhit;
        float f;
        float isprimary = !(this.projectiledeathtype & HITTYPE_SECONDARY);
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
 
        float a;
        a = bound(0, 1 - (time - this.fade_time) * this.fade_rate, 1);
 
-       finalhit = ((this.cnt <= 0) || (other.takedamage != DAMAGE_NO));
+       finalhit = ((this.cnt <= 0) || (toucher.takedamage != DAMAGE_NO));
        if(finalhit)
                f = 1;
        else
@@ -311,13 +312,13 @@ void W_Crylink_Touch(entity this)
        if(a)
                f *= a;
 
-       float totaldamage = RadiusDamage(this, this.realowner, WEP_CVAR_BOTH(crylink, isprimary, damage) * f, WEP_CVAR_BOTH(crylink, isprimary, edgedamage) * f, WEP_CVAR_BOTH(crylink, isprimary, radius), NULL, NULL, WEP_CVAR_BOTH(crylink, isprimary, force) * f, this.projectiledeathtype, other);
+       float totaldamage = RadiusDamage(this, this.realowner, WEP_CVAR_BOTH(crylink, isprimary, damage) * f, WEP_CVAR_BOTH(crylink, isprimary, edgedamage) * f, WEP_CVAR_BOTH(crylink, isprimary, radius), NULL, NULL, WEP_CVAR_BOTH(crylink, isprimary, force) * f, this.projectiledeathtype, toucher);
 
        if(totaldamage && ((WEP_CVAR_BOTH(crylink, isprimary, linkexplode) == 2) || ((WEP_CVAR_BOTH(crylink, isprimary, linkexplode) == 1) && !W_Crylink_Touch_WouldHitFriendly(this, WEP_CVAR_BOTH(crylink, isprimary, radius)))))
        {
                if(this == this.realowner.crylink_lastgroup)
                        this.realowner.crylink_lastgroup = NULL;
-               W_Crylink_LinkExplode(this.queuenext, this);
+               W_Crylink_LinkExplode(this.queuenext, this, toucher);
                this.classname = "spike_oktoremove";
                remove(this);
                return;
@@ -394,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;
@@ -502,7 +503,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;
index f2ca4265545d9dd31dce6d1650978699f069764a..3049225c4ffef66b20f13adfce03616ee2ac13e2 100644 (file)
@@ -81,15 +81,15 @@ void W_Devastator_Unregister(entity this)
        }
 }
 
-void W_Devastator_Explode(entity this)
+void W_Devastator_Explode(entity this, entity directhitentity)
 {
        W_Devastator_Unregister(this);
 
-       if(other.takedamage == DAMAGE_AIM)
-               if(IS_PLAYER(other))
-                       if(DIFF_TEAM(this.realowner, other))
-                               if(!IS_DEAD(other))
-                                       if(IsFlying(other))
+       if(directhitentity.takedamage == DAMAGE_AIM)
+               if(IS_PLAYER(directhitentity))
+                       if(DIFF_TEAM(this.realowner, directhitentity))
+                               if(!IS_DEAD(directhitentity))
+                                       if(IsFlying(directhitentity))
                                                Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
 
        this.event_damage = func_null;
@@ -105,7 +105,7 @@ void W_Devastator_Explode(entity this)
                NULL,
                WEP_CVAR(devastator, force),
                this.projectiledeathtype,
-               other
+               directhitentity
        );
 
        Weapon thiswep = WEP_DEVASTATOR;
@@ -123,6 +123,11 @@ void W_Devastator_Explode(entity this)
        remove(this);
 }
 
+void W_Devastator_Explode_think(entity this)
+{
+       W_Devastator_Explode(this, NULL);
+}
+
 void W_Devastator_DoRemoteExplode(entity this, .entity weaponentity)
 {
        W_Devastator_Unregister(this);
@@ -259,9 +264,8 @@ void W_Devastator_Think(entity this)
        this.nextthink = time;
        if(time > this.cnt)
        {
-               other = NULL;
                this.projectiledeathtype |= HITTYPE_BOUNCE;
-               W_Devastator_Explode(this);
+               W_Devastator_Explode(this, NULL);
                return;
        }
 
@@ -320,16 +324,16 @@ void W_Devastator_Think(entity this)
                UpdateCSQCProjectile(this);
 }
 
-void W_Devastator_Touch(entity this)
+void W_Devastator_Touch(entity this, entity toucher)
 {
-       if(WarpZone_Projectile_Touch(this))
+       if(WarpZone_Projectile_Touch(this, toucher))
        {
                if(wasfreed(this))
                        W_Devastator_Unregister(this);
                return;
        }
        W_Devastator_Unregister(this);
-       W_Devastator_Explode(this);
+       W_Devastator_Explode(this, toucher);
 }
 
 void W_Devastator_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
@@ -344,7 +348,7 @@ void W_Devastator_Damage(entity this, entity inflictor, entity attacker, float d
        this.angles = vectoangles(this.velocity);
 
        if(this.health <= 0)
-               W_PrepareExplosionByDamage(this, attacker, W_Devastator_Explode);
+               W_PrepareExplosionByDamage(this, attacker, W_Devastator_Explode_think);
 }
 
 void W_Devastator_Attack(Weapon thiswep, entity actor)
@@ -372,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
@@ -437,8 +441,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);
@@ -447,25 +450,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;
@@ -474,36 +475,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 1fc3cb4b1a71ac0ae217beeaad83106652cfe2cc..1f8cc19441db45195999fe3262d577a09e9a8b4a 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) \
@@ -144,19 +145,19 @@ void W_Electro_ExplodeCombo(entity this)
        remove(this);
 }
 
-void W_Electro_Explode(entity this)
+void W_Electro_Explode(entity this, entity directhitentity)
 {
-       if(other.takedamage == DAMAGE_AIM)
-               if(IS_PLAYER(other))
-                       if(DIFF_TEAM(this.realowner, other))
-                               if(!IS_DEAD(other))
-                                       if(IsFlying(other))
+       if(directhitentity.takedamage == DAMAGE_AIM)
+               if(IS_PLAYER(directhitentity))
+                       if(DIFF_TEAM(this.realowner, directhitentity))
+                               if(!IS_DEAD(directhitentity))
+                                       if(IsFlying(directhitentity))
                                                Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_ELECTROBITCH);
 
        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,
@@ -168,7 +169,7 @@ void W_Electro_Explode(entity this)
                        NULL,
                        WEP_CVAR_SEC(electro, force),
                        this.projectiledeathtype,
-                       other
+                       directhitentity
                );
        }
        else
@@ -184,7 +185,7 @@ void W_Electro_Explode(entity this)
                        NULL,
                        WEP_CVAR_PRI(electro, force),
                        this.projectiledeathtype,
-                       other
+                       directhitentity
                );
        }
 
@@ -193,13 +194,13 @@ void W_Electro_Explode(entity this)
 
 void W_Electro_Explode_use(entity this, entity actor, entity trigger)
 {
-       W_Electro_Explode(this);
+       W_Electro_Explode(this, trigger);
 }
 
-void W_Electro_TouchExplode(entity this)
+void W_Electro_TouchExplode(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
-       W_Electro_Explode(this);
+       PROJECTILE_TOUCH(this, toucher);
+       W_Electro_Explode(this, toucher);
 }
 
 
@@ -207,7 +208,7 @@ void sys_phys_update_single(entity this);
 
 void W_Electro_Bolt_Think(entity this)
 {
-       sys_phys_update_single(this);
+       // sys_phys_update_single(this);
        if(time >= this.ltime)
        {
                this.use(this, NULL, NULL);
@@ -256,7 +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;
+       // this.nextthink = time;
 }
 
 void W_Electro_Attack_Bolt(Weapon thiswep, entity actor)
@@ -290,7 +291,8 @@ void W_Electro_Attack_Bolt(Weapon thiswep, entity actor)
        proj.projectiledeathtype = WEP_ELECTRO.m_id;
        setorigin(proj, w_shotorg);
 
-       if (IS_CSQC) 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);
@@ -301,20 +303,60 @@ void W_Electro_Attack_Bolt(Weapon thiswep, entity actor)
        CSQCProjectile(proj, true, PROJECTILE_ELECTRO_BEAM, true);
 
        MUTATOR_CALLHOOK(EditProjectile, actor, proj);
-       proj.com_phys_pos = proj.origin;
-       proj.com_phys_vel = proj.velocity;
+       // proj.com_phys_pos = proj.origin;
+       // proj.com_phys_vel = proj.velocity;
 }
 
-void W_Electro_Orb_Touch(entity this)
+void W_Electro_Orb_Stick(entity this, entity to)
 {
-       PROJECTILE_TOUCH(this);
-       if(other.takedamage == DAMAGE_AIM)
-               { if(WEP_CVAR_SEC(electro, touchexplode)) { W_Electro_Explode(this); } }
+       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;
+
+       remove(this);
+
+       if(to)
+               SetMovetypeFollow(this, to);
+}
+
+void W_Electro_Orb_Touch(entity this, entity toucher)
+{
+       PROJECTILE_TOUCH(this, toucher);
+       if(toucher.takedamage == DAMAGE_AIM)
+               { if(WEP_CVAR_SEC(electro, touchexplode)) { W_Electro_Explode(this, toucher); } }
        else
        {
                //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);
        }
 }
 
@@ -366,8 +408,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,
@@ -392,10 +434,10 @@ 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);
index d07324701ad11da57d48d92ee4909e6d6a57de43..69c2dc006f5d5c3eabe3e57b0c0b8c7e86263bdd 100644 (file)
@@ -62,7 +62,7 @@ REGISTER_WEAPON(FIREBALL, fireball, NEW(Fireball));
 #ifdef SVQC
 spawnfunc(weapon_fireball) { weapon_defaultspawnfunc(this, WEP_FIREBALL); }
 
-void W_Fireball_Explode(entity this)
+void W_Fireball_Explode(entity this, entity directhitentity)
 {
        entity e;
        float dist;
@@ -75,7 +75,7 @@ void W_Fireball_Explode(entity this)
 
        // 1. dist damage
        d = (this.realowner.health + this.realowner.armorvalue);
-       RadiusDamage(this, this.realowner, WEP_CVAR_PRI(fireball, damage), WEP_CVAR_PRI(fireball, edgedamage), WEP_CVAR_PRI(fireball, radius), NULL, NULL, WEP_CVAR_PRI(fireball, force), this.projectiledeathtype, other);
+       RadiusDamage(this, this.realowner, WEP_CVAR_PRI(fireball, damage), WEP_CVAR_PRI(fireball, edgedamage), WEP_CVAR_PRI(fireball, radius), NULL, NULL, WEP_CVAR_PRI(fireball, force), this.projectiledeathtype, directhitentity);
        if(this.realowner.health + this.realowner.armorvalue >= d)
        if(!this.cnt)
        {
@@ -112,15 +112,20 @@ void W_Fireball_Explode(entity this)
        remove(this);
 }
 
+void W_Fireball_Explode_think(entity this)
+{
+       W_Fireball_Explode(this, NULL);
+}
+
 void W_Fireball_Explode_use(entity this, entity actor, entity trigger)
 {
-       W_Fireball_Explode(this);
+       W_Fireball_Explode(this, trigger);
 }
 
-void W_Fireball_TouchExplode(entity this)
+void W_Fireball_TouchExplode(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
-       W_Fireball_Explode(this);
+       PROJECTILE_TOUCH(this, toucher);
+       W_Fireball_Explode(this, toucher);
 }
 
 void W_Fireball_LaserPlay(entity this, float dt, float dist, float damage, float edgedamage, float burntime)
@@ -163,7 +168,7 @@ void W_Fireball_Think(entity this)
        {
                this.cnt = 1;
                this.projectiledeathtype |= HITTYPE_SPLASH;
-               W_Fireball_Explode(this);
+               W_Fireball_Explode(this, NULL);
                return;
        }
 
@@ -184,7 +189,7 @@ void W_Fireball_Damage(entity this, entity inflictor, entity attacker, float dam
        if(this.health <= 0)
        {
                this.cnt = 1;
-               W_PrepareExplosionByDamage(this, attacker, W_Fireball_Explode);
+               W_PrepareExplosionByDamage(this, attacker, W_Fireball_Explode_think);
        }
 }
 
@@ -213,7 +218,7 @@ 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);
@@ -290,11 +295,11 @@ void W_Fireball_Firemine_Think(entity this)
        this.nextthink = time + 0.1;
 }
 
-void W_Fireball_Firemine_Touch(entity this)
+void W_Fireball_Firemine_Touch(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
-       if(other.takedamage == DAMAGE_AIM)
-       if(Fire_AddDamage(other, this.realowner, WEP_CVAR_SEC(fireball, damage), WEP_CVAR_SEC(fireball, damagetime), this.projectiledeathtype) >= 0)
+       PROJECTILE_TOUCH(this, 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);
                return;
@@ -335,7 +340,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);
index d41ad95b9302cbee75425bfe38ffce8f331e414d..130c470636facc264f4b9759d187d87a52df3ecc 100644 (file)
@@ -63,30 +63,30 @@ spawnfunc(weapon_hagar) { weapon_defaultspawnfunc(this, WEP_HAGAR); }
 
 // NO bounce protection, as bounces are limited!
 
-void W_Hagar_Explode(entity this)
+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, other);
+       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);
 }
 
 void W_Hagar_Explode_use(entity this, entity actor, entity trigger)
 {
-       W_Hagar_Explode(this);
+       W_Hagar_Explode(this, trigger);
 }
 
-void W_Hagar_Explode2(entity this)
+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, other);
+       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);
 }
 
 void W_Hagar_Explode2_use(entity this, entity actor, entity trigger)
 {
-       W_Hagar_Explode2(this);
+       W_Hagar_Explode2(this, trigger);
 }
 
 void W_Hagar_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
@@ -113,18 +113,18 @@ void W_Hagar_Damage(entity this, entity inflictor, entity attacker, float damage
                W_PrepareExplosionByDamage(this, attacker, getthink(this));
 }
 
-void W_Hagar_Touch(entity this)
+void W_Hagar_Touch(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
-       this.use(this, NULL, NULL);
+       PROJECTILE_TOUCH(this, toucher);
+       this.use(this, NULL, toucher);
 }
 
-void W_Hagar_Touch2(entity this)
+void W_Hagar_Touch2(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
 
-       if(this.cnt > 0 || other.takedamage == DAMAGE_AIM) {
-               this.use(this, NULL, NULL);
+       if(this.cnt > 0 || toucher.takedamage == DAMAGE_AIM) {
+               this.use(this, NULL, toucher);
        } else {
                this.cnt++;
                Send_Effect(EFFECT_HAGAR_BOUNCE, this.origin, this.velocity, 1);
@@ -164,7 +164,7 @@ 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);
@@ -207,7 +207,7 @@ 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);
@@ -264,7 +264,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)
index c176e84c677ee90da7b1ee6e23ffc2c3d1cf4305..ab4e2f7a0803780bb57960396ca058a4944a0a94 100644 (file)
@@ -54,17 +54,17 @@ REGISTER_WEAPON(HLAC, hlac, NEW(HLAC));
 #ifdef SVQC
 spawnfunc(weapon_hlac) { weapon_defaultspawnfunc(this, WEP_HLAC); }
 
-void W_HLAC_Touch(entity this)
+void W_HLAC_Touch(entity this, entity toucher)
 {
        float isprimary;
 
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
 
        this.event_damage = func_null;
 
        isprimary = !(this.projectiledeathtype & HITTYPE_SECONDARY);
 
-       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, other);
+       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);
 }
@@ -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);
@@ -137,7 +137,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);
index 5963b3bc7db84b7d86b4c0a4473f096df8a78e0c..01a3497d06f83497c934117fdba52966e3a66bf9 100644 (file)
@@ -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)
@@ -137,9 +137,9 @@ void W_Hook_Damage(entity this, entity inflictor, entity attacker, float damage,
                W_PrepareExplosionByDamage(this, this.realowner, W_Hook_Explode2);
 }
 
-void W_Hook_Touch2(entity this)
+void W_Hook_Touch2(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
        this.use(this, NULL, NULL);
 }
 
@@ -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);
@@ -441,6 +441,10 @@ void Draw_GrapplingHook(entity this)
                        break;
        }
 
+       MUTATOR_CALLHOOK(DrawGrapplingHook, this, tex, rgb, t);
+       tex = M_ARGV(1, string);
+       rgb = M_ARGV(2, vector);
+
        Draw_GrapplingHook_trace_callback_tex = tex;
        Draw_GrapplingHook_trace_callback_rnd = offset;
        Draw_GrapplingHook_trace_callback_rgb = rgb;
@@ -537,6 +541,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 a406e750980e2749c656682821f49618a1de6079..8b1e0cd2e12bbc268551ee8a62e117483b621639 100644 (file)
@@ -91,7 +91,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;
@@ -108,19 +108,19 @@ void W_MineLayer_Stick(entity this, entity to)
                SetMovetypeFollow(newmine, to);
 }
 
-void W_MineLayer_Explode(entity this)
+void W_MineLayer_Explode(entity this, entity directhitentity)
 {
-       if(other.takedamage == DAMAGE_AIM)
-               if(IS_PLAYER(other))
-                       if(DIFF_TEAM(this.realowner, other))
-                               if(!IS_DEAD(other))
-                                       if(IsFlying(other))
+       if(directhitentity.takedamage == DAMAGE_AIM)
+               if(IS_PLAYER(directhitentity))
+                       if(DIFF_TEAM(this.realowner, directhitentity))
+                               if(!IS_DEAD(directhitentity))
+                                       if(IsFlying(directhitentity))
                                                Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
 
        this.event_damage = func_null;
        this.takedamage = DAMAGE_NO;
 
-       RadiusDamage(this, this.realowner, WEP_CVAR(minelayer, damage), WEP_CVAR(minelayer, edgedamage), WEP_CVAR(minelayer, radius), NULL, NULL, WEP_CVAR(minelayer, force), this.projectiledeathtype, other);
+       RadiusDamage(this, this.realowner, WEP_CVAR(minelayer, damage), WEP_CVAR(minelayer, edgedamage), WEP_CVAR(minelayer, radius), NULL, NULL, WEP_CVAR(minelayer, force), this.projectiledeathtype, directhitentity);
 
        if(PS(this.realowner).m_weapon == WEP_MINE_LAYER)
        {
@@ -138,12 +138,17 @@ void W_MineLayer_Explode(entity this)
        remove(this);
 }
 
+void W_MineLayer_Explode_think(entity this)
+{
+       W_MineLayer_Explode(this, NULL);
+}
+
 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);
@@ -192,7 +197,7 @@ void W_MineLayer_ProximityExplode(entity this)
        }
 
        this.mine_time = 0;
-       W_MineLayer_Explode(this);
+       W_MineLayer_Explode(this, NULL);
 }
 
 int W_MineLayer_Count(entity e)
@@ -211,12 +216,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);
                }
        }
 
@@ -234,9 +239,8 @@ void W_MineLayer_Think(entity this)
        // TODO: Do this on team change too -- Samual: But isn't a player killed when they switch teams?
        if(!IS_PLAYER(this.realowner) || IS_DEAD(this.realowner) || STAT(FROZEN, this.realowner))
        {
-               other = NULL;
                this.projectiledeathtype |= HITTYPE_BOUNCE;
-               W_MineLayer_Explode(this);
+               W_MineLayer_Explode(this, NULL);
                return;
        }
 
@@ -268,26 +272,26 @@ void W_MineLayer_Think(entity this)
                W_MineLayer_RemoteExplode(this);
 }
 
-void W_MineLayer_Touch(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))
+       if(WarpZone_Projectile_Touch(this, toucher))
        {
                if(wasfreed(this))
                        this.realowner.minelayer_mines -= 1;
                return;
        }
 
-       if(other && IS_PLAYER(other) && !IS_DEAD(other))
+       if(toucher && IS_PLAYER(toucher) && !IS_DEAD(toucher))
        {
                // hit a player
                // don't stick
        }
        else
        {
-               W_MineLayer_Stick(this, other);
+               W_MineLayer_Stick(this, toucher);
        }
 }
 
@@ -305,7 +309,7 @@ void W_MineLayer_Damage(entity this, entity inflictor, entity attacker, float da
        this.angles = vectoangles(this.velocity);
 
        if(this.health <= 0)
-               W_PrepareExplosionByDamage(this, attacker, W_MineLayer_Explode);
+               W_PrepareExplosionByDamage(this, attacker, W_MineLayer_Explode_think);
 }
 
 void W_MineLayer_Attack(Weapon thiswep, entity actor)
@@ -346,7 +350,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
@@ -411,8 +415,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);
@@ -421,31 +424,26 @@ 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)
+
+        FOREACH_ENTITY_ENT(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);
+               if(it.classname != "mine") continue;
+
+               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)
@@ -453,41 +451,37 @@ 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);
+        FOREACH_ENTITY_ENT(realowner, actor,
         {
-            if(mine.realowner != actor)
-            {
-                mine = find(mine, classname, "mine");
-                continue;
-            }
-            makevectors(mine.v_angle);
-            targ = targetlist;
+            if(it.classname != "mine") continue;
+
             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 5f56f19db19b2080d7255318562d150ee2be1787..748c2347f71ebda4805493d839f17612f1892802 100644 (file)
@@ -64,54 +64,54 @@ REGISTER_WEAPON(MORTAR, mortar, NEW(Mortar));
 spawnfunc(weapon_mortar) { weapon_defaultspawnfunc(this, WEP_MORTAR); }
 spawnfunc(weapon_grenadelauncher) { spawnfunc_weapon_mortar(this); }
 
-void W_Mortar_Grenade_Explode(entity this)
+void W_Mortar_Grenade_Explode(entity this, entity directhitentity)
 {
-       if(other.takedamage == DAMAGE_AIM)
-               if(IS_PLAYER(other))
-                       if(DIFF_TEAM(this.realowner, other))
-                               if(!IS_DEAD(other))
-                                       if(IsFlying(other))
+       if(directhitentity.takedamage == DAMAGE_AIM)
+               if(IS_PLAYER(directhitentity))
+                       if(DIFF_TEAM(this.realowner, directhitentity))
+                               if(!IS_DEAD(directhitentity))
+                                       if(IsFlying(directhitentity))
                                                Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
 
        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, other);
+       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);
 }
 
 void W_Mortar_Grenade_Explode_use(entity this, entity actor, entity trigger)
 {
-       W_Mortar_Grenade_Explode(this);
+       W_Mortar_Grenade_Explode(this, trigger);
 }
 
-void W_Mortar_Grenade_Explode2(entity this)
+void W_Mortar_Grenade_Explode2(entity this, entity directhitentity)
 {
-       if(other.takedamage == DAMAGE_AIM)
-               if(IS_PLAYER(other))
-                       if(DIFF_TEAM(this.realowner, other))
-                               if(!IS_DEAD(other))
-                                       if(IsFlying(other))
+       if(directhitentity.takedamage == DAMAGE_AIM)
+               if(IS_PLAYER(directhitentity))
+                       if(DIFF_TEAM(this.realowner, directhitentity))
+                               if(!IS_DEAD(directhitentity))
+                                       if(IsFlying(directhitentity))
                                                Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
 
        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, other);
+       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);
 }
 
 void W_Mortar_Grenade_Explode2_use(entity this, entity actor, entity trigger)
 {
-       W_Mortar_Grenade_Explode2(this);
+       W_Mortar_Grenade_Explode2(this, trigger);
 }
 
 void W_Mortar_Grenade_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
@@ -133,21 +133,20 @@ void W_Mortar_Grenade_Think1(entity this)
        this.nextthink = time;
        if(time > this.cnt)
        {
-               other = NULL;
                this.projectiledeathtype |= HITTYPE_BOUNCE;
-               W_Mortar_Grenade_Explode(this);
+               W_Mortar_Grenade_Explode(this, NULL);
                return;
        }
        if(this.gl_detonate_later && this.gl_bouncecnt >= WEP_CVAR_PRI(mortar, remote_minbouncecnt))
-               W_Mortar_Grenade_Explode(this);
+               W_Mortar_Grenade_Explode(this, NULL);
 }
 
-void W_Mortar_Grenade_Touch1(entity this)
+void W_Mortar_Grenade_Touch1(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
-       if(other.takedamage == DAMAGE_AIM || WEP_CVAR_PRI(mortar, type) == 0) // always explode when hitting a player, or if normal mortar projectile
+       PROJECTILE_TOUCH(this, toucher);
+       if(toucher.takedamage == DAMAGE_AIM || WEP_CVAR_PRI(mortar, type) == 0) // always explode when hitting a player, or if normal mortar projectile
        {
-               this.use(this, NULL, NULL);
+               this.use(this, NULL, toucher);
        }
        else if(WEP_CVAR_PRI(mortar, type) == 1) // bounce
        {
@@ -156,14 +155,14 @@ void W_Mortar_Grenade_Touch1(entity this)
                this.projectiledeathtype |= HITTYPE_BOUNCE;
                this.gl_bouncecnt += 1;
        }
-       else if(WEP_CVAR_PRI(mortar, type) == 2 && (!other || (other.takedamage != DAMAGE_AIM && other.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);
 
@@ -174,12 +173,12 @@ void W_Mortar_Grenade_Touch1(entity this)
        }
 }
 
-void W_Mortar_Grenade_Touch2(entity this)
+void W_Mortar_Grenade_Touch2(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
-       if(other.takedamage == DAMAGE_AIM || WEP_CVAR_SEC(mortar, type) == 0) // always explode when hitting a player, or if normal mortar projectile
+       PROJECTILE_TOUCH(this, toucher);
+       if(toucher.takedamage == DAMAGE_AIM || WEP_CVAR_SEC(mortar, type) == 0) // always explode when hitting a player, or if normal mortar projectile
        {
-               this.use(this, NULL, NULL);
+               this.use(this, NULL, toucher);
        }
        else if(WEP_CVAR_SEC(mortar, type) == 1) // bounce
        {
@@ -192,14 +191,14 @@ void W_Mortar_Grenade_Touch2(entity this)
                        this.nextthink = time + WEP_CVAR_SEC(mortar, lifetime_bounce);
 
        }
-       else if(WEP_CVAR_SEC(mortar, type) == 2 && (!other || (other.takedamage != DAMAGE_AIM && other.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);
 
@@ -225,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);
@@ -273,7 +272,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);
index 3b047dc8c9d017ee2de7790a85ef1b3e6feb3be4..f17a2ac505f178514b6ee04b433bb9948441b477 100644 (file)
@@ -118,14 +118,14 @@ void W_Porto_Think(entity this)
                W_Porto_Fail(this, 0);
 }
 
-void W_Porto_Touch(entity this)
+void W_Porto_Touch(entity this, entity toucher)
 {
        vector norm;
 
        // do not use PROJECTILE_TOUCH here
        // FIXME but DO handle warpzones!
 
-       if(other.classname == "portal")
+       if(toucher.classname == "portal")
                return; // handled by the portal
 
        norm = trace_plane_normal;
@@ -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;
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 a39c3958f14c1a8f357c55c9231fe739629ffa22..00e481ba26584ddc0cf4383b10e4646cffb93e7c 100644 (file)
@@ -94,19 +94,24 @@ spawnfunc(weapon_seeker) { weapon_defaultspawnfunc(this, WEP_SEEKER); }
 // ============================
 // Begin: Missile functions, these are general functions to be manipulated by other code
 // ============================
-void W_Seeker_Missile_Explode(entity this)
+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, other);
+       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);
 }
 
-void W_Seeker_Missile_Touch(entity this)
+void W_Seeker_Missile_Explode_think(entity this)
 {
-       PROJECTILE_TOUCH(this);
+       W_Seeker_Missile_Explode(this, NULL);
+}
+
+void W_Seeker_Missile_Touch(entity this, entity toucher)
+{
+       PROJECTILE_TOUCH(this, toucher);
 
-       W_Seeker_Missile_Explode(this);
+       W_Seeker_Missile_Explode(this, toucher);
 }
 
 void W_Seeker_Missile_Think(entity this)
@@ -120,7 +125,7 @@ void W_Seeker_Missile_Think(entity this)
        if(time > this.cnt)
        {
                this.projectiledeathtype |= HITTYPE_SPLASH;
-               W_Seeker_Missile_Explode(this);
+               W_Seeker_Missile_Explode(this, NULL);
        }
 
        spd = vlen(this.velocity);
@@ -178,7 +183,7 @@ void W_Seeker_Missile_Think(entity this)
                        {
                                if(this.autoswitch <= time)
                                {
-                                       W_Seeker_Missile_Explode(this);
+                                       W_Seeker_Missile_Explode(this, NULL);
                                        this.autoswitch = 0;
                                }
                        }
@@ -220,7 +225,7 @@ void W_Seeker_Missile_Damage(entity this, entity inflictor, entity attacker, flo
                this.health = this.health - damage;
 
        if(this.health <= 0)
-               W_PrepareExplosionByDamage(this, attacker, W_Seeker_Missile_Explode);
+               W_PrepareExplosionByDamage(this, attacker, W_Seeker_Missile_Explode_think);
 }
 
 /*
@@ -239,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);
@@ -288,7 +293,7 @@ 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;
+       set_movetype(missile, MOVETYPE_FLYMISSILE);
        missile.flags       = FL_PROJECTILE;
        missile.missile_flags = MIF_SPLASH | MIF_GUIDED_TAG;
 
@@ -304,18 +309,23 @@ void W_Seeker_Fire_Missile(Weapon thiswep, entity actor, vector f_diff, entity m
 // ============================
 // Begin: FLAC, close range attack meant for defeating rockets which are coming at you.
 // ============================
-void W_Seeker_Flac_Explode(entity this)
+void W_Seeker_Flac_Explode(entity this, entity directhitentity)
 {
        this.event_damage = func_null;
 
-       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, other);
+       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);
 }
 
+void W_Seeker_Flac_Touch(entity this, entity toucher)
+{
+       W_Seeker_Flac_Explode(this, toucher);
+}
+
 void W_Seeker_Flac_Explode_use(entity this, entity actor, entity trigger)
 {
-       W_Seeker_Flac_Explode(this);
+       W_Seeker_Flac_Explode(this, trigger);
 }
 
 void W_Seeker_Fire_Flac(Weapon thiswep, entity actor)
@@ -352,12 +362,12 @@ void W_Seeker_Fire_Flac(Weapon thiswep, entity actor)
        missile.owner                   = missile.realowner = actor;
        missile.bot_dodge               = true;
        missile.bot_dodgerating = WEP_CVAR(seeker, flac_damage);
-       settouch(missile, W_Seeker_Flac_Explode);
+       settouch(missile, W_Seeker_Flac_Touch);
        missile.use                     = W_Seeker_Flac_Explode_use;
        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;
@@ -478,7 +488,7 @@ void W_Seeker_Tag_Explode(entity this)
 {
        //if(other==this.realowner)
        //    return;
-       Damage_DamageInfo(this.origin, 0, 0, 0, this.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE, other.species, this);
+       Damage_DamageInfo(this.origin, 0, 0, 0, this.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE, 0, this);
 
        remove(this);
 }
@@ -492,13 +502,13 @@ void W_Seeker_Tag_Damage(entity this, entity inflictor, entity attacker, float d
                W_Seeker_Tag_Explode(this);
 }
 
-void W_Seeker_Tag_Touch(entity this)
+void W_Seeker_Tag_Touch(entity this, entity toucher)
 {
        vector dir;
        vector org2;
        entity e;
 
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
 
        dir     = normalize(this.realowner.origin - this.origin);
        org2    = findbetterlocation(this.origin, 8);
@@ -506,23 +516,23 @@ void W_Seeker_Tag_Touch(entity this)
        te_knightspike(org2);
 
        this.event_damage = func_null;
-       Damage_DamageInfo(this.origin, 0, 0, 0, this.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE | HITTYPE_SECONDARY, other.species, this);
+       Damage_DamageInfo(this.origin, 0, 0, 0, this.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE | HITTYPE_SECONDARY, toucher.species, this);
 
-       if(other.takedamage == DAMAGE_AIM && !IS_DEAD(other))
+       if(toucher.takedamage == DAMAGE_AIM && !IS_DEAD(toucher))
        {
                // check to see if this person is already tagged by me
-               entity tag = W_Seeker_Tagged_Info(this.realowner, other);
+               entity tag = W_Seeker_Tagged_Info(this.realowner, toucher);
 
                if(tag != NULL)
                {
-                       if(other.wps_tag_tracker && (WEP_CVAR(seeker, type) == 1)) // don't attach another waypointsprite without killing the old one first
-                               WaypointSprite_Kill(other.wps_tag_tracker);
+                       if(toucher.wps_tag_tracker && (WEP_CVAR(seeker, type) == 1)) // don't attach another waypointsprite without killing the old one first
+                               WaypointSprite_Kill(toucher.wps_tag_tracker);
 
                        tag.tag_time = time;
                }
                else
                {
-                       //sprint(this.realowner, strcat("You just tagged ^2", other.netname, "^7 with a tracking device!\n"));
+                       //sprint(this.realowner, strcat("You just tagged ^2", toucher.netname, "^7 with a tracking device!\n"));
                        e             = new(tag_tracker);
                        e.cnt         = WEP_CVAR(seeker, missile_count);
                        e.owner       = this.owner;
@@ -530,13 +540,13 @@ void W_Seeker_Tag_Touch(entity this)
 
                        if(WEP_CVAR(seeker, type) == 1)
                        {
-                               e.tag_target  = other;
+                               e.tag_target  = toucher;
                                e.tag_time    = time;
                                setthink(e, W_Seeker_Tracker_Think);
                        }
                        else
                        {
-                               e.enemy     = other;
+                               e.enemy     = toucher;
                                setthink(e, W_Seeker_Vollycontroller_Think);
                        }
 
@@ -545,8 +555,8 @@ void W_Seeker_Tag_Touch(entity this)
 
                if(WEP_CVAR(seeker, type) == 1)
                {
-                       WaypointSprite_Spawn(WP_Seeker, WEP_CVAR(seeker, tag_tracker_lifetime), 0, other, '0 0 64', this.realowner, 0, other, wps_tag_tracker, true, RADARICON_TAGGED);
-                       WaypointSprite_UpdateRule(other.wps_tag_tracker, 0, SPRITERULE_DEFAULT);
+                       WaypointSprite_Spawn(WP_Seeker, WEP_CVAR(seeker, tag_tracker_lifetime), 0, toucher, '0 0 64', this.realowner, 0, toucher, wps_tag_tracker, true, RADARICON_TAGGED);
+                       WaypointSprite_UpdateRule(toucher.wps_tag_tracker, 0, SPRITERULE_DEFAULT);
                }
        }
 
@@ -568,7 +578,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;
@@ -582,7 +592,7 @@ void W_Seeker_Fire_Tag(Weapon thiswep, entity actor)
        missile.flags       = FL_PROJECTILE;
        //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..539ccfdb72c444d8686be62258616cd9008155db 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"));
 
@@ -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))
@@ -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..f89ef6872b1db46ce3706b4a0799e2dc00ecb3b7 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");
@@ -73,8 +73,11 @@ void W_Shotgun_Attack(Weapon thiswep, entity actor, float isprimary)
 
        // casing code
        if(autocvar_g_casings >= 1)
+       {
+               makevectors(actor.v_angle); // for some reason, this is lost
                for(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();
index 8b061b72a5016013e39b9936de8ce66b6f7a8564..8a8e858ecb5ce197e1ce6b1a55ade7e718c85cbc 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();
@@ -233,11 +234,11 @@ void W_RocketMinsta_Laser_Explode_use(entity this, entity actor, entity trigger)
        W_RocketMinsta_Laser_Explode(this);
 }
 
-void W_RocketMinsta_Laser_Touch (entity this)
+void W_RocketMinsta_Laser_Touch(entity this, entity toucher)
 {
-       PROJECTILE_TOUCH(this);
+       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, other);
+       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);
 }
 
@@ -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);
@@ -329,7 +330,7 @@ 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);
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 377e1d1d8e27ca602cca0f92d9c64ef6a44ae657..f150a296c299e8d46980c1ba2d4fb278665947d4 100644 (file)
@@ -23,3 +23,4 @@ COMPONENT(phys);
 .bool com_phys_vel_2d;
 .bool com_phys_water;
 .bool com_phys_friction_air;
+.bool move_qcphysics;
index 52e8ed0caeb3c9800aa282449f50238de95913e3..206c80d96526f4001200bd8b6d0a56d9a05e3fd6 100644 (file)
@@ -10,7 +10,7 @@ void sys_phys_fix(entity this, float dt)
        this.spectatorspeed = STAT(SPECTATORSPEED, this);
        if (!(PHYS_INPUT_BUTTON_JUMP(this))) // !jump
                UNSET_JUMP_HELD(this);           // canjump = true
-       PM_ClientMovement_UpdateStatus(this, true);
+       PM_ClientMovement_UpdateStatus(this);
 }
 
 bool sys_phys_override(entity this)
index 7267a48644303ad98e939bc0b74782d0e2528c6c..8646b29cc983827a48be0387de3373d8f3295bf9 100644 (file)
@@ -28,7 +28,7 @@ void sys_phys_update(entity this, float dt)
        if (IS_SVQC) {
                if (PHYS_MOVETYPE(this) == MOVETYPE_NONE) { return; }
                // when we get here, disableclientprediction cannot be 2
-               this.disableclientprediction = 0;
+               this.disableclientprediction = (this.move_qcphysics) ? -1 : 0;
        }
 
        viewloc_PlayerPhysics(this);
@@ -76,8 +76,8 @@ void sys_phys_update(entity this, float dt)
        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
+               if (this.waterlevel == WATERLEVEL_NONE
+                   || time > PHYS_TELEPORT_TIME(this)
                    || PHYS_WATERJUMP_TIME(this) <= 0
                   ) {
                        this.flags &= ~FL_WATERJUMP;
@@ -192,7 +192,6 @@ void sys_phys_simulate(entity this, float dt)
                                if (!trace_startsolid) {
                                        this.velocity = forward * 50;
                                        this.velocity_z = 310;
-                                       if (IS_CSQC) { PHYS_WATERJUMP_TIME(this) = 2; }
                                        UNSET_ONGROUND(this);
                                        SET_JUMP_HELD(this);
                                }
@@ -205,6 +204,9 @@ void sys_phys_simulate(entity this, float dt)
            + 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') {
@@ -298,9 +300,7 @@ void sys_phys_simulate(entity this, float dt)
                        }
                }
        } else {
-               if (this.com_phys_ground || this.com_phys_water) {
-                       if (IS_DUCKED(this)) { wishspeed *= 0.5; }
-               }
+               if (this.com_phys_ground && IS_DUCKED(this)) { wishspeed *= 0.5; }
                if (this.com_phys_water) {
                        wishspeed *= 0.7;
 
@@ -325,6 +325,9 @@ void sys_phys_simulate(entity this, float dt)
                                        // 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) {
@@ -336,7 +339,6 @@ void sys_phys_simulate(entity this, float dt)
                        } else {
                                // water acceleration
                                PM_Accelerate(this, wishdir, wishspeed, wishspeed, this.com_phys_acc_rate, 1, 0, 0, 0);
-                               PM_ClientMovement_Move(this);
                        }
                        return;
                }
@@ -385,17 +387,13 @@ void sys_phys_simulate(entity this, float dt)
                                const float accelspeed = min(PHYS_ACCELERATE(this) * dt * wishspeed, addspeed);
                                this.velocity += accelspeed * wishdir;
                        }
-                       if (IS_CSQC && vdist(this.velocity, >, 0)) {
-                               PM_ClientMovement_Move(this);
-                       }
                        return;
                }
 
-               if (IS_CSQC || time >= PHYS_TELEPORT_TIME(this)) {
+               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);
                }
        }
-       PM_ClientMovement_Move(this);
 }
 
 .entity groundentity;
@@ -447,7 +445,7 @@ void sys_phys_simulate_simple(entity this, float dt)
                                            trace_dphitcontents = 0;
                                            trace_dphitq3surfaceflags = 0;
                                            trace_dphittexturename = string_null;
-                                           gettouch(it)((other = this, it));
+                                           gettouch(it)(this, it);
                                            vel = this.velocity;
                                        }
                                });
@@ -455,11 +453,11 @@ void sys_phys_simulate_simple(entity this, float dt)
                        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) touched = gettouch(this);
+                               void(entity, entity) touched = gettouch(this);
                                if (touched && this.solid != SOLID_NOT) {
-                                       touched((other = ent, this));
+                                       touched(ent, this);
                                }
-                               void(entity) touched2 = gettouch(ent);
+                               void(entity, entity) touched2 = gettouch(ent);
                                if (this && ent && touched2 && ent.solid != SOLID_NOT) {
                                        trace_endpos = ent.origin;
                                        trace_plane_normal *= -1;
@@ -469,7 +467,7 @@ void sys_phys_simulate_simple(entity this, float dt)
                                        trace_dphitcontents = 0;
                                        trace_dphitq3surfaceflags = 0;
                                        trace_dphittexturename = string_null;
-                                       touched2((other = this, ent));
+                                       touched2(this, ent);
                                }
                        }
                }
index 1d63a28e540425d8e6b12e5fcbf0fd853f652aca..f52c9a3c735437ef6195f8c1499baceba51842af 100644 (file)
@@ -89,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"
@@ -123,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(); }
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 0b0de75649aab42d97851711fca47dd1342c8bf8..4bea5e36a7399098aa3defabd15185a688524806 100644 (file)
@@ -35,6 +35,7 @@
 #include <common/viewloc.qh>
 
 float autocvar_cl_movement_errorcompensation = 0;
+bool autocvar_cl_movement_intermissionrunning = false;
 
 // engine stuff
 float pmove_onground; // weird engine flag we shouldn't really use but have to for now
@@ -105,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);
@@ -129,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)
@@ -230,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;
@@ -254,7 +223,7 @@ void CSQCPlayer_SetViewLocation()
 /** Called once per CSQC_UpdateView() */
 void CSQCPlayer_SetCamera()
 {
-       const vector v0 = pmove_vel; // TRICK: pmove_vel is set by the engine when we get here. No need to network velocity
+       const vector v0 = ((intermission && !autocvar_cl_movement_intermissionrunning) ? '0 0 0' : pmove_vel); // TRICK: pmove_vel is set by the engine when we get here. No need to network velocity
        const float vh = STAT(VIEWHEIGHT);
        const vector pl_viewofs = STAT(PL_VIEW_OFS, NULL);
        const vector pl_viewofs_crouch = STAT(PL_CROUCH_VIEW_OFS, NULL);
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;
diff --git a/qcsrc/lib/intrusivelist.qh b/qcsrc/lib/intrusivelist.qh
new file mode 100644 (file)
index 0000000..1d7b251
--- /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 \
+       { \
+               remove(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 49c2a41e856257b76214284d9ac1ae455561b2e8..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
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 537e04e05fd90ca8e0360d077cbb7cb227b56fa3..0ce157848e2ad6d1a411664016eb1644d99db88f 100644 (file)
@@ -130,7 +130,7 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); }
        .void(entity this) uncustomizeentityforclient;
        .float uncustomizeentityforclient_set;
 
-       void SetCustomizer(entity e, bool(entity this) customizer, void(entity this) uncustomizer)
+       void SetCustomizer(entity e, bool(entity this, entity client) customizer, void(entity this) uncustomizer)
        {
                setcefc(e, customizer);
                e.uncustomizeentityforclient = uncustomizer;
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 ec43a34022592ae86b5c0c26ec23c5005ffcc938..bc545b0d0f53721c338fe7b9d6af93b6a5e8bc6b 100644 (file)
@@ -66,20 +66,26 @@ SELFWRAP(think, void, (), (entity this), (this))
 #define setthink(e, f) SELFWRAP_SET(think, e, f)
 #define getthink(e) SELFWRAP_GET(think, e)
 
-SELFWRAP(touch, void, (), (entity this), (this))
+#ifndef MENUQC
+SELFWRAP(touch, void, (), (entity this, entity toucher), (this, other))
 #define settouch(e, f) SELFWRAP_SET(touch, e, f)
 #define gettouch(e) SELFWRAP_GET(touch, e)
+#endif
 
-SELFWRAP(blocked, void, (), (entity this), (this))
+#ifndef MENUQC
+SELFWRAP(blocked, void, (), (entity this, entity blocker), (this, other))
 #define setblocked(e, f) SELFWRAP_SET(blocked, e, f)
 #define blocked stopusingthis
+#endif
 
 SELFWRAP(predraw, void, (), (entity this), (this))
 #define setpredraw(e, f) SELFWRAP_SET(predraw, e, f)
 
-SELFWRAP(customizeentityforclient, bool, (), (entity this), (this))
+#ifndef MENUQC
+SELFWRAP(customizeentityforclient, bool, (), (entity this, entity client), (this, other))
 #define setcefc(e, f) SELFWRAP_SET(customizeentityforclient, e, f)
 #define getcefc(e) SELFWRAP_GET(customizeentityforclient, e)
+#endif
 
 SELFWRAP(camera_transform, vector, (vector org, vector ang), (entity this, vector org, vector ang), (this, org, ang))
 #define setcamera_transform(e, f) SELFWRAP_SET(camera_transform, e, f)
@@ -96,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 e1cfeb8721ce54f6b29a9f440e410d2c29bf5626..6b5febe6fbfcab9909de383b4d7ccd86940474d6 100644 (file)
@@ -9,8 +9,23 @@ void __static_init_precache() {}
 void __shutdown() {}
 #define shutdownhooks() CALL_ACCUMULATED_FUNCTION(__shutdown)
 
+#define GETTIME_REALTIME 1
+#ifdef MENUQC
+float(int tmr) _gettime = #67;
+#else
+float(int tmr) _gettime = #519;
+#endif
+
+void profile(string s)
+{
+       static float g_starttime;
+       float rt = _gettime(GETTIME_REALTIME);
+       if (!g_starttime) g_starttime = rt;
+       LOG_TRACEF("[%f] %s", rt - g_starttime, s);
+}
+
 #define _STATIC_INIT(where, func) \
-       void _static_##func(); \
+       [[accumulate]] void _static_##func() { profile(#func); } \
        ACCUMULATE_FUNCTION(where, _static_##func) \
        void _static_##func()
 
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 5a1e320e93462b32195814e54159d7ee26eab576..bd0397f897330d876cdede80e284e1a2062ed0cf 100644 (file)
@@ -25,7 +25,7 @@ void WarpZone_Fade_PreDraw(entity this)
                this.drawmask = MASK_NORMAL;
 }
 
-void WarpZone_Touch (entity this);
+void WarpZone_Touch(entity this, entity toucher);
 NET_HANDLE(ENT_CLIENT_WARPZONE, bool isnew)
 {
        warpzone_warpzones_exist = 1;
@@ -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 2cfa7ef9bc906e7beca25011b57c64527544186e..6669ae1aff4d300c7cde3fc0f9bfc34ce3feb4a3 100644 (file)
@@ -111,6 +111,6 @@ float WarpZoneLib_ExactTrigger_Touch(entity this, entity toucher);
 void WarpZoneLib_ExactTrigger_Init(entity this);
 
 // WARNING: this kills the trace globals
-#define EXACTTRIGGER_TOUCH if(WarpZoneLib_ExactTrigger_Touch(this, other)) return
+#define EXACTTRIGGER_TOUCH(e,t) if(WarpZoneLib_ExactTrigger_Touch((e), (t))) return
 #define EXACTTRIGGER_INIT  WarpZoneLib_ExactTrigger_Init(this)
 #endif
index 7ddb96cbbf32b6506028705ca23fb08caed0ec6d..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);
@@ -189,30 +166,26 @@ float WarpZone_Teleport(entity wz, entity player, float f0, float f1)
        return 1;
 }
 
-void WarpZone_Touch (entity this)
+void WarpZone_Touch(entity this, entity toucher)
 {
-       if(other.classname == "trigger_warpzone")
+       if(toucher.classname == "trigger_warpzone")
                return;
 
-       if(time <= other.warpzone_teleport_finishtime) // already teleported this frame
+       if(time <= toucher.warpzone_teleport_finishtime) // already teleported this frame
                return;
 
        // FIXME needs a better check to know what is safe to teleport and what not
-#ifdef SVQC
-       if(other.movetype == MOVETYPE_NONE || other.movetype == MOVETYPE_FOLLOW || other.tag_entity)
-#elif defined(CSQC)
-       if(other.move_movetype == MOVETYPE_NONE || other.move_movetype == MOVETYPE_FOLLOW || other.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, other))
+       if(WarpZoneLib_ExactTrigger_Touch(this, toucher))
                return;
 
-#ifdef SVQC
-       if(WarpZone_PlaneDist(this, other.origin + other.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet)
-#elif defined(CSQC)
-       if(WarpZone_PlaneDist(this, other.move_origin + other.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet)
-#endif
+       if(WarpZone_PlaneDist(this, toucher.origin + toucher.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet)
                return;
 
        float f;
@@ -227,29 +200,25 @@ void WarpZone_Touch (entity this)
        //       24/(0.25/frametime)
        //       96*frametime
        float d;
-       d = 24 + max(vlen(other.mins), vlen(other.maxs));
-       if(IS_NOT_A_CLIENT(other))
-       #ifdef SVQC
-               f = -d / bound(frametime * d * 1, frametime * vlen(other.velocity), d);
-       #elif defined(CSQC)
-               f = -d / bound(frametime * d * 1, frametime * vlen(other.move_velocity), d);
-       #endif
+       d = 24 + max(vlen(toucher.mins), vlen(toucher.maxs));
+       if(IS_NOT_A_CLIENT(toucher))
+               f = -d / bound(frametime * d * 1, frametime * vlen(toucher.velocity), d);
        else
                f = -1;
-       if(WarpZone_Teleport(this, other, f, 0))
+       if(WarpZone_Teleport(this, toucher, f, 0))
        {
 #ifdef SVQC
                string save1, save2;
 
                save1 = this.target; this.target = string_null;
                save2 = this.target3; this.target3 = string_null;
-               SUB_UseTargets(this, other, other); // use other too?
+               SUB_UseTargets(this, toucher, toucher); // use toucher too?
                if (!this.target) this.target = save1;
                if (!this.target3) this.target3 = save2;
 
                save1 = this.target; this.target = string_null;
                save2 = this.target2; this.target2 = string_null;
-               SUB_UseTargets(this.enemy, other, other); // use other too?
+               SUB_UseTargets(this.enemy, toucher, toucher); // use toucher too?
                if (!this.target) this.target = save1;
                if (!this.target2) this.target2 = save2;
 #endif
@@ -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;
@@ -434,9 +390,9 @@ float WarpZone_CheckProjectileImpact(entity player)
 #endif
 #endif
 
-float WarpZone_Projectile_Touch(entity this)
+float WarpZone_Projectile_Touch(entity this, entity toucher)
 {
-       if(other.classname == "trigger_warpzone")
+       if(toucher.classname == "trigger_warpzone")
                return true;
 
        // no further impacts if we teleported this frame!
@@ -496,7 +452,7 @@ float WarpZone_Projectile_Touch(entity this)
        }
 #endif
 
-       if(WarpZone_Projectile_Touch_ImpactFilter_Callback(this, other))
+       if(WarpZone_Projectile_Touch_ImpactFilter_Callback(this, toucher))
                return true;
 #endif
 
@@ -847,9 +803,7 @@ void WarpZone_StartFrame()
                WarpZone_PostInitialize_Callback();
        }
 
-       entity oldother = other;
-
-       FOREACH_ENTITY(!is_pure(it),
+       FOREACH_ENTITY_FLOAT(pure_data, false,
        {
                if(warpzone_warpzones_exist)
                        WarpZone_StoreProjectileData(it);
@@ -857,36 +811,34 @@ void WarpZone_StartFrame()
                if(IS_OBSERVER(it) || it.solid == SOLID_NOT)
                if(IS_CLIENT(it)) // we don't care about it being a bot
                {
-                       other = it; // player
-
                        // warpzones
                        if (warpzone_warpzones_exist) {
                                entity e = WarpZone_Find(it.origin + it.mins, it.origin + it.maxs);
                                if (e)
-                               if (!WarpZoneLib_ExactTrigger_Touch(e, other))
+                               if (!WarpZoneLib_ExactTrigger_Touch(e, it))
                                if (WarpZone_PlaneDist(e, it.origin + it.view_ofs) <= 0)
                                        WarpZone_Teleport(e, it, -1, 0); // NOT triggering targets by this!
                        }
 
                        // teleporters
-                       if(other.teleportable)
+                       if(it.teleportable)
                        {
                                entity ent = Teleport_Find(it.origin + it.mins, it.origin + it.maxs);
                                if (ent)
-                               if (!WarpZoneLib_ExactTrigger_Touch(ent, other))
-                                       Simple_TeleportPlayer(ent, other); // NOT triggering targets by this!
+                               if (!WarpZoneLib_ExactTrigger_Touch(ent, it))
+                                       Simple_TeleportPlayer(ent, it); // NOT triggering targets by this!
                        }
                }
        });
-       other = oldother;
 }
 
 .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 9abea2a689ac90b710e5652ea546d1bf4c80aac1..0ec67e4d38125b4eefe5f147a2c10ed4f5ee65e8 100644 (file)
@@ -3,7 +3,7 @@
 
 #ifdef SVQC
 void WarpZone_StartFrame();
-float WarpZone_Projectile_Touch(entity this);
+float WarpZone_Projectile_Touch(entity this, entity toucher);
 
 // THESE must be defined by calling QC code:
 void WarpZone_PostTeleportPlayer_Callback(entity pl);
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 c4a78fa568802c305e763aedca9e96eb59bfb595..f0aebabc2ee42196281e5ed7db578f0a390d33c8 100644 (file)
                                return 1;
                        }
                }
-               return SUPER(Dialog).keyDown(me, key, ascii, shift);
+               float r = SUPER(Dialog).keyDown(me, key, ascii, shift);
+               if (!me.closable && key == K_ESCAPE)
+                       return 1;
+               return r;
        }
index 3840721e35f9a032ab3f008471bb53e22a806802..37c46240f77fdcd8bf704b1b6d999aaa3de5e254 100644 (file)
@@ -20,7 +20,8 @@
        float InputContainer_keyDown(entity me, float scan, float ascii, float shift)
        {
                entity f, ff;
-               if (SUPER(InputContainer).keyDown(me, scan, ascii, shift)) return 1;
+               if (SUPER(InputContainer).keyDown(me, scan, ascii, shift))
+                       return 1;
                if (scan == K_ESCAPE)
                {
                        f = me.focusedChild;
index 96d98b9c502149cfe54d18461cbc08ec9ff0c1e6..f32b85298ed7e23a8a70c04f46aa8d1fedad6dde 100644 (file)
@@ -270,7 +270,8 @@ void m_keydown(float key, float ascii)
        else
        {
                draw_reset_cropped();
-               if (!mouseButtonsPressed && key >= K_MOUSE1 && key <= K_MOUSE3) main.mousePress(main, menuMousePos);
+               if (!mouseButtonsPressed && key >= K_MOUSE1 && key <= K_MOUSE3)
+                       main.mousePress(main, menuMousePos);
                if (!main.keyDown(main, key, ascii, menuShiftState))
                {
                        // disable menu on unhandled ESC
@@ -848,6 +849,7 @@ void m_draw(float width, float height)
        postMenuDraw();
 
        frametime = 0;
+       IL_ENDFRAME();
 }
 
 void m_display()
index 867f77b8402b797db0297b0e34c7343aff1a8b20..577c8225803461225c818ce07f6cf396d1806f10 100644 (file)
@@ -79,6 +79,7 @@
 #include <menu/xonotic/dialog_singleplayer.qc>
 #include <menu/xonotic/dialog_singleplayer_winner.qc>
 #include <menu/xonotic/dialog_teamselect.qc>
+#include <menu/xonotic/dialog_uid2name.qc>
 #include <menu/xonotic/gametypelist.qc>
 #include <menu/xonotic/hudskinlist.qc>
 #include <menu/xonotic/image.qc>
index adfefc05d7d5210ff1edd713b751a79afca1bf05..b6e34eff247606d774eb1d321fe9f7539071d3ff 100644 (file)
@@ -79,6 +79,7 @@
 #include <menu/xonotic/dialog_singleplayer.qh>
 #include <menu/xonotic/dialog_singleplayer_winner.qh>
 #include <menu/xonotic/dialog_teamselect.qh>
+#include <menu/xonotic/dialog_uid2name.qh>
 #include <menu/xonotic/gametypelist.qh>
 #include <menu/xonotic/hudskinlist.qh>
 #include <menu/xonotic/image.qh>
index d951275db15a8c1c21cb6953d6ddb65024414093..ede6543e7d983cfed14ee19587da465bd7411b06 100644 (file)
@@ -77,16 +77,15 @@ void XonoticMiscSettingsTab_fill(entity me)
        me.TR(me);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Maximum:")));
                me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_maxfps"));
-                       ADDVALUE_FPS(5);
-                       ADDVALUE_FPS(10);
-                       ADDVALUE_FPS(20);
                        ADDVALUE_FPS(30);
                        ADDVALUE_FPS(40);
                        ADDVALUE_FPS(50);
                        ADDVALUE_FPS(60);
                        ADDVALUE_FPS(70);
+                       ADDVALUE_FPS(80);
                        ADDVALUE_FPS(100);
                        ADDVALUE_FPS(125);
+                       ADDVALUE_FPS(150);
                        ADDVALUE_FPS(200);
                        e.addValue(e, ZCTX(_("MAXFPS^Unlimited")), "0");
                        e.configureXonoticTextSliderValues(e);
@@ -98,8 +97,10 @@ void XonoticMiscSettingsTab_fill(entity me)
                        ADDVALUE_FPS(40);
                        ADDVALUE_FPS(50);
                        ADDVALUE_FPS(60);
+                       ADDVALUE_FPS(80);
                        ADDVALUE_FPS(100);
                        ADDVALUE_FPS(125);
+                       ADDVALUE_FPS(150);
                        ADDVALUE_FPS(200);
                        e.configureXonoticTextSliderValues(e);
        me.TR(me);
index 9320a6ebf2101603fe79e478d3b1abf347f8fe7e..8ee51fde97405b4a424ff79f699c3fd6ded25684 100644 (file)
@@ -46,6 +46,7 @@ void XonoticVideoSettingsTab_fill(entity me)
                        e.addValue(e, ZCTX(_("SZ^Gigantic")), "0.75");
                        e.addValue(e, ZCTX(_("SZ^Colossal")), "1");
                        e.configureXonoticTextSliderValues(e);
+                       e.applyButton = videoApplyButton;
        me.TR(me);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Color depth:")));
                me.TD(me, 1, 2, e = makeXonoticTextSlider_T("vid_bitsperpixel",
diff --git a/qcsrc/menu/xonotic/dialog_uid2name.qc b/qcsrc/menu/xonotic/dialog_uid2name.qc
new file mode 100644 (file)
index 0000000..1cd77b0
--- /dev/null
@@ -0,0 +1,18 @@
+#include "dialog_uid2name.qh"
+
+#include "textlabel.qh"
+#include "commandbutton.qh"
+
+void XonoticUid2NameDialog_fill(entity me)
+{
+       entity e;
+       me.TR(me);
+               me.TD(me, 1, 2, makeXonoticTextLabel(0.5, _("Allow player statistics to use your nickname?")));
+       me.TR(me);
+               me.TD(me, 1, 2, makeXonoticTextLabel(0.5, _("Answering \"No\" you will appear as \"Anonymous player\"")));
+       me.TR(me);
+       me.TR(me);
+               me.TD(me, 1, 1, e = makeXonoticCommandButton(_("Yes"), '0 0 0', "vyes; setreport cl_allow_uid2name 1", COMMANDBUTTON_CLOSE));
+                       e.preferredFocusPriority = 1;
+               me.TD(me, 1, 1, e = makeXonoticCommandButton(_("No"), '0 0 0', "vno; setreport cl_allow_uid2name 0", COMMANDBUTTON_CLOSE));
+}
diff --git a/qcsrc/menu/xonotic/dialog_uid2name.qh b/qcsrc/menu/xonotic/dialog_uid2name.qh
new file mode 100644 (file)
index 0000000..4bec3d1
--- /dev/null
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticUid2NameDialog, XonoticRootDialog)
+       METHOD(XonoticUid2NameDialog, fill, void(entity));
+       ATTRIB(XonoticUid2NameDialog, title, string, string_null)
+       ATTRIB(XonoticUid2NameDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+       ATTRIB(XonoticUid2NameDialog, intendedWidth, float, 0.5)
+       ATTRIB(XonoticUid2NameDialog, rows, float, 4)
+       ATTRIB(XonoticUid2NameDialog, columns, float, 2)
+       ATTRIB(XonoticUid2NameDialog, name, string, "Uid2Name")
+       ATTRIB(XonoticUid2NameDialog, closable, float, 0)
+ENDCLASS(XonoticUid2NameDialog)
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 fb25eebdef39bc2d4bc92cb5b1fd78d0f33c767e..0e071c2e71efc20321722e13b4246f46ec81cfda 100644 (file)
@@ -39,6 +39,7 @@
 #include "dialog_sandboxtools.qh"
 #include "dialog_monstertools.qh"
 #include "dialog_teamselect.qh"
+#include "dialog_uid2name.qh"
 #include "dialog_singleplayer.qh"
 #include "dialog_multiplayer.qh"
 #include "dialog_settings.qh"
@@ -224,6 +225,10 @@ void MainWindow_configureMainWindow(entity me)
        i.configureDialog(i);
        me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
 
+       i = NEW(XonoticUid2NameDialog);
+       i.configureDialog(i);
+       me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
+
        i = NEW(XonoticMonsterToolsDialog);
        i.configureDialog(i);
        me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z * SKINALPHA_DIALOG_SANDBOXTOOLS);
index fc2ba573bbaa7448addcd648cde86d9a2ae421e2..46506dcfa0f71a8627a99b6cecd36037ce2fb8fa 100644 (file)
@@ -1070,7 +1070,7 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
                t = strcat(t, _("encryption:"), " ", (q ? sprintf(_("AES level %d"), q) : ZCTX(_("ENC^none"))), ", ");
                t = strcat(t, sprintf(_("mod: %s"), ((modname == "xonotic") ? ZCTX(_("MOD^Default")) : original_modname)));
                if(pure_available)
-                       t = strcat(t, sprintf(_(" (%s)"), (pure) ? _("official settings") : _("modified settings")));
+                       t = strcat(t, sprintf(" (%s)", (pure) ? _("official settings") : _("modified settings")));
                t = strcat(t, ", ");
                t = strcat(t, ((sflags >= 0 && (sflags & SERVERFLAG_PLAYERSTATS)) ? _("stats enabled") : _("stats disabled")));
                setZonedTooltip(me, t, string_null);
index 762b216f9b6801d9b4668a801737c15a2f84f36b..1e0a80b7676d91f349d21045f06167b5f9fe0b04 100644 (file)
@@ -103,10 +103,10 @@ void XonoticResolutionSlider_addResolution(entity me, float w, float h, float pi
                                bestdenom = denom;
                        }
                }
-               me.insertValue(me, i, strzone(sprintf(_("%dx%d (%d:%d)"), w, h, bestnum, bestdenom)), strzone(strcat(ftos(w), " ", ftos(h), " ", ftos(pixelheight))));
+               me.insertValue(me, i, strzone(sprintf("%dx%d (%d:%d)", w, h, bestnum, bestdenom)), strzone(strcat(ftos(w), " ", ftos(h), " ", ftos(pixelheight))));
        }
        else
-               me.insertValue(me, i, strzone(sprintf(_("%dx%d"), w, h)), strzone(strcat(ftos(w), " ", ftos(h), " ", ftos(pixelheight))));
+               me.insertValue(me, i, strzone(sprintf("%dx%d", w, h)), strzone(strcat(ftos(w), " ", ftos(h), " ", ftos(pixelheight))));
 }
 float autocvar_menu_vid_allowdualscreenresolution;
 void XonoticResolutionSlider_configureXonoticResolutionSlider(entity me)
index 4d704606d31275d4281b03e2fdb1f66c864bd6d4..a0018b99a905f7af574d043c37f8de75711c3021 100644 (file)
@@ -429,6 +429,12 @@ void UpdateNotification_URI_Get_Callback(float id, float status, string data)
                }
        }
 
+       if(un_bannedservers != "")
+       {
+               _Nex_ExtResponseSystem_BannedServers = strzone(un_bannedservers);
+               _Nex_ExtResponseSystem_BannedServersNeedsRefresh = 1;
+       }
+
        if(un_emergency_pk3s != "")
        {
                _Nex_ExtResponseSystem_Packs = strzone(un_emergency_pk3s);
@@ -680,7 +686,7 @@ float updateCompression()
        GAMETYPE(MAPINFO_TYPE_ONSLAUGHT) \
        GAMETYPE(MAPINFO_TYPE_ASSAULT) \
        if (cvar("developer")) GAMETYPE(MAPINFO_TYPE_RACE) \
-       GAMETYPE(MAPINFO_TYPE_CTS) \
+       if (cvar("developer")) GAMETYPE(MAPINFO_TYPE_CTS) \
        /* GAMETYPE(MAPINFO_TYPE_INVASION) */ \
        /**/
 
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 314858780bf7f6917035c71a10c89f66e7bd7ecb..f66b77a068145eadb0460bfdd776d531aed6b454 100644 (file)
@@ -197,6 +197,7 @@ float autocvar_g_jetpack_antigravity;
 int autocvar_g_jetpack_fuel;
 float autocvar_g_jetpack_maxspeed_side;
 float autocvar_g_jetpack_maxspeed_up;
+float autocvar_g_jetpack_reverse_thrust;
 #define autocvar_g_maplist cvar_string("g_maplist")
 bool autocvar_g_maplist_check_waypoints;
 int autocvar_g_maplist_index;
@@ -356,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;
@@ -552,3 +553,24 @@ float autocvar_g_frozen_revive_falldamage;
 int autocvar_g_frozen_revive_falldamage_health;
 bool autocvar_g_frozen_damage_trigger;
 float autocvar_g_frozen_force;
+float autocvar_sv_airaccel_qw;
+float autocvar_sv_airstrafeaccel_qw;
+float autocvar_sv_airspeedlimit_nonqw;
+float autocvar_sv_airaccel_qw_stretchfactor;
+float autocvar_sv_maxairstrafespeed;
+float autocvar_sv_airstrafeaccelerate;
+float autocvar_sv_warsowbunny_turnaccel;
+float autocvar_sv_airaccel_sideways_friction;
+float autocvar_sv_aircontrol;
+float autocvar_sv_aircontrol_power;
+float autocvar_sv_aircontrol_penalty;
+float autocvar_sv_warsowbunny_airforwardaccel;
+float autocvar_sv_warsowbunny_topspeed;
+float autocvar_sv_warsowbunny_accel;
+float autocvar_sv_warsowbunny_backtosideratio;
+float autocvar_sv_friction;
+float autocvar_sv_accelerate;
+float autocvar_sv_stopspeed;
+float autocvar_sv_airaccelerate;
+float autocvar_sv_airstopaccelerate;
+float autocvar_sv_track_canjump;
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..308cd95101ab09aa8ccb1203dcc6cc07af3e2504 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;
@@ -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..b22ded20fb618f0e7c58ca0b74612c327e47483e 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)
                                {
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 6f45ef6c864c903f60c3c7663f60753b4c214170..586f2a8c04758b8e5d9c5c3c6501c1996cf40f1f 100644 (file)
@@ -19,15 +19,14 @@ entity waypoint_spawn(vector m1, vector m2, float f)
 {
        if(!(f & WAYPOINTFLAG_PERSONAL))
        {
-               FOREACH_ENTITY_CLASS("waypoint", boxesoverlap(m1, m2, it.absmin, it.absmax),
+               IL_EACH(g_waypoints, boxesoverlap(m1, m2, it.absmin, it.absmax),
                {
-                       // if a matching spawnfunc_waypoint already exists, don't add a duplicate
                        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;
@@ -172,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))
                {
@@ -294,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);
@@ -343,28 +344,21 @@ void waypoint_remove(entity 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;
-       }
+               remove(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
@@ -587,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
@@ -722,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);
 }
 
@@ -809,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);
@@ -857,7 +833,7 @@ void botframe_showwaypointlinks()
                                w = head.wp31;if (w) te_lightning2(NULL, w.origin, head.origin);
                        }
                }
-       ));
+       });
 }
 
 float botframe_autowaypoints_fixdown(vector v)
@@ -870,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;
@@ -923,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");
@@ -1047,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 9706a2f1598820d972650d73fc14950d87f3ab55..86f46b067f28679d19958c57feac658144e364dc 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)
@@ -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;
@@ -733,7 +733,8 @@ float CheatFrame(entity this)
                        if(this.maycheat || (gamestart_sv_cheats && autocvar_sv_cheats))
                        {
                                // use cheat dragging if cheats are enabled
-                               crosshair_trace_plusvisibletriggers(this);
+                               //if(Drag_IsDragging(this))
+                                       //crosshair_trace_plusvisibletriggers(this);
                                Drag(this, true, true);
                        }
                        else
@@ -867,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;
@@ -894,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 608895b4e77cc630e2e84bb2ec8f20e4236f3ba1..fe307fc01ac5872538b0ffd5aada4cdd964cab24 100644 (file)
@@ -269,7 +269,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;
@@ -462,6 +462,8 @@ void PutClientInServer(entity this)
        if (IS_OBSERVER(this)) {
                PutObserverInServer(this);
        } else if (IS_PLAYER(this)) {
+               if (this.vehicle) vehicles_exit(this.vehicle, VHEF_RELEASE);
+               
                PlayerState_attach(this);
                accuracy_resend(this);
 
@@ -479,7 +481,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)
@@ -802,7 +804,7 @@ void ClientKill_Now(entity this)
        if(this.killindicator_teamchange)
                ClientKill_Now_TeamChange(this);
 
-       if(IS_PLAYER(this))
+       if(!IS_SPEC(this) && !IS_OBSERVER(this))
                Damage(this, this, this, 100000, DEATH_KILL.m_id, this.origin, '0 0 0');
 
        // now I am sure the player IS dead
@@ -905,7 +907,7 @@ void ClientKill_TeamChange (entity this, float targetteam) // 0 = don't change,
                                setorigin(it.killindicator, '0 0 52');
                                setthink(it.killindicator, KillIndicator_Think);
                                it.killindicator.nextthink = starttime + (it.lip) * 0.05;
-                               clientkilltime = max(clientkilltime, it.killindicator.nextthink + 0.05);
+                               //clientkilltime = max(clientkilltime, it.killindicator.nextthink + 0.05);
                                it.killindicator.cnt = ceil(killtime);
                        });
                        this.lip = 0;
@@ -1145,7 +1147,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();
 
@@ -1287,7 +1289,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;
@@ -1613,7 +1615,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);
@@ -1623,7 +1625,9 @@ void SpectateCopy(entity this, entity spectatee)
        this.hud = spectatee.hud;
        if(spectatee.vehicle)
     {
-        this.fixangle = false;
+       this.angles = spectatee.v_angle;
+
+        //this.fixangle = false;
         //this.velocity = spectatee.vehicle.velocity;
         this.vehicle_health = spectatee.vehicle_health;
         this.vehicle_shield = spectatee.vehicle_shield;
@@ -1633,12 +1637,12 @@ void SpectateCopy(entity this, entity spectatee)
         this.vehicle_reload1 = spectatee.vehicle_reload1;
         this.vehicle_reload2 = spectatee.vehicle_reload2;
 
-        msg_entity = this;
+        //msg_entity = this;
 
-        WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
-            WriteAngle(MSG_ONE,  spectatee.v_angle.x);
-            WriteAngle(MSG_ONE,  spectatee.v_angle.y);
-            WriteAngle(MSG_ONE,  spectatee.v_angle.z);
+       // WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
+            //WriteAngle(MSG_ONE,  spectatee.v_angle.x);
+           // WriteAngle(MSG_ONE,  spectatee.v_angle.y);
+           // WriteAngle(MSG_ONE,  spectatee.v_angle.z);
 
         //WriteByte (MSG_ONE, SVC_SETVIEW);
         //    WriteEntity(MSG_ONE, this);
@@ -1671,7 +1675,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))
@@ -1704,14 +1708,14 @@ bool Spectate(entity this, entity pl)
 
 bool SpectateNext(entity this)
 {
-       other = find(this.enemy, classname, STR_PLAYER);
+       entity ent = find(this.enemy, classname, STR_PLAYER);
 
-       if (MUTATOR_CALLHOOK(SpectateNext, this, other))
-               other = M_ARGV(1, entity);
-       else if (!other)
-               other = find(other, classname, STR_PLAYER);
+       if (MUTATOR_CALLHOOK(SpectateNext, this, ent))
+               ent = M_ARGV(1, entity);
+       else if (!ent)
+               ent = find(ent, classname, STR_PLAYER);
 
-       if(other) { SetSpectatee(this, other); }
+       if(ent) { SetSpectatee(this, ent); }
 
        return SpectateSet(this);
 }
@@ -1719,36 +1723,35 @@ bool SpectateNext(entity this)
 bool SpectatePrev(entity this)
 {
        // NOTE: chain order is from the highest to the lower entnum (unlike find)
-       other = findchain(classname, STR_PLAYER);
-       if (!other) // no player
+       entity ent = findchain(classname, STR_PLAYER);
+       if (!ent) // no player
                return false;
 
-       entity first = other;
+       entity first = ent;
        // skip players until current spectated player
        if(this.enemy)
-       while(other && other != this.enemy)
-               other = other.chain;
+       while(ent && ent != this.enemy)
+               ent = ent.chain;
 
-       switch (MUTATOR_CALLHOOK(SpectatePrev, this, other, first))
+       switch (MUTATOR_CALLHOOK(SpectatePrev, this, ent, first))
        {
                case MUT_SPECPREV_FOUND:
-                   other = M_ARGV(1, entity);
+                   ent = M_ARGV(1, entity);
                    break;
                case MUT_SPECPREV_RETURN:
-                   other = M_ARGV(1, entity);
                    return true;
                case MUT_SPECPREV_CONTINUE:
                default:
                {
-                       if(other.chain)
-                               other = other.chain;
+                       if(ent.chain)
+                               ent = ent.chain;
                        else
-                               other = first;
+                               ent = first;
                        break;
                }
        }
 
-       SetSpectatee(this, other);
+       SetSpectatee(this, ent);
        return SpectateSet(this);
 }
 
@@ -1922,7 +1925,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;
@@ -1933,9 +1935,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))) {
@@ -1956,6 +1957,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) {
@@ -2167,10 +2175,8 @@ void PlayerPreThink (entity this)
                        {
                                if(!it.team || SAME_TEAM(this, it))
                                        Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER);
-                       }
-                       else if(autocvar_g_vehicles_steal)
-                       {
-                               Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER_STEAL);
+                               else if(autocvar_g_vehicles_steal)
+                                       Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER_STEAL);
                        }
                });
 
@@ -2216,27 +2222,39 @@ void PlayerPreThink (entity this)
                                if (frametime) player_anim(this);
                                bool button_pressed = (PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_JUMP(this) || PHYS_INPUT_BUTTON_ATCK2(this) || PHYS_INPUT_BUTTON_HOOK(this) || PHYS_INPUT_BUTTON_USE(this));
 
-                               if (this.deadflag == DEAD_DYING) {
-                                       if ((this.respawn_flags & RESPAWN_FORCE) && !(this.respawn_time < this.respawn_time_max)) {
-                                               this.deadflag = DEAD_RESPAWNING;
-                                       } else if (!button_pressed) {
-                                               this.deadflag = DEAD_DEAD;
-                    }
-                               } else if (this.deadflag == DEAD_DEAD) {
-                                       if (button_pressed) {
-                                               this.deadflag = DEAD_RESPAWNABLE;
-                                       } else if (time >= this.respawn_time_max && (this.respawn_flags & RESPAWN_FORCE)) {
-                                               this.deadflag = DEAD_RESPAWNING;
-                    }
-                               } else if (this.deadflag == DEAD_RESPAWNABLE) {
-                                       if (!button_pressed) {
-                                               this.deadflag = DEAD_RESPAWNING;
-                    }
-                               } else if (this.deadflag == DEAD_RESPAWNING) {
-                                       if (time > this.respawn_time) {
-                                               this.respawn_time = time + 1; // only retry once a second
-                                               this.respawn_time_max = this.respawn_time;
-                                               respawn(this);
+                               switch(this.deadflag)
+                               {
+                                       case DEAD_DYING:
+                                       {
+                                               if ((this.respawn_flags & RESPAWN_FORCE) && !(this.respawn_time < this.respawn_time_max))
+                                                       this.deadflag = DEAD_RESPAWNING;
+                                               else if (!button_pressed || (this.respawn_flags & RESPAWN_FORCE))
+                                                       this.deadflag = DEAD_DEAD;
+                                               break;
+                                       }
+                                       case DEAD_DEAD:
+                                       {
+                                               if (button_pressed)
+                                                       this.deadflag = DEAD_RESPAWNABLE;
+                                               else if (time >= this.respawn_time_max && (this.respawn_flags & RESPAWN_FORCE))
+                                                       this.deadflag = DEAD_RESPAWNING;
+                                               break;
+                                       }
+                                       case DEAD_RESPAWNABLE:
+                                       {
+                                               if (!button_pressed || (this.respawn_flags & RESPAWN_FORCE))
+                                                       this.deadflag = DEAD_RESPAWNING;
+                                               break;
+                                       }
+                                       case DEAD_RESPAWNING:
+                                       {
+                                               if (time > this.respawn_time)
+                                               {
+                                                       this.respawn_time = time + 1; // only retry once a second
+                                                       this.respawn_time_max = this.respawn_time;
+                                                       respawn(this);
+                                               }
+                                               break;
                                        }
                                }
 
@@ -2268,12 +2286,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;
         }
 
@@ -2366,13 +2387,13 @@ void PlayerPreThink (entity this)
                entity e = this.teamkill_soundsource;
                entity oldpusher = e.pusher;
                e.pusher = this;
-               PlayerSound(e, playersound_teamshoot, CH_VOICE, VOICETYPE_LASTATTACKER_ONLY);
+               PlayerSound(e, playersound_teamshoot, CH_VOICE, VOL_BASEVOICE, VOICETYPE_LASTATTACKER_ONLY);
                e.pusher = oldpusher;
        }
 
        if (this.taunt_soundtime && time > this.taunt_soundtime) {
                this.taunt_soundtime = 0;
-               PlayerSound(this, playersound_taunt, CH_VOICE, VOICETYPE_AUTOTAUNT);
+               PlayerSound(this, playersound_taunt, CH_VOICE, VOL_BASEVOICE, VOICETYPE_AUTOTAUNT);
        }
 
        target_voicescript_next(this);
@@ -2388,10 +2409,10 @@ void DrownPlayer(entity this)
        if(IS_DEAD(this))
                return;
 
-       if (this.waterlevel != WATERLEVEL_SUBMERGED)
+       if (this.waterlevel != WATERLEVEL_SUBMERGED || this.vehicle)
        {
                if(this.air_finished < time)
-                       PlayerSound(this, playersound_gasp, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+                       PlayerSound(this, playersound_gasp, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
                this.air_finished = time + autocvar_g_balance_contents_drowndelay;
                this.dmg = 2;
        }
@@ -2405,6 +2426,30 @@ void DrownPlayer(entity this)
        }
 }
 
+void Player_Physics(entity this)
+{
+       this.movetype = ((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;
+               this.movetype = mt;
+               return;
+       }
+
+       if(!frametime && !this.pm_frametime)
+               return;
+
+       Movetype_Physics_NoMatchTicrate(this, this.pm_frametime, true);
+
+       this.pm_frametime = 0;
+}
+
 /*
 =============
 PlayerPostThink
@@ -2415,12 +2460,25 @@ 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))
        if (IS_PLAYER(this) || sv_maxidle_spectatorsareidle)
        {
-               if (time - this.parm_idlesince < 1) // instead of (time == this.parm_idlesince) to support sv_maxidle <= 10
+               int totalClients = 0;
+               if(sv_maxidle_slots > 0)
+               {
+                       FOREACH_CLIENT(IS_REAL_CLIENT(it) || sv_maxidle_slots_countbots,
+                       {
+                               ++totalClients;
+                       });
+               }
+
+               if (sv_maxidle_slots > 0 && (maxclients - totalClients) > sv_maxidle_slots)
+               { /* do nothing */ }
+               else if (time - this.parm_idlesince < 1) // instead of (time == this.parm_idlesince) to support sv_maxidle <= 10
                {
                        if (this.idlekick_lasttimeleft)
                        {
index 517ee3796100c028220a10e0842d64d9f675e7ce..5e276c4a3a3a16024b914cec67800e4c65e59841 100644 (file)
@@ -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 4c54dddaa6901f137e28772c913bac6d1b6d0d2b..098a176c8cc1919eb8a2bfedaef7394cbc12a2e4 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;
@@ -436,15 +437,15 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                                        // exclude pain sounds for laserjumps as long as you aren't REALLY low on health and would die of the next two
                                        {
                                                if(deathtype == DEATH_FALL.m_id)
-                                                       PlayerSound(this, playersound_fall, CH_PAIN, VOICETYPE_PLAYERSOUND);
+                                                       PlayerSound(this, playersound_fall, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
                                                else if(this.health > 75)
-                                                       PlayerSound(this, playersound_pain100, CH_PAIN, VOICETYPE_PLAYERSOUND);
+                                                       PlayerSound(this, playersound_pain100, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
                                                else if(this.health > 50)
-                                                       PlayerSound(this, playersound_pain75, CH_PAIN, VOICETYPE_PLAYERSOUND);
+                                                       PlayerSound(this, playersound_pain75, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
                                                else if(this.health > 25)
-                                                       PlayerSound(this, playersound_pain50, CH_PAIN, VOICETYPE_PLAYERSOUND);
+                                                       PlayerSound(this, playersound_pain50, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
                                                else
-                                                       PlayerSound(this, playersound_pain25, CH_PAIN, VOICETYPE_PLAYERSOUND);
+                                                       PlayerSound(this, playersound_pain25, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
                                        }
                                }
                        }
@@ -494,11 +495,14 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                valid_damage_for_weaponstats = 1;
        }
 
+       dh = dh - max(this.health, 0);
+       da = da - max(this.armorvalue, 0);
        if(valid_damage_for_weaponstats)
        {
-               dh = dh - max(this.health, 0);
-               da = da - max(this.armorvalue, 0);
                WeaponStats_LogDamage(awep.m_id, abot, PS(this).m_weapon.m_id, vbot, dh + da);
+       }
+       if (dh + da)
+       {
                MUTATOR_CALLHOOK(PlayerDamaged, attacker, this, dh, da, hitloc, deathtype);
        }
 
@@ -520,9 +524,9 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                if(sound_allowed(MSG_BROADCAST, attacker))
                {
                        if(deathtype == DEATH_DROWN.m_id)
-                               PlayerSound(this, playersound_drown, CH_PAIN, VOICETYPE_PLAYERSOUND);
+                               PlayerSound(this, playersound_drown, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
                        else
-                               PlayerSound(this, playersound_death, CH_PAIN, VOICETYPE_PLAYERSOUND);
+                               PlayerSound(this, playersound_death, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
                }
 
                // get rid of kill indicator
@@ -591,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..81dc1a60ea1549d58c4f909b03ff2cbee4b030f6 100644 (file)
@@ -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 8eea0dc203d189b4e4007dfbe8f51a23ea63ba27..a1c180cef831779830352ecfe6c0ad67c43409a7 100644 (file)
@@ -253,6 +253,8 @@ float lockteams;
 .float parm_idlesince;
 float sv_maxidle;
 float sv_maxidle_spectatorsareidle;
+int sv_maxidle_slots;
+bool sv_maxidle_slots_countbots;
 
 float tracebox_hits_trigger_hurt(vector start, vector mi, vector ma, vector end);
 
@@ -393,7 +395,6 @@ const float ACTIVE_TOGGLE   = 3;
 .float player_blocked;
 .float weapon_blocked; // weapon use disabled
 
-.float frozen = _STAT(FROZEN); // for freeze attacks
 .float revive_progress = _STAT(REVIVE_PROGRESS);
 .float revival_time; // time at which player was last revived
 .float revive_speed; // NOTE: multiplier (anything above 1 is instaheal)
@@ -442,3 +443,9 @@ 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(); }
index 4fbccc7b02c160b736b09cf82718ea338acdd1b7..5fbe6423098baefaee5d25f93651c7d2c32e1971 100644 (file)
@@ -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
index b22a81e0427d6145fa238a11cc385fb3f2eab1ce..88d63e384c11261fc3cb70499cda902c512822cc 100644 (file)
@@ -76,8 +76,8 @@ void RemoveGrapplingHook(entity pl)
                return;
        remove(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;
 }
@@ -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);
                }
@@ -301,18 +301,18 @@ void GrapplingHookThink(entity this)
        }
 }
 
-void GrapplingHookTouch (entity this)
+void GrapplingHookTouch(entity this, entity toucher)
 {
-       if(other.movetype == MOVETYPE_FOLLOW)
+       if(toucher.move_movetype == MOVETYPE_FOLLOW)
                return;
-       PROJECTILE_TOUCH(this);
+       PROJECTILE_TOUCH(this, toucher);
 
        GrapplingHook_Stop(this);
 
-       if(other)
-               if(other.movetype != MOVETYPE_NONE)
+       if(toucher)
+               if(toucher.move_movetype != MOVETYPE_NONE)
                {
-                       SetMovetypeFollow(this, other);
+                       SetMovetypeFollow(this, toucher);
                        WarpZone_RefSys_BeginAddingIncrementally(this, this.aiment);
                }
 
@@ -371,7 +371,7 @@ void FireGrapplingHook(entity actor)
        missile.classname = "grapplinghook";
        missile.flags = FL_PROJECTILE;
 
-       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..e79bbcaf76a5dd707acc48b764db9109d0bf13e5 100644 (file)
@@ -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 1b12174b990bd4f73869ab59323169bcab30cc60..e4affe265f8b7dd768089358b36198fa027c1ce1 100644 (file)
@@ -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);
                });
        }
 
@@ -234,7 +234,7 @@ vector findbetterlocation (vector org, float mindist)
        return org;
 }
 
-float LOD_customize(entity this)
+bool LOD_customize(entity this, entity client)
 {
        if(autocvar_loddebug)
        {
@@ -249,10 +249,10 @@ float LOD_customize(entity this)
        }
 
        // TODO csqc network this so it only gets sent once
-       vector near_point = NearestPointOnBox(this, other.origin);
-       if(vdist(near_point - other.origin, <, this.loddistance1))
+       vector near_point = NearestPointOnBox(this, client.origin);
+       if(vdist(near_point - client.origin, <, this.loddistance1))
                this.modelindex = this.lodmodelindex0;
-       else if(!this.lodmodelindex2 || vdist(near_point - other.origin, <, this.loddistance2))
+       else if(!this.lodmodelindex2 || vdist(near_point - client.origin, <, this.loddistance2))
                this.modelindex = this.lodmodelindex1;
        else
                this.modelindex = this.lodmodelindex2;
@@ -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 4f9fc471f55609698c5bb490be56fcd7a1741edb..1f5537cea52f92ffa5e7e1f3284edd20cadcea04 100644 (file)
@@ -138,7 +138,7 @@ float angc (float a1, float a2);
 .float loddistance1;
 .float loddistance2;
 
-float LOD_customize(entity this);
+bool LOD_customize(entity this, entity client);
 
 void LOD_uncustomize(entity this);
 
index 3ae2f27f397b3509fb1919e24972834dc3deb382..7d477ac577daf27f5074f1b4194766172b6512b3 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
 
@@ -1299,6 +1299,7 @@ When the player presses attack or jump, change to the next level
 void IntermissionThink(entity this)
 {
        FixIntermissionClient(this);
+       CSQCMODEL_AUTOUPDATE(this); // PlayerPostThink returns before calling this during intermission, so run it here
 
        float server_screenshot = (autocvar_sv_autoscreenshot && this.cvar_cl_autoscreenshot);
        float client_screenshot = (this.cvar_cl_autoscreenshot == 2);
@@ -1487,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)
                {
@@ -1983,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.movetype == MOVETYPE_PUSH || it.movetype == MOVETYPE_FAKEPUSH || it.movetype == MOVETYPE_PHYSICS)
+                       continue;
+
+               int mt = it.move_movetype;
+
+               if(mt == MOVETYPE_PUSH || mt == MOVETYPE_FAKEPUSH || mt == MOVETYPE_PHYSICS)
+               {
+                       it.move_qcphysics = false;
+                       it.movetype = mt;
+                       continue;
+               }
+
+               it.movetype = ((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) {
@@ -2008,7 +2052,8 @@ 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), {
@@ -2016,6 +2061,7 @@ void EndFrame()
                s.ps_push(s, it);
        });
        systems_update();
+       IL_ENDFRAME();
 }
 
 
index 317b897b0c8a98d922b9ff49c4f30a48271d15b9..64e10a2f2e0fdb01b40afb4ccfc06c137ddf4acc 100644 (file)
@@ -68,23 +68,23 @@ item_key
 /**
  * Key touch handler.
  */
-void item_key_touch(entity this)
+void item_key_touch(entity this, entity toucher)
 {
-       if (!IS_PLAYER(other))
+       if (!IS_PLAYER(toucher))
                return;
 
        // player already picked up this key
-       if (other.itemkeys & this.itemkeys)
+       if (toucher.itemkeys & this.itemkeys)
                return;
 
-       other.itemkeys |= this.itemkeys;
-       play2(other, this.noise);
+       toucher.itemkeys |= this.itemkeys;
+       play2(toucher, this.noise);
 
-       centerprint(other, this.message);
+       centerprint(toucher, this.message);
 
        string oldmsg = this.message;
        this.message = "";
-       SUB_UseTargets(this, other, other); // TODO: should we be using other for the trigger here?
+       SUB_UseTargets(this, toucher, toucher); // TODO: should we be using toucher for the trigger here?
        this.message = oldmsg;
 };
 
@@ -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);
 
index e4d9156f6653308dbf8df3ab9d45bad3323951a6..212e8cffb6dd60de37196936df8722dc9682668c 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;
@@ -1318,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
@@ -1327,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;
@@ -1349,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
@@ -1360,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 a8304b0e3aff44fa74e91510d4c82b7f1e042332..b6ddd3c6a17cfd76d37019e80330a51b93a6e16c 100644 (file)
@@ -121,7 +121,7 @@ void WarpZone_traceline_antilag (entity source, vector v1, vector v2, float nomo
 #define ITEM_TOUCH_NEEDKILL() (((trace_dpstartcontents | trace_dphitcontents) & DPCONTENTS_NODROP) || (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY))
 #define ITEM_DAMAGE_NEEDKILL(dt) (((dt) == DEATH_HURTTRIGGER.m_id) || ((dt) == DEATH_SLIME.m_id) || ((dt) == DEATH_LAVA.m_id) || ((dt) == DEATH_SWAMP.m_id))
 
-#define PROJECTILE_TOUCH(this) MACRO_BEGIN if (WarpZone_Projectile_Touch(this)) return; MACRO_END
+#define PROJECTILE_TOUCH(e,t) MACRO_BEGIN if (WarpZone_Projectile_Touch(e,t)) return; MACRO_END
 
 #define CENTER_OR_VIEWOFS(ent) (ent.origin + (IS_PLAYER(ent) ? ent.view_ofs : ((ent.mins + ent.maxs) * 0.5)))
 
@@ -256,6 +256,8 @@ void readlevelcvars()
        g_jetpack = cvar("g_jetpack");
        sv_maxidle = cvar("sv_maxidle");
        sv_maxidle_spectatorsareidle = cvar("sv_maxidle_spectatorsareidle");
+       sv_maxidle_slots = cvar("sv_maxidle_slots");
+       sv_maxidle_slots_countbots = cvar("sv_maxidle_slots_countbots");
        sv_autotaunt = cvar("sv_autotaunt");
        sv_taunt = cvar("sv_taunt");
 
index 20b3b54c04bb5f4d106064c2cb6db090024ea674..7285d7db36607738a58aa7c898a11a6c2cd5af55 100644 (file)
@@ -273,10 +273,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));
@@ -425,68 +429,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 +484,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 +667,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 2a8da29c275210b8646a31ba08bae7a0a6bc3d1f..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);
@@ -307,7 +321,7 @@ void ca_LastPlayerForTeam_Notify(entity this)
 MUTATOR_HOOKFUNCTION(ca, PlayerDies)
 {
        entity frag_target = M_ARGV(2, entity);
-       
+
        ca_LastPlayerForTeam_Notify(frag_target);
        if (!allowed_to_spawn)
                frag_target.respawn_flags =  RESPAWN_SILENT;
@@ -340,6 +354,8 @@ MUTATOR_HOOKFUNCTION(ca, MakePlayerObserver)
                player.caplayer = 0;
        if (player.caplayer)
                player.frags = FRAGS_LMS_LOSER;
+    else
+        player.frags = FRAGS_SPECTATOR;
        if (!warmup_stage)
                eliminatedPlayers.SendFlags |= 1;
        return true;  // prevent team reset
@@ -439,11 +455,11 @@ MUTATOR_HOOKFUNCTION(ca, SpectateSet)
 MUTATOR_HOOKFUNCTION(ca, SpectateNext)
 {
     entity client = M_ARGV(0, entity);
-    entity targ = M_ARGV(1, entity);
 
        if (!autocvar_g_ca_spectate_enemies && client.caplayer)
        {
-               targ = CA_SpectateNext(client, targ);
+               entity targ = M_ARGV(1, entity);
+               M_ARGV(1, entity) = CA_SpectateNext(client, targ);
                return true;
        }
 }
@@ -468,6 +484,8 @@ MUTATOR_HOOKFUNCTION(ca, SpectatePrev)
                }
        }
 
+       M_ARGV(1, entity) = targ;
+
        return MUT_SPECPREV_FOUND;
 }
 
index a184e68df9bb4e1398bca4555968305a846373fc..55ec4a462ed991dbc89c7bc787bbc3bc719f60b5 100644 (file)
@@ -152,12 +152,39 @@ void ctf_CaptureRecord(entity flag, entity player)
        }
 }
 
+bool ctf_Return_Customize(entity this, entity client)
+{
+       // only to the carrier
+       return boolean(client == this.owner);
+}
+
 void ctf_FlagcarrierWaypoints(entity player)
 {
        WaypointSprite_Spawn(WP_FlagCarrier, 0, 0, player, FLAG_WAYPOINT_OFFSET, NULL, player.team, player, wps_flagcarrier, true, RADARICON_FLAG);
        WaypointSprite_UpdateMaxHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(start_health, start_armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id) * 2);
        WaypointSprite_UpdateHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(player.health, player.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id));
        WaypointSprite_UpdateTeamRadar(player.wps_flagcarrier, RADARICON_FLAGCARRIER, WPCOLOR_FLAGCARRIER(player.team));
+
+       if(player.flagcarried && CTF_SAMETEAM(player, player.flagcarried))
+       {
+               if(!player.wps_enemyflagcarrier)
+               {
+                       entity wp = WaypointSprite_Spawn(((ctf_oneflag) ? WP_FlagCarrier : WP_FlagCarrierEnemy), 0, 0, player, FLAG_WAYPOINT_OFFSET, NULL, 0, player, wps_enemyflagcarrier, true, RADARICON_FLAG);
+                       wp.colormod = WPCOLOR_ENEMYFC(player.team);
+                       setcefc(wp, ctf_Stalemate_Customize);
+
+                       if(IS_REAL_CLIENT(player) && !ctf_stalemate)
+                               Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PICKUP_VISIBLE);
+               }
+
+               if(!player.wps_flagreturn)
+               {
+                       entity owp = WaypointSprite_SpawnFixed(WP_FlagReturn, player.flagcarried.ctf_spawnorigin + FLAG_WAYPOINT_OFFSET, player, wps_flagreturn, RADARICON_FLAG);
+                       owp.colormod = '0 0.8 0.8';
+                       //WaypointSprite_UpdateTeamRadar(player.wps_flagreturn, RADARICON_FLAG, ((player.team) ? colormapPaletteColor(player.team - 1, false) : '1 1 1'));
+                       setcefc(owp, ctf_Return_Customize);
+               }
+       }
 }
 
 void ctf_CalculatePassVelocity(entity flag, vector to, vector from, float turnrate)
@@ -278,24 +305,24 @@ void ctf_CaptureShield_Update(entity player, bool wanted_status)
        }
 }
 
-bool ctf_CaptureShield_Customize(entity this)
+bool ctf_CaptureShield_Customize(entity this, entity client)
 {
-       if(!other.ctf_captureshielded) { return false; }
-       if(CTF_SAMETEAM(this, other)) { return false; }
+       if(!client.ctf_captureshielded) { return false; }
+       if(CTF_SAMETEAM(this, client)) { return false; }
 
        return true;
 }
 
-void ctf_CaptureShield_Touch(entity this)
+void ctf_CaptureShield_Touch(entity this, entity toucher)
 {
-       if(!other.ctf_captureshielded) { return; }
-       if(CTF_SAMETEAM(this, other)) { return; }
+       if(!toucher.ctf_captureshielded) { return; }
+       if(CTF_SAMETEAM(this, toucher)) { return; }
 
        vector mymid = (this.absmin + this.absmax) * 0.5;
-       vector othermid = (other.absmin + other.absmax) * 0.5;
+       vector theirmid = (toucher.absmin + toucher.absmax) * 0.5;
 
-       Damage(other, this, this, 0, DEATH_HURTTRIGGER.m_id, mymid, normalize(othermid - mymid) * ctf_captureshield_force);
-       if(IS_REAL_CLIENT(other)) { Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED); }
+       Damage(toucher, this, this, 0, DEATH_HURTTRIGGER.m_id, mymid, normalize(theirmid - mymid) * ctf_captureshield_force);
+       if(IS_REAL_CLIENT(toucher)) { Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED); }
 }
 
 void ctf_CaptureShield_Spawn(entity flag)
@@ -307,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;
@@ -328,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;
@@ -387,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';
@@ -453,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;
@@ -498,6 +525,9 @@ void ctf_Handle_Throw(entity player, entity receiver, int droptype)
        if(player.wps_enemyflagcarrier)
                WaypointSprite_Kill(player.wps_enemyflagcarrier);
 
+       if(player.wps_flagreturn)
+               WaypointSprite_Kill(player.wps_flagreturn);
+
        // captureshield
        ctf_CaptureShield_Update(player, 0); // shield player from picking up flag
 }
@@ -638,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';
@@ -747,15 +777,14 @@ void ctf_CheckFlagReturn(entity flag, int returntype)
        }
 }
 
-bool ctf_Stalemate_Customize(entity this)
+bool ctf_Stalemate_Customize(entity this, entity client)
 {
        // make spectators see what the player would see
-       entity e, wp_owner;
-       e = WaypointSprite_getviewentity(other);
-       wp_owner = this.owner;
+       entity e = WaypointSprite_getviewentity(client);
+       entity wp_owner = this.owner;
 
        // team waypoints
-       if(CTF_SAMETEAM(wp_owner.flagcarried, wp_owner)) { return false; }
+       //if(CTF_SAMETEAM(wp_owner.flagcarried, wp_owner)) { return false; }
        if(SAME_TEAM(wp_owner, e)) { return false; }
        if(!IS_PLAYER(e)) { return false; }
 
@@ -908,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)
                        {
@@ -973,7 +1002,7 @@ void ctf_FlagThink(entity this)
                        if((this.pass_target == NULL)
                                || (IS_DEAD(this.pass_target))
                                || (this.pass_target.flagcarried)
-                               || (vdist(this.origin - targ_origin, <, autocvar_g_ctf_pass_radius))
+                               || (vdist(this.origin - targ_origin, >, autocvar_g_ctf_pass_radius))
                                || ((trace_fraction < 1) && (trace_ent != this.pass_target))
                                || (time > this.ctf_droptime + autocvar_g_ctf_pass_timelimit))
                        {
@@ -1109,6 +1138,7 @@ void ctf_RespawnFlag(entity flag)
        if((flag.owner) && (flag.owner.flagcarried == flag))
        {
                WaypointSprite_Kill(flag.owner.wps_enemyflagcarrier);
+               WaypointSprite_Kill(flag.owner.wps_flagreturn);
                WaypointSprite_Kill(flag.wps_flagcarrier);
 
                flag.owner.flagcarried = NULL;
@@ -1127,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;
@@ -1156,6 +1186,13 @@ void ctf_Reset(entity this)
        ctf_RespawnFlag(this);
 }
 
+bool ctf_FlagBase_Customize(entity this, entity client)
+{
+       if(client.flagcarried && CTF_SAMETEAM(client, client.flagcarried))
+               return false;
+       return true;
+}
+
 void ctf_DelayedFlagSetup(entity this) // called after a flag is placed on a map by ctf_FlagSetup()
 {
        // bot waypoints
@@ -1177,6 +1214,7 @@ void ctf_DelayedFlagSetup(entity this) // called after a flag is placed on a map
        entity wp = WaypointSprite_SpawnFixed(basename, this.origin + FLAG_WAYPOINT_OFFSET, this, wps_flagbase, RADARICON_FLAG);
        wp.colormod = ((this.team) ? Team_ColorRGB(this.team) : '1 1 1');
        WaypointSprite_UpdateTeamRadar(this.wps_flagbase, RADARICON_FLAG, ((this.team) ? colormapPaletteColor(this.team - 1, false) : '1 1 1'));
+       setcefc(wp, ctf_FlagBase_Customize);
 
        // captureshield setup
        ctf_CaptureShield_Spawn(this);
@@ -1280,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);
@@ -1490,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)
@@ -1987,7 +2021,7 @@ MUTATOR_HOOKFUNCTION(ctf, PlayerPreThink)
                                                   | CTF_YELLOW_FLAG_CARRYING   | CTF_YELLOW_FLAG_TAKEN         | CTF_YELLOW_FLAG_LOST
                                                   | CTF_PINK_FLAG_CARRYING     | CTF_PINK_FLAG_TAKEN           | CTF_PINK_FLAG_LOST
                                                   | CTF_NEUTRAL_FLAG_CARRYING  | CTF_NEUTRAL_FLAG_TAKEN        | CTF_NEUTRAL_FLAG_LOST
-                                                  | CTF_FLAG_NEUTRAL | CTF_SHIELDED);
+                                                  | CTF_FLAG_NEUTRAL | CTF_SHIELDED | CTF_STALEMATE);
 
        // scan through all the flags and notify the client about them
        for(entity flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
@@ -2021,6 +2055,9 @@ MUTATOR_HOOKFUNCTION(ctf, PlayerPreThink)
        if(player.ctf_captureshielded)
                player.ctf_flagstatus |= CTF_SHIELDED;
 
+       if(ctf_stalemate)
+               player.ctf_flagstatus |= CTF_STALEMATE;
+
        // update the health of the flag carrier waypointsprite
        if(player.wps_flagcarrier)
                WaypointSprite_UpdateHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(player.health, player.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id));
@@ -2293,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
@@ -2381,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;
                        }
                }
 
@@ -2567,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 95e0bcd424ded55bc032f93b0706baf02eb4f882..b4d2459c3e26ed078e84ff89a11afa0b5725939c 100644 (file)
@@ -20,7 +20,7 @@ CLASS(Flag, Pickup)
     ATTRIB(Flag, m_maxs, vector, PL_MAX_CONST + '0 0 -13')
 ENDCLASS(Flag)
 Flag CTF_FLAG; STATIC_INIT(Flag) { CTF_FLAG = NEW(Flag); }
-void ctf_FlagTouch(entity this) { ITEM_HANDLE(Pickup, CTF_FLAG, this, other); }
+void ctf_FlagTouch(entity this, entity toucher) { ITEM_HANDLE(Pickup, CTF_FLAG, this, toucher); }
 
 // flag constants // for most of these, there is just one question to be asked: WHYYYYY?
 
@@ -70,6 +70,7 @@ entity ctf_worldflaglist;
 .entity wps_flagbase;
 .entity wps_flagcarrier;
 .entity wps_flagdropped;
+.entity wps_flagreturn;
 .entity wps_enemyflagcarrier;
 .float wps_helpme_time;
 bool wpforenemy_announced;
@@ -98,6 +99,8 @@ const int RETURN_DAMAGE = 3;
 const int RETURN_SPEEDRUN = 4;
 const int RETURN_NEEDKILL = 5;
 
+bool ctf_Stalemate_Customize(entity this, entity client);
+
 void ctf_Handle_Throw(entity player, entity receiver, float droptype);
 
 // flag properties
@@ -171,3 +174,4 @@ const int CTF_NEUTRAL_FLAG_LOST                     = 512;
 const int CTF_NEUTRAL_FLAG_CARRYING            = 768;
 const int CTF_FLAG_NEUTRAL                             = 2048;
 const int CTF_SHIELDED                                 = 4096;
+const int CTF_STALEMATE                                        = 8192;
index bfddc30b01bbbc7439a2fb76ab793e0662db4e41..444fe5692e8bee057c004ac997e408b095ed934c 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;
                }
        }
index 6bbbaee999abca13352a492bcbeae66168dd09aa..3f75db9f387c320ab72a94840fa1badd366138a7 100644 (file)
@@ -249,11 +249,11 @@ void dompointthink(entity this)
        }
 }
 
-void dompointtouch(entity this)
+void dompointtouch(entity this, entity toucher)
 {
-       if (!IS_PLAYER(other))
+       if (!IS_PLAYER(toucher))
                return;
-       if (other.health < 1)
+       if (toucher.health < 1)
                return;
 
        if(round_handler_IsActive() && !round_handler_IsRoundStarted())
@@ -264,7 +264,7 @@ void dompointtouch(entity this)
 
        // only valid teams can claim it
        entity head = find(NULL, classname, "dom_team");
-       while (head && head.team != other.team)
+       while (head && head.team != toucher.team)
                head = find(head, classname, "dom_team");
        if (!head || head.netname == "" || head == this.goalentity)
                return;
@@ -273,9 +273,9 @@ void dompointtouch(entity this)
 
        this.team = this.goalentity.team; // this stores the PREVIOUS team!
 
-       this.cnt = other.team;
+       this.cnt = toucher.team;
        this.owner = head; // team to switch to after the delay
-       this.dmg_inflictor = other;
+       this.dmg_inflictor = toucher;
 
        // this.state = 1;
        // this.delay = time + cvar("g_domination_point_capturetime");
@@ -298,8 +298,8 @@ void dompointtouch(entity this)
        this.modelindex = head.dmg;
        this.skin = head.skin;
 
-       this.enemy = other; // individual player scoring
-       this.enemy_playerid = other.playerid;
+       this.enemy = toucher; // individual player scoring
+       this.enemy_playerid = toucher.playerid;
        dompoint_captured(this);
 }
 
@@ -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..b1a74f2aa998c92e28614b46905f4e9479eb8ca2 100644 (file)
@@ -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 454e2f168f984369d6e3a6b40c3e8675ff7d4f00..1ce62672d8b6e5d9eaf6c5ffb0d608dcced47edf 100644 (file)
@@ -81,7 +81,7 @@ void ka_EventLog(string mode, entity actor) // use an alias for easy changing an
                GameLogEcho(strcat(":ka:", mode, ((actor != NULL) ? (strcat(":", ftos(actor.playerid))) : "")));
 }
 
-void ka_TouchEvent(entity this);
+void ka_TouchEvent(entity this, entity toucher);
 void ka_RespawnBall(entity this);
 void ka_RespawnBall(entity this) // runs whenever the ball needs to be relocated
 {
@@ -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;
@@ -125,7 +125,7 @@ void ka_TimeScoring(entity this)
        }
 }
 
-void ka_TouchEvent(entity this) // runs any time that the ball comes in contact with something
+void ka_TouchEvent(entity this, entity toucher) // runs any time that the ball comes in contact with something
 {
        if(gameover) { return; }
        if(!this) { return; }
@@ -134,9 +134,9 @@ void ka_TouchEvent(entity this) // runs any time that the ball comes in contact
                ka_RespawnBall(this);
                return;
        }
-       if(IS_DEAD(other)) { return; }
-       if(STAT(FROZEN, other)) { return; }
-       if (!IS_PLAYER(other))
+       if(IS_DEAD(toucher)) { return; }
+       if(STAT(FROZEN, toucher)) { return; }
+       if (!IS_PLAYER(toucher))
        {  // The ball just touched an object, most likely the world
                Send_Effect(EFFECT_BALL_SPARKS, this.origin, '0 0 0', 1);
                sound(this, CH_TRIGGER, SND_KA_TOUCH, VOL_BASE, ATTEN_NORM);
@@ -145,14 +145,14 @@ void ka_TouchEvent(entity this) // runs any time that the ball comes in contact
        else if(this.wait > time) { return; }
 
        // attach the ball to the player
-       this.owner = other;
-       other.ballcarried = this;
-       setattachment(this, other, "");
+       this.owner = toucher;
+       toucher.ballcarried = this;
+       setattachment(this, toucher, "");
        setorigin(this, '0 0 0');
 
        // 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);
@@ -160,25 +160,25 @@ void ka_TouchEvent(entity this) // runs any time that the ball comes in contact
        this.takedamage = DAMAGE_NO;
 
        // apply effects to player
-       other.glow_color = autocvar_g_keepawayball_trail_color;
-       other.glow_trail = true;
-       other.effects |= autocvar_g_keepaway_ballcarrier_effects;
+       toucher.glow_color = autocvar_g_keepawayball_trail_color;
+       toucher.glow_trail = true;
+       toucher.effects |= autocvar_g_keepaway_ballcarrier_effects;
 
        // messages and sounds
-       ka_EventLog("pickup", other);
-       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_KEEPAWAY_PICKUP, other.netname);
-       Send_Notification(NOTIF_ALL_EXCEPT, other, MSG_CENTER, CENTER_KEEPAWAY_PICKUP, other.netname);
-       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_KEEPAWAY_PICKUP_SELF);
+       ka_EventLog("pickup", toucher);
+       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_KEEPAWAY_PICKUP, toucher.netname);
+       Send_Notification(NOTIF_ALL_EXCEPT, toucher, MSG_CENTER, CENTER_KEEPAWAY_PICKUP, toucher.netname);
+       Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_KEEPAWAY_PICKUP_SELF);
        sound(this.owner, CH_TRIGGER, SND_KA_PICKEDUP, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
 
        // scoring
-       PlayerScore_Add(other, SP_KEEPAWAY_PICKUPS, 1);
+       PlayerScore_Add(toucher, SP_KEEPAWAY_PICKUPS, 1);
 
        // waypoints
-       WaypointSprite_AttachCarrier(WP_KaBallCarrier, other, RADARICON_FLAGCARRIER);
-       other.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = ka_ballcarrier_waypointsprite_visible_for_player;
-       WaypointSprite_UpdateRule(other.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT);
-       WaypointSprite_Ping(other.waypointsprite_attachedforcarrier);
+       WaypointSprite_AttachCarrier(WP_KaBallCarrier, toucher, RADARICON_FLAGCARRIER);
+       toucher.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = ka_ballcarrier_waypointsprite_visible_for_player;
+       WaypointSprite_UpdateRule(toucher.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT);
+       WaypointSprite_Ping(toucher.waypointsprite_attachedforcarrier);
        WaypointSprite_Kill(this.waypointsprite_attachedforcarrier);
 }
 
@@ -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);
@@ -211,7 +211,7 @@ void ka_DropEvent(entity plyr) // runs any time that a player is supposed to los
        ka_EventLog("dropped", plyr);
        Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_KEEPAWAY_DROPPED, plyr.netname);
        Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_KEEPAWAY_DROPPED, plyr.netname);
-       sound(other, CH_TRIGGER, SND_KA_DROPPED, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
+       sound(NULL, CH_TRIGGER, SND_KA_DROPPED, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
 
        // scoring
        // PlayerScore_Add(plyr, SP_KEEPAWAY_DROPS, 1); Not anymore, this is 100% the same as pickups and is useless.
@@ -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 448a2bbc78c47d1d905de3a9d13910e71a987e74..1ffe6e60c07518e44d625b9551a7ac1db74db995 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;
@@ -505,7 +505,7 @@ void kh_Key_Collect(entity key, entity player)  //a player picks up a dropped ke
        kh_Key_AssignTo(key, player); // this also updates .kh_state
 }
 
-void kh_Key_Touch(entity this)  // runs many, many times when a key has been dropped and can be picked up
+void kh_Key_Touch(entity this, entity toucher)  // runs many, many times when a key has been dropped and can be picked up
 {
        if(intermission_running)
                return;
@@ -521,14 +521,14 @@ void kh_Key_Touch(entity this)  // runs many, many times when a key has been dro
                // maybe start a shorter countdown?
        }
 
-       if (!IS_PLAYER(other))
+       if (!IS_PLAYER(toucher))
                return;
-       if(IS_DEAD(other))
+       if(IS_DEAD(toucher))
                return;
-       if(other == this.enemy)
+       if(toucher == this.enemy)
                if(time < this.kh_droptime + autocvar_g_balance_keyhunt_delay_collect)
                        return;  // you just dropped it!
-       kh_Key_Collect(this, other);
+       kh_Key_Collect(this, toucher);
 }
 
 void kh_Key_Remove(entity key)  // runs after when all the keys have been collected or when a key has been dropped for more than X seconds
@@ -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);
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 787412908513449a6f5c28a81d4a47557ca95023..0c7c87c030644f24c062a06bd1a5158f05c788e4 100644 (file)
@@ -58,13 +58,14 @@ spawnfunc(tdm_team)
 }
 
 // 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(tdm_team);
+       entity this = new_pure(tdm_team);
        this.netname = teamname;
-       this.cnt = teamcolor;
+       this.cnt = teamcolor - 1;
+       this.team = teamcolor;
        this.spawnfunc_checked = true;
-       spawnfunc_tdm_team(this);
+       //spawnfunc_tdm_team(this);
 }
 
 void tdm_DelayedInit(entity this)
@@ -74,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..0a28f206d0b4cb8e0e9ceab1c0f9738903741b47 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;
 }
@@ -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 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 7d85eec7eb06714b95d51bb170d1919789c01a1f..6cb569149fb89be93781f550e3a242eb3cdfaf99 100644 (file)
@@ -249,7 +249,7 @@ float Portal_WillHitPlane(vector eorg, vector emins, vector emaxs, vector evel,
 #endif
 }
 
-void Portal_Touch(entity this)
+void Portal_Touch(entity this, entity toucher)
 {
        vector g;
 
@@ -258,18 +258,18 @@ void Portal_Touch(entity this)
        if(this.solid != SOLID_TRIGGER)
                return; // possibly engine bug
 
-       if(IS_PLAYER(other))
+       if(IS_PLAYER(toucher))
                return; // handled by think
 #endif
 
-       if(other.classname == "item_flag_team")
+       if(toucher.classname == "item_flag_team")
                return; // never portal these
 
-       if(other.classname == "grapplinghook")
+       if(toucher.classname == "grapplinghook")
                return; // handled by think
 
        if(!autocvar_g_vehicles_teleportable)
-       if(IS_VEHICLE(other))
+       if(IS_VEHICLE(toucher))
                return; // no teleporting vehicles?
 
        if(!this.enemy)
@@ -283,43 +283,43 @@ void Portal_Touch(entity this)
                return; // only handle impacts
 #endif
 
-       if(other.classname == "porto")
+       if(toucher.classname == "porto")
        {
-               if(other.portal_id == this.portal_id)
+               if(toucher.portal_id == this.portal_id)
                        return;
        }
        if(time < this.portal_activatetime)
-               if(other == this.aiment)
+               if(toucher == this.aiment)
                {
                        this.portal_activatetime = time + 0.1;
                        return;
                }
-       if(other != this.aiment)
-               if(IS_PLAYER(other))
-                       if(IS_INDEPENDENT_PLAYER(other) || IS_INDEPENDENT_PLAYER(this.aiment))
+       if(toucher != this.aiment)
+               if(IS_PLAYER(toucher))
+                       if(IS_INDEPENDENT_PLAYER(toucher) || IS_INDEPENDENT_PLAYER(this.aiment))
                                return; // cannot go through someone else's portal
-       if(other.aiment != this.aiment)
-               if(IS_PLAYER(other.aiment))
-                       if(IS_INDEPENDENT_PLAYER(other.aiment) || IS_INDEPENDENT_PLAYER(this.aiment))
+       if(toucher.aiment != this.aiment)
+               if(IS_PLAYER(toucher.aiment))
+                       if(IS_INDEPENDENT_PLAYER(toucher.aiment) || IS_INDEPENDENT_PLAYER(this.aiment))
                                return; // cannot go through someone else's portal
        fixedmakevectors(this.mangle);
        g = frametime * '0 0 -1' * autocvar_sv_gravity;
-       if(!Portal_WillHitPlane(other.origin, other.mins, other.maxs, other.velocity + g, this.origin, v_forward, this.maxs.x))
+       if(!Portal_WillHitPlane(toucher.origin, toucher.mins, toucher.maxs, toucher.velocity + g, this.origin, v_forward, this.maxs.x))
                return;
 
        /*
-       if(other.mins_x < PL_MIN.x || other.mins_y < PL_MIN.y || other.mins_z < PL_MIN.z
-       || other.maxs_x > PL_MAX.x || other.maxs_y > PL_MAX.y || other.maxs_z > PL_MAX.z)
+       if(toucher.mins_x < PL_MIN.x || toucher.mins_y < PL_MIN.y || toucher.mins_z < PL_MIN.z
+       || toucher.maxs_x > PL_MAX.x || toucher.maxs_y > PL_MAX.y || toucher.maxs_z > PL_MAX.z)
        {
                // can't teleport this
                return;
        }
        */
 
-       if(Portal_TeleportPlayer(this, other))
-               if(other.classname == "porto")
-                       if(other.effects & EF_RED)
-                               other.effects += EF_BLUE - EF_RED;
+       if(Portal_TeleportPlayer(this, toucher))
+               if(toucher.classname == "porto")
+                       if(toucher.effects & EF_RED)
+                               toucher.effects += EF_BLUE - EF_RED;
 }
 
 void Portal_Think(entity this);
@@ -494,15 +494,15 @@ void Portal_Think(entity this)
                Portal_Remove(this, 0);
 }
 
-float Portal_Customize(entity this)
+bool Portal_Customize(entity this, entity client)
 {
-       if(IS_SPEC(other))
-               other = other.enemy;
-       if(other == this.aiment)
+       if(IS_SPEC(client))
+               client = client.enemy;
+       if(client == this.aiment)
        {
                this.modelindex = this.savemodelindex;
        }
-       else if(IS_INDEPENDENT_PLAYER(other) || IS_INDEPENDENT_PLAYER(this.aiment))
+       else if(IS_INDEPENDENT_PLAYER(client) || IS_INDEPENDENT_PLAYER(this.aiment))
        {
                this.modelindex = 0;
        }
index c4e94cd13ddca230dd60a5bd766c522799c104d8..e32968c56d54e1f400bb0c8b6070c0738918836f 100644 (file)
@@ -698,10 +698,10 @@ void checkpoint_passed(entity this, entity player)
        }
 }
 
-void checkpoint_touch(entity this)
+void checkpoint_touch(entity this, entity toucher)
 {
-       EXACTTRIGGER_TOUCH;
-       checkpoint_passed(this, other);
+       EXACTTRIGGER_TOUCH(this, toucher);
+       checkpoint_passed(this, toucher);
 }
 
 void checkpoint_use(entity this, entity actor, entity trigger)
@@ -1092,13 +1092,13 @@ void race_ImposePenaltyTime(entity pl, float penalty, string reason)
        }
 }
 
-void penalty_touch(entity this)
+void penalty_touch(entity this, entity toucher)
 {
-       EXACTTRIGGER_TOUCH;
-       if(other.race_lastpenalty != this)
+       EXACTTRIGGER_TOUCH(this, toucher);
+       if(toucher.race_lastpenalty != this)
        {
-               other.race_lastpenalty = this;
-               race_ImposePenaltyTime(other, this.race_penalty, this.race_penalty_reason);
+               toucher.race_lastpenalty = this;
+               race_ImposePenaltyTime(toucher, this.race_penalty, this.race_penalty_reason);
        }
 }
 
index aa108dd985d9622e167a3db2649d08fec0dfc0d4..89815b71b132af3f5f3a9a122aec0defbf693c27 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");
 }
 
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 21112d93f3e55f1063723dcdc463b5b4c4f265b5..4be19b879d317ac5976bbe87f3c70cd7f1870e93 100644 (file)
@@ -252,16 +252,16 @@ vector Spawn_Score(entity this, entity spot, float mindist, float teamcheck)
        if(spot.target != "")
        {
                int found = 0;
-               FOREACH_ENTITY_STRING(targetname, spot.target,
+               for(entity targ = findchain(targetname, spot.target); targ; targ = targ.chain)
                {
                        ++found;
-                       if(it.spawn_evalfunc)
+                       if(targ.spawn_evalfunc)
                        {
-                               spawn_score = it.spawn_evalfunc(it, this, spot, spawn_score);
+                               spawn_score = targ.spawn_evalfunc(targ, this, spot, spawn_score);
                                if(spawn_score.x < 0)
                                        return spawn_score;
                        }
-               });
+               }
 
                if(!found)
                {
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 dc2019792b134bbf826f86ddf232f3402fdf70c3..a10edf45b4173a8a01df3b1632aa0578430ca027 100644 (file)
@@ -96,6 +96,7 @@ void CreatureFrame_Liquids(entity this)
 void CreatureFrame_FallDamage(entity this)
 {
        if(!IS_VEHICLE(this) && !(this.flags & FL_PROJECTILE)) // vehicles don't get falling damage
+       if(this.velocity || this.oldvelocity) // moving or has moved
        {
                // check for falling damage
                float velocity_len = vlen(this.velocity);
@@ -118,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;
@@ -152,7 +153,7 @@ 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 systems_update();
 void sys_phys_update(entity this, float dt);
@@ -165,7 +166,7 @@ void StartFrame()
        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;
@@ -368,6 +369,8 @@ LABEL(cvar_fail)
                return;
        }
 
+       this.move_movetype = this.movetype;
+
        // support special -1 and -2 angle from radiant
        if (this.angles == '0 -1 0')
                this.angles = '-90 0 0';
index e24a790a148a2cdebbe4bf3c40302178e6ee6adb..32024aec5f258fe6c0615652d4838b2bc7357b98 100644 (file)
@@ -10,7 +10,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 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 5c64a0ec64d3ff6e89f5d7f2efbf8d0ac7383355..6e7279618cc497a2b0ae99d6baa6785a112851bd 100644 (file)
@@ -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 77904aca5d0912713f3e1e57402d224f7473eb38..7c8061e94e02d24cfd2e08510983296e89ea0ee1 100644 (file)
@@ -40,10 +40,10 @@ float W_WeaponSpeedFactor(entity this)
 }
 
 
-bool CL_Weaponentity_CustomizeEntityForClient(entity this)
+bool CL_Weaponentity_CustomizeEntityForClient(entity this, entity client)
 {
        this.viewmodelforclient = this.owner;
-       if (IS_SPEC(other) && other.enemy == this.owner) this.viewmodelforclient = other;
+       if (IS_SPEC(client) && client.enemy == this.owner) this.viewmodelforclient = client;
        return true;
 }
 
@@ -391,7 +391,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
                        ;
@@ -408,6 +410,7 @@ bool forbidWeaponUse(entity player)
        if (time < game_starttime && !autocvar_sv_ready_restart_after_countdown) return true;
        if (round_handler_IsActive() && !round_handler_IsRoundStarted()) return true;
        if (player.player_blocked) return true;
+       if (gameover) return true;
        if (STAT(FROZEN, player)) return true;
        if (player.weapon_blocked) return true;
        return false;
index 822be77f722a64a13f84fb61c961322debbc854a..8df3e2a55883c619162445816cf69237b0210b91 100644 (file)
@@ -1,10 +1,7 @@
-fireball
+fireball_plasma
 {
-       {
-               map textures/fireball
-               tcgen environment
-       }
-       {
-               map $lightmap
-       }
+ {
+       map textures/fireball_plasma.tga
+       tcMod scroll 0.03 0.001
+ }
 }
index ab2d0c61125909fdebcd6abc316ca84529de83d8..b6ee3cd8ae597e31e38b5141b03724a036edb188 100644 (file)
@@ -423,3 +423,25 @@ g_uzi_luma
                blendfunc blend
        }
 }
+
+g_ok_hmg_luma
+{
+       deformVertexes autosprite
+       cull none
+       nopicmip
+       {
+               map models/weapons/g_ok_hmg_luma
+               blendfunc blend
+       }
+}
+
+g_ok_rl_luma
+{
+       deformVertexes autosprite
+       cull none
+       nopicmip
+       {
+               map models/weapons/g_ok_rl_luma
+               blendfunc blend
+       }
+}
index 92e9e5affd847cbdc578d8d41239ff7d3ba9c4d0..3a7d11eafe739237f63844571cb895614c38c7eb 100644 (file)
@@ -300,6 +300,32 @@ g_tuba_simple // tuba
        }
 }
 
+g_ok_hmg_simple // heavy machinegun
+{
+       deformVertexes autosprite
+       cull none
+       nopicmip
+
+       {
+               map models/weapons/g_ok_hmg_simple
+               blendfunc blend
+
+       }
+}
+
+g_ok_rl_simple // rocket propelled chainsaw
+{
+       deformVertexes autosprite
+       cull none
+       nopicmip
+
+       {
+               map models/weapons/g_ok_rl_simple
+               blendfunc blend
+
+       }
+}
+
 ////////// ARMOR + HEALTH ITEMS //////////
 
 ///// ARMOR /////
index 53b47a192cc15ed112834ccc703459006e1c0260..c631e8c880dc98a903d13d2683e7ef0dacd54cf6 100644 (file)
Binary files a/textures/fireball.tga and b/textures/fireball.tga differ
index 8cd8b25bdc50041f5a84b7519551802a32a5c3db..eaf50d0a2e63d8f4a51c8ff2f26fe4d33d158d1d 100644 (file)
Binary files a/textures/fireball_gloss.tga and b/textures/fireball_gloss.tga differ
index c949f92a47d69059cfdadd94a810b87785abadb0..358784d8fd784613e6766861f34404b496b92150 100644 (file)
Binary files a/textures/fireball_glow.tga and b/textures/fireball_glow.tga differ
diff --git a/textures/fireball_norm.tga b/textures/fireball_norm.tga
new file mode 100644 (file)
index 0000000..b0bd3f9
Binary files /dev/null and b/textures/fireball_norm.tga differ
diff --git a/textures/fireball_pants.tga b/textures/fireball_pants.tga
new file mode 100644 (file)
index 0000000..2fbc09a
Binary files /dev/null and b/textures/fireball_pants.tga differ
diff --git a/textures/fireball_shirt.tga b/textures/fireball_shirt.tga
new file mode 100644 (file)
index 0000000..3d93916
Binary files /dev/null and b/textures/fireball_shirt.tga differ
diff --git a/textures/items/a_rocket_bottom.jpg b/textures/items/a_rocket_bottom.jpg
new file mode 100644 (file)
index 0000000..b2db595
Binary files /dev/null and b/textures/items/a_rocket_bottom.jpg differ