From: Mario Date: Thu, 21 Jul 2016 16:21:06 +0000 (+1000) Subject: Merge branch 'master' into Mario/showspecs X-Git-Tag: xonotic-v0.8.2~750^2~5 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=c6ebaefab2aca7df4648dac3ccdd4b52de45d0ed;hp=8e0690ba978a6a0c7287bc3cfa2873a05b15fc5f Merge branch 'master' into Mario/showspecs --- diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3cdd43f305..7909c3286a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -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=9b2513f29762de886296f998ac8725c9 - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg | tee /dev/stderr | grep '^:' diff --git a/CMakeLists.txt b/CMakeLists.txt index c2b8564351..fdbce7d5ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ project(xonotic-data LANGUAGES ASM) include_directories(qcsrc) +add_definitions(-DXONOTIC=1) add_definitions(-DNDEBUG=1) find_package(Git REQUIRED) diff --git a/_hud_common.cfg b/_hud_common.cfg index bf8fe80b60..7bf9111cd4 100644 --- a/_hud_common.cfg +++ b/_hud_common.cfg @@ -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" @@ -111,9 +111,9 @@ seta hud_dynamic_follow_scale 0.01 "HUD following scale" seta hud_dynamic_follow_scale_xyz "1 1 1" "HUD following scale for the x, y and z axis" seta hud_dynamic_shake 1 "shake the HUD when hurt" -seta hud_dynamic_shake_damage_max 90 "damage value at which the HUD shake effect is maximum" +seta hud_dynamic_shake_damage_max 130 "damage value at which the HUD shake effect is maximum" seta hud_dynamic_shake_damage_min 10 "damage value at which the HUD shake effect is minimum" -seta hud_dynamic_shake_scale 0.4 "HUD shake scale" +seta hud_dynamic_shake_scale 0.2 "HUD shake scale" seta hud_showbinds 1 "what to show in the HUD to indicate certain keys to press: 0 display commands, 1 bound keys, 2 both" seta hud_showbinds_limit 2 "maximum number of bound keys to show for a command. 0 for unlimited" diff --git a/bal-wep-mario.cfg b/bal-wep-mario.cfg new file mode 100644 index 0000000000..9bfca55f37 --- /dev/null +++ b/bal-wep-mario.cfg @@ -0,0 +1,804 @@ +// {{{ #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 17 +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 8 +set g_balance_shotgun_primary_damage 6 +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 +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 1 +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 "" +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 40 +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.3 +set g_balance_electro_primary_midaircombo_radius 150 +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.04 +set g_balance_electro_secondary_touchexplode 0 +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 8 +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 1 +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 10 +set g_balance_crylink_secondary_edgedamage 5 +set g_balance_crylink_secondary_force -200 +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 5 +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 1 +set g_balance_vortex_charge_animlimit 0.5 +set g_balance_vortex_charge_limit 1 +set g_balance_vortex_charge_maxspeed 800 +set g_balance_vortex_charge_mindmg 50 +set g_balance_vortex_charge_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 80 +set g_balance_vortex_primary_damagefalloff_forcehalflife 0 +set g_balance_vortex_primary_damagefalloff_halflife 0 +set g_balance_vortex_primary_damagefalloff_maxdist 0 +set g_balance_vortex_primary_damagefalloff_mindist 0 +set g_balance_vortex_primary_force 450 +set g_balance_vortex_primary_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.2 +set g_balance_vortex_switchdelay_raise 0.2 +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 1 +set g_balance_hagar_secondary_load_speed 0.5 +set g_balance_hagar_secondary_load_spread 0.075 +set g_balance_hagar_secondary_load_spread_bias 0.5 +set g_balance_hagar_secondary_radius 80 +set g_balance_hagar_secondary_refire 0.5 +set g_balance_hagar_secondary_speed 2000 +set g_balance_hagar_secondary_spread 0.05 +set g_balance_hagar_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 450 +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 150 +set g_balance_devastator_refire 1.1 +set g_balance_devastator_reload_ammo 0 +set g_balance_devastator_reload_time 2 +set g_balance_devastator_remote_damage 70 +set g_balance_devastator_remote_edgedamage 35 +set g_balance_devastator_remote_force 400 +set g_balance_devastator_remote_jump_damage 70 +set g_balance_devastator_remote_jump_radius 0 +set g_balance_devastator_remote_jump_velocity_z_add 400 +set g_balance_devastator_remote_jump_velocity_z_max 1500 +set g_balance_devastator_remote_jump_velocity_z_min 400 +set g_balance_devastator_remote_radius 150 +set g_balance_devastator_speed 1200 +set g_balance_devastator_speedaccel 1200 +set g_balance_devastator_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_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 20 +set g_balance_shockwave_blast_distance 1000 +set g_balance_shockwave_blast_edgedamage 0 +set g_balance_shockwave_blast_force 200 +set g_balance_shockwave_blast_force_forwardbias 50 +set g_balance_shockwave_blast_force_zscale 2 +set g_balance_shockwave_blast_jump_damage 20 +set g_balance_shockwave_blast_jump_edgedamage 0 +set g_balance_shockwave_blast_jump_force 300 +set g_balance_shockwave_blast_jump_force_velocitybias 0 +set g_balance_shockwave_blast_jump_force_zscale 1.25 +set g_balance_shockwave_blast_jump_multiplier_accuracy 0.5 +set g_balance_shockwave_blast_jump_multiplier_distance 0.5 +set g_balance_shockwave_blast_jump_multiplier_min 0 +set g_balance_shockwave_blast_jump_radius 150 +set g_balance_shockwave_blast_multiplier_accuracy 0.5 +set g_balance_shockwave_blast_multiplier_distance 0.5 +set g_balance_shockwave_blast_multiplier_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 0 +set g_balance_shockwave_weaponstartoverride -1 +set g_balance_shockwave_weaponthrowable 0 +// }}} +// {{{ #20: Arc +set g_balance_arc_beam_ammo 4 +set g_balance_arc_beam_animtime 0.2 +set g_balance_arc_beam_botaimlifetime 0 +set g_balance_arc_beam_botaimspeed 0 +set g_balance_arc_beam_damage 115 +set g_balance_arc_beam_degreespersegment 1 +set g_balance_arc_beam_distancepersegment 0 +set g_balance_arc_beam_falloff_halflifedist 0 +set g_balance_arc_beam_falloff_maxdist 0 +set g_balance_arc_beam_falloff_mindist 0 +set g_balance_arc_beam_force 900 +set g_balance_arc_beam_healing_amax 100 +set g_balance_arc_beam_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_overheat_max 5 +set g_balance_arc_overheat_min 3 +set g_balance_arc_beam_heat 1 +set g_balance_arc_burst_heat 5 +set g_balance_arc_beam_maxangle 10 +set g_balance_arc_beam_nonplayerdamage 80 +set g_balance_arc_beam_range 1000 +set g_balance_arc_beam_refire 0.5 +set g_balance_arc_beam_returnspeed 8 +set g_balance_arc_beam_tightness 0.5 +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 +// }}} diff --git a/bal-wep-nexuiz25.cfg b/bal-wep-nexuiz25.cfg index 97707a7255..8a47e40d50 100644 --- a/bal-wep-nexuiz25.cfg +++ b/bal-wep-nexuiz25.cfg @@ -720,7 +720,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 // }}} diff --git a/balance-mario.cfg b/balance-mario.cfg new file mode 100644 index 0000000000..9995e5ec5c --- /dev/null +++ b/balance-mario.cfg @@ -0,0 +1,235 @@ +g_mod_balance Mario + +// {{{ starting gear +set g_balance_health_start 100 +set g_balance_armor_start 50 +set g_start_ammo_shells 20 +set g_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 20 +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.5 +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.07 +set g_balance_falldamage_maxdamage 250 +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 diff --git a/balance-nexuiz25.cfg b/balance-nexuiz25.cfg index 3ac47371ee..ebce2fabe7 100644 --- a/balance-nexuiz25.cfg +++ b/balance-nexuiz25.cfg @@ -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 diff --git a/balance-overkill.cfg b/balance-overkill.cfg index a691a19183..7571001c67 100644 --- a/balance-overkill.cfg +++ b/balance-overkill.cfg @@ -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 diff --git a/balance-samual.cfg b/balance-samual.cfg index 6d7831adac..58a0f37584 100644 --- a/balance-samual.cfg +++ b/balance-samual.cfg @@ -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 diff --git a/balance-xdf.cfg b/balance-xdf.cfg index 07b38e830a..ff2ec18716 100644 --- a/balance-xdf.cfg +++ b/balance-xdf.cfg @@ -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 diff --git a/balance-xonotic.cfg b/balance-xonotic.cfg index ddc40e288e..e9fb9994dd 100644 --- a/balance-xonotic.cfg +++ b/balance-xonotic.cfg @@ -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 diff --git a/balance-xpm.cfg b/balance-xpm.cfg index e0aa8b0827..0c24cf2067 100644 --- a/balance-xpm.cfg +++ b/balance-xpm.cfg @@ -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 diff --git a/binds-xonotic.cfg b/binds-xonotic.cfg index 361621c6a8..82ea7815e5 100644 --- a/binds-xonotic.cfg +++ b/binds-xonotic.cfg @@ -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 diff --git a/defaultXonotic.cfg b/defaultXonotic.cfg index c26d0c8ca0..1be91c72f2 100644 --- a/defaultXonotic.cfg +++ b/defaultXonotic.cfg @@ -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" @@ -978,6 +980,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 +1009,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 @@ -1193,6 +1199,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 +1297,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/models/items/a_rockets.md3 b/models/items/a_rockets.md3 index 61384b5fe7..3f1a594d06 100644 Binary files a/models/items/a_rockets.md3 and b/models/items/a_rockets.md3 differ diff --git a/models/player/erebus.iqm_1.skin b/models/player/erebus.iqm_1.skin new file mode 100644 index 0000000000..4597ceff1e --- /dev/null +++ b/models/player/erebus.iqm_1.skin @@ -0,0 +1,2 @@ +erebus,erebusfullbright +erebus.001,shadowhead diff --git a/models/player/erebus_lod1.iqm_1.skin b/models/player/erebus_lod1.iqm_1.skin new file mode 100644 index 0000000000..4597ceff1e --- /dev/null +++ b/models/player/erebus_lod1.iqm_1.skin @@ -0,0 +1,2 @@ +erebus,erebusfullbright +erebus.001,shadowhead diff --git a/models/player/erebus_lod2.iqm_1.skin b/models/player/erebus_lod2.iqm_1.skin new file mode 100644 index 0000000000..4597ceff1e --- /dev/null +++ b/models/player/erebus_lod2.iqm_1.skin @@ -0,0 +1,2 @@ +erebus,erebusfullbright +erebus.001,shadowhead diff --git a/models/player/gak.iqm_0.skin b/models/player/gak.iqm_0.skin new file mode 100644 index 0000000000..f2da16714c --- /dev/null +++ b/models/player/gak.iqm_0.skin @@ -0,0 +1,2 @@ +gak2.001,gakarmor +gak2,gak diff --git a/models/player/gak.iqm_1.skin b/models/player/gak.iqm_1.skin new file mode 100644 index 0000000000..3844f6ceb7 --- /dev/null +++ b/models/player/gak.iqm_1.skin @@ -0,0 +1,2 @@ +gak2.001,gakarmorfb +gak2,gakfullbright diff --git a/models/player/gak_lod1.iqm_0.skin b/models/player/gak_lod1.iqm_0.skin new file mode 100644 index 0000000000..f2da16714c --- /dev/null +++ b/models/player/gak_lod1.iqm_0.skin @@ -0,0 +1,2 @@ +gak2.001,gakarmor +gak2,gak diff --git a/models/player/gak_lod1.iqm_1.skin b/models/player/gak_lod1.iqm_1.skin new file mode 100644 index 0000000000..3844f6ceb7 --- /dev/null +++ b/models/player/gak_lod1.iqm_1.skin @@ -0,0 +1,2 @@ +gak2.001,gakarmorfb +gak2,gakfullbright diff --git a/models/player/gak_lod2.iqm_0.skin b/models/player/gak_lod2.iqm_0.skin new file mode 100644 index 0000000000..f2da16714c --- /dev/null +++ b/models/player/gak_lod2.iqm_0.skin @@ -0,0 +1,2 @@ +gak2.001,gakarmor +gak2,gak diff --git a/models/player/gak_lod2.iqm_1.skin b/models/player/gak_lod2.iqm_1.skin new file mode 100644 index 0000000000..3844f6ceb7 --- /dev/null +++ b/models/player/gak_lod2.iqm_1.skin @@ -0,0 +1,2 @@ +gak2.001,gakarmorfb +gak2,gakfullbright diff --git a/models/player/gakarmored.iqm_0.skin b/models/player/gakarmored.iqm_0.skin new file mode 100644 index 0000000000..1e8d3e9cfa --- /dev/null +++ b/models/player/gakarmored.iqm_0.skin @@ -0,0 +1,2 @@ +gak1.001,gak +gak1,gakarmor diff --git a/models/player/gakarmored.iqm_1.skin b/models/player/gakarmored.iqm_1.skin new file mode 100644 index 0000000000..3377bcb48e --- /dev/null +++ b/models/player/gakarmored.iqm_1.skin @@ -0,0 +1,2 @@ +gak1.001,gakfullbright +gak1,gakarmorfb diff --git a/models/player/gakarmored_lod1.iqm_0.skin b/models/player/gakarmored_lod1.iqm_0.skin new file mode 100644 index 0000000000..1e8d3e9cfa --- /dev/null +++ b/models/player/gakarmored_lod1.iqm_0.skin @@ -0,0 +1,2 @@ +gak1.001,gak +gak1,gakarmor diff --git a/models/player/gakarmored_lod1.iqm_1.skin b/models/player/gakarmored_lod1.iqm_1.skin new file mode 100644 index 0000000000..3377bcb48e --- /dev/null +++ b/models/player/gakarmored_lod1.iqm_1.skin @@ -0,0 +1,2 @@ +gak1.001,gakfullbright +gak1,gakarmorfb diff --git a/models/player/gakarmored_lod2.iqm_0.skin b/models/player/gakarmored_lod2.iqm_0.skin new file mode 100644 index 0000000000..1e8d3e9cfa --- /dev/null +++ b/models/player/gakarmored_lod2.iqm_0.skin @@ -0,0 +1,2 @@ +gak1.001,gak +gak1,gakarmor diff --git a/models/player/gakarmored_lod2.iqm_1.skin b/models/player/gakarmored_lod2.iqm_1.skin new file mode 100644 index 0000000000..3377bcb48e --- /dev/null +++ b/models/player/gakarmored_lod2.iqm_1.skin @@ -0,0 +1,2 @@ +gak1.001,gakfullbright +gak1,gakarmorfb diff --git a/models/player/gakmasked.iqm_0.skin b/models/player/gakmasked.iqm_0.skin new file mode 100644 index 0000000000..2df68ec5aa --- /dev/null +++ b/models/player/gakmasked.iqm_0.skin @@ -0,0 +1,2 @@ +gak3,gak +gak3.001,gakarmor diff --git a/models/player/gakmasked.iqm_1.skin b/models/player/gakmasked.iqm_1.skin new file mode 100644 index 0000000000..802db3e155 --- /dev/null +++ b/models/player/gakmasked.iqm_1.skin @@ -0,0 +1,2 @@ +gak3,gakfullbright +gak3.001,gakarmorfb diff --git a/models/player/gakmasked_lod1.iqm_0.skin b/models/player/gakmasked_lod1.iqm_0.skin new file mode 100644 index 0000000000..2df68ec5aa --- /dev/null +++ b/models/player/gakmasked_lod1.iqm_0.skin @@ -0,0 +1,2 @@ +gak3,gak +gak3.001,gakarmor diff --git a/models/player/gakmasked_lod1.iqm_1.skin b/models/player/gakmasked_lod1.iqm_1.skin new file mode 100644 index 0000000000..802db3e155 --- /dev/null +++ b/models/player/gakmasked_lod1.iqm_1.skin @@ -0,0 +1,2 @@ +gak3,gakfullbright +gak3.001,gakarmorfb diff --git a/models/player/gakmasked_lod2.iqm_0.skin b/models/player/gakmasked_lod2.iqm_0.skin new file mode 100644 index 0000000000..2df68ec5aa --- /dev/null +++ b/models/player/gakmasked_lod2.iqm_0.skin @@ -0,0 +1,2 @@ +gak3,gak +gak3.001,gakarmor diff --git a/models/player/gakmasked_lod2.iqm_1.skin b/models/player/gakmasked_lod2.iqm_1.skin new file mode 100644 index 0000000000..802db3e155 --- /dev/null +++ b/models/player/gakmasked_lod2.iqm_1.skin @@ -0,0 +1,2 @@ +gak3,gakfullbright +gak3.001,gakarmorfb diff --git a/models/player/ignis.iqm_0.skin b/models/player/ignis.iqm_0.skin new file mode 100644 index 0000000000..a0e69e9fc7 --- /dev/null +++ b/models/player/ignis.iqm_0.skin @@ -0,0 +1,2 @@ +ignis1,ignis +ignis1.001,ignishead diff --git a/models/player/ignis.iqm_1.skin b/models/player/ignis.iqm_1.skin new file mode 100644 index 0000000000..2c93e982f5 --- /dev/null +++ b/models/player/ignis.iqm_1.skin @@ -0,0 +1,2 @@ +ignis1,ignisfullbright +ignis1.001,ignishead diff --git a/models/player/ignis_lod1.iqm_0.skin b/models/player/ignis_lod1.iqm_0.skin new file mode 100644 index 0000000000..a0e69e9fc7 --- /dev/null +++ b/models/player/ignis_lod1.iqm_0.skin @@ -0,0 +1,2 @@ +ignis1,ignis +ignis1.001,ignishead diff --git a/models/player/ignis_lod1.iqm_1.skin b/models/player/ignis_lod1.iqm_1.skin new file mode 100644 index 0000000000..2c93e982f5 --- /dev/null +++ b/models/player/ignis_lod1.iqm_1.skin @@ -0,0 +1,2 @@ +ignis1,ignisfullbright +ignis1.001,ignishead diff --git a/models/player/ignis_lod2.iqm_0.skin b/models/player/ignis_lod2.iqm_0.skin new file mode 100644 index 0000000000..a0e69e9fc7 --- /dev/null +++ b/models/player/ignis_lod2.iqm_0.skin @@ -0,0 +1,2 @@ +ignis1,ignis +ignis1.001,ignishead diff --git a/models/player/ignis_lod2.iqm_1.skin b/models/player/ignis_lod2.iqm_1.skin new file mode 100644 index 0000000000..2c93e982f5 --- /dev/null +++ b/models/player/ignis_lod2.iqm_1.skin @@ -0,0 +1,2 @@ +ignis1,ignisfullbright +ignis1.001,ignishead diff --git a/models/player/ignishalfmasked.iqm_0.skin b/models/player/ignishalfmasked.iqm_0.skin new file mode 100644 index 0000000000..9523f9edba --- /dev/null +++ b/models/player/ignishalfmasked.iqm_0.skin @@ -0,0 +1,2 @@ +ignis1,ignis +ignis2.001,ignishead diff --git a/models/player/ignishalfmasked.iqm_1.skin b/models/player/ignishalfmasked.iqm_1.skin new file mode 100644 index 0000000000..89a0020284 --- /dev/null +++ b/models/player/ignishalfmasked.iqm_1.skin @@ -0,0 +1,2 @@ +ignis1,ignisfullbright +ignis2.001,ignishead diff --git a/models/player/ignishalfmasked_lod1.iqm_0.skin b/models/player/ignishalfmasked_lod1.iqm_0.skin new file mode 100644 index 0000000000..9523f9edba --- /dev/null +++ b/models/player/ignishalfmasked_lod1.iqm_0.skin @@ -0,0 +1,2 @@ +ignis1,ignis +ignis2.001,ignishead diff --git a/models/player/ignishalfmasked_lod1.iqm_1.skin b/models/player/ignishalfmasked_lod1.iqm_1.skin new file mode 100644 index 0000000000..89a0020284 --- /dev/null +++ b/models/player/ignishalfmasked_lod1.iqm_1.skin @@ -0,0 +1,2 @@ +ignis1,ignisfullbright +ignis2.001,ignishead diff --git a/models/player/ignishalfmasked_lod2.iqm_0.skin b/models/player/ignishalfmasked_lod2.iqm_0.skin new file mode 100644 index 0000000000..9523f9edba --- /dev/null +++ b/models/player/ignishalfmasked_lod2.iqm_0.skin @@ -0,0 +1,2 @@ +ignis1,ignis +ignis2.001,ignishead diff --git a/models/player/ignishalfmasked_lod2.iqm_1.skin b/models/player/ignishalfmasked_lod2.iqm_1.skin new file mode 100644 index 0000000000..89a0020284 --- /dev/null +++ b/models/player/ignishalfmasked_lod2.iqm_1.skin @@ -0,0 +1,2 @@ +ignis1,ignisfullbright +ignis2.001,ignishead diff --git a/models/player/ignismasked.iqm_0.skin b/models/player/ignismasked.iqm_0.skin new file mode 100644 index 0000000000..d46d1576ac --- /dev/null +++ b/models/player/ignismasked.iqm_0.skin @@ -0,0 +1,2 @@ +ignis1,ignis +ignis3,ignishead diff --git a/models/player/ignismasked.iqm_1.skin b/models/player/ignismasked.iqm_1.skin new file mode 100644 index 0000000000..eb257cc1d6 --- /dev/null +++ b/models/player/ignismasked.iqm_1.skin @@ -0,0 +1,2 @@ +ignis1,ignisfullbright +ignis3,ignishead diff --git a/models/player/ignismasked_lod1.iqm_0.skin b/models/player/ignismasked_lod1.iqm_0.skin new file mode 100644 index 0000000000..d46d1576ac --- /dev/null +++ b/models/player/ignismasked_lod1.iqm_0.skin @@ -0,0 +1,2 @@ +ignis1,ignis +ignis3,ignishead diff --git a/models/player/ignismasked_lod1.iqm_1.skin b/models/player/ignismasked_lod1.iqm_1.skin new file mode 100644 index 0000000000..eb257cc1d6 --- /dev/null +++ b/models/player/ignismasked_lod1.iqm_1.skin @@ -0,0 +1,2 @@ +ignis1,ignisfullbright +ignis3,ignishead diff --git a/models/player/ignismasked_lod2.iqm_0.skin b/models/player/ignismasked_lod2.iqm_0.skin new file mode 100644 index 0000000000..d46d1576ac --- /dev/null +++ b/models/player/ignismasked_lod2.iqm_0.skin @@ -0,0 +1,2 @@ +ignis1,ignis +ignis3,ignishead diff --git a/models/player/ignismasked_lod2.iqm_1.skin b/models/player/ignismasked_lod2.iqm_1.skin new file mode 100644 index 0000000000..eb257cc1d6 --- /dev/null +++ b/models/player/ignismasked_lod2.iqm_1.skin @@ -0,0 +1,2 @@ +ignis1,ignisfullbright +ignis3,ignishead diff --git a/models/player/nyx.iqm_0.skin b/models/player/nyx.iqm_0.skin new file mode 100644 index 0000000000..383252cb85 --- /dev/null +++ b/models/player/nyx.iqm_0.skin @@ -0,0 +1,2 @@ +nyx,nyx +nyx.001,shadowhead diff --git a/models/player/nyx.iqm_1.skin b/models/player/nyx.iqm_1.skin new file mode 100644 index 0000000000..19b5fd59b1 --- /dev/null +++ b/models/player/nyx.iqm_1.skin @@ -0,0 +1,2 @@ +nyx,nyxfullbright +nyx.001,shadowhead diff --git a/models/player/nyx_lod1.iqm_0.skin b/models/player/nyx_lod1.iqm_0.skin new file mode 100644 index 0000000000..383252cb85 --- /dev/null +++ b/models/player/nyx_lod1.iqm_0.skin @@ -0,0 +1,2 @@ +nyx,nyx +nyx.001,shadowhead diff --git a/models/player/nyx_lod1.iqm_1.skin b/models/player/nyx_lod1.iqm_1.skin new file mode 100644 index 0000000000..19b5fd59b1 --- /dev/null +++ b/models/player/nyx_lod1.iqm_1.skin @@ -0,0 +1,2 @@ +nyx,nyxfullbright +nyx.001,shadowhead diff --git a/models/player/nyx_lod2.iqm_0.skin b/models/player/nyx_lod2.iqm_0.skin new file mode 100644 index 0000000000..383252cb85 --- /dev/null +++ b/models/player/nyx_lod2.iqm_0.skin @@ -0,0 +1,2 @@ +nyx,nyx +nyx.001,shadowhead diff --git a/models/player/nyx_lod2.iqm_1.skin b/models/player/nyx_lod2.iqm_1.skin new file mode 100644 index 0000000000..19b5fd59b1 --- /dev/null +++ b/models/player/nyx_lod2.iqm_1.skin @@ -0,0 +1,2 @@ +nyx,nyxfullbright +nyx.001,shadowhead diff --git a/models/player/pyria.iqm_0.skin b/models/player/pyria.iqm_0.skin new file mode 100644 index 0000000000..1932354e80 --- /dev/null +++ b/models/player/pyria.iqm_0.skin @@ -0,0 +1,2 @@ +pyria_obj.001,pyriahair +pyria_obj,pyriafullbright diff --git a/models/player/pyria.iqm_1.skin b/models/player/pyria.iqm_1.skin new file mode 100644 index 0000000000..1932354e80 --- /dev/null +++ b/models/player/pyria.iqm_1.skin @@ -0,0 +1,2 @@ +pyria_obj.001,pyriahair +pyria_obj,pyriafullbright diff --git a/models/player/pyria_lod1.iqm_0.skin b/models/player/pyria_lod1.iqm_0.skin new file mode 100644 index 0000000000..1932354e80 --- /dev/null +++ b/models/player/pyria_lod1.iqm_0.skin @@ -0,0 +1,2 @@ +pyria_obj.001,pyriahair +pyria_obj,pyriafullbright diff --git a/models/player/pyria_lod1.iqm_1.skin b/models/player/pyria_lod1.iqm_1.skin new file mode 100644 index 0000000000..1932354e80 --- /dev/null +++ b/models/player/pyria_lod1.iqm_1.skin @@ -0,0 +1,2 @@ +pyria_obj.001,pyriahair +pyria_obj,pyriafullbright diff --git a/models/player/pyria_lod2.iqm_0.skin b/models/player/pyria_lod2.iqm_0.skin new file mode 100644 index 0000000000..1932354e80 --- /dev/null +++ b/models/player/pyria_lod2.iqm_0.skin @@ -0,0 +1,2 @@ +pyria_obj.001,pyriahair +pyria_obj,pyriafullbright diff --git a/models/player/pyria_lod2.iqm_1.skin b/models/player/pyria_lod2.iqm_1.skin new file mode 100644 index 0000000000..1932354e80 --- /dev/null +++ b/models/player/pyria_lod2.iqm_1.skin @@ -0,0 +1,2 @@ +pyria_obj.001,pyriahair +pyria_obj,pyriafullbright diff --git a/models/player/seraphina.iqm_0.skin b/models/player/seraphina.iqm_0.skin new file mode 100644 index 0000000000..a8ea4ee627 --- /dev/null +++ b/models/player/seraphina.iqm_0.skin @@ -0,0 +1,2 @@ +ignis42.001,seraphina +ignis42,ignis diff --git a/models/player/seraphina.iqm_1.skin b/models/player/seraphina.iqm_1.skin new file mode 100644 index 0000000000..cf702a3c2a --- /dev/null +++ b/models/player/seraphina.iqm_1.skin @@ -0,0 +1,2 @@ +ignis42.001,seraphina +ignis42,ignisfullbright diff --git a/models/player/seraphina_lod1.iqm_0.skin b/models/player/seraphina_lod1.iqm_0.skin new file mode 100644 index 0000000000..a8ea4ee627 --- /dev/null +++ b/models/player/seraphina_lod1.iqm_0.skin @@ -0,0 +1,2 @@ +ignis42.001,seraphina +ignis42,ignis diff --git a/models/player/seraphina_lod1.iqm_1.skin b/models/player/seraphina_lod1.iqm_1.skin new file mode 100644 index 0000000000..cf702a3c2a --- /dev/null +++ b/models/player/seraphina_lod1.iqm_1.skin @@ -0,0 +1,2 @@ +ignis42.001,seraphina +ignis42,ignisfullbright diff --git a/models/player/seraphina_lod2.iqm_0.skin b/models/player/seraphina_lod2.iqm_0.skin new file mode 100644 index 0000000000..a8ea4ee627 --- /dev/null +++ b/models/player/seraphina_lod2.iqm_0.skin @@ -0,0 +1,2 @@ +ignis42.001,seraphina +ignis42,ignis diff --git a/models/player/seraphina_lod2.iqm_1.skin b/models/player/seraphina_lod2.iqm_1.skin new file mode 100644 index 0000000000..cf702a3c2a --- /dev/null +++ b/models/player/seraphina_lod2.iqm_1.skin @@ -0,0 +1,2 @@ +ignis42.001,seraphina +ignis42,ignisfullbright diff --git a/models/player/seraphinamasked.iqm_0.skin b/models/player/seraphinamasked.iqm_0.skin new file mode 100644 index 0000000000..7b94ebe4a4 --- /dev/null +++ b/models/player/seraphinamasked.iqm_0.skin @@ -0,0 +1,2 @@ +ignis42,ignisfullbright +ignis42.002,ignishead diff --git a/models/player/seraphinamasked.iqm_1.skin b/models/player/seraphinamasked.iqm_1.skin new file mode 100644 index 0000000000..7b94ebe4a4 --- /dev/null +++ b/models/player/seraphinamasked.iqm_1.skin @@ -0,0 +1,2 @@ +ignis42,ignisfullbright +ignis42.002,ignishead diff --git a/models/player/seraphinamasked_lod1.iqm_0.skin b/models/player/seraphinamasked_lod1.iqm_0.skin new file mode 100644 index 0000000000..7b94ebe4a4 --- /dev/null +++ b/models/player/seraphinamasked_lod1.iqm_0.skin @@ -0,0 +1,2 @@ +ignis42,ignisfullbright +ignis42.002,ignishead diff --git a/models/player/seraphinamasked_lod1.iqm_1.skin b/models/player/seraphinamasked_lod1.iqm_1.skin new file mode 100644 index 0000000000..7b94ebe4a4 --- /dev/null +++ b/models/player/seraphinamasked_lod1.iqm_1.skin @@ -0,0 +1,2 @@ +ignis42,ignisfullbright +ignis42.002,ignishead diff --git a/models/player/seraphinamasked_lod2.iqm_0.skin b/models/player/seraphinamasked_lod2.iqm_0.skin new file mode 100644 index 0000000000..7b94ebe4a4 --- /dev/null +++ b/models/player/seraphinamasked_lod2.iqm_0.skin @@ -0,0 +1,2 @@ +ignis42,ignisfullbright +ignis42.002,ignishead diff --git a/models/player/seraphinamasked_lod2.iqm_1.skin b/models/player/seraphinamasked_lod2.iqm_1.skin new file mode 100644 index 0000000000..7b94ebe4a4 --- /dev/null +++ b/models/player/seraphinamasked_lod2.iqm_1.skin @@ -0,0 +1,2 @@ +ignis42,ignisfullbright +ignis42.002,ignishead diff --git a/models/player/umbra.iqm_0.skin b/models/player/umbra.iqm_0.skin new file mode 100644 index 0000000000..447eeadfc4 --- /dev/null +++ b/models/player/umbra.iqm_0.skin @@ -0,0 +1 @@ +umbra,umbra diff --git a/models/player/umbra.iqm_1.skin b/models/player/umbra.iqm_1.skin new file mode 100644 index 0000000000..cb9c3d0517 --- /dev/null +++ b/models/player/umbra.iqm_1.skin @@ -0,0 +1 @@ +umbra,umbrafullbright diff --git a/models/player/umbra_lod1.iqm_0.skin b/models/player/umbra_lod1.iqm_0.skin new file mode 100644 index 0000000000..447eeadfc4 --- /dev/null +++ b/models/player/umbra_lod1.iqm_0.skin @@ -0,0 +1 @@ +umbra,umbra diff --git a/models/player/umbra_lod1.iqm_1.skin b/models/player/umbra_lod1.iqm_1.skin new file mode 100644 index 0000000000..cb9c3d0517 --- /dev/null +++ b/models/player/umbra_lod1.iqm_1.skin @@ -0,0 +1 @@ +umbra,umbrafullbright diff --git a/models/player/umbra_lod2.iqm_0.skin b/models/player/umbra_lod2.iqm_0.skin new file mode 100644 index 0000000000..447eeadfc4 --- /dev/null +++ b/models/player/umbra_lod2.iqm_0.skin @@ -0,0 +1 @@ +umbra,umbra diff --git a/models/player/umbra_lod2.iqm_1.skin b/models/player/umbra_lod2.iqm_1.skin new file mode 100644 index 0000000000..cb9c3d0517 --- /dev/null +++ b/models/player/umbra_lod2.iqm_1.skin @@ -0,0 +1 @@ +umbra,umbrafullbright diff --git a/models/weapons/g_fireball.md3 b/models/weapons/g_fireball.md3 index c953426724..b1463090f7 100644 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 index 0000000000..a5cc3e602c 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 index 0000000000..2c77f8ec7e --- /dev/null +++ b/models/weapons/g_ok_hmg_luma.iqm_0.skin @@ -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 index 0000000000..5f8e135488 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 index 0000000000..a5cc3e602c 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 index 0000000000..f4316a52cd --- /dev/null +++ b/models/weapons/g_ok_hmg_simple.iqm_0.skin @@ -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 index 0000000000..c811a597e2 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 index 0000000000..a5cc3e602c 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 index 0000000000..502ff5b256 --- /dev/null +++ b/models/weapons/g_ok_rl_luma.iqm_0.skin @@ -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 index 0000000000..b2471c8ddd 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 index 0000000000..a5cc3e602c 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 index 0000000000..804fe521f0 --- /dev/null +++ b/models/weapons/g_ok_rl_simple.iqm_0.skin @@ -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 index 0000000000..53f1be5677 Binary files /dev/null and b/models/weapons/g_ok_rl_simple.tga differ diff --git a/models/weapons/h_fireball.iqm b/models/weapons/h_fireball.iqm index 40a6b06a83..3a9db00ced 100644 Binary files a/models/weapons/h_fireball.iqm and b/models/weapons/h_fireball.iqm differ diff --git a/models/weapons/v_fireball.md3 b/models/weapons/v_fireball.md3 index a5e847c37b..18fbf74890 100644 Binary files a/models/weapons/v_fireball.md3 and b/models/weapons/v_fireball.md3 differ diff --git a/notifications.cfg b/notifications.cfg index 2ee0a4084e..2409b83d68 100644 --- a/notifications.cfg +++ b/notifications.cfg @@ -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 diff --git a/qcsrc/.editorconfig b/qcsrc/.editorconfig new file mode 100644 index 0000000000..013c331e8a --- /dev/null +++ b/qcsrc/.editorconfig @@ -0,0 +1,7 @@ +root = true + +[*.{qc,qh,inc}] +end_of_line = lf +insert_final_newline = true +indent_style = tab +charset = utf-8 diff --git a/qcsrc/Makefile b/qcsrc/Makefile index ee335d9b00..0ed67281b4 100644 --- a/qcsrc/Makefile +++ b/qcsrc/Makefile @@ -7,6 +7,7 @@ WORKDIR ?= ../.tmp QCCFLAGS_WATERMARK ?= $(shell git describe --tags --dirty='~') VER = $(subst *,\*,$(QCCFLAGS_WATERMARK)) NDEBUG ?= 1 +XONOTIC ?= 1 BUILD_MOD ?= 0 ifndef ZIP @@ -30,6 +31,7 @@ QCCFLAGS_WTFS ?= \ -Wno-field-redeclared QCCDEFS ?= \ + -DXONOTIC=$(XONOTIC) \ -DWATERMARK="$(QCCFLAGS_WATERMARK)" \ -DNDEBUG=$(NDEBUG) \ -DBUILD_MOD=$(BUILD_MOD) \ diff --git a/qcsrc/client/autocvars.qh b/qcsrc/client/autocvars.qh index 18b3b78e6b..ec9ac10ae6 100644 --- a/qcsrc/client/autocvars.qh +++ b/qcsrc/client/autocvars.qh @@ -418,7 +418,7 @@ float autocvar_scoreboard_offset_left; float autocvar_scoreboard_offset_right; float autocvar_scoreboard_offset_vertical; float autocvar_scoreboard_respawntime_decimals; -float autocvar_scoreboard_dynamichud = 1; +bool autocvar_scoreboard_dynamichud = false; bool autocvar_v_flipped; float autocvar_vid_conheight; float autocvar_vid_conwidth; diff --git a/qcsrc/client/defs.qh b/qcsrc/client/defs.qh index 84bcb2b3d1..e62f0704f1 100644 --- a/qcsrc/client/defs.qh +++ b/qcsrc/client/defs.qh @@ -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; diff --git a/qcsrc/client/hud/hud.qc b/qcsrc/client/hud/hud.qc index c87cb5a89c..d575e8cb54 100644 --- a/qcsrc/client/hud/hud.qc +++ b/qcsrc/client/hud/hud.qc @@ -387,10 +387,10 @@ void HUD_Reset() HUD_Mod_CTF_Reset(); } -float autocvar_hud_dynamic_shake; -float autocvar_hud_dynamic_shake_damage_max; -float autocvar_hud_dynamic_shake_damage_min; -float autocvar_hud_dynamic_shake_scale; +float autocvar_hud_dynamic_shake = 1; +float autocvar_hud_dynamic_shake_damage_max = 130; +float autocvar_hud_dynamic_shake_damage_min = 10; +float autocvar_hud_dynamic_shake_scale = 0.2; float hud_dynamic_shake_x[10] = {0, 1, -0.7, 0.5, -0.3, 0.2, -0.1, 0.1, 0.0, 0}; float hud_dynamic_shake_y[10] = {0, 0.4, 0.8, -0.2, -0.6, 0.0, 0.3, 0.1, -0.1, 0}; bool Hud_Shake_Update() @@ -446,12 +446,15 @@ void Hud_Dynamic_Frame() if(autocvar_hud_dynamic_shake > 0) { + static float old_health = 0; + float health = max(-1, STAT(HEALTH)); if(hud_dynamic_shake_factor == -1) // don't allow the effect for this frame + { hud_dynamic_shake_factor = 0; + old_health = health; + } else { - static float old_health = 0; - float health = max(-1, STAT(HEALTH)); float new_hud_dynamic_shake_factor = 0; if (old_health - health >= autocvar_hud_dynamic_shake_damage_min && autocvar_hud_dynamic_shake_damage_max > autocvar_hud_dynamic_shake_damage_min @@ -490,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 diff --git a/qcsrc/client/hud/hud_config.qc b/qcsrc/client/hud/hud_config.qc index f45a052aa1..56a79364d4 100644 --- a/qcsrc/client/hud/hud_config.qc +++ b/qcsrc/client/hud/hud_config.qc @@ -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; diff --git a/qcsrc/client/hud/panel/centerprint.qc b/qcsrc/client/hud/panel/centerprint.qc index afda329838..e2e82acffe 100644 --- a/qcsrc/client/hud/panel/centerprint.qc +++ b/qcsrc/client/hud/panel/centerprint.qc @@ -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; diff --git a/qcsrc/client/hud/panel/chat.qc b/qcsrc/client/hud/panel/chat.qc index a27e7b9070..5817142ae6 100644 --- a/qcsrc/client/hud/panel/chat.qc +++ b/qcsrc/client/hud/panel/chat.qc @@ -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) { diff --git a/qcsrc/client/hud/panel/modicons.qc b/qcsrc/client/hud/panel/modicons.qc index 54c835831d..b869f96194 100644 --- a/qcsrc/client/hud/panel/modicons.qc +++ b/qcsrc/client/hud/panel/modicons.qc @@ -117,6 +117,7 @@ void HUD_Mod_CTF(vector pos, vector mySize) int redflag, blueflag, yellowflag, pinkflag, neutralflag; // current status float redflag_statuschange_elapsedtime = 0, blueflag_statuschange_elapsedtime = 0, yellowflag_statuschange_elapsedtime = 0, pinkflag_statuschange_elapsedtime = 0, neutralflag_statuschange_elapsedtime = 0; // time since the status changed bool ctf_oneflag; // one-flag CTF mode enabled/disabled + bool ctf_stalemate; // currently in stalemate int stat_items = STAT(CTF_FLAGSTATUS); float fs, fs2, fs3, size1, size2; vector e1, e2; @@ -129,6 +130,8 @@ void HUD_Mod_CTF(vector pos, vector mySize) ctf_oneflag = (stat_items & CTF_FLAG_NEUTRAL); + ctf_stalemate = (stat_items & CTF_STALEMATE); + mod_active = (redflag || blueflag || yellowflag || pinkflag || neutralflag || (stat_items & CTF_SHIELDED)); if (autocvar__hud_configure) { diff --git a/qcsrc/client/hud/panel/physics.qc b/qcsrc/client/hud/panel/physics.qc index 371a9f344b..5fc8c1ca90 100644 --- a/qcsrc/client/hud/panel/physics.qc +++ b/qcsrc/client/hud/panel/physics.qc @@ -1,5 +1,6 @@ #include "physics.qh" +#include #include #include @@ -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 ); diff --git a/qcsrc/client/hud/panel/quickmenu.qc b/qcsrc/client/hud/panel/quickmenu.qc index 08d97ffd2e..4cb5c9fd4e 100644 --- a/qcsrc/client/hud/panel/quickmenu.qc +++ b/qcsrc/client/hud/panel/quickmenu.qc @@ -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" diff --git a/qcsrc/client/hud/panel/radar.qc b/qcsrc/client/hud/panel/radar.qc index 1642e41891..ad0fa28f15 100644 --- a/qcsrc/client/hud/panel/radar.qc +++ b/qcsrc/client/hud/panel/radar.qc @@ -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))) @@ -350,8 +355,8 @@ void HUD_Radar() FOREACH_ENTITY_FLAGS(teamradar_icon, 0xFFFFFF, { 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)) diff --git a/qcsrc/client/hud/panel/vote.qc b/qcsrc/client/hud/panel/vote.qc index 89c784a108..d7d4d252be 100644 --- a/qcsrc/client/hud/panel/vote.qc +++ b/qcsrc/client/hud/panel/vote.qc @@ -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) { diff --git a/qcsrc/client/hud/panel/weapons.qc b/qcsrc/client/hud/panel/weapons.qc index 984cb4f505..a30006c263 100644 --- a/qcsrc/client/hud/panel/weapons.qc +++ b/qcsrc/client/hud/panel/weapons.qc @@ -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? diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index 57c08d7cd6..9637c98c55 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -700,6 +700,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; @@ -796,8 +798,8 @@ NET_HANDLE(ENT_CLIENT_SPAWNEVENT, bool is_new) // CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured. // The only parameter reflects if the entity is "new" to the client, meaning it just came into the client's PVS. -void CSQC_Ent_Update(bool isnew) -{ENGINE_EVENT(); +void CSQC_Ent_Update(entity this, bool isnew) +{ this.sourceLoc = __FILE__ ":" STR(__LINE__); int t = ReadByte(); @@ -841,6 +843,7 @@ void CSQC_Ent_Update(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; @@ -876,8 +879,8 @@ void Ent_Remove(entity this) // TODO possibly set more stuff to defaults } // CSQC_Ent_Remove : Called when the server requests a SSQC / CSQC entity to be removed. Essentially call remove(this) as well. -void CSQC_Ent_Remove() -{ENGINE_EVENT(); +void CSQC_Ent_Remove(entity this) +{ if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Ent_Remove() with this=%i {.entnum=%d, .enttype=%d}\n", this, this.entnum, this.enttype); if (wasfreed(this)) { @@ -999,6 +1002,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(); @@ -1087,16 +1126,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; diff --git a/qcsrc/client/main.qh b/qcsrc/client/main.qh index 65aad3e9f6..bc6b5afec0 100644 --- a/qcsrc/client/main.qh +++ b/qcsrc/client/main.qh @@ -147,3 +147,6 @@ int spectatorlist[MAX_SPECTATORS]; int framecount; .float health; + +float GetSpeedUnitFactor(int speed_unit); +string GetSpeedUnit(int speed_unit); diff --git a/qcsrc/client/miscfunctions.qc b/qcsrc/client/miscfunctions.qc index d3b3e46d73..01b0ee3cb4 100644 --- a/qcsrc/client/miscfunctions.qc +++ b/qcsrc/client/miscfunctions.qc @@ -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(); } diff --git a/qcsrc/client/mutators/events.qh b/qcsrc/client/mutators/events.qh index 9a2e8b1373..b72f7abe1a 100644 --- a/qcsrc/client/mutators/events.qh +++ b/qcsrc/client/mutators/events.qh @@ -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); diff --git a/qcsrc/client/player_skeleton.qc b/qcsrc/client/player_skeleton.qc index c8abdc6f57..85a798f3f4 100644 --- a/qcsrc/client/player_skeleton.qc +++ b/qcsrc/client/player_skeleton.qc @@ -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) diff --git a/qcsrc/client/progs.inc b/qcsrc/client/progs.inc index a736d32622..48579ecbb3 100644 --- a/qcsrc/client/progs.inc +++ b/qcsrc/client/progs.inc @@ -1,4 +1,7 @@ #include + +#if XONOTIC + #include "_all.qh" #include "../client/_mod.inc" @@ -20,6 +23,10 @@ #include #include +#endif + +#include + #if BUILD_MOD #include "../../mod/client/progs.inc" #endif diff --git a/qcsrc/client/scoreboard.qc b/qcsrc/client/scoreboard.qc index 2fb239ba10..b86e0d8f6a 100644 --- a/qcsrc/client/scoreboard.qc +++ b/qcsrc/client/scoreboard.qc @@ -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); diff --git a/qcsrc/client/shownames.qc b/qcsrc/client/shownames.qc index 6700ba61c7..165b033fb3 100644 --- a/qcsrc/client/shownames.qc +++ b/qcsrc/client/shownames.qc @@ -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; diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 5cb3c18c1f..4ca30d4a8d 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -447,7 +447,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; @@ -1369,8 +1369,8 @@ float prev_myteam; int lasthud; float vh_notice_time; void WaypointSprite_Load(); -void CSQC_UpdateView(float w, float h) -{ENGINE_EVENT(); +void CSQC_UpdateView(entity this, float w, float h) +{ TC(int, w); TC(int, h); entity e; float fov; diff --git a/qcsrc/client/weapons/projectile.qc b/qcsrc/client/weapons/projectile.qc index 6261fa842f..39032cd70d 100644 --- a/qcsrc/client/weapons/projectile.qc +++ b/qcsrc/client/weapons/projectile.qc @@ -16,7 +16,7 @@ .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.move_movetype = MOVETYPE_NONE; diff --git a/qcsrc/client/weapons/projectile.qh b/qcsrc/client/weapons/projectile.qh index 66e1be4707..27bca00c80 100644 --- a/qcsrc/client/weapons/projectile.qh +++ b/qcsrc/client/weapons/projectile.qh @@ -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); diff --git a/qcsrc/common/effects/all.qc b/qcsrc/common/effects/all.qc index e69a03f729..b6f378d472 100644 --- a/qcsrc/common/effects/all.qc +++ b/qcsrc/common/effects/all.qc @@ -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 diff --git a/qcsrc/common/effects/qc/casings.qc b/qcsrc/common/effects/qc/casings.qc index 605d42e671..308a7b2194 100644 --- a/qcsrc/common/effects/qc/casings.qc +++ b/qcsrc/common/effects/qc/casings.qc @@ -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) { diff --git a/qcsrc/common/effects/qc/gibs.qc b/qcsrc/common/effects/qc/gibs.qc index bc82b50d0c..b88a57f4d9 100644 --- a/qcsrc/common/effects/qc/gibs.qc +++ b/qcsrc/common/effects/qc/gibs.qc @@ -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. diff --git a/qcsrc/common/effects/qc/globalsound.qc b/qcsrc/common/effects/qc/globalsound.qc index a2653238e7..8c1ed1ca83 100644 --- a/qcsrc/common/effects/qc/globalsound.qc +++ b/qcsrc/common/effects/qc/globalsound.qc @@ -316,7 +316,7 @@ #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; @@ -334,9 +334,9 @@ 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; @@ -355,15 +355,15 @@ 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(); }); @@ -390,9 +390,9 @@ ? 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) @@ -415,15 +415,15 @@ 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; } diff --git a/qcsrc/common/effects/qc/globalsound.qh b/qcsrc/common/effects/qc/globalsound.qh index 44925cd510..640d330f1c 100644 --- a/qcsrc/common/effects/qc/globalsound.qh +++ b/qcsrc/common/effects/qc/globalsound.qh @@ -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 diff --git a/qcsrc/common/ent_cs.qc b/qcsrc/common/ent_cs.qc index cafef4868b..e69998563d 100644 --- a/qcsrc/common/ent_cs.qc +++ b/qcsrc/common/ent_cs.qc @@ -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) diff --git a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc index 46b4e03455..07479cc197 100644 --- a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc +++ b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc @@ -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; @@ -289,9 +289,9 @@ void ResetBall(entity this) } } -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,23 +357,23 @@ 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) @@ -609,11 +609,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 +729,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); @@ -838,7 +837,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 +847,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 +1072,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"; diff --git a/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc b/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc index 2c52982709..7d9c93d94c 100644 --- a/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc +++ b/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc @@ -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); } } @@ -776,9 +776,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) @@ -1083,13 +1082,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); } } @@ -1759,7 +1758,7 @@ MUTATOR_HOOKFUNCTION(ons, reset_map_global) FOREACH_CLIENT(IS_PLAYER(it), { it.ons_roundlost = false; it.ons_deathloc = '0 0 0'; - WITHSELF(it, PutClientInServer()); + PutClientInServer(it); }); return false; } diff --git a/qcsrc/common/items/item/pickup.qh b/qcsrc/common/items/item/pickup.qh index 08f7ff9c3d..6d91494818 100644 --- a/qcsrc/common/items/item/pickup.qh +++ b/qcsrc/common/items/item/pickup.qh @@ -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); } diff --git a/qcsrc/common/minigames/cl_minigames.qc b/qcsrc/common/minigames/cl_minigames.qc index 3d3ef42dff..1aa748faab 100644 --- a/qcsrc/common/minigames/cl_minigames.qc +++ b/qcsrc/common/minigames/cl_minigames.qc @@ -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 diff --git a/qcsrc/common/minigames/cl_minigames_hud.qc b/qcsrc/common/minigames/cl_minigames_hud.qc index f64ed44c84..c26109bfd3 100644 --- a/qcsrc/common/minigames/cl_minigames_hud.qc +++ b/qcsrc/common/minigames/cl_minigames_hud.qc @@ -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; diff --git a/qcsrc/common/minigames/sv_minigames.qc b/qcsrc/common/minigames/sv_minigames.qc index 689ce83d02..992eab054b 100644 --- a/qcsrc/common/minigames/sv_minigames.qc +++ b/qcsrc/common/minigames/sv_minigames.qc @@ -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; } diff --git a/qcsrc/common/minigames/sv_minigames.qh b/qcsrc/common/minigames/sv_minigames.qh index 70c9bf8058..de9e3f6961 100644 --- a/qcsrc/common/minigames/sv_minigames.qh +++ b/qcsrc/common/minigames/sv_minigames.qh @@ -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); diff --git a/qcsrc/common/models/model.qh b/qcsrc/common/models/model.qh index 1c34a2547e..91fb278ae0 100644 --- a/qcsrc/common/models/model.qh +++ b/qcsrc/common/models/model.qh @@ -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) diff --git a/qcsrc/common/monsters/monster/mage.qc b/qcsrc/common/monsters/monster/mage.qc index 44d7121fcd..46a9fb18e4 100644 --- a/qcsrc/common/monsters/monster/mage.qc +++ b/qcsrc/common/monsters/monster/mage.qc @@ -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); @@ -249,52 +249,51 @@ void M_Mage_Attack_Spike(entity this, vector dir) void M_Mage_Defend_Heal(entity this) { - entity head; float washealed = false; - for(head = findradius(this.origin, (autocvar_g_monster_mage_heal_range)); head; head = head.chain) if(M_Mage_Defend_Heal_Check(this, head)) + FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_monster_mage_heal_range, M_Mage_Defend_Heal_Check(this, it), { washealed = true; string fx = ""; - if(IS_PLAYER(head)) + if(IS_PLAYER(it)) { switch(this.skin) { case 0: - if(head.health < autocvar_g_balance_health_regenstable) head.health = bound(0, head.health + (autocvar_g_monster_mage_heal_allies), autocvar_g_balance_health_regenstable); + if(it.health < autocvar_g_balance_health_regenstable) it.health = bound(0, it.health + (autocvar_g_monster_mage_heal_allies), autocvar_g_balance_health_regenstable); fx = EFFECT_HEALING.eent_eff_name; break; case 1: - if(head.ammo_cells) head.ammo_cells = bound(head.ammo_cells, head.ammo_cells + 1, g_pickup_cells_max); - if(head.ammo_plasma) head.ammo_plasma = bound(head.ammo_plasma, head.ammo_plasma + 1, g_pickup_plasma_max); - if(head.ammo_rockets) head.ammo_rockets = bound(head.ammo_rockets, head.ammo_rockets + 1, g_pickup_rockets_max); - if(head.ammo_shells) head.ammo_shells = bound(head.ammo_shells, head.ammo_shells + 2, g_pickup_shells_max); - if(head.ammo_nails) head.ammo_nails = bound(head.ammo_nails, head.ammo_nails + 5, g_pickup_nails_max); + if(it.ammo_cells) it.ammo_cells = bound(it.ammo_cells, it.ammo_cells + 1, g_pickup_cells_max); + if(it.ammo_plasma) it.ammo_plasma = bound(it.ammo_plasma, it.ammo_plasma + 1, g_pickup_plasma_max); + if(it.ammo_rockets) it.ammo_rockets = bound(it.ammo_rockets, it.ammo_rockets + 1, g_pickup_rockets_max); + if(it.ammo_shells) it.ammo_shells = bound(it.ammo_shells, it.ammo_shells + 2, g_pickup_shells_max); + if(it.ammo_nails) it.ammo_nails = bound(it.ammo_nails, it.ammo_nails + 5, g_pickup_nails_max); fx = "ammoregen_fx"; break; case 2: - if(head.armorvalue < autocvar_g_balance_armor_regenstable) + if(it.armorvalue < autocvar_g_balance_armor_regenstable) { - head.armorvalue = bound(0, head.armorvalue + (autocvar_g_monster_mage_heal_allies), autocvar_g_balance_armor_regenstable); + it.armorvalue = bound(0, it.armorvalue + (autocvar_g_monster_mage_heal_allies), autocvar_g_balance_armor_regenstable); fx = "armorrepair_fx"; } break; case 3: - head.health = bound(0, head.health - ((head == this) ? (autocvar_g_monster_mage_heal_self) : (autocvar_g_monster_mage_heal_allies)), autocvar_g_balance_health_regenstable); + it.health = bound(0, it.health - ((it == this) ? (autocvar_g_monster_mage_heal_self) : (autocvar_g_monster_mage_heal_allies)), autocvar_g_balance_health_regenstable); fx = EFFECT_RAGE.eent_eff_name; break; } - Send_Effect_(fx, head.origin, '0 0 0', 1); + Send_Effect_(fx, it.origin, '0 0 0', 1); } else { - Send_Effect(EFFECT_HEALING, head.origin, '0 0 0', 1); - head.health = bound(0, head.health + (autocvar_g_monster_mage_heal_allies), head.max_health); - if(!(head.spawnflags & MONSTERFLAG_INVINCIBLE) && head.sprite) - WaypointSprite_UpdateHealth(head.sprite, head.health); + Send_Effect(EFFECT_HEALING, it.origin, '0 0 0', 1); + it.health = bound(0, it.health + (autocvar_g_monster_mage_heal_allies), it.max_health); + if(!(it.spawnflags & MONSTERFLAG_INVINCIBLE) && it.sprite) + WaypointSprite_UpdateHealth(it.sprite, it.health); } - } + }); if(washealed) { diff --git a/qcsrc/common/monsters/monster/shambler.qc b/qcsrc/common/monsters/monster/shambler.qc index 7a11b139e4..dd9a61d418 100644 --- a/qcsrc/common/monsters/monster/shambler.qc +++ b/qcsrc/common/monsters/monster/shambler.qc @@ -78,10 +78,8 @@ void M_Shambler_Attack_Swing(entity this) #include -void M_Shambler_Attack_Lightning_Explode(entity this) +void M_Shambler_Attack_Lightning_Explode(entity this, entity directhitentity) { - entity head; - sound(this, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_NORM); Send_Effect(EFFECT_ELECTRO_IMPACT, this.origin, '0 0 0', 1); @@ -93,13 +91,14 @@ void M_Shambler_Attack_Lightning_Explode(entity this) if(this.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); - for(head = findradius(this.origin, (autocvar_g_monster_shambler_attack_lightning_radius_zap)); head; head = head.chain) if(head != this.realowner) if(head.takedamage) + FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_monster_shambler_attack_lightning_radius_zap, it != this.realowner && it.takedamage, { - te_csqc_lightningarc(this.origin, head.origin); - Damage(head, this, this.realowner, (autocvar_g_monster_shambler_attack_lightning_damage_zap) * MONSTER_SKILLMOD(this), DEATH_MONSTER_SHAMBLER_ZAP.m_id, head.origin, '0 0 0'); - } + te_csqc_lightningarc(this.origin, it.origin); + Damage(it, this, this.realowner, (autocvar_g_monster_shambler_attack_lightning_damage_zap) * MONSTER_SKILLMOD(this), DEATH_MONSTER_SHAMBLER_ZAP.m_id, it.origin, '0 0 0'); + }); setthink(this, SUB_Remove); this.nextthink = time + 0.2; @@ -107,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) @@ -124,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) @@ -136,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; } } diff --git a/qcsrc/common/monsters/monster/spider.qc b/qcsrc/common/monsters/monster/spider.qc index 9338657082..b6d41dbb42 100644 --- a/qcsrc/common/monsters/monster/spider.qc +++ b/qcsrc/common/monsters/monster/spider.qc @@ -143,8 +143,10 @@ void M_Spider_Attack_Web_Explode(entity this) Send_Effect(EFFECT_ELECTRO_IMPACT, this.origin, '0 0 0', 1); RadiusDamage(this, this.realowner, 0, 0, 25, NULL, NULL, 25, this.projectiledeathtype, NULL); - for(entity e = findradius(this.origin, 25); e; e = e.chain) if(e != this) if(e.takedamage && !IS_DEAD(e)) if(e.health > 0) if(e.monsterid != MON_SPIDER.monsterid) - e.spider_slowness = time + (autocvar_g_monster_spider_attack_web_damagetime); + FOREACH_ENTITY_RADIUS(this.origin, 25, it != this && it.takedamage && !IS_DEAD(it) && it.health > 0 && it.monsterid != MON_SPIDER.monsterid, + { + it.spider_slowness = time + (autocvar_g_monster_spider_attack_web_damagetime); + }); remove(this); } @@ -155,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); } diff --git a/qcsrc/common/monsters/monster/wyvern.qc b/qcsrc/common/monsters/monster/wyvern.qc index 001b2e24d8..345d6459cd 100644 --- a/qcsrc/common/monsters/monster/wyvern.qc +++ b/qcsrc/common/monsters/monster/wyvern.qc @@ -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)) @@ -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); } diff --git a/qcsrc/common/monsters/monster/zombie.qc b/qcsrc/common/monsters/monster/zombie.qc index 1eafd4bfd1..fd270a1e1e 100644 --- a/qcsrc/common/monsters/monster/zombie.qc +++ b/qcsrc/common/monsters/monster/zombie.qc @@ -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; } diff --git a/qcsrc/common/monsters/sv_monsters.qc b/qcsrc/common/monsters/sv_monsters.qc index c0a15e97b1..005f128b9b 100644 --- a/qcsrc/common/monsters/sv_monsters.qc +++ b/qcsrc/common/monsters/sv_monsters.qc @@ -123,29 +123,26 @@ entity Monster_FindTarget(entity mon) { if(MUTATOR_CALLHOOK(MonsterFindTarget)) { return mon.enemy; } // Handled by a mutator - entity head, closest_target = NULL; - head = findradius(mon.origin, mon.target_range); + entity closest_target = NULL; - while(head) // find the closest acceptable target to pass to + // find the closest acceptable target to pass to + FOREACH_ENTITY_RADIUS(mon.origin, mon.target_range, it.monster_attack, { - if(head.monster_attack) - if(Monster_ValidTarget(mon, head)) + if(Monster_ValidTarget(mon, it)) { // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc) - vector head_center = CENTER_OR_VIEWOFS(head); + vector head_center = CENTER_OR_VIEWOFS(it); vector ent_center = CENTER_OR_VIEWOFS(mon); if(closest_target) { vector closest_target_center = CENTER_OR_VIEWOFS(closest_target); if(vlen2(ent_center - head_center) < vlen2(ent_center - closest_target_center)) - { closest_target = head; } + { closest_target = it; } } - else { closest_target = head; } + else { closest_target = it; } } - - head = head.chain; - } + }); return closest_target; } @@ -341,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; } @@ -394,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; @@ -466,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) diff --git a/qcsrc/common/monsters/sv_monsters.qh b/qcsrc/common/monsters/sv_monsters.qh index f8501fc758..ffade7b6a2 100644 --- a/qcsrc/common/monsters/sv_monsters.qh +++ b/qcsrc/common/monsters/sv_monsters.qh @@ -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); diff --git a/qcsrc/common/mutators/base.qh b/qcsrc/common/mutators/base.qh index 4d92b5d405..c1f7501c9b 100644 --- a/qcsrc/common/mutators/base.qh +++ b/qcsrc/common/mutators/base.qh @@ -120,9 +120,10 @@ ENDCLASS(CallbackChain) void RegisterHooks() {}; void RegisterCallbacks() {}; -#define _MUTATOR_HOOKABLE(id, ...) CallbackChain HOOK_##id; bool __Mutator_Send_##id(__VA_ARGS__) -#define MUTATOR_HOOKABLE(id, params) \ - _MUTATOR_HOOKABLE(id, int params(_MUTATOR_HANDLE_PARAMS, _MUTATOR_HANDLE_NOP)) { \ +#define MUTATOR_HOOKABLE(id, params) _MUTATOR_HOOKABLE(id, params) +#define _MUTATOR_HOOKABLE(id, params) \ + CallbackChain HOOK_##id; \ + bool __Mutator_Send_##id(int params(_MUTATOR_HANDLE_PARAMS, _MUTATOR_HANDLE_NOP)) { \ params(_MUTATOR_HANDLE_PUSHTMP, _MUTATOR_HANDLE_NOP) \ params(_MUTATOR_HANDLE_PREPARE, _MUTATOR_HANDLE_NOP) \ bool ret = CallbackChain_Call(HOOK_##id); \ @@ -132,10 +133,12 @@ void RegisterCallbacks() {}; return ret; \ } \ [[accumulate]] void RegisterHooks() { HOOK_##id = NEW(CallbackChain, #id); } + +#define MUTATOR_CALLHOOK(id, ...) _MUTATOR_CALLHOOK(id, __VA_ARGS__) #ifdef __STDC__ - #define MUTATOR_CALLHOOK(id, ...) APPLY(__Mutator_Send_##id, 0 P99_IF_EMPTY(__VA_ARGS__)()(, __VA_ARGS__)) + #define _MUTATOR_CALLHOOK(id, ...) APPLY(__Mutator_Send_##id, 0 P99_IF_EMPTY(__VA_ARGS__)()(, __VA_ARGS__)) #else - #define MUTATOR_CALLHOOK(id, ...) APPLY(__Mutator_Send_##id, 0, ##__VA_ARGS__) + #define _MUTATOR_CALLHOOK(id, ...) APPLY(__Mutator_Send_##id, 0, ##__VA_ARGS__) #endif enum { diff --git a/qcsrc/common/mutators/mutator/buffs/buffs.qc b/qcsrc/common/mutators/mutator/buffs/buffs.qc index ec1fadabe5..921cd03cd3 100644 --- a/qcsrc/common/mutators/mutator/buffs/buffs.qc +++ b/qcsrc/common/mutators/mutator/buffs/buffs.qc @@ -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; @@ -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; @@ -626,6 +626,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerSpawn) entity player = M_ARGV(0, entity); player.buffs = 0; + player.buff_time = 0; // reset timers here to prevent them continuing after re-spawn player.buff_disability_time = 0; player.buff_disability_effect_time = 0; @@ -708,6 +709,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerUseKey, CBC_ORDER_FIRST) Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid); player.buffs = 0; + player.buff_time = 0; // already notified sound(player, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM); return true; } @@ -870,9 +872,12 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) // 2: notify carrier as well int buff_lost = 0; - if(player.buff_time) + if(player.buff_time && player.buffs) if(time >= player.buff_time) + { + player.buff_time = 0; buff_lost = 2; + } if(STAT(FROZEN, player)) { buff_lost = 1; } @@ -881,12 +886,13 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) if(player.buffs) { int buffid = buff_FirstFromFlags(player.buffs).m_id; - Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid); - if(buff_lost >= 2) + if(buff_lost == 2) { Send_Notification(NOTIF_ONE, player, MSG_MULTI, ITEM_BUFF_DROP, buffid); // TODO: special timeout message? sound(player, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM); } + else + Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid); player.buffs = 0; } } @@ -904,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); } }); } diff --git a/qcsrc/common/mutators/mutator/damagetext/damagetext.qc b/qcsrc/common/mutators/mutator/damagetext/damagetext.qc index 2a1795d63c..3cca0d9d11 100644 --- a/qcsrc/common/mutators/mutator/damagetext/damagetext.qc +++ b/qcsrc/common/mutators/mutator/damagetext/damagetext.qc @@ -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,9 +81,10 @@ 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); } ENDCLASS(DamageText) @@ -111,6 +122,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 +136,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 +150,7 @@ NET_HANDLE(damagetext, bool isNew) } } } - NEW(DamageText, group, location, health, armor, deathtype); + NEW(DamageText, group, location, health, armor, deathtype, friendlyfire); } } #endif @@ -174,6 +190,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 diff --git a/qcsrc/common/mutators/mutator/dodging/dodging.qc b/qcsrc/common/mutators/mutator/dodging/dodging.qc index 0d20ff7af8..64312727e4 100644 --- a/qcsrc/common/mutators/mutator/dodging/dodging.qc +++ b/qcsrc/common/mutators/mutator/dodging/dodging.qc @@ -226,7 +226,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 diff --git a/qcsrc/common/mutators/mutator/nades/nades.qc b/qcsrc/common/mutators/mutator/nades/nades.qc index 1d5a8c37b3..fd9a4226a7 100644 --- a/qcsrc/common/mutators/mutator/nades/nades.qc +++ b/qcsrc/common/mutators/mutator/nades/nades.qc @@ -426,16 +426,13 @@ void nade_ice_think(entity this) float current_freeze_time = this.ltime - time - 0.1; - entity e; - for(e = findradius(this.origin, autocvar_g_nades_nade_radius); e; e = e.chain) - if(e != this) - if(!autocvar_g_nades_ice_teamcheck || (DIFF_TEAM(e, this.realowner) || e == this.realowner)) - if(e.takedamage && !IS_DEAD(e)) - if(e.health > 0) - if(!e.revival_time || ((time - e.revival_time) >= 1.5)) - if(!STAT(FROZEN, e)) - if(current_freeze_time > 0) - nade_ice_freeze(this, e, current_freeze_time); + FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_nades_nade_radius, it != this && it.takedamage && !IS_DEAD(it) && it.health > 0 && current_freeze_time > 0, + { + if(!autocvar_g_nades_ice_teamcheck || (DIFF_TEAM(it, this.realowner) || it == this.realowner)) + if(!it.revival_time || ((time - it.revival_time) >= 1.5)) + if(!STAT(FROZEN, it)) + nade_ice_freeze(this, it, current_freeze_time); + }); } void nade_ice_boom(entity this) @@ -562,35 +559,35 @@ 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); + UpdateCSQCProjectile(toucher); #elif defined(CSQC) - other.move_velocity = other.move_velocity * pow(autocvar_g_nades_entrap_strength, pushdeltatime); + toucher.move_velocity = toucher.move_velocity * pow(autocvar_g_nades_entrap_strength, pushdeltatime); #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; } @@ -604,43 +601,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; } @@ -759,22 +756,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; @@ -795,7 +792,7 @@ void nade_touch(entity this) return; } - PROJECTILE_TOUCH(this); + PROJECTILE_TOUCH(this, toucher); //setsize(this, '-2 -2 -2', '2 2 2'); //UpdateCSQCProjectile(this); @@ -805,7 +802,7 @@ void nade_touch(entity this) return; } - this.enemy = other; + this.enemy = toucher; nade_boom(this); } @@ -1002,10 +999,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; diff --git a/qcsrc/common/mutators/mutator/overkill/hmg.qc b/qcsrc/common/mutators/mutator/overkill/hmg.qc index e0ae539318..b8fd743098 100644 --- a/qcsrc/common/mutators/mutator/overkill/hmg.qc +++ b/qcsrc/common/mutators/mutator/overkill/hmg.qc @@ -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); diff --git a/qcsrc/common/mutators/mutator/overkill/rpc.qc b/qcsrc/common/mutators/mutator/overkill/rpc.qc index 90c671a609..b14b6bce49 100644 --- a/qcsrc/common/mutators/mutator/overkill/rpc.qc +++ b/qcsrc/common/mutators/mutator/overkill/rpc.qc @@ -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) diff --git a/qcsrc/common/mutators/mutator/physical_items/physical_items.qc b/qcsrc/common/mutators/mutator/physical_items/physical_items.qc index 10ec0cf5a8..6e4bfa5661 100644 --- a/qcsrc/common/mutators/mutator/physical_items/physical_items.qc +++ b/qcsrc/common/mutators/mutator/physical_items/physical_items.qc @@ -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()) diff --git a/qcsrc/common/mutators/mutator/sandbox/sandbox.qc b/qcsrc/common/mutators/mutator/sandbox/sandbox.qc index bc4cb67752..973ff3151c 100644 --- a/qcsrc/common/mutators/mutator/sandbox/sandbox.qc +++ b/qcsrc/common/mutators/mutator/sandbox/sandbox.qc @@ -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)) @@ -142,25 +142,23 @@ void sandbox_ObjectAttach_Remove(entity e) { // detaches any object attached to e - entity head; - for(head = NULL; (head = find(head, classname, "object")); ) + FOREACH_ENTITY_ENT(owner, e, { - if(head.owner == e) - { - vector org; - org = gettaginfo(head, 0); - setattachment(head, NULL, ""); - head.owner = NULL; - - // objects change origin and angles when detached, so apply previous position - setorigin(head, org); - head.angles = e.angles; // don't allow detached objects to spin or roll - - head.solid = head.old_solid; // restore persisted solidity - head.movetype = head.old_movetype; // restore persisted physics - head.takedamage = DAMAGE_AIM; - } - } + if(it.classname != "object") continue; + + vector org; + org = gettaginfo(it, 0); + setattachment(it, NULL, ""); + it.owner = NULL; + + // objects change origin and angles when detached, so apply previous position + setorigin(it, org); + 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 + it.takedamage = DAMAGE_AIM; + }); } entity sandbox_ObjectSpawn(entity this, float database) @@ -462,7 +460,7 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand) switch(argv(1)) { entity e; - float i; + int j; string s; // ---------------- COMMAND: HELP ---------------- @@ -704,8 +702,8 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand) if(e.material) strunzone(e.material); if(argv(3)) { - for (i = 1; i <= 5; i++) // precache material sounds, 5 in total - precache_sound(strcat("object/impact_", argv(3), "_", ftos(i), ".wav")); + for (j = 1; j <= 5; j++) // precache material sounds, 5 in total + precache_sound(strcat("object/impact_", argv(3), "_", ftos(j), ".wav")); e.material = strzone(argv(3)); } else @@ -783,20 +781,18 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand) case "attachments": // this should show the same info as 'mesh' but for attachments s = ""; - entity head; - i = 0; - for(head = NULL; (head = find(head, classname, "object")); ) + j = 0; + FOREACH_ENTITY_ENT(owner, e, { - if(head.owner == e) - { - ++i; // start from 1 - gettaginfo(e, head.tag_index); - s = strcat(s, "^1attachment ", ftos(i), "^7 has mesh \"^3", head.model, "^7\" at animation frame ^3", ftos(head.frame)); - s = strcat(s, "^7 and is attached to bone \"^5", gettaginfo_name, "^7\", "); - } - } - if(i) // object contains attachments - print_to(player, strcat("^2SANDBOX - INFO: ^7Object contains the following ^1", ftos(i), "^7 attachment(s): ", s)); + if(it.classname != "object") continue; + + ++j; // start from 1 + gettaginfo(e, it.tag_index); + s = strcat(s, "^1attachment ", ftos(j), "^7 has mesh \"^3", it.model, "^7\" at animation frame ^3", ftos(it.frame)); + s = strcat(s, "^7 and is attached to bone \"^5", gettaginfo_name, "^7\", "); + }); + if(j) // object contains attachments + print_to(player, strcat("^2SANDBOX - INFO: ^7Object contains the following ^1", ftos(j), "^7 attachment(s): ", s)); else print_to(player, "^2SANDBOX - INFO: ^7Object contains no attachments"); return true; diff --git a/qcsrc/common/mutators/mutator/waypoints/all.inc b/qcsrc/common/mutators/mutator/waypoints/all.inc index c74715ea71..0fb3d6139c 100644 --- a/qcsrc/common/mutators/mutator/waypoints/all.inc +++ b/qcsrc/common/mutators/mutator/waypoints/all.inc @@ -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); diff --git a/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc b/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc index 5fdb7ec428..56c4c5b5da 100644 --- a/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc +++ b/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc @@ -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); @@ -225,6 +227,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; } @@ -963,17 +966,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); diff --git a/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qh b/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qh index 7fb578f824..fa9f4fbdf6 100644 --- a/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qh +++ b/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qh @@ -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); diff --git a/qcsrc/common/net_notice.qc b/qcsrc/common/net_notice.qc index 1e1726ae45..20d1351ebc 100644 --- a/qcsrc/common/net_notice.qc +++ b/qcsrc/common/net_notice.qc @@ -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 } diff --git a/qcsrc/common/notifications/all.inc b/qcsrc/common/notifications/all.inc index 42cf6a2149..4ffa885beb 100644 --- a/qcsrc/common/notifications/all.inc +++ b/qcsrc/common/notifications/all.inc @@ -546,6 +546,7 @@ 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!"), "") diff --git a/qcsrc/common/physics/movetypes/follow.qc b/qcsrc/common/physics/movetypes/follow.qc index 2d3e24f44c..421c0e73f6 100644 --- a/qcsrc/common/physics/movetypes/follow.qc +++ b/qcsrc/common/physics/movetypes/follow.qc @@ -1,31 +1,29 @@ void _Movetype_Physics_Follow(entity this) // SV_Physics_Follow { - entity e = this.move_aiment; // TODO: networking? + entity e = this.aiment; - // LordHavoc: implemented rotation on MOVETYPE_FOLLOW objects - if(this.move_angles == this.move_punchangle) + if(e.angles == this.punchangle) { - this.move_origin = e.move_origin + this.view_ofs; + this.move_origin = e.origin + this.view_ofs; } else { vector ang, v; - ang_x = -this.move_punchangle_x; - ang_y = this.move_punchangle_y; - ang_z = this.move_punchangle_z; + ang_x = -this.punchangle_x; + ang_y = this.punchangle_y; + ang_z = this.punchangle_z; makevectors(ang); v_x = this.view_ofs_x * v_forward_x + this.view_ofs_y * v_right_x + this.view_ofs_z * v_up_x; v_y = this.view_ofs_x * v_forward_y + this.view_ofs_y * v_right_y + this.view_ofs_z * v_up_y; v_z = this.view_ofs_x * v_forward_z + this.view_ofs_y * v_right_z + this.view_ofs_z * v_up_z; - ang_x = -e.move_angles_x; - ang_y = e.move_angles_y; - ang_z = e.move_angles_z; + 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.move_origin_x; - this.move_origin_x = v_x * v_right_x + v_y * v_right_y + v_z * v_right_z + e.move_origin_y; - this.move_origin_x = v_x * v_up_x + v_y * v_up_y + v_z * v_up_z + e.move_origin_z; + 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.move_angles = e.move_angles + this.v_angle; + this.move_angles = e.angles + this.v_angle; _Movetype_LinkEdict(this, false); } diff --git a/qcsrc/common/physics/movetypes/movetypes.qc b/qcsrc/common/physics/movetypes/movetypes.qc index eee217200f..78429dda97 100644 --- a/qcsrc/common/physics/movetypes/movetypes.qc +++ b/qcsrc/common/physics/movetypes/movetypes.qc @@ -315,25 +315,11 @@ void _Movetype_CheckWaterTransition(entity ent) // SV_CheckWaterTransition 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,15 +327,11 @@ 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; @@ -360,11 +342,9 @@ void _Movetype_LinkEdict_TouchAreaGrid(entity this) // SV_LinkEdict_TouchAreaGr 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 @@ -620,8 +600,8 @@ void _Movetype_Physics_ClientFrame(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.move_origin = this.move_origin + movedt * this.move_velocity; + this.move_angles = this.move_angles + movedt * this.move_avelocity; _Movetype_LinkEdict(this, false); break; case MOVETYPE_STEP: diff --git a/qcsrc/common/physics/movetypes/movetypes.qh b/qcsrc/common/physics/movetypes/movetypes.qh index 61b7e94a95..09b6e4d96d 100644 --- a/qcsrc/common/physics/movetypes/movetypes.qh +++ b/qcsrc/common/physics/movetypes/movetypes.qh @@ -8,7 +8,7 @@ .float move_ltime; .void(entity this) move_think; .float move_nextthink; -.void(entity this) move_blocked; +.void(entity this, entity blocker) move_blocked; .float move_movetype; .float move_time; @@ -24,8 +24,8 @@ .float move_bounce_stopspeed; .float move_nomonsters; // -1 for MOVE_NORMAL, otherwise a MOVE_ constant -.entity move_aiment; -.vector move_punchangle; +.entity aiment; +.vector punchangle; // should match sv_gameplayfix_fixedcheckwatertransition float autocvar_cl_gameplayfix_fixedcheckwatertransition = 1; diff --git a/qcsrc/common/physics/movetypes/push.qc b/qcsrc/common/physics/movetypes/push.qc index 0d03bfff8f..5a0426edce 100644 --- a/qcsrc/common/physics/movetypes/push.qc +++ b/qcsrc/common/physics/movetypes/push.qc @@ -148,7 +148,6 @@ void _Movetype_Physics_Pusher(entity this, float dt) // SV_Physics_Pusher { this.move_nextthink = 0; this.move_time = time; - other = NULL; this.move_think(this); } } diff --git a/qcsrc/common/physics/movetypes/toss.qc b/qcsrc/common/physics/movetypes/toss.qc index f515a75f9f..5bea38c5b8 100644 --- a/qcsrc/common/physics/movetypes/toss.qc +++ b/qcsrc/common/physics/movetypes/toss.qc @@ -23,13 +23,19 @@ 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) * 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.move_velocity_z -= (((this.gravity) ? this.gravity : 1) * PHYS_GRAVITY(this) * dt); } this.move_angles = this.move_angles + this.move_avelocity * dt; @@ -108,8 +114,8 @@ void _Movetype_Physics_Toss(entity this, float dt) // SV_Physics_Toss 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 && !(this.move_flags & FL_ONGROUND)) + // this.move_velocity_z -= 0.5 * dt * (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this); _Movetype_CheckWaterTransition(this); } diff --git a/qcsrc/common/physics/player.qc b/qcsrc/common/physics/player.qc index 5079bd9761..36c5bdad40 100644 --- a/qcsrc/common/physics/player.qc +++ b/qcsrc/common/physics/player.qc @@ -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) \ @@ -541,7 +541,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 +781,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 +802,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 } @@ -1012,11 +1013,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 @@ -1330,6 +1335,9 @@ void PM_Main(entity this) if (this.PlayerPhysplug) if (this.PlayerPhysplug(this)) return; +#elif defined(CSQC) + if(hud != HUD_NORMAL) + return; // no vehicle prediction (yet) #endif #ifdef SVQC @@ -1546,13 +1554,10 @@ LABEL(end) } #if defined(SVQC) -void SV_PlayerPhysics() +void SV_PlayerPhysics(entity this) #elif defined(CSQC) void CSQC_ClientMovement_PlayerMove_Frame(entity this) #endif { -#ifdef SVQC - ENGINE_EVENT(); -#endif PM_Main(this); } diff --git a/qcsrc/common/physics/player.qh b/qcsrc/common/physics/player.qh index fd1b610de6..de76bb8d8c 100644 --- a/qcsrc/common/physics/player.qh +++ b/qcsrc/common/physics/player.qh @@ -67,6 +67,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) diff --git a/qcsrc/common/sounds/sound.qh b/qcsrc/common/sounds/sound.qh index 90b2758aca..519f910b0d 100644 --- a/qcsrc/common/sounds/sound.qh +++ b/qcsrc/common/sounds/sound.qh @@ -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) diff --git a/qcsrc/common/state.qc b/qcsrc/common/state.qc index 0ffe55eb4f..7c6882088d 100644 --- a/qcsrc/common/state.qc +++ b/qcsrc/common/state.qc @@ -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); diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh index 2c471f0db3..2ed679e30f 100644 --- a/qcsrc/common/stats.qh +++ b/qcsrc/common/stats.qh @@ -227,6 +227,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) diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc index a0255d7d61..e722c96c6d 100644 --- a/qcsrc/common/t_items.qc +++ b/qcsrc/common/t_items.qc @@ -761,7 +761,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 +774,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 +797,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 +812,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); @@ -825,15 +825,15 @@ LABEL(pickup) if(this.team) { RandomSelection_Init(); - for(entity head = NULL; (head = findfloat(head, team, this.team)); ) + FOREACH_ENTITY_FLAGS(flags, FL_ITEM, { - if(head.flags & FL_ITEM) - if(head.classname != "item_flag_team" && head.classname != "item_key_team") + if(it.team == this.team) + if(it.classname != "item_flag_team" && it.classname != "item_key_team") { - Item_Show(head, -1); - RandomSelection_Add(head, 0, string_null, head.cnt, 0); + Item_Show(it, -1); + RandomSelection_Add(it, 0, string_null, it.cnt, 0); } - } + }); e = RandomSelection_chosen_ent; } @@ -1421,11 +1421,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 +1434,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 +1449,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 +1467,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 +1541,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 +1766,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; }); diff --git a/qcsrc/common/t_items.qh b/qcsrc/common/t_items.qh index 5ebc9d7e62..1ed807c7c1 100644 --- a/qcsrc/common/t_items.qh +++ b/qcsrc/common/t_items.qh @@ -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); diff --git a/qcsrc/common/triggers/func/button.qc b/qcsrc/common/triggers/func/button.qc index a8ec50a865..b186066e60 100644 --- a/qcsrc/common/triggers/func/button.qc +++ b/qcsrc/common/triggers/func/button.qc @@ -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); } diff --git a/qcsrc/common/triggers/func/conveyor.qc b/qcsrc/common/triggers/func/conveyor.qc index e2335b8831..ab4cc12d5a 100644 --- a/qcsrc/common/triggers/func/conveyor.qc +++ b/qcsrc/common/triggers/func/conveyor.qc @@ -8,47 +8,46 @@ void conveyor_think(entity this) this.move_time = time; if(dt <= 0) { return; } #endif - entity e; // set mythis as current conveyor where possible - for(e = NULL; (e = findentity(e, conveyor, this)); ) - e.conveyor = NULL; + FOREACH_ENTITY_ENT(conveyor, this, + { + it.conveyor = NULL; + }); if(this.state) { - for(e = findradius((this.absmin + this.absmax) * 0.5, vlen(this.absmax - this.absmin) * 0.5 + 1); e; e = e.chain) - if(!e.conveyor.state) - if(isPushable(e)) - { - vector emin = e.absmin; - vector emax = e.absmax; - if(this.solid == SOLID_BSP) - { - emin -= '1 1 1'; - emax += '1 1 1'; - } - if(boxesoverlap(emin, emax, this.absmin, this.absmax)) // quick - if(WarpZoneLib_BoxTouchesBrush(emin, emax, this, e)) // accurate - e.conveyor = this; - } - - for(e = NULL; (e = findentity(e, conveyor, this)); ) + FOREACH_ENTITY_RADIUS((this.absmin + this.absmax) * 0.5, vlen(this.absmax - this.absmin) * 0.5 + 1, !it.conveyor.state && isPushable(it), + { + vector emin = it.absmin; + vector emax = it.absmax; + if(this.solid == SOLID_BSP) + { + emin -= '1 1 1'; + emax += '1 1 1'; + } + if(boxesoverlap(emin, emax, this.absmin, this.absmax)) // quick + if(WarpZoneLib_BoxTouchesBrush(emin, emax, this, it)) // accurate + it.conveyor = this; + }); + + FOREACH_ENTITY_ENT(conveyor, this, { - if(IS_CLIENT(e)) // doing it via velocity has quite some advantages + if(IS_CLIENT(it)) // doing it via velocity has quite some advantages continue; // done in SV_PlayerPhysics continue; - setorigin(e, e.origin + this.movedir * PHYS_INPUT_FRAMETIME); - move_out_of_solid(e); + setorigin(it, it.origin + this.movedir * PHYS_INPUT_FRAMETIME); + move_out_of_solid(it); #ifdef SVQC - UpdateCSQCProjectile(e); + UpdateCSQCProjectile(it); #endif /* // stupid conveyor code - tracebox(e.origin, e.mins, e.maxs, e.origin + this.movedir * sys_frametime, MOVE_NORMAL, e); + tracebox(it.origin, it.mins, it.maxs, it.origin + this.movedir * sys_frametime, MOVE_NORMAL, it); if(trace_fraction > 0) - setorigin(e, trace_endpos); + setorigin(it, trace_endpos); */ - } + }); } #ifdef SVQC diff --git a/qcsrc/common/triggers/func/door.qc b/qcsrc/common/triggers/func/door.qc index f32a8d75de..2b3decf64f 100644 --- a/qcsrc/common/triggers/func/door.qc +++ b/qcsrc/common/triggers/func/door.qc @@ -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) diff --git a/qcsrc/common/triggers/func/door_secret.qc b/qcsrc/common/triggers/func/door_secret.qc index f02fc61f64..600949fe5c 100644 --- a/qcsrc/common/triggers/func/door_secret.qc +++ b/qcsrc/common/triggers/func/door_secret.qc @@ -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); } } diff --git a/qcsrc/common/triggers/func/ladder.qc b/qcsrc/common/triggers/func/ladder.qc index af5065643b..ae9160dfda 100644 --- a/qcsrc/common/triggers/func/ladder.qc +++ b/qcsrc/common/triggers/func/ladder.qc @@ -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 diff --git a/qcsrc/common/triggers/func/rainsnow.qc b/qcsrc/common/triggers/func/rainsnow.qc index dc569f69a1..265d45e0a9 100644 --- a/qcsrc/common/triggers/func/rainsnow.qc +++ b/qcsrc/common/triggers/func/rainsnow.qc @@ -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) diff --git a/qcsrc/common/triggers/platforms.qc b/qcsrc/common/triggers/platforms.qc index c089039a60..c1f481f8af 100644 --- a/qcsrc/common/triggers/platforms.qc +++ b/qcsrc/common/triggers/platforms.qc @@ -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 } @@ -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 @@ -139,23 +139,23 @@ void plat_trigger_use(entity this, entity actor, entity trigger) } -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 diff --git a/qcsrc/common/triggers/platforms.qh b/qcsrc/common/triggers/platforms.qh index 6bdfb23d68..f0727be3ca 100644 --- a/qcsrc/common/triggers/platforms.qh +++ b/qcsrc/common/triggers/platforms.qh @@ -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; diff --git a/qcsrc/common/triggers/target/music.qc b/qcsrc/common/triggers/target/music.qc index d43cbec769..7abcd67403 100644 --- a/qcsrc/common/triggers/target/music.qc +++ b/qcsrc/common/triggers/target/music.qc @@ -71,13 +71,13 @@ spawnfunc(target_music) } void TargetMusic_RestoreGame() { - for(entity e = NULL; (e = find(e, classname, "target_music")); ) + FOREACH_ENTITY_CLASS("target_music", true, { - if(e.targetname == "") - target_music_sendto(e, MSG_INIT, 1); + if(it.targetname == "") + target_music_sendto(it, MSG_INIT, 1); else - target_music_sendto(e, MSG_INIT, 0); - } + target_music_sendto(it, MSG_INIT, 0); + }); } // values: // volume diff --git a/qcsrc/common/triggers/target/spawn.qc b/qcsrc/common/triggers/target/spawn.qc index eced856d7e..bc5271040c 100644 --- a/qcsrc/common/triggers/target/spawn.qc +++ b/qcsrc/common/triggers/target/spawn.qc @@ -287,8 +287,10 @@ void target_spawn_use(entity this, entity actor, entity trigger) else { // edit entity - for(entity e = NULL; (e = find(e, targetname, this.target)); ) - target_spawn_useon(e, this, actor, trigger); + FOREACH_ENTITY_STRING(targetname, this.target, + { + target_spawn_useon(it, this, actor, trigger); + }); } } diff --git a/qcsrc/common/triggers/teleporters.qc b/qcsrc/common/triggers/teleporters.qc index ba472ac557..20f618aa24 100644 --- a/qcsrc/common/triggers/teleporters.qc +++ b/qcsrc/common/triggers/teleporters.qc @@ -187,21 +187,21 @@ entity Simple_TeleportPlayer(entity teleporter, entity player) else { RandomSelection_Init(); - for(e = NULL; (e = find(e, targetname, teleporter.target)); ) + FOREACH_ENTITY_STRING(targetname, teleporter.target, { p = 1; if(STAT(TELEPORT_TELEFRAG_AVOID, player)) { #ifdef SVQC - locout = e.origin + '0 0 1' * (1 - player.mins.z - 24); + locout = it.origin + '0 0 1' * (1 - player.mins.z - 24); #elif defined(CSQC) - locout = e.origin + '0 0 1' * (1 - player.mins.z - 24); + locout = it.origin + '0 0 1' * (1 - player.mins.z - 24); #endif if(check_tdeath(player, locout, '0 0 0', '0 0 0')) p = 0; } - RandomSelection_Add(e, 0, string_null, (e.cnt ? e.cnt : 1), p); - } + RandomSelection_Add(it, 0, string_null, (it.cnt ? it.cnt : 1), p); + }); e = RandomSelection_chosen_ent; } diff --git a/qcsrc/common/triggers/teleporters.qh b/qcsrc/common/triggers/teleporters.qh index ef47b0c6c8..c0f45f263d 100644 --- a/qcsrc/common/triggers/teleporters.qh +++ b/qcsrc/common/triggers/teleporters.qh @@ -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); diff --git a/qcsrc/common/triggers/trigger/gravity.qc b/qcsrc/common/triggers/trigger/gravity.qc index 9dcc710f03..cef8cb8bbe 100644 --- a/qcsrc/common/triggers/trigger/gravity.qc +++ b/qcsrc/common/triggers/trigger/gravity.qc @@ -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); } } diff --git a/qcsrc/common/triggers/trigger/heal.qc b/qcsrc/common/triggers/trigger/heal.qc index 41519e20cc..5a2bc78de8 100644 --- a/qcsrc/common/triggers/trigger/heal.qc +++ b/qcsrc/common/triggers/trigger/heal.qc @@ -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); } } } diff --git a/qcsrc/common/triggers/trigger/hurt.qc b/qcsrc/common/triggers/trigger/hurt.qc index 92a4dd0299..4579fd7524 100644 --- a/qcsrc/common/triggers/trigger/hurt.qc +++ b/qcsrc/common/triggers/trigger/hurt.qc @@ -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'); } } diff --git a/qcsrc/common/triggers/trigger/impulse.qc b/qcsrc/common/triggers/trigger/impulse.qc index 91381f4877..3d9a87a465 100644 --- a/qcsrc/common/triggers/trigger/impulse.qc +++ b/qcsrc/common/triggers/trigger/impulse.qc @@ -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) @@ -22,9 +22,9 @@ void trigger_impulse_touch1(entity this) } #ifdef SVQC - str = min(this.radius, vlen(this.origin - other.origin)); + str = min(this.radius, vlen(this.origin - toucher.origin)); #elif defined(CSQC) - str = min(this.radius, vlen(this.origin - other.move_origin)); + str = min(this.radius, vlen(this.origin - toucher.move_origin)); #endif if(this.falloff == 1) @@ -34,75 +34,75 @@ 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); + float addspeed = str - toucher.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); + toucher.move_velocity += accelspeed * normalize(targ.origin - this.origin); } #endif } else #ifdef SVQC - other.velocity = other.velocity + normalize(targ.origin - this.origin) * str * pushdeltatime; + toucher.velocity = toucher.velocity + normalize(targ.origin - this.origin) * str * pushdeltatime; #elif defined(CSQC) - other.move_velocity = other.move_velocity + normalize(targ.origin - this.origin) * str * pushdeltatime; + toucher.move_velocity = toucher.move_velocity + normalize(targ.origin - this.origin) * str * pushdeltatime; #endif #ifdef SVQC - UNSET_ONGROUND(other); + UNSET_ONGROUND(toucher); - UpdateCSQCProjectile(other); + UpdateCSQCProjectile(toucher); #elif defined(CSQC) - other.move_flags &= ~FL_ONGROUND; + toucher.move_flags &= ~FL_ONGROUND; #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); + UpdateCSQCProjectile(toucher); #elif defined(CSQC) - other.move_velocity = other.move_velocity * pow(this.strength, pushdeltatime); + toucher.move_velocity = toucher.move_velocity * pow(this.strength, pushdeltatime); #endif } // Spherical (gravity/repulsor) mode -void trigger_impulse_touch3(entity this) +void trigger_impulse_touch3(entity this, entity toucher) { float pushdeltatime; float str; @@ -110,22 +110,22 @@ 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)); + str = min(this.radius, vlen(this.origin - toucher.origin)); #elif defined(CSQC) - str = min(this.radius, vlen(this.origin - other.move_origin)); + str = min(this.radius, vlen(this.origin - toucher.move_origin)); #endif if(this.falloff == 1) @@ -136,11 +136,11 @@ void trigger_impulse_touch3(entity this) 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); + UpdateCSQCProjectile(toucher); #elif defined(CSQC) - other.move_velocity = other.move_velocity + normalize(other.move_origin - this.origin) * str * pushdeltatime; + toucher.move_velocity = toucher.move_velocity + normalize(toucher.move_origin - this.origin) * str * pushdeltatime; #endif } diff --git a/qcsrc/common/triggers/trigger/jumppads.qc b/qcsrc/common/triggers/trigger/jumppads.qc index 8100f6b797..88f785f39e 100644 --- a/qcsrc/common/triggers/trigger/jumppads.qc +++ b/qcsrc/common/triggers/trigger/jumppads.qc @@ -129,24 +129,24 @@ 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); + toucher.move_velocity = toucher.velocity; } else if(this.target && this.target != "") { @@ -159,105 +159,105 @@ 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); + toucher.move_velocity = toucher.velocity; } else { - other.velocity = this.movedir; - other.move_velocity = other.velocity; + toucher.velocity = this.movedir; + toucher.move_velocity = toucher.velocity; } #ifdef SVQC - UNSET_ONGROUND(other); + UNSET_ONGROUND(toucher); #elif defined(CSQC) - other.move_flags &= ~FL_ONGROUND; + toucher.move_flags &= ~FL_ONGROUND; - if (other.flags & FL_PROJECTILE) + if (toucher.flags & FL_PROJECTILE) { - other.move_angles = vectoangles (other.move_velocity); - switch(other.move_movetype) + toucher.move_angles = vectoangles (toucher.move_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); - switch(other.movetype) + toucher.angles = vectoangles (toucher.velocity); + switch(toucher.movetype) { case MOVETYPE_FLY: - other.movetype = MOVETYPE_TOSS; - other.gravity = 1; + toucher.movetype = MOVETYPE_TOSS; + toucher.gravity = 1; break; case MOVETYPE_BOUNCEMISSILE: - other.movetype = MOVETYPE_BOUNCE; - other.gravity = 1; + toucher.movetype = 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) diff --git a/qcsrc/common/triggers/trigger/jumppads.qh b/qcsrc/common/triggers/trigger/jumppads.qh index 4e8bf1809f..e03f14d335 100644 --- a/qcsrc/common/triggers/trigger/jumppads.qh +++ b/qcsrc/common/triggers/trigger/jumppads.qh @@ -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); diff --git a/qcsrc/common/triggers/trigger/keylock.qc b/qcsrc/common/triggers/trigger/keylock.qc index 1333978768..2cc81e597c 100644 --- a/qcsrc/common/triggers/trigger/keylock.qc +++ b/qcsrc/common/triggers/trigger/keylock.qc @@ -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); diff --git a/qcsrc/common/triggers/trigger/multi.qc b/qcsrc/common/triggers/trigger/multi.qc index 14d7fda04b..b801e9f4f3 100644 --- a/qcsrc/common/triggers/trigger/multi.qc +++ b/qcsrc/common/triggers/trigger/multi.qc @@ -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); } diff --git a/qcsrc/common/triggers/trigger/secret.qc b/qcsrc/common/triggers/trigger/secret.qc index bf4178beae..b54f99dcd4 100644 --- a/qcsrc/common/triggers/trigger/secret.qc +++ b/qcsrc/common/triggers/trigger/secret.qc @@ -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); } diff --git a/qcsrc/common/triggers/trigger/swamp.qc b/qcsrc/common/triggers/trigger/swamp.qc index fb792b94bb..0f8d1a73ee 100644 --- a/qcsrc/common/triggers/trigger/swamp.qc +++ b/qcsrc/common/triggers/trigger/swamp.qc @@ -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) diff --git a/qcsrc/common/triggers/trigger/teleport.qc b/qcsrc/common/triggers/trigger/teleport.qc index 8ee6b7a697..484daeedf9 100644 --- a/qcsrc/common/triggers/trigger/teleport.qc +++ b/qcsrc/common/triggers/trigger/teleport.qc @@ -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 } diff --git a/qcsrc/common/turrets/sv_turrets.qc b/qcsrc/common/turrets/sv_turrets.qc index 57bb008fcd..1f8450f395 100644 --- a/qcsrc/common/turrets/sv_turrets.qc +++ b/qcsrc/common/turrets/sv_turrets.qc @@ -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); } diff --git a/qcsrc/common/turrets/targettrigger.qc b/qcsrc/common/turrets/targettrigger.qc index 15dbaec4f0..62ed2fb722 100644 --- a/qcsrc/common/turrets/targettrigger.qc +++ b/qcsrc/common/turrets/targettrigger.qc @@ -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; } diff --git a/qcsrc/common/turrets/turret/walker.qc b/qcsrc/common/turrets/turret/walker.qc index 1a5c3f09ab..0294952767 100644 --- a/qcsrc/common/turrets/turret/walker.qc +++ b/qcsrc/common/turrets/turret/walker.qc @@ -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; @@ -253,7 +258,7 @@ void walker_fire_rocket(entity this, vector org) rocket.movetype = 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; diff --git a/qcsrc/common/vehicles/sv_vehicles.qc b/qcsrc/common/vehicles/sv_vehicles.qc index a797f84c8d..fc2a062413 100644 --- a/qcsrc/common/vehicles/sv_vehicles.qc +++ b/qcsrc/common/vehicles/sv_vehicles.qc @@ -1,45 +1,7 @@ #include "sv_vehicles.qh" -#if 0 -bool vehicle_send(entity to, int sf) -{ - WriteByte(MSG_ENTITY, ENT_CLIENT_VEHICLE); - WriteByte(MSG_ENTITY, sf); - - if(sf & VSF_SPAWN) - { - WriteByte(MSG_ENTITY, this.vehicleid); - } - - if(sf & VSF_SETUP) - { - // send stuff? - } - - if(sf & VSF_ENTER) - { - // player handles the .vehicle stuff, we need only set ourselves up for driving - - // send stuff? - } - - if(sf & VSF_EXIT) - { - // senf stuff? - } - - if(sf & VSF_PRECACHE) - { - // send stuff?! - } - - return true; -} -#endif - bool SendAuxiliaryXhair(entity this, entity to, int sf) { - WriteHeader(MSG_ENTITY, ENT_CLIENT_AUXILIARYXHAIR); WriteByte(MSG_ENTITY, this.cnt); @@ -60,12 +22,10 @@ void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, int axh_id) if(!IS_REAL_CLIENT(own)) return; - entity axh; - axh_id = bound(0, axh_id, MAX_AXH); - axh = own.(AuxiliaryXhair[axh_id]); + entity axh = own.(AuxiliaryXhair[axh_id]); - if(axh == NULL || wasfreed(axh)) // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?) + 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; @@ -164,6 +124,12 @@ void vehicles_locktarget(entity this, float incr, float decr, float _lock_time) } } +float vehicle_altitude(entity this, float amax) +{ + tracebox(this.origin, this.mins, this.maxs, this.origin - ('0 0 1' * amax), MOVE_WORLDONLY, this); + return vlen(this.origin - trace_endpos); +} + vector vehicles_force_fromtag_hover(entity this, string tag_name, float spring_length, float max_power) { force_fromtag_origin = gettaginfo(this, gettagindex(this, tag_name)); @@ -213,28 +179,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, @@ -298,6 +269,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; @@ -327,7 +303,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 { @@ -436,21 +412,19 @@ void vehicles_reset_colors(entity this) void vehicles_clearreturn(entity veh) { - // Remove "return helper", if any. - for (entity ret = findchain(classname, "vehicle_return"); ret; ret = ret.chain) + // Remove "return helper" entities, if any. + FOREACH_ENTITY_ENT(wp00, veh, { - if(ret.wp00 == veh) + if(it.classname == "vehicle_return") { - ret.classname = ""; - setthink(ret, SUB_Remove); - ret.nextthink = time + 0.1; + it.classname = ""; + setthink(it, SUB_Remove); + it.nextthink = time + 0.1; - if(ret.waypointsprite_attached) - WaypointSprite_Kill(ret.waypointsprite_attached); - - return; + if(it.waypointsprite_attached) + WaypointSprite_Kill(it.waypointsprite_attached); } - } + }); } void vehicles_spawn(entity this); @@ -473,13 +447,10 @@ void vehicles_showwp_goaway(entity this) WaypointSprite_Kill(this.waypointsprite_attached); remove(this); - } void vehicles_showwp(entity this) { - vector rgb; - entity ent = this; if(ent.cnt) @@ -493,7 +464,6 @@ void vehicles_showwp(entity this) ent.nextthink = time + 1; ent = spawn(); - setmodel(ent, MDL_Null); ent.team = this.wp00.team; ent.wp00 = this.wp00; setorigin(ent, this.wp00.pos1); @@ -502,6 +472,7 @@ void vehicles_showwp(entity this) setthink(ent, vehicles_showwp_goaway); } + vector rgb; if(teamplay && ent.team) rgb = Team_ColorRGB(ent.team); else @@ -519,11 +490,9 @@ void vehicles_showwp(entity this) void vehicles_setreturn(entity veh) { - entity ret; - vehicles_clearreturn(veh); - ret = new(vehicle_return); + entity ret = new(vehicle_return); ret.wp00 = veh; ret.team = veh.team; setthink(ret, vehicles_showwp); @@ -538,14 +507,12 @@ void vehicles_setreturn(entity veh) ret.nextthink = min(time + veh.respawntime, time + veh.respawntime - 1); } - setmodel(ret, MDL_Null); setorigin(ret, veh.pos1 + '0 0 96'); - } void vehicle_use(entity this, entity actor, entity trigger) { - LOG_TRACE("vehicle ",this.netname, " used by ", actor.classname, "\n"); + LOG_DEBUG("vehicle ", this.netname, " used by ", actor.classname, "\n"); this.tur_head.team = actor.team; @@ -556,7 +523,7 @@ void vehicle_use(entity this, entity actor, entity trigger) if(this.active == ACTIVE_ACTIVE && !IS_DEAD(this) && !gameover) { - LOG_TRACE("Respawning vehicle: ", this.netname, "\n"); + LOG_DEBUG("Respawning vehicle: ", this.netname, "\n"); if(this.effects & EF_NODRAW) { setthink(this, vehicles_spawn); @@ -634,20 +601,15 @@ void vehicles_damage(entity this, entity inflictor, entity attacker, float damag // WEAPONTODO if(DEATH_ISWEAPON(deathtype, WEP_VORTEX)) damage *= autocvar_g_vehicles_vortex_damagerate; - - if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN)) + else if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN)) damage *= autocvar_g_vehicles_machinegun_damagerate; - - if(DEATH_ISWEAPON(deathtype, WEP_RIFLE)) + else if(DEATH_ISWEAPON(deathtype, WEP_RIFLE)) damage *= autocvar_g_vehicles_rifle_damagerate; - - if(DEATH_ISWEAPON(deathtype, WEP_VAPORIZER)) + else if(DEATH_ISWEAPON(deathtype, WEP_VAPORIZER)) damage *= autocvar_g_vehicles_vaporizer_damagerate; - - if(DEATH_ISWEAPON(deathtype, WEP_SEEKER)) + else if(DEATH_ISWEAPON(deathtype, WEP_SEEKER)) damage *= autocvar_g_vehicles_tag_damagerate; - - if(DEATH_WEAPONOF(deathtype) != WEP_Null) + else if(DEATH_WEAPONOF(deathtype) != WEP_Null) damage *= autocvar_g_vehicles_weapon_damagerate; this.enemy = attacker; @@ -721,7 +683,7 @@ void vehicles_damage(entity this, entity inflictor, entity attacker, float damag } } -float vehicles_crushable(entity e) +bool vehicles_crushable(entity e) { if(IS_PLAYER(e) && time >= e.vehicle_enter_delay) return true; @@ -757,18 +719,14 @@ void vehicles_impact(entity this, float _minspeed, float _speedfac, float _maxpa // vehicle enter/exit handling vector vehicles_findgoodexit(entity this, vector prefer_spot) { - //vector exitspot; - float mysize; - tracebox(this.origin + '0 0 32', STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), prefer_spot, MOVE_NORMAL, this.owner); if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) return prefer_spot; - mysize = 1.5 * vlen(this.maxs - this.mins); - float i; - vector v, v2; - v2 = 0.5 * (this.absmin + this.absmax); - for(i = 0; i < 100; ++i) + float mysize = 1.5 * vlen(this.maxs - this.mins); + vector v; + vector v2 = 0.5 * (this.absmin + this.absmax); + for(int i = 0; i < autocvar_g_vehicles_exit_attempts; ++i) { v = randomvec(); v_z = 0; @@ -778,28 +736,6 @@ vector vehicles_findgoodexit(entity this, vector prefer_spot) return v; } - /* - exitspot = (this.origin + '0 0 48') + v_forward * mysize; - tracebox(this.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, this.owner); - if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) - return exitspot; - - exitspot = (this.origin + '0 0 48') - v_forward * mysize; - tracebox(this.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, this.owner); - if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) - return exitspot; - - exitspot = (this.origin + '0 0 48') + v_right * mysize; - tracebox(this.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, this.owner); - if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) - return exitspot; - - exitspot = (this.origin + '0 0 48') - v_right * mysize; - tracebox(this.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, this.owner); - if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) - return exitspot; - */ - return this.origin; } @@ -891,21 +827,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". } @@ -921,7 +857,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) @@ -956,23 +892,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) + 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)) @@ -1005,7 +938,6 @@ void vehicles_enter(entity pl, entity veh) veh.vehicle_hudmodel.viewmodelforclient = pl; - tracebox(pl.origin, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), pl.origin, false, pl); pl.crouch = false; pl.view_ofs = STAT(PL_VIEW_OFS, NULL); setsize (pl, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL)); @@ -1073,7 +1005,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)); @@ -1081,7 +1012,7 @@ void vehicles_enter(entity pl, entity veh) void vehicles_think(entity this) { - this.nextthink = time; + this.nextthink = time + autocvar_g_vehicles_thinkrate; if(this.owner) this.owner.vehicle_weapon2mode = this.vehicle_weapon2mode; @@ -1094,10 +1025,21 @@ 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) { - LOG_TRACE("Spawning vehicle: ", this.classname, "\n"); + LOG_DEBUG("Spawning vehicle: ", this.classname, "\n"); // disown & reset this.vehicle_hudmodel.viewmodelforclient = this; @@ -1105,6 +1047,7 @@ 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; @@ -1159,7 +1102,7 @@ bool vehicle_initialize(entity this, Vehicle info, bool nodrop) this.vehicle_controller = find(NULL, target, this.targetname); if(!this.vehicle_controller) { - bprint("^1WARNING: ^7Vehicle with invalid .targetname\n"); + LOG_DEBUG("^1WARNING: ^7Vehicle with invalid .targetname\n"); this.active = ACTIVE_ACTIVE; } else @@ -1234,6 +1177,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); @@ -1245,8 +1190,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) diff --git a/qcsrc/common/vehicles/sv_vehicles.qh b/qcsrc/common/vehicles/sv_vehicles.qh index 8c53724b57..e593922fcb 100644 --- a/qcsrc/common/vehicles/sv_vehicles.qh +++ b/qcsrc/common/vehicles/sv_vehicles.qh @@ -16,6 +16,8 @@ float autocvar_g_vehicles_crush_force = 50; bool autocvar_g_vehicles_delayspawn = true; float autocvar_g_vehicles_delayspawn_jitter = 10; float autocvar_g_vehicles_allow_bots; +int autocvar_g_vehicles_exit_attempts = 25; +float autocvar_g_vehicles_thinkrate = 0.1; AUTOCVAR(g_vehicles_teams, bool, true, "allow team specific vehicles"); float autocvar_g_vehicles_teleportable; @@ -105,6 +107,7 @@ void vehicles_exit(entity vehic, int eject); bool vehicle_initialize(entity this, Vehicle info, float nodrop); bool vehicle_impulse(entity this, int imp); bool vehicles_crushable(entity e); +float vehicle_altitude(entity this, float amax); #endif #endif diff --git a/qcsrc/common/vehicles/vehicle.qh b/qcsrc/common/vehicles/vehicle.qh index 45cdacf398..927465ea6b 100644 --- a/qcsrc/common/vehicles/vehicle.qh +++ b/qcsrc/common/vehicles/vehicle.qh @@ -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 */ @@ -57,20 +59,20 @@ CLASS(Vehicle, Object) ENDCLASS(Vehicle) // vehicle spawn flags (need them here for common registrations) -const int VHF_ISVEHICLE = 2; /// Indicates vehicle -const int VHF_HASSHIELD = 4; /// Vehicle has shileding -const int VHF_SHIELDREGEN = 8; /// Vehicles shield regenerates -const int VHF_HEALTHREGEN = 16; /// Vehicles health regenerates -const int VHF_ENERGYREGEN = 32; /// Vehicles energy regenerates -const int VHF_DEATHEJECT = 64; /// Vehicle ejects pilot upon fatal damage -const int VHF_MOVE_GROUND = 128; /// Vehicle moves on gound -const int VHF_MOVE_HOVER = 256; /// Vehicle hover close to gound -const int VHF_MOVE_FLY = 512; /// Vehicle is airborn -const int VHF_DMGSHAKE = 1024; /// Add random velocity each frame if health < 50% -const int VHF_DMGROLL = 2048; /// Add random angles each frame if health < 50% -const int VHF_DMGHEADROLL = 4096; /// Add random head angles each frame if health < 50% -const int VHF_MULTISLOT = 8192; /// Vehicle has multiple player slots -const int VHF_PLAYERSLOT = 16384; /// This ent is a player slot on a multi-person vehicle +const int VHF_ISVEHICLE = BIT(1); /// Indicates vehicle +const int VHF_HASSHIELD = BIT(2); /// Vehicle has shileding +const int VHF_SHIELDREGEN = BIT(3); /// Vehicles shield regenerates +const int VHF_HEALTHREGEN = BIT(4); /// Vehicles health regenerates +const int VHF_ENERGYREGEN = BIT(5); /// Vehicles energy regenerates +const int VHF_DEATHEJECT = BIT(6); /// Vehicle ejects pilot upon fatal damage +const int VHF_MOVE_GROUND = BIT(7); /// Vehicle moves on gound +const int VHF_MOVE_HOVER = BIT(8); /// Vehicle hover close to gound +const int VHF_MOVE_FLY = BIT(9); /// Vehicle is airborn +const int VHF_DMGSHAKE = BIT(10); /// Add random velocity each frame if health < 50% +const int VHF_DMGROLL = BIT(11); /// Add random angles each frame if health < 50% +const int VHF_DMGHEADROLL = BIT(12); /// Add random head angles each frame if health < 50% +const int VHF_MULTISLOT = BIT(13); /// Vehicle has multiple player slots +const int VHF_PLAYERSLOT = BIT(14); /// This ent is a player slot on a multi-person vehicle // fields: .entity tur_head; diff --git a/qcsrc/common/vehicles/vehicle/bumblebee.qc b/qcsrc/common/vehicles/vehicle/bumblebee.qc index 401483735c..a0c0dd2ecc 100644 --- a/qcsrc/common/vehicles/vehicle/bumblebee.qc +++ b/qcsrc/common/vehicles/vehicle/bumblebee.qc @@ -297,15 +297,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; } @@ -369,26 +371,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) @@ -562,7 +564,7 @@ bool bumblebee_pilot_frame(entity this) if((teamplay && trace_ent.team == this.team) || !teamplay) { - if(trace_ent.vehicle_flags & VHF_ISVEHICLE) + if(IS_VEHICLE(trace_ent)) { if(autocvar_g_vehicle_bumblebee_healgun_sps && trace_ent.vehicle_health <= trace_ent.max_health) trace_ent.vehicle_shield = min(trace_ent.vehicle_shield + autocvar_g_vehicle_bumblebee_healgun_sps * frametime, trace_ent.tur_head.max_health); @@ -629,7 +631,7 @@ void bumblebee_land(entity this) { float hgt; - hgt = raptor_altitude(this, 512); + hgt = vehicle_altitude(this, 512); this.velocity = (this.velocity * 0.9) + ('0 0 -1800' * (hgt / 256) * sys_frametime); this.angles_x *= 0.95; this.angles_z *= 0.95; @@ -701,6 +703,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) @@ -732,6 +739,20 @@ METHOD(Bumblebee, vr_enter, void(Bumblebee thisveh, entity instance)) instance.nextthink = 0; instance.movetype = 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)) { instance.angles_z *= 0.8; @@ -745,11 +766,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 +775,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 +805,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); diff --git a/qcsrc/common/vehicles/vehicle/bumblebee.qh b/qcsrc/common/vehicles/vehicle/bumblebee.qh index 7a9fc2ccbe..b043038921 100644 --- a/qcsrc/common/vehicles/vehicle/bumblebee.qh +++ b/qcsrc/common/vehicles/vehicle/bumblebee.qh @@ -6,8 +6,4 @@ void CSQC_BUMBLE_GUN_HUD(); #endif -#ifdef SVQC -float raptor_altitude(entity this, float amax); -#endif - #endif diff --git a/qcsrc/common/vehicles/vehicle/racer.qc b/qcsrc/common/vehicles/vehicle/racer.qc index 254f9bfc4a..334320b321 100644 --- a/qcsrc/common/vehicles/vehicle/racer.qc +++ b/qcsrc/common/vehicles/vehicle/racer.qc @@ -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) { @@ -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; diff --git a/qcsrc/common/vehicles/vehicle/raptor.qc b/qcsrc/common/vehicles/vehicle/raptor.qc index 28716fc266..562f522f3e 100644 --- a/qcsrc/common/vehicles/vehicle/raptor.qc +++ b/qcsrc/common/vehicles/vehicle/raptor.qc @@ -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; @@ -77,23 +79,16 @@ vector autocvar_g_vehicle_raptor_bouncepain = '1 4 1000'; .entity bomb1; .entity bomb2; -float raptor_altitude(entity this, float amax) -{ - tracebox(this.origin, this.mins, this.maxs, this.origin - ('0 0 1' * amax), MOVE_WORLDONLY, this); - return vlen(this.origin - trace_endpos); -} - void raptor_land(entity this) { float hgt; - hgt = raptor_altitude(this, 512); + hgt = vehicle_altitude(this, 512); this.velocity = (this.velocity * 0.9) + ('0 0 -1800' * (hgt / 256) * sys_frametime); this.angles_x *= 0.95; this.angles_z *= 0.95; - if(hgt < 128) - if(hgt > 0) + if(hgt < 128 && hgt > 0) this.frame = (hgt / 128) * 25; this.bomb1.gun1.avelocity_y = 90 + ((this.frame / 25) * 2000); @@ -113,19 +108,19 @@ void raptor_land(entity this) void raptor_exit(entity this, int eject) { - vector spot; this.tur_head.exteriormodeltoclient = NULL; if(!IS_DEAD(this)) { setthink(this, raptor_land); - this.nextthink = time; + this.nextthink = time; } if(!this.owner) return; makevectors(this.angles); + vector spot; if(eject) { spot = this.origin + v_forward * 100 + '0 0 64'; @@ -172,7 +167,6 @@ bool raptor_frame(entity this) vehicles_frame(vehic, this); - float ftmp = 0; /* ftmp = vlen(vehic.velocity); if(ftmp > autocvar_g_vehicle_raptor_speed_forward) @@ -186,7 +180,7 @@ bool raptor_frame(entity this) vehic.sound_nexttime = time + 7.955812; //sound (vehic.tur_head, CH_TRIGGER_SINGLE, SND_VEH_RAPTOR_FLY, 1 - ftmp, ATTEN_NORM ); sound (vehic, CH_TRIGGER_SINGLE, SND_VEH_RAPTOR_SPEED, 1, ATTEN_NORM); - vehic.wait = ftmp; + vehic.wait = 0; } /* else if(fabs(ftmp - vehic.wait) > 0.2) @@ -226,7 +220,7 @@ bool raptor_frame(entity this) if(df_y > 180) df_y -= 360; if(df_y < -180) df_y += 360; - ftmp = shortangle_f(this.v_angle_y - vang_y, vang_y); + float ftmp = shortangle_f(this.v_angle_y - vang_y, vang_y); if(ftmp > 180) ftmp -= 360; if(ftmp < -180) ftmp += 360; vehic.avelocity_y = bound(-autocvar_g_vehicle_raptor_turnspeed, ftmp + vehic.avelocity_y * 0.9, autocvar_g_vehicle_raptor_turnspeed); @@ -516,7 +510,7 @@ 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); @@ -537,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) { @@ -620,7 +617,7 @@ METHOD(Raptor, vr_enter, void(Raptor thisveh, entity instance)) 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; @@ -731,6 +728,9 @@ METHOD(Raptor, vr_spawn, void(Raptor thisveh, entity instance)) 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; @@ -763,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 @@ -786,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; diff --git a/qcsrc/common/vehicles/vehicle/raptor_weapons.qc b/qcsrc/common/vehicles/vehicle/raptor_weapons.qc index 56c3e8c610..a9b9a86587 100644 --- a/qcsrc/common/vehicles/vehicle/raptor_weapons.qc +++ b/qcsrc/common/vehicles/vehicle/raptor_weapons.qc @@ -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); @@ -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; } @@ -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; @@ -157,8 +162,8 @@ void raptor_bombdrop(entity this) bomb_1.movetype = bomb_2.movetype = 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 +185,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); } diff --git a/qcsrc/common/vehicles/vehicle/spiderbot.qc b/qcsrc/common/vehicles/vehicle/spiderbot.qc index d41e81ce61..8015b31027 100644 --- a/qcsrc/common/vehicles/vehicle/spiderbot.qc +++ b/qcsrc/common/vehicles/vehicle/spiderbot.qc @@ -337,19 +337,14 @@ bool spiderbot_frame(entity this) void spiderbot_exit(entity this, int eject) { - entity e; vector spot; - e = findchain(classname,"spiderbot_rocket"); - while(e) + FOREACH_ENTITY_ENT(owner, this.owner, { - if(e.owner == this.owner) - { - e.realowner = this.owner; - e.owner = NULL; - } - e = e.chain; - } + if(it.classname != "spiderbot_rocket") continue; + it.realowner = this.owner; + it.owner = NULL; + }); setthink(this, vehicles_think); this.nextthink = time; diff --git a/qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc b/qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc index 27177019ef..8876f89594 100644 --- a/qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc +++ b/qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc @@ -140,7 +140,7 @@ vector spiberbot_calcartillery(vector org, vector tgt, float ht) } void spiderbot_rocket_do(entity this) -{; +{ vector v; entity rocket = NULL; @@ -196,7 +196,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; diff --git a/qcsrc/common/weapons/weapon/arc.qc b/qcsrc/common/weapons/weapon/arc.qc index 9262698daa..012b2c0f14 100644 --- a/qcsrc/common/weapons/weapon/arc.qc +++ b/qcsrc/common/weapons/weapon/arc.qc @@ -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) @@ -857,6 +857,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 +868,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; diff --git a/qcsrc/common/weapons/weapon/blaster.qc b/qcsrc/common/weapons/weapon/blaster.qc index a4fb13c44e..79a680e367 100644 --- a/qcsrc/common/weapons/weapon/blaster.qc +++ b/qcsrc/common/weapons/weapon/blaster.qc @@ -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); diff --git a/qcsrc/common/weapons/weapon/crylink.qc b/qcsrc/common/weapons/weapon/crylink.qc index eb3e72f8ac..d1f2522abb 100644 --- a/qcsrc/common/weapons/weapon/crylink.qc +++ b/qcsrc/common/weapons/weapon/crylink.qc @@ -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; diff --git a/qcsrc/common/weapons/weapon/devastator.qc b/qcsrc/common/weapons/weapon/devastator.qc index f2ca426554..9d955f058d 100644 --- a/qcsrc/common/weapons/weapon/devastator.qc +++ b/qcsrc/common/weapons/weapon/devastator.qc @@ -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) diff --git a/qcsrc/common/weapons/weapon/electro.qc b/qcsrc/common/weapons/weapon/electro.qc index 09cb77c8bd..b9811abd87 100644 --- a/qcsrc/common/weapons/weapon/electro.qc +++ b/qcsrc/common/weapons/weapon/electro.qc @@ -144,13 +144,13 @@ 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; @@ -168,7 +168,7 @@ void W_Electro_Explode(entity this) NULL, WEP_CVAR_SEC(electro, force), this.projectiledeathtype, - other + directhitentity ); } else @@ -184,7 +184,7 @@ void W_Electro_Explode(entity this) NULL, WEP_CVAR_PRI(electro, force), this.projectiledeathtype, - other + directhitentity ); } @@ -193,13 +193,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); } void W_Electro_Bolt_Think(entity this) @@ -298,11 +298,11 @@ void W_Electro_Attack_Bolt(Weapon thiswep, entity actor) MUTATOR_CALLHOOK(EditProjectile, actor, proj); } -void W_Electro_Orb_Touch(entity this) +void W_Electro_Orb_Touch(entity this, entity toucher) { - PROJECTILE_TOUCH(this); - if(other.takedamage == DAMAGE_AIM) - { if(WEP_CVAR_SEC(electro, touchexplode)) { W_Electro_Explode(this); } } + PROJECTILE_TOUCH(this, toucher); + if(toucher.takedamage == DAMAGE_AIM) + { if(WEP_CVAR_SEC(electro, touchexplode)) { W_Electro_Explode(this, toucher); } } else { //UpdateCSQCProjectile(this); diff --git a/qcsrc/common/weapons/weapon/fireball.qc b/qcsrc/common/weapons/weapon/fireball.qc index d07324701a..37deb14528 100644 --- a/qcsrc/common/weapons/weapon/fireball.qc +++ b/qcsrc/common/weapons/weapon/fireball.qc @@ -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); } } @@ -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; diff --git a/qcsrc/common/weapons/weapon/hagar.qc b/qcsrc/common/weapons/weapon/hagar.qc index d41ad95b93..1a078dff0a 100644 --- a/qcsrc/common/weapons/weapon/hagar.qc +++ b/qcsrc/common/weapons/weapon/hagar.qc @@ -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); diff --git a/qcsrc/common/weapons/weapon/hlac.qc b/qcsrc/common/weapons/weapon/hlac.qc index c176e84c67..d46972fa1c 100644 --- a/qcsrc/common/weapons/weapon/hlac.qc +++ b/qcsrc/common/weapons/weapon/hlac.qc @@ -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); } diff --git a/qcsrc/common/weapons/weapon/hook.qc b/qcsrc/common/weapons/weapon/hook.qc index 5963b3bc7d..f46e592e29 100644 --- a/qcsrc/common/weapons/weapon/hook.qc +++ b/qcsrc/common/weapons/weapon/hook.qc @@ -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); } @@ -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; diff --git a/qcsrc/common/weapons/weapon/minelayer.qc b/qcsrc/common/weapons/weapon/minelayer.qc index a406e75098..08b3634f41 100644 --- a/qcsrc/common/weapons/weapon/minelayer.qc +++ b/qcsrc/common/weapons/weapon/minelayer.qc @@ -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,6 +138,11 @@ 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; @@ -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) @@ -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) 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) diff --git a/qcsrc/common/weapons/weapon/mortar.qc b/qcsrc/common/weapons/weapon/mortar.qc index 5f56f19db1..8cbe75e74b 100644 --- a/qcsrc/common/weapons/weapon/mortar.qc +++ b/qcsrc/common/weapons/weapon/mortar.qc @@ -64,13 +64,13 @@ 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; @@ -79,23 +79,23 @@ void W_Mortar_Grenade_Explode(entity this) if(this.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; @@ -104,14 +104,14 @@ void W_Mortar_Grenade_Explode2(entity this) if(this.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,7 +155,7 @@ 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.movetype == MOVETYPE_NONE))) // stick { spamsound(this, CH_SHOTS, SND(GRENADE_STICK), VOL_BASE, ATTN_NORM); @@ -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,7 +191,7 @@ 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.movetype == MOVETYPE_NONE))) // stick { spamsound(this, CH_SHOTS, SND(GRENADE_STICK), VOL_BASE, ATTN_NORM); diff --git a/qcsrc/common/weapons/weapon/porto.qc b/qcsrc/common/weapons/weapon/porto.qc index 3b047dc8c9..dbcad2c1e6 100644 --- a/qcsrc/common/weapons/weapon/porto.qc +++ b/qcsrc/common/weapons/weapon/porto.qc @@ -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; diff --git a/qcsrc/common/weapons/weapon/seeker.qc b/qcsrc/common/weapons/weapon/seeker.qc index a39c3958f1..524c6791f9 100644 --- a/qcsrc/common/weapons/weapon/seeker.qc +++ b/qcsrc/common/weapons/weapon/seeker.qc @@ -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); } /* @@ -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,7 +362,7 @@ 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); @@ -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); } } diff --git a/qcsrc/common/weapons/weapon/vaporizer.qc b/qcsrc/common/weapons/weapon/vaporizer.qc index 8b061b72a5..8a2fbdac3c 100644 --- a/qcsrc/common/weapons/weapon/vaporizer.qc +++ b/qcsrc/common/weapons/weapon/vaporizer.qc @@ -233,11 +233,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); } diff --git a/qcsrc/dpdefs/doc.md b/qcsrc/dpdefs/doc.md index d279ced478..240eec0c1c 100644 --- a/qcsrc/dpdefs/doc.md +++ b/qcsrc/dpdefs/doc.md @@ -18,6 +18,7 @@ bool CSQC_InputEvent(int eventtype, int x, int y); void CSQC_UpdateView(int width, int height); +// catch commands registered with registercommand bool CSQC_ConsoleCommand(string cmd); bool CSQC_Parse_TempEntity(); bool CSQC_Parse_StuffCmd(string msg); @@ -229,3 +230,85 @@ void URI_Get_Callback(int id, int status, string data); void GameCommand(string cmd); ``` + +# Misc + +## Trace + +### tracebox + + void tracebox(vector v1, vector min, vector max, vector v2, int tryents, entity ignoreentity); + +attempt to move an object from v1 to v2 of given size + +tryents: + * MOVE_NORMAL (0) + * MOVE_NOMONSTERS (1): ignore monsters + * MOVE_MISSILE (2): +15 to every extent + * MOVE_WORLDONLY (3): ignore everything except bsp + * MOVE_HITMODEL (4): hit model, not bbox + +### traceline + + void traceline(vector v1, vector v2, int tryents, entity ignoreentity); + +degenerate case of tracebox when min and max are equal + +### result globals + + bool trace_allsolid; + +trace never left solid + + bool trace_startsolid; + +trace started inside solid + + float trace_fraction; + +distance before collision: 0..1, 1 if no collision + + vector trace_endpos; + +v1 + (v2 - v1) * trace_fraction + + vector trace_plane_normal; + +normalized plane normal, '0 0 0' if no collision. +May be present if edges touch without clipping, use `trace_fraction < 1` as a determinant instead + + float trace_plane_dist; + + + + entity trace_ent; + +entity hit, if any + + bool trace_inopen; + + + + bool trace_inwater; + + + + int trace_dpstartcontents; + +DPCONTENTS_ value at start position of trace + + int trace_dphitcontents; + +DPCONTENTS_ value of impacted surface (not contents at impact point, just contents of the surface that was hit) + + int trace_dphitq3surfaceflags; + +Q3SURFACEFLAG_ value of impacted surface + + string trace_dphittexturename; + +texture name of impacted surface + + int trace_networkentity; + + diff --git a/qcsrc/ecs/README.md b/qcsrc/ecs/README.md new file mode 100644 index 0000000000..9fd6ad6948 --- /dev/null +++ b/qcsrc/ecs/README.md @@ -0,0 +1,48 @@ +# Xonotic entity component system + +## guidelines + +* avoid #if and #ifdef +* avoid string +* avoid declaring entity fields outside of components +* uncrustify relentlessly +* shared code in $file, prog specific code uses prefix: { client: cl_, server: sv_, menu: ui_ }. $file must exist +* component naming =~ com_$component_$name +* system naming =~ sys_$system_$name +* event naming =~ evt_$component_$name +* global naming =~ g_$name +* cvar naming =~ xon_$name + +## components + + COMPONENT($component); + .int com_$component_$property; + +## entities + + entity e = new(foo); + e.com_$component = true; + e.com_$component_$property = 42; + +## systems + + SYSTEM($system, 30, 10); + sys_$system_update(entity this, float dt) { + code; + } + +## events + +### declaring + + EVENT($component_$name, (entity this)); + +### emitting + + emit($event, it); + +### listening + + entity listener = new_pure(someListener); + listener.evt_$event = void(entity this) { code; }; + subscribe(listener, $event); diff --git a/qcsrc/ecs/_lib.inc b/qcsrc/ecs/_lib.inc new file mode 100644 index 0000000000..32db1f3d3e --- /dev/null +++ b/qcsrc/ecs/_lib.inc @@ -0,0 +1,60 @@ +/** Components always interpolate from the previous state */ +#define COMPONENT(com) \ + void com_##com##_interpolate(entity it, float a); \ + .bool com_##com + +#define FOREACH_COMPONENT(com, body) FOREACH_ENTITY_FLOAT(com_##com, true, body) + + +#define EVENT(T, args) .bool evt_##T##_listener; .void args evt_##T + +#define emit(T, ...) \ + MACRO_BEGIN \ + FOREACH_ENTITY_FLOAT_ORDERED(evt_##T##_listener, true, it.evt_##T(__VA_ARGS__)); \ + MACRO_END + +#define subscribe(listener, T) \ + MACRO_BEGIN \ + listener.evt_##T##_listener = true; \ + MACRO_END + + +/** + * framelimit 0 is no limit, interpolation does not apply + * framerate below minfps will result in less than 100% speed + */ +#define SYSTEM(sys, frameLimit, minfps) \ + void sys_##sys##_update(entity this, float dt); \ + float autocvar_xon_sys_##sys##_dt = ((frameLimit) ? (1 / (frameLimit)) : 0); \ + float autocvar_xon_sys_##sys##_minfps = (1 / (1 / (minfps))) + +#define SYSTEM_UPDATE(sys) \ + MACRO_BEGIN \ + static float t = 0; \ + float dt = autocvar_xon_sys_##sys##_dt; \ + float minfps = autocvar_xon_sys_##sys##_minfps; \ + static float accumulator = 0; \ + float a = 0; \ + if (dt) { \ + accumulator += min(frametime, 1 / (minfps)); \ + } else { \ + accumulator += frametime; \ + dt = accumulator; \ + a = 1; \ + } \ + while (accumulator >= dt) \ + { \ + time = t; \ + FOREACH_COMPONENT(sys, sys_##sys##_update(it, dt)); \ + t += dt; \ + accumulator -= dt; \ + } \ + if (!a) a = accumulator / dt; \ + FOREACH_COMPONENT(sys, com_##sys##_interpolate(it, a)); \ + MACRO_END + + +#include "_mod.inc" +#include "components/_mod.inc" +#include "events/_mod.inc" +#include "systems/_mod.inc" diff --git a/qcsrc/ecs/_mod.inc b/qcsrc/ecs/_mod.inc new file mode 100644 index 0000000000..683c3a91d5 --- /dev/null +++ b/qcsrc/ecs/_mod.inc @@ -0,0 +1,2 @@ +// generated file; do not modify +#include diff --git a/qcsrc/ecs/_mod.qh b/qcsrc/ecs/_mod.qh new file mode 100644 index 0000000000..4d8bc34da3 --- /dev/null +++ b/qcsrc/ecs/_mod.qh @@ -0,0 +1,2 @@ +// generated file; do not modify +#include diff --git a/qcsrc/ecs/components/_mod.inc b/qcsrc/ecs/components/_mod.inc new file mode 100644 index 0000000000..097587129f --- /dev/null +++ b/qcsrc/ecs/components/_mod.inc @@ -0,0 +1,3 @@ +// generated file; do not modify +#include +#include diff --git a/qcsrc/ecs/components/_mod.qh b/qcsrc/ecs/components/_mod.qh new file mode 100644 index 0000000000..64fad31b30 --- /dev/null +++ b/qcsrc/ecs/components/_mod.qh @@ -0,0 +1,3 @@ +// generated file; do not modify +#include +#include diff --git a/qcsrc/ecs/components/input.qc b/qcsrc/ecs/components/input.qc new file mode 100644 index 0000000000..13b341367b --- /dev/null +++ b/qcsrc/ecs/components/input.qc @@ -0,0 +1,3 @@ +#include "input.qh" + +void com_in_interpolate(entity it, float a) { } diff --git a/qcsrc/ecs/components/input.qh b/qcsrc/ecs/components/input.qh new file mode 100644 index 0000000000..37944ca5c3 --- /dev/null +++ b/qcsrc/ecs/components/input.qh @@ -0,0 +1,6 @@ +#pragma once + +COMPONENT(in); +.vector com_in_move; +.vector com_in_angles; +.bool com_in_jump; diff --git a/qcsrc/ecs/components/physics.qc b/qcsrc/ecs/components/physics.qc new file mode 100644 index 0000000000..5094ad17a8 --- /dev/null +++ b/qcsrc/ecs/components/physics.qc @@ -0,0 +1,10 @@ +#include "physics.qh" + +bool autocvar_xon_com_phys_interpolate = true; + +void com_phys_interpolate(entity it, float a) +{ + if (!autocvar_xon_com_phys_interpolate) a = 1; + it.origin = it.com_phys_pos_prev * (1 - a) + it.com_phys_pos * a; + it.angles = it.com_phys_ang_prev * (1 - a) + it.com_phys_ang * a; // TODO: slerp, not lerp +} diff --git a/qcsrc/ecs/components/physics.qh b/qcsrc/ecs/components/physics.qh new file mode 100644 index 0000000000..502657e4bc --- /dev/null +++ b/qcsrc/ecs/components/physics.qh @@ -0,0 +1,7 @@ +#pragma once + +COMPONENT(phys); +.vector com_phys_pos, com_phys_pos_prev; +.vector com_phys_ang, com_phys_ang_prev; +.vector com_phys_vel; +.vector com_phys_acc; diff --git a/qcsrc/ecs/events/_mod.inc b/qcsrc/ecs/events/_mod.inc new file mode 100644 index 0000000000..98fb4815c1 --- /dev/null +++ b/qcsrc/ecs/events/_mod.inc @@ -0,0 +1 @@ +// generated file; do not modify diff --git a/qcsrc/ecs/events/_mod.qh b/qcsrc/ecs/events/_mod.qh new file mode 100644 index 0000000000..98fb4815c1 --- /dev/null +++ b/qcsrc/ecs/events/_mod.qh @@ -0,0 +1 @@ +// generated file; do not modify diff --git a/qcsrc/ecs/main.qc b/qcsrc/ecs/main.qc new file mode 100644 index 0000000000..29be3f367f --- /dev/null +++ b/qcsrc/ecs/main.qc @@ -0,0 +1,12 @@ +#include "main.qh" + +#include "components/_mod.qh" +#include "events/_mod.qh" +#include "systems/_mod.qh" + +void systems_update() +{ + float realtime = time; + SYSTEM_UPDATE(phys); + time = realtime; +} diff --git a/qcsrc/ecs/main.qh b/qcsrc/ecs/main.qh new file mode 100644 index 0000000000..9b7bf35238 --- /dev/null +++ b/qcsrc/ecs/main.qh @@ -0,0 +1,3 @@ +#pragma once + +void systems_update(); diff --git a/qcsrc/ecs/systems/_mod.inc b/qcsrc/ecs/systems/_mod.inc new file mode 100644 index 0000000000..f79d7f0651 --- /dev/null +++ b/qcsrc/ecs/systems/_mod.inc @@ -0,0 +1,2 @@ +// generated file; do not modify +#include diff --git a/qcsrc/ecs/systems/_mod.qh b/qcsrc/ecs/systems/_mod.qh new file mode 100644 index 0000000000..e71e0591c7 --- /dev/null +++ b/qcsrc/ecs/systems/_mod.qh @@ -0,0 +1,2 @@ +// generated file; do not modify +#include diff --git a/qcsrc/ecs/systems/physics.qc b/qcsrc/ecs/systems/physics.qc new file mode 100644 index 0000000000..8348b87851 --- /dev/null +++ b/qcsrc/ecs/systems/physics.qc @@ -0,0 +1,6 @@ +#include "physics.qh" + +void sys_phys_update(entity this, float dt) +{ + PM_Main(this); +} diff --git a/qcsrc/ecs/systems/physics.qh b/qcsrc/ecs/systems/physics.qh new file mode 100644 index 0000000000..38d4e55e55 --- /dev/null +++ b/qcsrc/ecs/systems/physics.qh @@ -0,0 +1,3 @@ +#pragma once + +SYSTEM(phys, 30, 10); diff --git a/qcsrc/lib/_all.inc b/qcsrc/lib/_all.inc index 03b9436258..61755fe943 100644 --- a/qcsrc/lib/_all.inc +++ b/qcsrc/lib/_all.inc @@ -39,28 +39,28 @@ #include "macro.qh" #if NDEBUG - #define TC(T, sym) MACRO_BEGIN MACRO_END + #define TC(T, sym) MACRO_BEGIN MACRO_END #else - #define TC(T, sym) MACRO_BEGIN \ - if (!is_##T(sym)) { \ - LOG_WARNINGF("Type check failed: " #sym " :: " #T); \ - isnt_##T(sym); \ - } \ - MACRO_END + #define TC(T, sym) MACRO_BEGIN \ + if (!is_##T(sym)) { \ + LOG_WARNINGF("Type check failed: " #sym " :: " #T); \ + isnt_##T(sym); \ + } \ + MACRO_END #endif -#define is_float( this) (true || ftoe(this)) -#define isnt_float( this) -#define is_vector( this) (true || vtos(this)) -#define isnt_vector( this) -#define is_string( this) (true || stof(this)) -#define isnt_string( this) -#define is_entity( this) (true || etof(this)) -#define isnt_entity( this) -bool is_int( float this) { return this == floor(this); } -void isnt_int( float this) { print(ftos(this)); } -bool is_bool( float this) { return this == true || this == false; } -void isnt_bool( float this) { print(ftos(this)); } +#define is_float(this) (true || ftoe(this)) +#define isnt_float(this) +#define is_vector(this) (true || vtos(this)) +#define isnt_vector(this) +#define is_string(this) (true || stof(this)) +#define isnt_string(this) +#define is_entity(this) (true || etof(this)) +#define isnt_entity(this) +bool is_int(float this) { return this == floor(this); } +void isnt_int(float this) { print(ftos(this)); } +bool is_bool(float this) { return this == true || this == false; } +void isnt_bool(float this) { print(ftos(this)); } #include "warpzone/mathlib.qc" @@ -110,3 +110,129 @@ void isnt_bool( float this) { print(ftos(this)); } #include "yenc.qh" #include "matrix/_mod.inc" + +#ifdef MENUQC + void _m_init(); + void m_init() { if (_m_init) _m_init(); } + #define m_init _m_init + + void _m_shutdown(); + void m_shutdown() { if (_m_shutdown) _m_shutdown(); } + #define m_shutdown _m_shutdown + + void _m_draw(float width, float height); + void m_draw(float width, float height) { if (_m_draw) _m_draw(width, height); } + #define m_draw _m_draw + + void _m_keydown(int keynr, int ascii); + void m_keydown(int keynr, int ascii) { if (_m_keydown) _m_keydown(keynr, ascii); } + #define m_keydown _m_keydown + + void _m_toggle(int mode); + void m_toggle(int mode) { if (_m_toggle) _m_toggle(mode); } + #define m_toggle _m_toggle +#endif + +#ifdef SVQC + void _main(); + void main() { if (_main) _main(); } + #define main _main + + void _SV_Shutdown(); + void SV_Shutdown() { if (_SV_Shutdown) _SV_Shutdown(); } + #define SV_Shutdown _SV_Shutdown + + void _StartFrame(); + void StartFrame() { if (_StartFrame) _StartFrame(); } + #define StartFrame _StartFrame + + void _SetNewParms(); + void SetNewParms() { if (_SetNewParms) _SetNewParms(); } + #define SetNewParms _SetNewParms + + void _SetChangeParms(entity this); + void SetChangeParms() { ENGINE_EVENT(); if (_SetChangeParms) _SetChangeParms(this); } + #define SetChangeParms _SetChangeParms + + void _ClientConnect(entity this); + void ClientConnect() { ENGINE_EVENT(); if (_ClientConnect) _ClientConnect(this); } + #define ClientConnect _ClientConnect + + void _ClientDisconnect(entity this); + void ClientDisconnect() { ENGINE_EVENT(); if (_ClientDisconnect) _ClientDisconnect(this); } + #define ClientDisconnect _ClientDisconnect + + void _PutClientInServer(entity this); + void PutClientInServer() { ENGINE_EVENT(); if (_PutClientInServer) _PutClientInServer(this); } + #define PutClientInServer _PutClientInServer + + void _ClientKill(entity this); + void ClientKill() { ENGINE_EVENT(); if (_ClientKill) _ClientKill(this); } + #define ClientKill _ClientKill + + void _PlayerPreThink(entity this); + void PlayerPreThink() { ENGINE_EVENT(); if (_PlayerPreThink) _PlayerPreThink(this); } + #define PlayerPreThink _PlayerPreThink + + void _PlayerPostThink(entity this); + void PlayerPostThink() { ENGINE_EVENT(); if (_PlayerPostThink) _PlayerPostThink(this); } + #define PlayerPostThink _PlayerPostThink + + void _SV_PlayerPhysics(entity this); + void SV_PlayerPhysics() { ENGINE_EVENT(); if (_SV_PlayerPhysics) _SV_PlayerPhysics(this); } + #define SV_PlayerPhysics _SV_PlayerPhysics + + void _SV_OnEntityPreSpawnFunction(entity this); + void SV_OnEntityPreSpawnFunction() + { + ENGINE_EVENT(); + if (_SV_OnEntityPreSpawnFunction) _SV_OnEntityPreSpawnFunction(this); + } + #define SV_OnEntityPreSpawnFunction _SV_OnEntityPreSpawnFunction + + void _SV_ChangeTeam(entity this, int _color); + void SV_ChangeTeam(int _color) { ENGINE_EVENT(); if (_SV_ChangeTeam) _SV_ChangeTeam(this, _color); } + #define SV_ChangeTeam _SV_ChangeTeam + + void _SV_ParseClientCommand(entity this, string command); + void SV_ParseClientCommand(string command) + { + ENGINE_EVENT(); + if (_SV_ParseClientCommand) _SV_ParseClientCommand(this, command); + } + #define SV_ParseClientCommand _SV_ParseClientCommand +#endif + +#ifdef CSQC + void _CSQC_Init(); + void CSQC_Init() { if (_CSQC_Init) _CSQC_Init(); } + #define CSQC_Init _CSQC_Init + + void _CSQC_Shutdown(); + void CSQC_Shutdown() { if (_CSQC_Shutdown) _CSQC_Shutdown(); } + #define CSQC_Shutdown _CSQC_Shutdown + + void _CSQC_UpdateView(entity this, float w, float h); + void CSQC_UpdateView(float w, float h) { ENGINE_EVENT(); if (_CSQC_UpdateView) _CSQC_UpdateView(this, w, h); } + #define CSQC_UpdateView _CSQC_UpdateView + + bool _CSQC_InputEvent(int inputType, float nPrimary, float nSecondary); + bool CSQC_InputEvent(int inputType, float nPrimary, float nSecondary) + { + return _CSQC_InputEvent ? _CSQC_InputEvent(inputType, nPrimary, nSecondary) : false; + } + #define CSQC_InputEvent _CSQC_InputEvent + + bool _CSQC_ConsoleCommand(string s); + bool CSQC_ConsoleCommand(string s) { return _CSQC_ConsoleCommand ? _CSQC_ConsoleCommand(s) : false; } + #define CSQC_ConsoleCommand _CSQC_ConsoleCommand + + void _CSQC_Ent_Update(entity this, bool isNew); + void CSQC_Ent_Update(bool isNew) { ENGINE_EVENT(); if (_CSQC_Ent_Update) _CSQC_Ent_Update(this, isNew); } + #define CSQC_Ent_Update _CSQC_Ent_Update + + void _CSQC_Ent_Remove(entity this); + void CSQC_Ent_Remove() { ENGINE_EVENT(); if (_CSQC_Ent_Remove) _CSQC_Ent_Remove(this); } + #define CSQC_Ent_Remove _CSQC_Ent_Remove +#endif +#undef ENGINE_EVENT diff --git a/qcsrc/lib/csqcmodel/cl_player.qc b/qcsrc/lib/csqcmodel/cl_player.qc index 0b0de75649..1a8ba710ae 100644 --- a/qcsrc/lib/csqcmodel/cl_player.qc +++ b/qcsrc/lib/csqcmodel/cl_player.qc @@ -35,6 +35,7 @@ #include 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 @@ -254,7 +255,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); diff --git a/qcsrc/lib/macro.qh b/qcsrc/lib/macro.qh index dff3710a5f..1541b9997c 100644 --- a/qcsrc/lib/macro.qh +++ b/qcsrc/lib/macro.qh @@ -14,3 +14,6 @@ #define _STR(it) #it #define STR(it) _STR(it) + +#define EMPTY() +#define DEFER(id) id EMPTY() diff --git a/qcsrc/lib/misc.qh b/qcsrc/lib/misc.qh index 950000f047..21e0c5239f 100644 --- a/qcsrc/lib/misc.qh +++ b/qcsrc/lib/misc.qh @@ -1,9 +1,6 @@ #pragma once #ifdef __STDC__ - #define EMPTY() - #define DEFER(id) id EMPTY() - #define EVAL(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__))) #define EVAL1(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__))) #define EVAL2(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__))) diff --git a/qcsrc/lib/net.qh b/qcsrc/lib/net.qh index 4e09d4b010..0ce157848e 100644 --- a/qcsrc/lib/net.qh +++ b/qcsrc/lib/net.qh @@ -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; @@ -203,6 +203,54 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); } } MACRO_END #endif +// serialization: new style + +USING(Stream, int); +#if defined(SVQC) + #define stream_reading(stream) false + #define stream_writing(stream) true +#elif defined(CSQC) + #define stream_reading(stream) true + #define stream_writing(stream) false +#endif + +#define serialize(T, stream, ...) serialize_##T(stream, __VA_ARGS__) + +#if defined(SVQC) + #define serialize_byte(stream, this) \ + MACRO_BEGIN \ + WriteByte(stream, this); \ + MACRO_END +#elif defined(CSQC) + #define serialize_byte(stream, this) \ + MACRO_BEGIN \ + this = ReadByte(); \ + MACRO_END +#endif + +#if defined(SVQC) + #define serialize_float(stream, this) \ + MACRO_BEGIN \ + WriteCoord(stream, this); \ + MACRO_END +#elif defined(CSQC) + #define serialize_float(stream, this) \ + MACRO_BEGIN \ + this = ReadCoord(); \ + MACRO_END +#endif + +#define serialize_vector(stream, this) \ + MACRO_BEGIN \ + vector _v = this; \ + serialize_float(stream, _v.x); \ + serialize_float(stream, _v.y); \ + serialize_float(stream, _v.z); \ + this = _v; \ + MACRO_END + +// serialization: old + #define ReadRegistered(r) r##_from(Read_byte()) #define WriteRegistered(r, to, it) Write_byte(to, it.m_id) diff --git a/qcsrc/lib/self.qh b/qcsrc/lib/self.qh index ec43a34022..5d42bdccd7 100644 --- a/qcsrc/lib/self.qh +++ b/qcsrc/lib/self.qh @@ -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) diff --git a/qcsrc/lib/static.qh b/qcsrc/lib/static.qh index e1cfeb8721..6b5febe6fb 100644 --- a/qcsrc/lib/static.qh +++ b/qcsrc/lib/static.qh @@ -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() diff --git a/qcsrc/lib/unsafe.qh b/qcsrc/lib/unsafe.qh index 97e1c79584..60ad3d88da 100644 --- a/qcsrc/lib/unsafe.qh +++ b/qcsrc/lib/unsafe.qh @@ -1,10 +1,13 @@ #pragma once #define reinterpret_cast(T, it) _unsafe_cast_##T(0, it) -#define X(T) T _unsafe_cast_##T(int dummy, ...) { return ...(0, T); } +#define X(T) \ + T _unsafe_cast_##T(int dummy, ...) { return ...(0, T); } \ + USING(T##_fld, .T); T##_fld _unsafe_cast_##T##_fld(int dummy, ...) { return ...(0, T##_fld); } X(bool) X(int) X(float) +X(vector) X(entity) X(string) USING(rawfunc, float(...)); @@ -24,3 +27,5 @@ STATIC_INIT(INTEGER_ONE) { INTEGER_ONE = reinterpret_cast(int, _unsafe_fld2) - reinterpret_cast(int, _unsafe_fld1); } + +#define ARRAY_INDEX(T, arr, idx) (reinterpret_cast(T##_fld, reinterpret_cast(int, arr[0]) + FTOI(idx))) diff --git a/qcsrc/lib/vector.qh b/qcsrc/lib/vector.qh index def1dae2d4..adb6d6a95b 100644 --- a/qcsrc/lib/vector.qh +++ b/qcsrc/lib/vector.qh @@ -116,6 +116,14 @@ vector reflect(vector dir, vector norm) return dir - 2 * (dir * norm) * norm; } +/** + * clip vel along the plane defined by norm (assuming 0 distance away), bounciness determined by bounce 0..1 + */ +vector vec_reflect(vector vel, vector norm, float bounce) +{ + return vel - (1 + bounce) * (vel * norm) * norm; +} + #ifndef MENUQC vector get_corner_position(entity box, int corner) { diff --git a/qcsrc/lib/warpzone/client.qc b/qcsrc/lib/warpzone/client.qc index b539b5bcc3..fd0925db93 100644 --- a/qcsrc/lib/warpzone/client.qc +++ b/qcsrc/lib/warpzone/client.qc @@ -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; @@ -258,10 +258,28 @@ void WarpZone_FixView() #ifndef KEEP_ROLL float rick; float f; - if(autocvar_cl_rollkillspeed) - f = max(0, (1 - frametime * autocvar_cl_rollkillspeed)); - else + static float rollkill; + if (STAT(HEALTH) > 0 || STAT(HEALTH) == -666 || STAT(HEALTH) == -2342) + { f = 0; + // reset roll when passing through a warpzone that change player's roll angle + if(autocvar_cl_rollkillspeed) + f = max(0, (1 - frametime * autocvar_cl_rollkillspeed)); + if(rollkill) + rollkill = 0; + } + else + { + f = 1; + // roll the view when killed (v_deathtilt) + if(autocvar_cl_rollkillspeed) + { + rollkill += frametime * autocvar_cl_rollkillspeed; + f = min(1, rollkill); + } + else if(rollkill) + rollkill = 0; + } rick = getproperty(VF_CL_VIEWANGLES_Z); rick *= f; diff --git a/qcsrc/lib/warpzone/common.qh b/qcsrc/lib/warpzone/common.qh index 2cfa7ef9bc..6669ae1aff 100644 --- a/qcsrc/lib/warpzone/common.qh +++ b/qcsrc/lib/warpzone/common.qh @@ -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 diff --git a/qcsrc/lib/warpzone/server.qc b/qcsrc/lib/warpzone/server.qc index 7ddb96cbbf..6dd0ea3c7f 100644 --- a/qcsrc/lib/warpzone/server.qc +++ b/qcsrc/lib/warpzone/server.qc @@ -189,29 +189,29 @@ 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) + if(toucher.movetype == MOVETYPE_NONE || toucher.movetype == MOVETYPE_FOLLOW || toucher.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_FOLLOW || toucher.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) + if(WarpZone_PlaneDist(this, toucher.origin + toucher.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet) #elif defined(CSQC) - if(WarpZone_PlaneDist(this, other.move_origin + other.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet) + if(WarpZone_PlaneDist(this, toucher.move_origin + toucher.view_ofs) >= 0) // wrong side of the trigger_warpzone (don't teleport yet) #endif return; @@ -227,29 +227,29 @@ 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)) + d = 24 + max(vlen(toucher.mins), vlen(toucher.maxs)); + if(IS_NOT_A_CLIENT(toucher)) #ifdef SVQC - f = -d / bound(frametime * d * 1, frametime * vlen(other.velocity), d); + f = -d / bound(frametime * d * 1, frametime * vlen(toucher.velocity), d); #elif defined(CSQC) - f = -d / bound(frametime * d * 1, frametime * vlen(other.move_velocity), d); + f = -d / bound(frametime * d * 1, frametime * vlen(toucher.move_velocity), d); #endif 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 @@ -434,9 +434,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 +496,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,8 +847,6 @@ void WarpZone_StartFrame() WarpZone_PostInitialize_Callback(); } - entity oldother = other; - FOREACH_ENTITY(!is_pure(it), { if(warpzone_warpzones_exist) @@ -857,28 +855,25 @@ 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; diff --git a/qcsrc/lib/warpzone/server.qh b/qcsrc/lib/warpzone/server.qh index 9abea2a689..0ec67e4d38 100644 --- a/qcsrc/lib/warpzone/server.qh +++ b/qcsrc/lib/warpzone/server.qh @@ -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); diff --git a/qcsrc/menu/item/dialog.qc b/qcsrc/menu/item/dialog.qc index c4a78fa568..f0aebabc2e 100644 --- a/qcsrc/menu/item/dialog.qc +++ b/qcsrc/menu/item/dialog.qc @@ -118,5 +118,8 @@ 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; } diff --git a/qcsrc/menu/item/inputcontainer.qc b/qcsrc/menu/item/inputcontainer.qc index 3840721e35..37c46240f7 100644 --- a/qcsrc/menu/item/inputcontainer.qc +++ b/qcsrc/menu/item/inputcontainer.qc @@ -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; diff --git a/qcsrc/menu/menu.qc b/qcsrc/menu/menu.qc index 96d98b9c50..9b617ab8a1 100644 --- a/qcsrc/menu/menu.qc +++ b/qcsrc/menu/menu.qc @@ -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 diff --git a/qcsrc/menu/progs.inc b/qcsrc/menu/progs.inc index 9b15d8caa6..ad08af93dd 100644 --- a/qcsrc/menu/progs.inc +++ b/qcsrc/menu/progs.inc @@ -1,5 +1,7 @@ #include +#if XONOTIC + #include "../menu/_mod.inc" #include "anim/_mod.inc" #include "command/_mod.inc" @@ -9,6 +11,8 @@ #include +#endif + #if BUILD_MOD #include "../../mod/menu/progs.inc" #endif diff --git a/qcsrc/menu/xonotic/_mod.inc b/qcsrc/menu/xonotic/_mod.inc index 867f77b840..577c822580 100644 --- a/qcsrc/menu/xonotic/_mod.inc +++ b/qcsrc/menu/xonotic/_mod.inc @@ -79,6 +79,7 @@ #include #include #include +#include #include #include #include diff --git a/qcsrc/menu/xonotic/_mod.qh b/qcsrc/menu/xonotic/_mod.qh index adfefc05d7..b6e34eff24 100644 --- a/qcsrc/menu/xonotic/_mod.qh +++ b/qcsrc/menu/xonotic/_mod.qh @@ -79,6 +79,7 @@ #include #include #include +#include #include #include #include diff --git a/qcsrc/menu/xonotic/dialog_settings_misc.qc b/qcsrc/menu/xonotic/dialog_settings_misc.qc index d951275db1..ede6543e7d 100644 --- a/qcsrc/menu/xonotic/dialog_settings_misc.qc +++ b/qcsrc/menu/xonotic/dialog_settings_misc.qc @@ -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); diff --git a/qcsrc/menu/xonotic/dialog_settings_video.qc b/qcsrc/menu/xonotic/dialog_settings_video.qc index 9320a6ebf2..8ee51fde97 100644 --- a/qcsrc/menu/xonotic/dialog_settings_video.qc +++ b/qcsrc/menu/xonotic/dialog_settings_video.qc @@ -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 index 0000000000..1cd77b0cad --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_uid2name.qc @@ -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 index 0000000000..4bec3d1f9c --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_uid2name.qh @@ -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) diff --git a/qcsrc/menu/xonotic/mainwindow.qc b/qcsrc/menu/xonotic/mainwindow.qc index fb25eebdef..0e071c2e71 100644 --- a/qcsrc/menu/xonotic/mainwindow.qc +++ b/qcsrc/menu/xonotic/mainwindow.qc @@ -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); diff --git a/qcsrc/menu/xonotic/serverlist.qc b/qcsrc/menu/xonotic/serverlist.qc index fc2ba573bb..46506dcfa0 100644 --- a/qcsrc/menu/xonotic/serverlist.qc +++ b/qcsrc/menu/xonotic/serverlist.qc @@ -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); diff --git a/qcsrc/menu/xonotic/slider_resolution.qc b/qcsrc/menu/xonotic/slider_resolution.qc index 762b216f9b..1e0a80b767 100644 --- a/qcsrc/menu/xonotic/slider_resolution.qc +++ b/qcsrc/menu/xonotic/slider_resolution.qc @@ -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) diff --git a/qcsrc/menu/xonotic/util.qc b/qcsrc/menu/xonotic/util.qc index 4d704606d3..a0018b99a9 100644 --- a/qcsrc/menu/xonotic/util.qc +++ b/qcsrc/menu/xonotic/util.qc @@ -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) */ \ /**/ diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index 314858780b..78dfc8062c 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -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; @@ -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; diff --git a/qcsrc/server/bot/bot.qc b/qcsrc/server/bot/bot.qc index f9afb39d8a..8707a03bd4 100644 --- a/qcsrc/server/bot/bot.qc +++ b/qcsrc/server/bot/bot.qc @@ -43,8 +43,8 @@ entity bot_spawn() { currentbots = currentbots + 1; bot_setnameandstuff(bot); - WITHSELF(bot, ClientConnect()); - WITHSELF(bot, PutClientInServer()); + ClientConnect(bot); + PutClientInServer(bot); } return bot; } diff --git a/qcsrc/server/bot/havocbot/havocbot.qc b/qcsrc/server/bot/havocbot/havocbot.qc index f6c0348d28..c3603e9ff1 100644 --- a/qcsrc/server/bot/havocbot/havocbot.qc +++ b/qcsrc/server/bot/havocbot/havocbot.qc @@ -1233,15 +1233,11 @@ float havocbot_moveto(entity this, vector pos) this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_LINKING; // if pos is inside a teleport, then let's mark it as teleport waypoint - entity head; - for(head = NULL; (head = find(head, classname, "trigger_teleport")); ) + FOREACH_ENTITY_CLASS("trigger_teleport", WarpZoneLib_BoxTouchesBrush(pos, pos, it, NULL), { - if(WarpZoneLib_BoxTouchesBrush(pos, pos, head, NULL)) - { - wp.wpflags |= WAYPOINTFLAG_TELEPORT; - this.lastteleporttime = 0; - } - } + wp.wpflags |= WAYPOINTFLAG_TELEPORT; + this.lastteleporttime = 0; + }); /* if(wp.wpflags & WAYPOINTFLAG_TELEPORT) diff --git a/qcsrc/server/bot/scripting.qc b/qcsrc/server/bot/scripting.qc index 3734ad8501..01a1117c9f 100644 --- a/qcsrc/server/bot/scripting.qc +++ b/qcsrc/server/bot/scripting.qc @@ -476,10 +476,9 @@ void bot_list_commands() // Commands code .int bot_exec_status; -void SV_ParseClientCommand(string s); float bot_cmd_cc(entity this) { - WITHSELF(this, SV_ParseClientCommand(bot_cmd.bot_cmd_parm_string)); + SV_ParseClientCommand(this, bot_cmd.bot_cmd_parm_string); return CMD_STATUS_FINISHED; } diff --git a/qcsrc/server/bot/waypoints.qc b/qcsrc/server/bot/waypoints.qc index e8322c2e0c..58bb0b46ba 100644 --- a/qcsrc/server/bot/waypoints.qc +++ b/qcsrc/server/bot/waypoints.qc @@ -17,19 +17,18 @@ // (suitable for spawnfunc_waypoint editor) entity waypoint_spawn(vector m1, vector m2, float f) { - entity w; - w = find(NULL, classname, "waypoint"); - - if (!(f & WAYPOINTFLAG_PERSONAL)) - while (w) + if(!(f & WAYPOINTFLAG_PERSONAL)) { - // if a matching spawnfunc_waypoint already exists, don't add a duplicate - if (boxesoverlap(m1, m2, w.absmin, w.absmax)) - return w; - w = find(w, classname, "waypoint"); + for(entity wp = findchain(classname, "waypoint"); wp; wp = wp.chain) + { + // if a matching spawnfunc_waypoint already exists, don't add a duplicate + if(boxesoverlap(m1, m2, wp.absmin, wp.absmax)) + return wp; + } } + - w = new(waypoint); + entity w = new(waypoint); w.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP; w.wpflags = f; w.solid = SOLID_TRIGGER; @@ -165,7 +164,6 @@ void waypoint_addlink(entity from, entity to) // (SLOW!) void waypoint_think(entity this) { - entity e; vector sv, sm1, sm2, ev, em1, em2, dv; bot_calculate_stepheightvec(); @@ -175,28 +173,28 @@ void waypoint_think(entity this) //dprint("waypoint_think wpisbox = ", ftos(this.wpisbox), "\n"); sm1 = this.origin + this.mins; sm2 = this.origin + this.maxs; - for(e = NULL; (e = find(e, classname, "waypoint")); ) + FOREACH_ENTITY_CLASS("waypoint", true, { - if (boxesoverlap(this.absmin, this.absmax, e.absmin, e.absmax)) + if (boxesoverlap(this.absmin, this.absmax, it.absmin, it.absmax)) { - waypoint_addlink(this, e); - waypoint_addlink(e, this); + waypoint_addlink(this, it); + waypoint_addlink(it, this); } else { ++relink_total; - if(!checkpvs(this.origin, e)) + if(!checkpvs(this.origin, it)) { ++relink_pvsculled; continue; } - sv = e.origin; + sv = it.origin; sv.x = bound(sm1_x, sv.x, sm2_x); sv.y = bound(sm1_y, sv.y, sm2_y); sv.z = bound(sm1_z, sv.z, sm2_z); ev = this.origin; - em1 = e.origin + e.mins; - em2 = e.origin + e.maxs; + em1 = it.origin + it.mins; + em2 = it.origin + it.maxs; ev.x = bound(em1_x, ev.x, em2_x); ev.y = bound(em1_y, ev.y, em2_y); ev.z = bound(em1_z, ev.z, em2_z); @@ -217,27 +215,27 @@ void waypoint_think(entity this) sv = trace_endpos + '0 0 1'; } } - if (!e.wpisbox) + if (!it.wpisbox) { - tracebox(ev - STAT(PL_MIN, NULL).z * '0 0 1', STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), ev, false, e); + tracebox(ev - STAT(PL_MIN, NULL).z * '0 0 1', STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), ev, false, it); if (!trace_startsolid) { //dprint("ev deviation", vtos(trace_endpos - ev), "\n"); ev = trace_endpos + '0 0 1'; } } - //traceline(this.origin, e.origin, false, NULL); + //traceline(this.origin, it.origin, false, NULL); //if (trace_fraction == 1) if (!this.wpisbox && tracewalk(this, sv, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), ev, MOVE_NOMONSTERS)) - waypoint_addlink(this, e); + waypoint_addlink(this, it); else relink_walkculled += 0.5; - if (!e.wpisbox && tracewalk(e, ev, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), sv, MOVE_NOMONSTERS)) - waypoint_addlink(e, this); + if (!it.wpisbox && tracewalk(it, ev, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), sv, MOVE_NOMONSTERS)) + waypoint_addlink(it, this); else relink_walkculled += 0.5; } - } + }); navigation_testtracewalk = 0; this.wplinked = true; } diff --git a/qcsrc/server/cheats.qc b/qcsrc/server/cheats.qc index 9706a2f159..a7cbeae285 100644 --- a/qcsrc/server/cheats.qc +++ b/qcsrc/server/cheats.qc @@ -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 diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index c2a5877761..f375e71f0a 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -55,21 +55,20 @@ STATIC_METHOD(Client, Add, void(Client this, int _team)) { - WITHSELF(this, ClientConnect()); + ClientConnect(this); TRANSMUTE(Player, this); this.frame = 12; // 7 this.team = _team; - WITHSELF(this, PutClientInServer()); + PutClientInServer(this); } void PutObserverInServer(entity this); -void ClientDisconnect(); STATIC_METHOD(Client, Remove, void(Client this)) { TRANSMUTE(Observer, this); - WITHSELF(this, PutClientInServer()); - WITHSELF(this, ClientDisconnect()); + PutClientInServer(this); + ClientDisconnect(this); } void send_CSQC_teamnagger() { @@ -474,8 +473,8 @@ void FixPlayermodel(entity player) /** Called when a client spawns in the server */ -void PutClientInServer() -{ENGINE_EVENT(); +void PutClientInServer(entity this) +{ if (IS_BOT_CLIENT(this)) { TRANSMUTE(Player, this); } else if (IS_REAL_CLIENT(this)) { @@ -497,6 +496,8 @@ void PutClientInServer() 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); @@ -765,8 +766,8 @@ void SetNewParms () SetChangeParms ============= */ -void SetChangeParms () -{ENGINE_EVENT(); +void SetChangeParms (entity this) +{ // save parms for level change parm1 = this.parm_idlesince - time; @@ -813,7 +814,7 @@ void ClientKill_Now_TeamChange(entity this) PutObserverInServer(this); } else - WITHSELF(this, SV_ChangeTeam(this.killindicator_teamchange - 1)); + SV_ChangeTeam(this, this.killindicator_teamchange - 1); this.killindicator_teamchange = 0; } @@ -837,7 +838,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 @@ -887,7 +888,6 @@ void ClientKill_TeamChange (entity this, float targetteam) // 0 = don't change, { float killtime; float starttime; - entity e; if (gameover) return; @@ -930,20 +930,20 @@ void ClientKill_TeamChange (entity this, float targetteam) // 0 = don't change, this.killindicator.count = bound(0, ceil(killtime), 10); //sprint(this, strcat("^1You'll be dead in ", ftos(this.killindicator.cnt), " seconds\n")); - for(e = NULL; (e = find(e, classname, "body")) != NULL; ) + FOREACH_ENTITY_ENT(enemy, this, { - if(e.enemy != this) + if(it.classname != "body") continue; - e.killindicator = spawn(); - e.killindicator.owner = e; - e.killindicator.scale = 0.5; - setattachment(e.killindicator, e, ""); - setorigin(e.killindicator, '0 0 52'); - setthink(e.killindicator, KillIndicator_Think); - e.killindicator.nextthink = starttime + (e.lip) * 0.05; - clientkilltime = max(clientkilltime, e.killindicator.nextthink + 0.05); - e.killindicator.cnt = ceil(killtime); - } + it.killindicator = spawn(); + it.killindicator.owner = it; + it.killindicator.scale = 0.5; + setattachment(it.killindicator, it, ""); + 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); + it.killindicator.cnt = ceil(killtime); + }); this.lip = 0; } } @@ -981,8 +981,8 @@ void ClientKill_TeamChange (entity this, float targetteam) // 0 = don't change, } -void ClientKill () -{ENGINE_EVENT(); +void ClientKill (entity this) +{ if(gameover) return; if(this.player_blocked) return; if(STAT(FROZEN, this)) return; @@ -1051,8 +1051,8 @@ ClientConnect Called when a client connects to the server ============= */ -void ClientConnect() -{ENGINE_EVENT(); +void ClientConnect(entity this) +{ if (Ban_MaybeEnforceBanOnce(this)) return; assert(!IS_CLIENT(this), return); this.flags |= FL_CLIENT; @@ -1207,8 +1207,8 @@ Called when a client disconnects from the server */ .entity chatbubbleentity; void ReadyCount(); -void ClientDisconnect() -{ENGINE_EVENT(); +void ClientDisconnect(entity this) +{ assert(IS_CLIENT(this), return); PlayerStats_GameReport_FinalizePlayer(this); @@ -1337,7 +1337,7 @@ void respawn(entity this) CopyBody(this, 1); this.effects |= EF_NODRAW; // prevent another CopyBody - WITHSELF(this, PutClientInServer()); + PutClientInServer(this); } void play_countdown(entity this, float finished, Sound samp) @@ -1661,7 +1661,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; @@ -1671,12 +1673,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); @@ -1747,14 +1749,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); } @@ -1762,36 +1764,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); } @@ -1841,7 +1842,7 @@ void LeaveSpectatorMode(entity this) Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_PREVENT_JOIN); - WITHSELF(this, PutClientInServer()); + PutClientInServer(this); if(IS_PLAYER(this)) { Send_Notification(NOTIF_ALL, NULL, MSG_INFO, ((teamplay && this.team != -1) ? APP_TEAM_ENT(this, INFO_JOIN_PLAY_TEAM) : INFO_JOIN_PLAY), this.netname); } } @@ -2012,7 +2013,7 @@ void SpectatorThink(entity this) TRANSMUTE(Spectator, this); } else { TRANSMUTE(Observer, this); - WITHSELF(this, PutClientInServer()); + PutClientInServer(this); } this.impulse = 0; } else if(this.impulse == 12 || this.impulse == 16 || this.impulse == 19 || (this.impulse >= 220 && this.impulse <= 229)) { @@ -2021,13 +2022,13 @@ void SpectatorThink(entity this) TRANSMUTE(Spectator, this); } else { TRANSMUTE(Observer, this); - WITHSELF(this, PutClientInServer()); + PutClientInServer(this); } this.impulse = 0; } else if (PHYS_INPUT_BUTTON_ATCK2(this)) { this.flags &= ~FL_JUMPRELEASED; TRANSMUTE(Observer, this); - WITHSELF(this, PutClientInServer()); + PutClientInServer(this); } else { if(!SpectateUpdate(this)) PutObserverInServer(this); @@ -2074,7 +2075,7 @@ void PlayerUseKey(entity this) while(head) // find the closest acceptable target to enter { - if(head.vehicle_flags & VHF_ISVEHICLE) + if(IS_VEHICLE(head)) if(!IS_DEAD(head)) if(!head.owner || ((head.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(head.owner, this))) if(head.takedamage != DAMAGE_NO) @@ -2109,8 +2110,8 @@ Called every frame for each client before the physics are run .float usekeypressed; .float last_vehiclecheck; .int items_added; -void PlayerPreThink () -{ENGINE_EVENT(); +void PlayerPreThink (entity this) +{ WarpZone_PlayerPhysics_FixVAngle(this); STAT(GAMESTARTTIME, this) = game_starttime; @@ -2198,26 +2199,24 @@ void PlayerPreThink () MUTATOR_CALLHOOK(PlayerPreThink, this); - if(autocvar_g_vehicles_enter) - if(time > this.last_vehiclecheck) - if(IS_PLAYER(this)) - if(!gameover) - if(!STAT(FROZEN, this)) - if(!this.vehicle) - if(!IS_DEAD(this)) - { - entity veh; - for(veh = NULL; (veh = findflags(veh, vehicle_flags, VHF_ISVEHICLE)); ) - if(vdist(veh.origin - this.origin, <, autocvar_g_vehicles_enter_radius)) - if(!IS_DEAD(veh)) - if(veh.takedamage != DAMAGE_NO) - if((veh.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(veh.owner, this)) - Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER_GUNNER); - else if(!veh.owner) - if(!veh.team || SAME_TEAM(this, veh)) - 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); + if(autocvar_g_vehicles_enter && (time > this.last_vehiclecheck) && !gameover && !this.vehicle) + if(IS_PLAYER(this) && !STAT(FROZEN, this) && !IS_DEAD(this)) + { + FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_vehicles_enter_radius, IS_VEHICLE(it), + { + if(!IS_DEAD(it) && it.takedamage != DAMAGE_NO) + if((it.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(it.owner, this)) + { + Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER_GUNNER); + } + else if(!it.owner) + { + 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); + } + }); this.last_vehiclecheck = time + 1; } @@ -2261,27 +2260,39 @@ void PlayerPreThink () 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; } } @@ -2411,13 +2422,13 @@ void PlayerPreThink () 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); @@ -2433,10 +2444,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; } @@ -2458,14 +2469,25 @@ Called every frame for each client after the physics are run ============= */ .float idlekick_lasttimeleft; -void PlayerPostThink () -{ENGINE_EVENT(); +void PlayerPostThink (entity 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) { diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index 4c54dddaa6..50ceba3101 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -436,15 +436,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 +494,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 +523,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 diff --git a/qcsrc/server/command/cmd.qc b/qcsrc/server/command/cmd.qc index 2ede443b36..13c883f36b 100644 --- a/qcsrc/server/command/cmd.qc +++ b/qcsrc/server/command/cmd.qc @@ -177,7 +177,7 @@ void ClientCommand_join(entity caller, float request) PlayerScore_Clear(caller); Kill_Notification(NOTIF_ONE_ONLY, caller, MSG_CENTER, CPID_PREVENT_JOIN); Send_Notification(NOTIF_ALL, NULL, MSG_INFO, ((teamplay && caller.team != -1) ? APP_TEAM_ENT(caller, INFO_JOIN_PLAY_TEAM) : INFO_JOIN_PLAY), caller.netname); - WITHSELF(caller, PutClientInServer()); + PutClientInServer(caller); } else { @@ -704,8 +704,8 @@ void ClientCommand_macro_write_aliases(float fh) // ====================================== // If this function exists, server game code parses clientcommand before the engine code gets it. -void SV_ParseClientCommand(string command) -{ENGINE_EVENT(); +void SV_ParseClientCommand(entity this, string command) +{ // If invalid UTF-8, don't even parse it string command2 = ""; float len = strlen(command); diff --git a/qcsrc/server/command/vote.qc b/qcsrc/server/command/vote.qc index 337b428c55..0aa48c2fe7 100644 --- a/qcsrc/server/command/vote.qc +++ b/qcsrc/server/command/vote.qc @@ -378,7 +378,7 @@ void reset_map(bool dorespawn) it.velocity = '0 0 0'; it.avelocity = '0 0 0'; it.movement = '0 0 0'; - WITHSELF(it, PutClientInServer()); + PutClientInServer(it); } } )); diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index 8eea0dc203..df791a6262 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -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) diff --git a/qcsrc/server/g_hook.qc b/qcsrc/server/g_hook.qc index b22a81e042..fd3cd08ecf 100644 --- a/qcsrc/server/g_hook.qc +++ b/qcsrc/server/g_hook.qc @@ -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.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.movetype != MOVETYPE_NONE) { - SetMovetypeFollow(this, other); + SetMovetypeFollow(this, toucher); WarpZone_RefSys_BeginAddingIncrementally(this, this.aiment); } diff --git a/qcsrc/server/g_subs.qc b/qcsrc/server/g_subs.qc index 1b12174b99..dba509b28b 100644 --- a/qcsrc/server/g_subs.qc +++ b/qcsrc/server/g_subs.qc @@ -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; diff --git a/qcsrc/server/g_subs.qh b/qcsrc/server/g_subs.qh index 4f9fc471f5..1f5537cea5 100644 --- a/qcsrc/server/g_subs.qh +++ b/qcsrc/server/g_subs.qh @@ -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); diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 56bc0b34d8..f2eb1d1186 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -1038,7 +1038,7 @@ float Map_Check(float position, float pass) return 0; } else - LOG_TRACE( "Couldn't select '", filename, "'..\n" ); + LOG_DEBUG( "Couldn't select '", filename, "'...\n" ); return 0; } @@ -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); diff --git a/qcsrc/server/item_key.qc b/qcsrc/server/item_key.qc index 317b897b0c..cf2b25acff 100644 --- a/qcsrc/server/item_key.qc +++ b/qcsrc/server/item_key.qc @@ -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; }; diff --git a/qcsrc/server/miscfunctions.qh b/qcsrc/server/miscfunctions.qh index a8304b0e3a..b6ddd3c6a1 100644 --- a/qcsrc/server/miscfunctions.qh +++ b/qcsrc/server/miscfunctions.qh @@ -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"); diff --git a/qcsrc/server/mutators/events.qh b/qcsrc/server/mutators/events.qh index 6fbce15b95..257416538f 100644 --- a/qcsrc/server/mutators/events.qh +++ b/qcsrc/server/mutators/events.qh @@ -656,7 +656,7 @@ MUTATOR_HOOKABLE(SetChangeParms, EV_NO_ARGS); MUTATOR_HOOKABLE(DecodeLevelParms, EV_NO_ARGS); #define EV_GetRecords(i, o) \ - /** page */ i(int, MUTATOR_ARGV_1_int) \ + /** page */ i(int, MUTATOR_ARGV_0_int) \ /** record list */ i(string, MUTATOR_ARGV_1_string) \ /**/ o(string, MUTATOR_ARGV_1_string) \ /**/ diff --git a/qcsrc/server/mutators/mutator/gamemode_assault.qc b/qcsrc/server/mutators/mutator/gamemode_assault.qc index 938cdd748b..20b3b54c04 100644 --- a/qcsrc/server/mutators/mutator/gamemode_assault.qc +++ b/qcsrc/server/mutators/mutator/gamemode_assault.qc @@ -140,18 +140,17 @@ void assault_objective_decrease_use(entity this, entity actor, entity trigger) void assault_setenemytoobjective(entity this) { - entity objective; - for(objective = NULL; (objective = find(objective, targetname, this.target)); ) + FOREACH_ENTITY_STRING(targetname, this.target, { - if(objective.classname == "target_objective") + if(it.classname == "target_objective") { if(this.enemy == NULL) - this.enemy = objective; + this.enemy = it; else objerror(this, "more than one objective as target - fix the map!"); break; } - } + }); if(this.enemy == NULL) objerror(this, "no objective as target - fix the map!"); @@ -167,32 +166,32 @@ bool assault_decreaser_sprite_visible(entity this, entity player, entity view) void target_objective_decrease_activate(entity this) { - entity ent, spr; + entity spr; this.owner = NULL; - for(ent = NULL; (ent = find(ent, target, this.targetname)); ) + FOREACH_ENTITY_STRING(target, this.targetname, { - if(ent.assault_sprite != NULL) + if(it.assault_sprite != NULL) { - WaypointSprite_Disown(ent.assault_sprite, waypointsprite_deadlifetime); - if(ent.classname == "func_assault_destructible") - ent.sprite = NULL; // TODO: just unsetting it?! + WaypointSprite_Disown(it.assault_sprite, waypointsprite_deadlifetime); + if(it.classname == "func_assault_destructible") + it.sprite = NULL; // TODO: just unsetting it?! } - spr = WaypointSprite_SpawnFixed(WP_Assault, 0.5 * (ent.absmin + ent.absmax), ent, assault_sprite, RADARICON_OBJECTIVE); + spr = WaypointSprite_SpawnFixed(WP_Assault, 0.5 * (it.absmin + it.absmax), it, assault_sprite, RADARICON_OBJECTIVE); spr.assault_decreaser = this; spr.waypointsprite_visible_for_player = assault_decreaser_sprite_visible; spr.classname = "sprite_waypoint"; WaypointSprite_UpdateRule(spr, assault_attacker_team, SPRITERULE_TEAMPLAY); - if(ent.classname == "func_assault_destructible") + if(it.classname == "func_assault_destructible") { WaypointSprite_UpdateSprites(spr, WP_AssaultDefend, WP_AssaultDestroy, WP_AssaultDestroy); - WaypointSprite_UpdateMaxHealth(spr, ent.max_health); - WaypointSprite_UpdateHealth(spr, ent.health); - ent.sprite = spr; + WaypointSprite_UpdateMaxHealth(spr, it.max_health); + WaypointSprite_UpdateHealth(spr, it.health); + it.sprite = spr; } else WaypointSprite_UpdateSprites(spr, WP_AssaultDefend, WP_AssaultPush, WP_AssaultPush); - } + }); } void target_objective_decrease_findtarget(entity this) @@ -426,8 +425,9 @@ spawnfunc(target_assault_roundstart) // legacy bot code void havocbot_goalrating_ast_targets(entity this, float ratingscale) { - entity ad, best, wp, tod; - float radius, found, bestvalue; + entity ad, best, wp; + float radius, bestvalue; + bool found; vector p; ad = findchain(classname, "func_assault_destructible"); @@ -441,18 +441,18 @@ void havocbot_goalrating_ast_targets(entity this, float ratingscale) continue; found = false; - for(tod = NULL; (tod = find(tod, targetname, ad.target)); ) + FOREACH_ENTITY_STRING(targetname, ad.target, { - if(tod.classname == "target_objective_decrease") + if(it.classname == "target_objective_decrease") { - if(tod.enemy.health > 0 && tod.enemy.health < ASSAULT_VALUE_INACTIVE) + if(it.enemy.health > 0 && it.enemy.health < ASSAULT_VALUE_INACTIVE) { // dprint(etos(ad),"\n"); found = true; break; } } - } + }); if(!found) { diff --git a/qcsrc/server/mutators/mutator/gamemode_ca.qc b/qcsrc/server/mutators/mutator/gamemode_ca.qc index 901a04f2a7..6e302a1779 100644 --- a/qcsrc/server/mutators/mutator/gamemode_ca.qc +++ b/qcsrc/server/mutators/mutator/gamemode_ca.qc @@ -254,7 +254,7 @@ MUTATOR_HOOKFUNCTION(ca, reset_map_players) { TRANSMUTE(Player, it); it.caplayer = 1; - WITHSELF(it, PutClientInServer()); + PutClientInServer(it); } }); return true; @@ -307,7 +307,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 +340,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 +441,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 +470,8 @@ MUTATOR_HOOKFUNCTION(ca, SpectatePrev) } } + M_ARGV(1, entity) = targ; + return MUT_SPECPREV_FOUND; } diff --git a/qcsrc/server/mutators/mutator/gamemode_ctf.qc b/qcsrc/server/mutators/mutator/gamemode_ctf.qc index 70a2c040bf..b3a06416cd 100644 --- a/qcsrc/server/mutators/mutator/gamemode_ctf.qc +++ b/qcsrc/server/mutators/mutator/gamemode_ctf.qc @@ -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) @@ -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 } @@ -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; } @@ -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; @@ -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); @@ -1987,7 +2025,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 +2059,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)); @@ -2238,14 +2279,13 @@ MUTATOR_HOOKFUNCTION(ctf, VehicleEnter) if(player.flagcarried) { - player.flagcarried.nodrawtoclient = player; // hide the flag from the driver - if(!autocvar_g_ctf_allow_vehicle_carry && !autocvar_g_ctf_allow_vehicle_touch) { ctf_Handle_Throw(player, NULL, DROP_NORMAL); } else { + player.flagcarried.nodrawtoclient = player; // hide the flag from the driver setattachment(player.flagcarried, veh, ""); setorigin(player.flagcarried, VEHICLE_FLAG_OFFSET); player.flagcarried.scale = VEHICLE_FLAG_SCALE; @@ -2561,9 +2601,9 @@ void ctf_SpawnTeam (string teamname, int teamcolor) { entity this = new_pure(ctf_team); this.netname = teamname; - this.cnt = teamcolor; + this.cnt = teamcolor - 1; this.spawnfunc_checked = true; - spawnfunc_ctf_team(this); + this.team = teamcolor; } void ctf_DelayedInit(entity this) // Do this check with a delay so we can wait for teams to be set up. @@ -2584,12 +2624,12 @@ void ctf_DelayedInit(entity this) // Do this check with a delay so we can wait f 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 - 1); - ctf_SpawnTeam("Blue", NUM_TEAM_2 - 1); + ctf_SpawnTeam("Red", NUM_TEAM_1); + ctf_SpawnTeam("Blue", NUM_TEAM_2); if(ctf_teams >= 3) - ctf_SpawnTeam("Yellow", NUM_TEAM_3 - 1); + ctf_SpawnTeam("Yellow", NUM_TEAM_3); if(ctf_teams >= 4) - ctf_SpawnTeam("Pink", NUM_TEAM_4 - 1); + ctf_SpawnTeam("Pink", NUM_TEAM_4); } ctf_ScoreRules(ctf_teams); diff --git a/qcsrc/server/mutators/mutator/gamemode_ctf.qh b/qcsrc/server/mutators/mutator/gamemode_ctf.qh index 95e0bcd424..b4d2459c3e 100644 --- a/qcsrc/server/mutators/mutator/gamemode_ctf.qh +++ b/qcsrc/server/mutators/mutator/gamemode_ctf.qh @@ -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; diff --git a/qcsrc/server/mutators/mutator/gamemode_domination.qc b/qcsrc/server/mutators/mutator/gamemode_domination.qc index 6a217133a7..7acddd32df 100644 --- a/qcsrc/server/mutators/mutator/gamemode_domination.qc +++ b/qcsrc/server/mutators/mutator/gamemode_domination.qc @@ -165,7 +165,6 @@ void dompoint_captured(entity this) WaypointSprite_UpdateSprites(this.sprite, msg, WP_Null, WP_Null); total_pps = 0, pps_red = 0, pps_blue = 0, pps_yellow = 0, pps_pink = 0; - for(head = NULL; (head = find(head, classname, "dom_controlpoint")) != NULL; ) FOREACH_ENTITY_CLASS("dom_controlpoint", true, LAMBDA( if (autocvar_g_domination_point_amt) points = autocvar_g_domination_point_amt; @@ -250,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()) @@ -265,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; @@ -274,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"); @@ -299,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); } @@ -362,16 +361,15 @@ void dom_controlpoint_setup(entity this) float total_controlpoints; void Domination_count_controlpoints() { - entity e; total_controlpoints = redowned = blueowned = yellowowned = pinkowned = 0; - for(e = NULL; (e = find(e, classname, "dom_controlpoint")) != NULL; ) + FOREACH_ENTITY_CLASS("dom_controlpoint", true, { ++total_controlpoints; - redowned += (e.goalentity.team == NUM_TEAM_1); - blueowned += (e.goalentity.team == NUM_TEAM_2); - yellowowned += (e.goalentity.team == NUM_TEAM_3); - pinkowned += (e.goalentity.team == NUM_TEAM_4); - } + redowned += (it.goalentity.team == NUM_TEAM_1); + blueowned += (it.goalentity.team == NUM_TEAM_2); + yellowowned += (it.goalentity.team == NUM_TEAM_3); + pinkowned += (it.goalentity.team == NUM_TEAM_4); + }); } float Domination_GetWinnerTeam() @@ -495,7 +493,7 @@ MUTATOR_HOOKFUNCTION(dom, reset_map_players) { total_pps = 0, pps_red = 0, pps_blue = 0, pps_yellow = 0, pps_pink = 0; FOREACH_CLIENT(IS_PLAYER(it), LAMBDA( - WITHSELF(it, PutClientInServer()); + PutClientInServer(it); if(domination_roundbased) it.player_blocked = 1; if(IS_REAL_CLIENT(it)) diff --git a/qcsrc/server/mutators/mutator/gamemode_freezetag.qc b/qcsrc/server/mutators/mutator/gamemode_freezetag.qc index 6db1db73d4..4f8f0fde7b 100644 --- a/qcsrc/server/mutators/mutator/gamemode_freezetag.qc +++ b/qcsrc/server/mutators/mutator/gamemode_freezetag.qc @@ -464,7 +464,7 @@ MUTATOR_HOOKFUNCTION(ft, reset_map_players) FOREACH_CLIENT(IS_PLAYER(it), LAMBDA( it.killcount = 0; it.freezetag_frozen_timeout = -1; - WITHSELF(it, PutClientInServer()); + PutClientInServer(it); it.freezetag_frozen_timeout = 0; )); freezetag_count_alive_players(); diff --git a/qcsrc/server/mutators/mutator/gamemode_invasion.qc b/qcsrc/server/mutators/mutator/gamemode_invasion.qc index 7c949d8663..9d31506e6d 100644 --- a/qcsrc/server/mutators/mutator/gamemode_invasion.qc +++ b/qcsrc/server/mutators/mutator/gamemode_invasion.qc @@ -112,15 +112,13 @@ float invasion_PickMonster(float supermonster_count) entity invasion_PickSpawn() { - entity e; - RandomSelection_Init(); - for(e = NULL;(e = find(e, classname, "invasion_spawnpoint")); ) + FOREACH_ENTITY_CLASS("invasion_spawnpoint", true, { - RandomSelection_Add(e, 0, string_null, 1, ((time >= e.spawnshieldtime) ? 0.2 : 1)); // give recently used spawnpoints a very low rating - e.spawnshieldtime = time + autocvar_g_invasion_spawnpoint_spawn_delay; - } + RandomSelection_Add(it, 0, string_null, 1, ((time >= it.spawnshieldtime) ? 0.2 : 1)); // give recently used spawnpoints a very low rating + it.spawnshieldtime = time + autocvar_g_invasion_spawnpoint_spawn_delay; + }); return RandomSelection_chosen_ent; } diff --git a/qcsrc/server/mutators/mutator/gamemode_keepaway.qc b/qcsrc/server/mutators/mutator/gamemode_keepaway.qc index 454e2f168f..00cdf0d687 100644 --- a/qcsrc/server/mutators/mutator/gamemode_keepaway.qc +++ b/qcsrc/server/mutators/mutator/gamemode_keepaway.qc @@ -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 { @@ -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,9 +145,9 @@ 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 @@ -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); } @@ -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. diff --git a/qcsrc/server/mutators/mutator/gamemode_keyhunt.qc b/qcsrc/server/mutators/mutator/gamemode_keyhunt.qc index 448a2bbc78..9ac66b5f57 100644 --- a/qcsrc/server/mutators/mutator/gamemode_keyhunt.qc +++ b/qcsrc/server/mutators/mutator/gamemode_keyhunt.qc @@ -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 diff --git a/qcsrc/server/mutators/mutator/gamemode_tdm.qc b/qcsrc/server/mutators/mutator/gamemode_tdm.qc index 7874129085..0d516b2626 100644 --- a/qcsrc/server/mutators/mutator/gamemode_tdm.qc +++ b/qcsrc/server/mutators/mutator/gamemode_tdm.qc @@ -60,11 +60,12 @@ 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) { - entity this = new(tdm_team); + entity this = new_pure(tdm_team); this.netname = teamname; this.cnt = teamcolor; + this.team = this.cnt + 1; this.spawnfunc_checked = true; - spawnfunc_tdm_team(this); + //spawnfunc_tdm_team(this); } void tdm_DelayedInit(entity this) diff --git a/qcsrc/server/playerdemo.qc b/qcsrc/server/playerdemo.qc index 61104ebe2f..9bc0855f5b 100644 --- a/qcsrc/server/playerdemo.qc +++ b/qcsrc/server/playerdemo.qc @@ -147,9 +147,9 @@ float playerdemo_read(entity this) PLAYERDEMO_FIELDS(this, playerdemo_read_) { time = this.playerdemo_time; - WITHSELF(this, PlayerPreThink()); + PlayerPreThink(this); // not running physics though... this is just so we can run weapon stuff - WITHSELF(this, PlayerPostThink()); + PlayerPostThink(this); } this.playerdemo_time = stof(fgets(this.playerdemo_fh)); if(this.playerdemo_time == 0) diff --git a/qcsrc/server/portals.qc b/qcsrc/server/portals.qc index f6502dfd81..6cb569149f 100644 --- a/qcsrc/server/portals.qc +++ b/qcsrc/server/portals.qc @@ -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(other.vehicle_flags & VHF_ISVEHICLE) + 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; } diff --git a/qcsrc/server/progs.inc b/qcsrc/server/progs.inc index 0396dee6cd..163b166744 100644 --- a/qcsrc/server/progs.inc +++ b/qcsrc/server/progs.inc @@ -3,6 +3,9 @@ #endif #include + +#if XONOTIC + #include "_all.qh" #include "../server/_mod.inc" @@ -23,6 +26,10 @@ #include #include +#endif + +#include + #if BUILD_MOD #include "../../mod/server/progs.inc" #endif diff --git a/qcsrc/server/race.qc b/qcsrc/server/race.qc index c4e94cd13d..e32968c56d 100644 --- a/qcsrc/server/race.qc +++ b/qcsrc/server/race.qc @@ -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); } } diff --git a/qcsrc/server/spawnpoints.qc b/qcsrc/server/spawnpoints.qc index f55fb1122a..4be19b879d 100644 --- a/qcsrc/server/spawnpoints.qc +++ b/qcsrc/server/spawnpoints.qc @@ -249,17 +249,15 @@ vector Spawn_Score(entity this, entity spot, float mindist, float teamcheck) vector spawn_score = prio * '1 0 0' + shortest * '0 1 0'; // filter out spots for assault - if(spot.target != "") { - entity ent; - float found; - - found = 0; - for(ent = NULL; (ent = find(ent, targetname, spot.target)); ) + if(spot.target != "") + { + int found = 0; + for(entity targ = findchain(targetname, spot.target); targ; targ = targ.chain) { ++found; - if(ent.spawn_evalfunc) + if(targ.spawn_evalfunc) { - spawn_score = ent.spawn_evalfunc(ent, this, spot, spawn_score); + spawn_score = targ.spawn_evalfunc(targ, this, spot, spawn_score); if(spawn_score.x < 0) return spawn_score; } diff --git a/qcsrc/server/sv_main.qc b/qcsrc/server/sv_main.qc index aac9c497d1..bc68148791 100644 --- a/qcsrc/server/sv_main.qc +++ b/qcsrc/server/sv_main.qc @@ -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); @@ -159,7 +160,7 @@ void StartFrame() { // TODO: if move is more than 50ms, split it into two moves (this matches QWSV behavior and the client prediction) FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), PM_Main(it)); - FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), WITHSELF(it, PlayerPreThink())); + FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), PlayerPreThink(it)); execute_next_frame(); if (autocvar_sv_autopause && !server_is_dedicated) Pause_TryPause(true); @@ -228,7 +229,7 @@ void StartFrame() MUTATOR_CALLHOOK(SV_StartFrame); FOREACH_CLIENT(true, GlobalStats_update(it)); - FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), WITHSELF(it, PlayerPostThink())); + FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), PlayerPostThink(it)); } .vector originjitter; @@ -237,8 +238,8 @@ void StartFrame() .string gametypefilter; .string cvarfilter; bool DoesQ3ARemoveThisEntity(entity this); -void SV_OnEntityPreSpawnFunction() -{ENGINE_EVENT(); +void SV_OnEntityPreSpawnFunction(entity this) +{ __spawnfunc_expecting = true; __spawnfunc_expect = this; if (this) diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index 8709a6aae6..3dda784eb3 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -559,8 +559,8 @@ int JoinBestTeam(entity this, bool only_return_best, bool forcebestteam) } //void() ctf_playerchanged; -void SV_ChangeTeam(float _color) -{ENGINE_EVENT(); +void SV_ChangeTeam(entity this, float _color) +{ float scolor, dcolor, steam, dteam; //, dbotcount, scount, dcount; // in normal deathmatch we can just apply the color and we're done diff --git a/qcsrc/server/teamplay.qh b/qcsrc/server/teamplay.qh index c9713984e8..f34c6d59df 100644 --- a/qcsrc/server/teamplay.qh +++ b/qcsrc/server/teamplay.qh @@ -48,6 +48,5 @@ float FindSmallestTeam(entity pl, float ignore_pl); int JoinBestTeam(entity this, bool only_return_best, bool forcebestteam); //void() ctf_playerchanged; -void SV_ChangeTeam(float _color); void ShufflePlayerOutOfTeam (float source_team); diff --git a/qcsrc/server/weapons/selection.qc b/qcsrc/server/weapons/selection.qc index 70284a8f4b..0288347ee1 100644 --- a/qcsrc/server/weapons/selection.qc +++ b/qcsrc/server/weapons/selection.qc @@ -21,7 +21,7 @@ void Send_WeaponComplain(entity e, float wpn, float type) void Weapon_whereis(Weapon this, entity cl) { if (!autocvar_g_showweaponspawns) return; - for (entity it = NULL; (it = findfloat(it, weapon, this.m_id)); ) + FOREACH_ENTITY_FLOAT(weapon, this.m_id, { if (it.classname == "droppedweapon" && autocvar_g_showweaponspawns < 2) continue; @@ -37,7 +37,7 @@ void Weapon_whereis(Weapon this, entity cl) RADARICON_NONE ); wp.wp_extra = this.m_id; - } + }); } bool client_hasweapon(entity this, Weapon wpn, float andammo, bool complain) diff --git a/qcsrc/server/weapons/weaponsystem.qc b/qcsrc/server/weapons/weaponsystem.qc index 21057e4a0b..32e9a56702 100644 --- a/qcsrc/server/weapons/weaponsystem.qc +++ b/qcsrc/server/weapons/weaponsystem.qc @@ -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; } @@ -214,8 +214,13 @@ bool weapon_prepareattack_checkammo(Weapon thiswep, entity actor, bool secondary if (ammo) return true; // always keep the Mine Layer if we placed mines, so that we can detonate them if (thiswep == WEP_MINE_LAYER) - for (entity mine; (mine = find(mine, classname, "mine")); ) - if (mine.owner == actor) return false; + { + FOREACH_ENTITY_ENT(owner, actor, + { + if(it.classname != "mine") continue; + if(it.owner == actor) return false; + }); + } if (thiswep == WEP_SHOTGUN) if (!secondary && WEP_CVAR(shotgun, secondary) == 1) return false; // no clicking, just allow @@ -403,6 +408,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; diff --git a/qcsrc/tools/compilationunits.sh b/qcsrc/tools/compilationunits.sh index 3c794e93fb..2fa17825ec 100755 --- a/qcsrc/tools/compilationunits.sh +++ b/qcsrc/tools/compilationunits.sh @@ -1,6 +1,6 @@ -#!/bin/bash +#!/usr/bin/env bash set -eu -cd "$(dirname "$0")" +cd ${0%/*} WORKDIR=../.tmp @@ -9,6 +9,7 @@ CPP="cc -xc -E" declare -a QCCDEFS=( -DNDEBUG=1 + -DXONOTIC=1 -DWATERMARK="\"$(git describe --tags --dirty='~')\"" -DDEBUGPATHING=0 ) diff --git a/qcsrc/tools/genmod.sh b/qcsrc/tools/genmod.sh index b4c4fc3048..2c34e67134 100755 --- a/qcsrc/tools/genmod.sh +++ b/qcsrc/tools/genmod.sh @@ -1,6 +1,6 @@ -#!/bin/bash +#!/usr/bin/env bash set -eu -cd "$(dirname "$0")" +cd ${0%/*} cd .. ROOT=$PWD/ @@ -32,6 +32,7 @@ function genmod() { (cd lib; genmod) (cd common; genmod) +(cd ecs; genmod) (cd client; genmod) (cd server; genmod) (cd menu; genmod) diff --git a/qcsrc/tools/headerstyle.sh b/qcsrc/tools/headerstyle.sh index ef17315926..b638927bf4 100755 --- a/qcsrc/tools/headerstyle.sh +++ b/qcsrc/tools/headerstyle.sh @@ -24,7 +24,7 @@ function check() { include="#include \"${include}\"" startswith "$file" "$include" done - find "$base" -type f -name '*.qh' -print0 | sort -z | while read -r -d '' file; do + find "$base" -type f -name '*.qh' -a \! -name '_mod.qh' -print0 | sort -z | while read -r -d '' file; do echo "$file" startswith "$file" "#pragma once" done diff --git a/scripts/fireball.shader b/scripts/fireball.shader index 822be77f72..8df3e2a558 100644 --- a/scripts/fireball.shader +++ b/scripts/fireball.shader @@ -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 + } } diff --git a/scripts/luma.shader b/scripts/luma.shader index ab2d0c6112..b6ee3cd8ae 100644 --- a/scripts/luma.shader +++ b/scripts/luma.shader @@ -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 + } +} diff --git a/scripts/player_gak.shader b/scripts/player_gak.shader index 858a758c6e..7341757972 100644 --- a/scripts/player_gak.shader +++ b/scripts/player_gak.shader @@ -6,6 +6,14 @@ gak rgbgen lightingDiffuse } } +gakfullbright +{ + dpreflectcube cubemaps/default/sky + { + map textures/gakfullbright.tga + rgbgen lightingDiffuse + } +} gakarmor { @@ -15,3 +23,11 @@ gakarmor rgbgen lightingDiffuse } } +gakarmorfb +{ + dpreflectcube cubemaps/default/sky + { + map textures/gakarmorfb.tga + rgbgen lightingDiffuse + } +} diff --git a/scripts/player_ignis.shader b/scripts/player_ignis.shader index 5a14f12ee6..23d1329516 100644 --- a/scripts/player_ignis.shader +++ b/scripts/player_ignis.shader @@ -6,6 +6,14 @@ ignis rgbgen lightingDiffuse } } +ignisfullbright +{ + dpreflectcube cubemaps/default/sky + { + map textures/ignisfullbright.tga + rgbgen lightingDiffuse + } +} ignishead { diff --git a/scripts/player_nyx.shader b/scripts/player_nyx.shader index 0f21b09f00..e7df7ec30c 100644 --- a/scripts/player_nyx.shader +++ b/scripts/player_nyx.shader @@ -6,4 +6,12 @@ nyx rgbgen lightingDiffuse } } +nyxfullbright +{ + dpreflectcube cubemaps/default/sky + { + map textures/nyxfullbright.tga + rgbgen lightingDiffuse + } +} diff --git a/scripts/player_pyria.shader b/scripts/player_pyria.shader index 49a54c6bee..3d8e1dd237 100644 --- a/scripts/player_pyria.shader +++ b/scripts/player_pyria.shader @@ -6,6 +6,14 @@ pyria rgbgen lightingDiffuse } } +pyriafullbright +{ + dpreflectcube cubemaps/default/sky + { + map textures/pyriafullbright.tga + rgbgen lightingDiffuse + } +} pyriahair { diff --git a/scripts/player_umbra.shader b/scripts/player_umbra.shader index 3f4b5ed1b8..be722a123d 100644 --- a/scripts/player_umbra.shader +++ b/scripts/player_umbra.shader @@ -6,4 +6,12 @@ umbra rgbgen lightingDiffuse } } +umbrafullbright +{ + dpreflectcube cubemaps/default/sky + { + map textures/umbrafullbright.tga + rgbgen lightingDiffuse + } +} diff --git a/scripts/simpleitems.shader b/scripts/simpleitems.shader index 92e9e5affd..3a7d11eafe 100644 --- a/scripts/simpleitems.shader +++ b/scripts/simpleitems.shader @@ -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 ///// diff --git a/textures/fireball.tga b/textures/fireball.tga index 53b47a192c..c631e8c880 100644 Binary files a/textures/fireball.tga and b/textures/fireball.tga differ diff --git a/textures/fireball_gloss.tga b/textures/fireball_gloss.tga index 8cd8b25bdc..eaf50d0a2e 100644 Binary files a/textures/fireball_gloss.tga and b/textures/fireball_gloss.tga differ diff --git a/textures/fireball_glow.tga b/textures/fireball_glow.tga index c949f92a47..358784d8fd 100644 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 index 0000000000..b0bd3f93cc 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 index 0000000000..2fbc09a4ed 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 index 0000000000..3d93916836 Binary files /dev/null and b/textures/fireball_shirt.tga differ diff --git a/textures/gakarmorfb.tga b/textures/gakarmorfb.tga new file mode 100644 index 0000000000..b570c017d8 Binary files /dev/null and b/textures/gakarmorfb.tga differ diff --git a/textures/gakarmorfb_gloss.tga b/textures/gakarmorfb_gloss.tga new file mode 100644 index 0000000000..137f0e59da Binary files /dev/null and b/textures/gakarmorfb_gloss.tga differ diff --git a/textures/gakarmorfb_glow.tga b/textures/gakarmorfb_glow.tga new file mode 100644 index 0000000000..e506ce05fd Binary files /dev/null and b/textures/gakarmorfb_glow.tga differ diff --git a/textures/gakarmorfb_norm.tga b/textures/gakarmorfb_norm.tga new file mode 100644 index 0000000000..910c453417 Binary files /dev/null and b/textures/gakarmorfb_norm.tga differ diff --git a/textures/gakarmorfb_reflect.tga b/textures/gakarmorfb_reflect.tga new file mode 100644 index 0000000000..c486aeddb3 Binary files /dev/null and b/textures/gakarmorfb_reflect.tga differ diff --git a/textures/gakarmorfb_shirt.tga b/textures/gakarmorfb_shirt.tga new file mode 100644 index 0000000000..ce4b6d6d3f Binary files /dev/null and b/textures/gakarmorfb_shirt.tga differ diff --git a/textures/gakfullbright.tga b/textures/gakfullbright.tga new file mode 100644 index 0000000000..7a6075fbda Binary files /dev/null and b/textures/gakfullbright.tga differ diff --git a/textures/gakfullbright_gloss.tga b/textures/gakfullbright_gloss.tga new file mode 100644 index 0000000000..43f9d42961 Binary files /dev/null and b/textures/gakfullbright_gloss.tga differ diff --git a/textures/gakfullbright_glow.tga b/textures/gakfullbright_glow.tga new file mode 100644 index 0000000000..edd50b1be4 Binary files /dev/null and b/textures/gakfullbright_glow.tga differ diff --git a/textures/gakfullbright_norm.tga b/textures/gakfullbright_norm.tga new file mode 100644 index 0000000000..0df3a07e7e Binary files /dev/null and b/textures/gakfullbright_norm.tga differ diff --git a/textures/gakfullbright_reflect.tga b/textures/gakfullbright_reflect.tga new file mode 100644 index 0000000000..1f9ed2f11d Binary files /dev/null and b/textures/gakfullbright_reflect.tga differ diff --git a/textures/gakfullbright_shirt.tga b/textures/gakfullbright_shirt.tga new file mode 100644 index 0000000000..4f9d05336f Binary files /dev/null and b/textures/gakfullbright_shirt.tga differ diff --git a/textures/ignisfullbright.tga b/textures/ignisfullbright.tga new file mode 100644 index 0000000000..768ac88967 Binary files /dev/null and b/textures/ignisfullbright.tga differ diff --git a/textures/ignisfullbright_gloss.tga b/textures/ignisfullbright_gloss.tga new file mode 100644 index 0000000000..ec7185d74f Binary files /dev/null and b/textures/ignisfullbright_gloss.tga differ diff --git a/textures/ignisfullbright_glow.tga b/textures/ignisfullbright_glow.tga new file mode 100644 index 0000000000..a010bdf3e9 Binary files /dev/null and b/textures/ignisfullbright_glow.tga differ diff --git a/textures/ignisfullbright_norm.tga b/textures/ignisfullbright_norm.tga new file mode 100644 index 0000000000..fd7695ef90 Binary files /dev/null and b/textures/ignisfullbright_norm.tga differ diff --git a/textures/ignisfullbright_reflect.tga b/textures/ignisfullbright_reflect.tga new file mode 100644 index 0000000000..df8e31d552 Binary files /dev/null and b/textures/ignisfullbright_reflect.tga differ diff --git a/textures/ignisfullbright_shirt.tga b/textures/ignisfullbright_shirt.tga new file mode 100644 index 0000000000..0a2f7fac55 Binary files /dev/null and b/textures/ignisfullbright_shirt.tga differ diff --git a/textures/items/a_rocket_bottom.jpg b/textures/items/a_rocket_bottom.jpg new file mode 100644 index 0000000000..b2db59520c Binary files /dev/null and b/textures/items/a_rocket_bottom.jpg differ diff --git a/textures/nyxfullbright.tga b/textures/nyxfullbright.tga new file mode 100644 index 0000000000..8169f3779f Binary files /dev/null and b/textures/nyxfullbright.tga differ diff --git a/textures/nyxfullbright_gloss.tga b/textures/nyxfullbright_gloss.tga new file mode 100644 index 0000000000..6b53f91cfe Binary files /dev/null and b/textures/nyxfullbright_gloss.tga differ diff --git a/textures/nyxfullbright_glow.tga b/textures/nyxfullbright_glow.tga new file mode 100644 index 0000000000..a91959d366 Binary files /dev/null and b/textures/nyxfullbright_glow.tga differ diff --git a/textures/nyxfullbright_norm.tga b/textures/nyxfullbright_norm.tga new file mode 100644 index 0000000000..a27d97436b Binary files /dev/null and b/textures/nyxfullbright_norm.tga differ diff --git a/textures/nyxfullbright_reflect.tga b/textures/nyxfullbright_reflect.tga new file mode 100644 index 0000000000..e825195ef5 Binary files /dev/null and b/textures/nyxfullbright_reflect.tga differ diff --git a/textures/nyxfullbright_shirt.tga b/textures/nyxfullbright_shirt.tga new file mode 100644 index 0000000000..364bae2d9a Binary files /dev/null and b/textures/nyxfullbright_shirt.tga differ diff --git a/textures/pyriafullbright.tga b/textures/pyriafullbright.tga new file mode 100644 index 0000000000..b659f62fcd Binary files /dev/null and b/textures/pyriafullbright.tga differ diff --git a/textures/pyriafullbright_gloss.jpg b/textures/pyriafullbright_gloss.jpg new file mode 100644 index 0000000000..8cd77a771f Binary files /dev/null and b/textures/pyriafullbright_gloss.jpg differ diff --git a/textures/pyriafullbright_glow.tga b/textures/pyriafullbright_glow.tga new file mode 100644 index 0000000000..ef6f686c6c Binary files /dev/null and b/textures/pyriafullbright_glow.tga differ diff --git a/textures/pyriafullbright_norm.tga b/textures/pyriafullbright_norm.tga new file mode 100644 index 0000000000..4301faa783 Binary files /dev/null and b/textures/pyriafullbright_norm.tga differ diff --git a/textures/pyriafullbright_reflect.jpg b/textures/pyriafullbright_reflect.jpg new file mode 100644 index 0000000000..219469cb38 Binary files /dev/null and b/textures/pyriafullbright_reflect.jpg differ diff --git a/textures/pyriafullbright_shirt.tga b/textures/pyriafullbright_shirt.tga new file mode 100644 index 0000000000..62ca44604f Binary files /dev/null and b/textures/pyriafullbright_shirt.tga differ diff --git a/textures/umbrafullbright.tga b/textures/umbrafullbright.tga new file mode 100644 index 0000000000..390882aa81 Binary files /dev/null and b/textures/umbrafullbright.tga differ diff --git a/textures/umbrafullbright_gloss.jpg b/textures/umbrafullbright_gloss.jpg new file mode 100644 index 0000000000..116ebbd04b Binary files /dev/null and b/textures/umbrafullbright_gloss.jpg differ diff --git a/textures/umbrafullbright_glow.tga b/textures/umbrafullbright_glow.tga new file mode 100644 index 0000000000..4924c2a988 Binary files /dev/null and b/textures/umbrafullbright_glow.tga differ diff --git a/textures/umbrafullbright_norm.tga b/textures/umbrafullbright_norm.tga new file mode 100644 index 0000000000..d5f9d8b2fb Binary files /dev/null and b/textures/umbrafullbright_norm.tga differ diff --git a/textures/umbrafullbright_reflect.jpg b/textures/umbrafullbright_reflect.jpg new file mode 100644 index 0000000000..c1fa10ec13 Binary files /dev/null and b/textures/umbrafullbright_reflect.jpg differ diff --git a/textures/umbrafullbright_shirt.tga b/textures/umbrafullbright_shirt.tga new file mode 100644 index 0000000000..8d04c364cc Binary files /dev/null and b/textures/umbrafullbright_shirt.tga differ